From bdf7ea85d39b565e7e82d373e57b86350eb3c36f Mon Sep 17 00:00:00 2001 From: Luke Wilson Date: Tue, 20 May 2025 19:20:16 -0500 Subject: [PATCH] Hello, world! --- Makefile | 2 ++ internal/main.go | 92 +++++++++++++++++++++++++++++++++++++++++++++++ programs/hello.go | 5 +++ 3 files changed, 99 insertions(+) create mode 100644 Makefile create mode 100644 internal/main.go create mode 100644 programs/hello.go diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..47f5f42 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +run: + go run internal/main.go -o hello.zig programs/hello.go \ No newline at end of file diff --git a/internal/main.go b/internal/main.go new file mode 100644 index 0000000..ff45b38 --- /dev/null +++ b/internal/main.go @@ -0,0 +1,92 @@ +package main + +import ( + "flag" + "fmt" + "go/ast" + "go/parser" + "go/token" + "os" + "strings" +) + +var ( + outputFilepath *string = flag.String("o", "out.zig", "Zig output filename") +) + +func init() { + flag.Parse() +} + +func main() { + inputFilepaths := flag.Args() + + if len(inputFilepaths) > 1 { + panic("Only support one file!") + } else if len(inputFilepaths) < 1 { + panic("Must supply one input file") + } + + inputFilepath := inputFilepaths[0] + + fset := token.NewFileSet() + + f, err := parser.ParseFile(fset, inputFilepath, nil, parser.AllErrors) + if err != nil { + panic(err) + } + + output, err := generate(f) + if err != nil { + panic(err) + } + outputFile, err := os.Create(*outputFilepath) + if err != nil { + panic(err) + } + _, err = outputFile.WriteString(output) + if err != nil { + panic(err) + } + fmt.Printf("%v:\n", *outputFilepath) + fmt.Println("--------------------") + fmt.Println(output) +} + +func generate(f *ast.File) (string, error) { + sb := new(strings.Builder) + + def := f.Decls[0].(*ast.FuncDecl) + + if def.Name.Name != "main" { + return "", fmt.Errorf("must have main") + } + + sb.WriteString(`const std = @import("std");`) + sb.WriteString("\npub fn main() void {\n") + + stmt := def.Body.List[0].(*ast.ExprStmt) + call := stmt.X.(*ast.CallExpr) + fn := call.Fun.(*ast.Ident) + + if fn.Name == "print" { + sb.WriteString(fmt.Sprintf(`std.debug.print(`)) + + args := call.Args + for _, arg := range args { + if s, ok := arg.(*ast.BasicLit); ok { + sb.WriteString(fmt.Sprintf("%s", s.Value)) + } else { + panic("WTF") + } + } + + sb.WriteString(", .{});\n") + } else { + return "", fmt.Errorf("expected printf") + } + + sb.WriteString("}\n") + + return sb.String(), nil +} diff --git a/programs/hello.go b/programs/hello.go new file mode 100644 index 0000000..fdc7ec1 --- /dev/null +++ b/programs/hello.go @@ -0,0 +1,5 @@ +package main + +func main() { + print("Hello, world\n") +}