functions with bindings
This commit is contained in:
@@ -193,8 +193,13 @@ func (c *Compiler) Compile(node ast.Node) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
symbol := c.symbolTable.Define(node.Name.Value)
|
||||
c.emit(code.OpSetGlobal, symbol.Index)
|
||||
if symbol.Scope == GlobalScope {
|
||||
c.emit(code.OpSetGlobal, symbol.Index)
|
||||
} else {
|
||||
c.emit(code.OpSetLocal, symbol.Index)
|
||||
}
|
||||
|
||||
case *ast.Identifier:
|
||||
symbol, ok := c.symbolTable.Resolve(node.Value)
|
||||
@@ -202,7 +207,11 @@ func (c *Compiler) Compile(node ast.Node) error {
|
||||
return fmt.Errorf("undefined varible %s", node.Value)
|
||||
}
|
||||
|
||||
c.emit(code.OpGetGlobal, symbol.Index)
|
||||
if symbol.Scope == GlobalScope {
|
||||
c.emit(code.OpGetGlobal, symbol.Index)
|
||||
} else {
|
||||
c.emit(code.OpGetLocal, symbol.Index)
|
||||
}
|
||||
|
||||
case *ast.StringLiteral:
|
||||
str := &object.String{Value: node.Value}
|
||||
@@ -268,9 +277,10 @@ func (c *Compiler) Compile(node ast.Node) error {
|
||||
c.emit(code.OpReturn)
|
||||
}
|
||||
|
||||
numLocals := c.symbolTable.numDefinitions
|
||||
instructions := c.leaveScope()
|
||||
|
||||
compiledFn := &object.CompiledFunction{Instructions: instructions}
|
||||
compiledFn := &object.CompiledFunction{Instructions: instructions, NumLocals: numLocals}
|
||||
c.emit(code.OpConstant, c.addConstant(compiledFn))
|
||||
|
||||
case *ast.ReturnStatement:
|
||||
@@ -374,6 +384,8 @@ func (c *Compiler) enterScope() {
|
||||
}
|
||||
c.scopes = append(c.scopes, scope)
|
||||
c.scopeIndex++
|
||||
|
||||
c.symbolTable = NewEnclosedSymbolTable(c.symbolTable)
|
||||
}
|
||||
|
||||
func (c *Compiler) leaveScope() code.Instructions {
|
||||
@@ -382,6 +394,8 @@ func (c *Compiler) leaveScope() code.Instructions {
|
||||
c.scopes = c.scopes[:len(c.scopes)-1]
|
||||
c.scopeIndex--
|
||||
|
||||
c.symbolTable = c.symbolTable.Outer
|
||||
|
||||
return instructions
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user