closures and they can recurse!!!
Some checks failed
Build / build (push) Failing after 1m35s
Test / build (push) Has been cancelled

This commit is contained in:
Chuck Smith
2024-03-14 20:08:40 -04:00
parent 78b560e457
commit cc78fee3c8
10 changed files with 640 additions and 39 deletions

View File

@@ -196,12 +196,12 @@ func (c *Compiler) Compile(node ast.Node) error {
}
case *ast.LetStatement:
symbol := c.symbolTable.Define(node.Name.Value)
err := c.Compile(node.Value)
if err != nil {
return err
}
symbol := c.symbolTable.Define(node.Name.Value)
if symbol.Scope == GlobalScope {
c.emit(code.OpSetGlobal, symbol.Index)
} else {
@@ -268,6 +268,10 @@ func (c *Compiler) Compile(node ast.Node) error {
case *ast.FunctionLiteral:
c.enterScope()
if node.Name != "" {
c.symbolTable.DefineFunctionName(node.Name)
}
for _, p := range node.Parameters {
c.symbolTable.Define(p.Value)
}
@@ -284,9 +288,14 @@ func (c *Compiler) Compile(node ast.Node) error {
c.emit(code.OpReturn)
}
freeSymbols := c.symbolTable.FreeSymbols
numLocals := c.symbolTable.numDefinitions
instructions := c.leaveScope()
for _, s := range freeSymbols {
c.loadSymbol(s)
}
compiledFn := &object.CompiledFunction{
Instructions: instructions,
NumLocals: numLocals,
@@ -294,7 +303,7 @@ func (c *Compiler) Compile(node ast.Node) error {
}
fnIndex := c.addConstant(compiledFn)
c.emit(code.OpClosure, fnIndex, 0)
c.emit(code.OpClosure, fnIndex, len(freeSymbols))
case *ast.ReturnStatement:
err := c.Compile(node.ReturnValue)
@@ -439,5 +448,9 @@ func (c *Compiler) loadSymbol(s Symbol) {
c.emit(code.OpGetLocal, s.Index)
case BuiltinScope:
c.emit(code.OpGetBuiltin, s.Index)
case FreeScope:
c.emit(code.OpGetFree, s.Index)
case FunctionScope:
c.emit(code.OpCurrentClosure)
}
}