Change assignment into expressions
Some checks failed
Test / build (push) Waiting to run
Build / build (push) Has been cancelled

This commit is contained in:
Chuck Smith
2024-03-19 20:30:30 -04:00
parent aa0582ed72
commit be81b9a6d6
12 changed files with 478 additions and 153 deletions

View File

@@ -246,23 +246,50 @@ func (c *Compiler) Compile(node ast.Node) error {
}
}
case *ast.AssignmentStatement:
symbol, ok := c.symbolTable.Resolve(node.Name.Value)
if !ok {
return fmt.Errorf("undefined variable %s", node.Value)
}
case *ast.AssignmentExpression:
if ident, ok := node.Left.(*ast.Identifier); ok {
symbol, ok := c.symbolTable.Resolve(ident.Value)
if !ok {
return fmt.Errorf("undefined variable %s", ident.Value)
}
c.l++
err := c.Compile(node.Value)
c.l--
if err != nil {
return err
}
c.l++
err := c.Compile(node.Value)
c.l--
if err != nil {
return err
}
if symbol.Scope == GlobalScope {
c.emit(code.OpAssignGlobal, symbol.Index)
if symbol.Scope == GlobalScope {
c.emit(code.OpAssignGlobal, symbol.Index)
} else {
c.emit(code.OpAssignLocal, symbol.Index)
}
} else if ie, ok := node.Left.(*ast.IndexExpression); ok {
c.l++
err := c.Compile(ie.Left)
c.l--
if err != nil {
return err
}
c.l++
err = c.Compile(ie.Index)
c.l--
if err != nil {
return err
}
c.l++
err = c.Compile(node.Value)
c.l--
if err != nil {
return err
}
c.emit(code.OpSetItem)
} else {
c.emit(code.OpAssignLocal, symbol.Index)
return fmt.Errorf("expected identifier or index expression got=%s", node.Left)
}
case *ast.LetStatement:
@@ -349,7 +376,7 @@ func (c *Compiler) Compile(node ast.Node) error {
return err
}
c.emit(code.OpIndex)
c.emit(code.OpGetItem)
case *ast.FunctionLiteral:
c.enterScope()
@@ -446,9 +473,12 @@ func (c *Compiler) Compile(node ast.Node) error {
}
c.l--
// Pop off the LoadNull(s) from ast.BlockStatement(s)
c.emit(code.OpPop)
c.emit(code.OpJump, jumpConditionPos)
afterConsequencePos := c.emit(code.OpNoop)
afterConsequencePos := c.emit(code.OpNull)
c.changeOperand(jumpIfFalsePos, afterConsequencePos)
}