Change assignment into expressions
This commit is contained in:
@@ -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)
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user