aboutsummaryrefslogtreecommitdiff
path: root/generate.go
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-08-30 09:17:43 +0200
committerHimbeer <himbeer@disroot.org>2024-08-30 09:17:43 +0200
commit3adfc2d52c29fd90257813f33b8286225f7adc04 (patch)
tree39e4d064af273fc1fc1e271a4f4a135a4227e102 /generate.go
Initial commit
Diffstat (limited to 'generate.go')
-rw-r--r--generate.go85
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
+}