about summary refs log tree commit diff
path: root/pkg/lang/compiler/compiler.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/lang/compiler/compiler.go')
-rw-r--r--pkg/lang/compiler/compiler.go57
1 files changed, 16 insertions, 41 deletions
diff --git a/pkg/lang/compiler/compiler.go b/pkg/lang/compiler/compiler.go
index e446dd6..0424862 100644
--- a/pkg/lang/compiler/compiler.go
+++ b/pkg/lang/compiler/compiler.go
@@ -24,15 +24,6 @@ func New(ast ast.Program) *Compiler {
 }
 
 func (comp *Compiler) Compile() (code.Code, error) {
-	// Pre-declare all top-level functions
-	for _, stmt := range comp.ast.Stmts {
-		if stmt.Kind == ast.StmtKindFnDecl {
-			if err := comp.preDeclareFunction(stmt.Value.(ast.StmtFnDecl)); err != nil {
-				return code.Code{}, err
-			}
-		}
-	}
-
 	target := code.NewBuilder()
 
 	for _, stmt := range comp.ast.Stmts {
@@ -50,14 +41,6 @@ func (comp *Compiler) Compile() (code.Code, error) {
 	return target.Build()
 }
 
-func (comp *Compiler) preDeclareFunction(fnDeclStmt ast.StmtFnDecl) error {
-	if _, ok := comp.scopes.DeclareFunction(fnDeclStmt.Name.Value, uint(len(fnDeclStmt.Args))); !ok {
-		return fmt.Errorf("function %s already declared", fnDeclStmt.Name.Value)
-	}
-
-	return nil
-}
-
 func (comp *Compiler) compileStmt(t *code.Builder, stmt ast.Stmt) error {
 	var err error
 	switch stmt.Kind {
@@ -106,23 +89,13 @@ func (comp *Compiler) compileStmt(t *code.Builder, stmt ast.Stmt) error {
 }
 
 func (comp *Compiler) compileFnDeclStmt(t *code.Builder, fnDeclStmt ast.StmtFnDecl) error {
-	marker, ok := comp.scopes.DeclareFunction(fnDeclStmt.Name.Value, uint(len(fnDeclStmt.Args)))
+	_, ok := comp.scopes.Declare(fnDeclStmt.Name.Value)
 	if !ok {
-		// If we are in the root scope, the function was simply predeclared :)
-		if comp.scopes.IsRootScope() {
-			symbolID, ok := comp.scopes.Lookup(fnDeclStmt.Name.Value)
-			if !ok {
-				panic("function said it was declared but apparently it was lying")
-			}
-
-			symbol := comp.scopes.GetFunction(symbolID)
-
-			marker = symbol.Data().Marker()
-		} else {
-			return fmt.Errorf("function %s already declared", fnDeclStmt.Name.Value)
-		}
+		return fmt.Errorf("function %s already declared", fnDeclStmt.Name.Value)
 	}
 
+	marker := comp.scopes.CreateFunctionSubUnit(fnDeclStmt.Name.Value)
+
 	functionTarget := code.NewBuilder()
 
 	functionTarget.PutMarker(marker)
@@ -144,6 +117,18 @@ func (comp *Compiler) compileFnDeclStmt(t *code.Builder, fnDeclStmt ast.StmtFnDe
 
 	comp.funcs = append(comp.funcs, &functionTarget)
 
+	// Put the function value on the stack
+
+	t.AppendOp(code.OpPushFunction)
+	t.AppendMarkerReference(marker)
+
+	if len(fnDeclStmt.Args) != 0 {
+		t.AppendOp(code.OpSetArgCount)
+		t.AppendInt(int64(len(fnDeclStmt.Args)))
+	}
+
+	// TODO: Attach the function environment
+
 	return nil
 }
 
@@ -654,16 +639,6 @@ func (comp *Compiler) compileIdentExpr(t *code.Builder, expr ast.ExprIdent) erro
 
 		t.AppendOp(code.OpGetLocal)
 		t.AppendInt(int64(symbol.Data().LocalIndex()))
-	case scope.SymbolKindFunction:
-		symbol := comp.scopes.GetFunction(symbolId)
-
-		t.AppendOp(code.OpPushFunction)
-		t.AppendMarkerReference(symbol.Data().Marker())
-
-		if symbol.Data().Args() != 0 {
-			t.AppendOp(code.OpSetArgCount)
-			t.AppendInt(int64(symbol.Data().Args()))
-		}
 	default:
 		panic(fmt.Errorf("unknown symbol kind: %v", symbolId.SymbolKind()))
 	}