package main import ( _ "embed" "flag" "fmt" "html/template" "jinx/pkg/lang/compiler" "jinx/pkg/lang/parser" "jinx/pkg/lang/scanner" "jinx/pkg/lang/vm/code" "os" ) //go:embed compiled.tmpl var compiledTemplateString string type compiledTemplateInfo struct { Module string Globals []string Bytes string } func main() { flag.Parse() moduleName := flag.Arg(0) if moduleName == "" { exit("no module specified") } moduleSourcePath := fmt.Sprintf("pkg/lang/modules/%s/%s.lang", moduleName, moduleName) moduleOutputPath := fmt.Sprintf("pkg/lang/modules/%s/compiled.go", moduleName) sourceFile, err := os.Open(moduleSourcePath) if err != nil { exit("could not open file: %v", err) } defer sourceFile.Close() scanner := scanner.New(sourceFile) tokens, err := scanner.Scan() if err != nil { exit("error during scanning: %v", err) } parser := parser.New(tokens) program, err := parser.Parse() if err != nil { exit("error during parsing: %v", err) } comp := compiler.New(moduleName, "", program) module, err := comp.Compile() if err != nil { exit("compilation failed: %v", err) } code := turnCodeIntoBytes(module.Code().Code()) info := compiledTemplateInfo{ Module: module.Name(), Globals: module.Globals(), Bytes: code, } compiledTemplate, err := template.New("compiled").Parse(compiledTemplateString) if err != nil { exit("could not parse template: %v", err) } outputFile, err := os.Create(moduleOutputPath) if err != nil { exit("could not create file: %v", err) } if err := compiledTemplate.Execute(outputFile, info); err != nil { exit("could not write to file: %v", err) } } func turnCodeIntoBytes(code code.Raw) string { var result string for _, b := range []byte(code) { result += fmt.Sprintf("0x%x, ", b) } return result } func exit(format string, args ...any) { message := fmt.Sprintf(format, args...) fmt.Printf("error: %s\n", message) os.Exit(1) }