aboutsummaryrefslogtreecommitdiff
path: root/generate.go
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-08-30 19:29:38 +0200
committerHimbeer <himbeer@disroot.org>2024-08-30 19:29:38 +0200
commit358edcaaeadfe632ff9a3a0479b11785c9ca2466 (patch)
tree1005e1c959c1d1970df07de181c1a8db2653df70 /generate.go
parent56ccd1992d5a0e420200b36e394f9ee39458e9eb (diff)
Add redeclaration checks for functions and locals
Closes #1.
Diffstat (limited to 'generate.go')
-rw-r--r--generate.go26
1 files changed, 26 insertions, 0 deletions
diff --git a/generate.go b/generate.go
index 3fa09f7..511ce05 100644
--- a/generate.go
+++ b/generate.go
@@ -11,6 +11,8 @@ import (
"strings"
)
+var currentFunc string
+
var funcRegIndex int
func allocReg() string {
@@ -61,6 +63,7 @@ func generate(root *rootExpr, w io.Writer, errs chan<- error) {
for _, toplevel := range root.toplevels {
if err := generateToplevel(toplevel, w); err != nil {
errs <- err
+ select {}
}
}
@@ -77,8 +80,19 @@ func generateToplevel(toplevel expression, w io.Writer) error {
}
func generateFunction(function *functionExpr, w io.Writer) error {
+ if isDeclared(function.name, true) {
+ return errAlreadyDeclared{name: function.name, line: function.line()}
+ }
+
resetRegs()
+ currentFunc = function.name
+ defer func() { currentFunc = "" }()
+
+ funcs[currentFunc] = struct{}{}
+ localConsts[currentFunc] = map[string]string{}
+ localMuts[currentFunc] = map[string]struct{}{}
+
if function.link != defaultLinkage {
fmt.Fprintf(w, "%s ", function.link)
}
@@ -129,21 +143,33 @@ func generateReturnStmt(stmt *returnStmt, w io.Writer) error {
}
func generateConstStmt(stmt *constStmt, toplevel bool, w io.Writer) error {
+ if isDeclared(stmt.name, toplevel) {
+ return errAlreadyDeclared{name: stmt.name, line: stmt.line()}
+ }
+
value, err := stmt.initial.generate(w)
if err != nil {
return err
}
+ localConsts[currentFunc][stmt.name] = value
+
fmt.Fprintf(w, "%%%s =w add %s, 0\n", stmt.name, value)
return nil
}
func generateMutStmt(stmt *mutStmt, toplevel bool, w io.Writer) error {
+ if isDeclared(stmt.name, toplevel) {
+ return errAlreadyDeclared{name: stmt.name, line: stmt.line()}
+ }
+
value, err := stmt.initial.generate(w)
if err != nil {
return err
}
+ localMuts[currentFunc][stmt.name] = struct{}{}
+
fmt.Fprintf(w, "%%%s =l alloc4 4\n", stmt.name)
fmt.Fprintf(w, "storew %s, %%%s\n", value, stmt.name)
return nil