diff options
author | Himbeer <himbeer@disroot.org> | 2024-08-30 09:17:43 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-08-30 09:17:43 +0200 |
commit | 3adfc2d52c29fd90257813f33b8286225f7adc04 (patch) | |
tree | 39e4d064af273fc1fc1e271a4f4a135a4227e102 /generate.go |
Initial commit
Diffstat (limited to 'generate.go')
-rw-r--r-- | generate.go | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/generate.go b/generate.go new file mode 100644 index 0000000..75da82e --- /dev/null +++ b/generate.go @@ -0,0 +1,85 @@ +package main + +import ( + "fmt" + "io" +) + +type invalidToplevel struct { + got expression +} + +func (i invalidToplevel) Error() string { + return fmt.Sprintf("%d: expected top-level declaration, got %s", i.got.line(), i.got) +} + +func generate(root *rootExpr, w io.Writer, errs chan<- error) { + defer wg.Done() + + for _, toplevel := range root.toplevels { + if err := generateToplevel(toplevel, w); err != nil { + errs <- err + } + } +} + +func generateToplevel(toplevel expression, w io.Writer) error { + switch expr := toplevel.(type) { + case *functionExpr: + return generateFunction(expr, w) + } + + return invalidToplevel{got: toplevel} +} + +func generateFunction(function *functionExpr, w io.Writer) error { + if function.link != defaultLinkage { + fmt.Fprintf(w, "%s ", function.link) + } + + fmt.Fprintf(w, "function %s $%s", function.returnType, function.name) + fmt.Fprintf(w, "(%s) {\n", function.params) + fmt.Fprintln(w, "@start") + if err := generateBlock(function.blk, w); err != nil { + return err + } + fmt.Fprintf(w, "}\n") + + return nil +} + +func generateBlock(blk *blockExpr, w io.Writer) error { + for _, stmt := range blk.stmts { + if err := generateStatement(stmt, w); err != nil { + return err + } + } + + return nil +} + +func generateStatement(stmt statementExpr, w io.Writer) error { + switch s := stmt.(type) { + case *returnStmt: + return generateReturnStmt(s, w) + } + + return nil +} + +func generateReturnStmt(stmt *returnStmt, w io.Writer) error { + eq := stmt.value.(*equalityExpr) + cmp := eq.lhs + trm := cmp.lhs + num := trm.lhs + fct := num.lhs + un := fct.lhs + prm := un.value + lit := prm.(literalExpr) + n := lit.(*numberExpr) + value := n.s + + fmt.Fprintln(w, "ret", value) + + return nil +} |