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.go41
1 files changed, 30 insertions, 11 deletions
diff --git a/pkg/lang/compiler/compiler.go b/pkg/lang/compiler/compiler.go
index 0424862..5e2a645 100644
--- a/pkg/lang/compiler/compiler.go
+++ b/pkg/lang/compiler/compiler.go
@@ -112,8 +112,8 @@ func (comp *Compiler) compileFnDeclStmt(t *code.Builder, fnDeclStmt ast.StmtFnDe
 		return err
 	}
 
-	// Function declaration scopes do not pollute stack
-	_ = comp.scopes.Exit()
+	fnScope := comp.scopes.CurrentFunction()
+	_ = comp.scopes.Exit() // Function declaration scopes do not pollute stack
 
 	comp.funcs = append(comp.funcs, &functionTarget)
 
@@ -127,7 +127,15 @@ func (comp *Compiler) compileFnDeclStmt(t *code.Builder, fnDeclStmt ast.StmtFnDe
 		t.AppendInt(int64(len(fnDeclStmt.Args)))
 	}
 
-	// TODO: Attach the function environment
+	for _, outsideSymbol := range fnScope.OutsideSymbolsInEnv() {
+		// TODO: Implement env inheritance
+		if comp.scopes.CurrentFunction().ID() != outsideSymbol.ScopeID() {
+			panic("env inheritance not implemented")
+		}
+
+		t.AppendOp(code.OpAddToEnv)
+		t.AppendInt(int64(outsideSymbol.IndexInScope()))
+	}
 
 	return nil
 }
@@ -537,18 +545,24 @@ func (comp *Compiler) compileAssignExpr(t *code.Builder, expr ast.ExprBinary) er
 		return fmt.Errorf("variable %s not declared", name)
 	}
 
-	if symbolId.SymbolKind() != scope.SymbolKindVariable {
-		return fmt.Errorf("can't assign to a %v", symbolId.SymbolKind())
-	}
-
-	symbol := comp.scopes.GetVariable(symbolId)
-
 	if err := comp.compileExpr(t, expr.Right); err != nil {
 		return err
 	}
 
-	t.AppendOp(code.OpSetLocal)
-	t.AppendInt(int64(symbol.Data().LocalIndex()))
+	switch symbolId.SymbolKind() {
+	case scope.SymbolKindVariable:
+		symbol := comp.scopes.GetVariable(symbolId)
+
+		t.AppendOp(code.OpSetLocal)
+		t.AppendInt(int64(symbol.Data().LocalIndex()))
+	case scope.SymbolKindEnv:
+		symbol := comp.scopes.GetEnv(symbolId)
+
+		t.AppendOp(code.OpSetEnv)
+		t.AppendInt(int64(symbol.Data().IndexInEnv()))
+	default:
+		panic("unknown symbol kind")
+	}
 
 	return nil
 }
@@ -639,6 +653,11 @@ func (comp *Compiler) compileIdentExpr(t *code.Builder, expr ast.ExprIdent) erro
 
 		t.AppendOp(code.OpGetLocal)
 		t.AppendInt(int64(symbol.Data().LocalIndex()))
+	case scope.SymbolKindEnv:
+		symbol := comp.scopes.GetEnv(symbolId)
+
+		t.AppendOp(code.OpGetEnv)
+		t.AppendInt(int64(symbol.Data().IndexInEnv()))
 	default:
 		panic(fmt.Errorf("unknown symbol kind: %v", symbolId.SymbolKind()))
 	}