package core import ( "git.akyoto.dev/cli/q/src/asm" "git.akyoto.dev/cli/q/src/ast" "git.akyoto.dev/cli/q/src/errors" "git.akyoto.dev/cli/q/src/expression" "git.akyoto.dev/cli/q/src/token" ) // CompileAssign compiles an assign statement. func (f *Function) CompileAssign(node *ast.Assign) error { operator := node.Expression.Token left := node.Expression.Children[0] right := node.Expression.Children[1] if left.IsLeaf() { name := left.Token.Text(f.File.Bytes) variable := f.VariableByName(name) if variable == nil { return errors.New(&errors.UnknownIdentifier{Name: name}, f.File, left.Token.Position) } defer f.UseVariable(variable) return f.Execute(operator, variable.Register, right) } if left.Token.Kind == token.Period { return f.CompileAssignField(node) } if left.Token.Kind == token.Array { return f.CompileAssignArray(node) } if left.Token.Kind == token.Separator && right.Token.Kind == token.Div { return f.CompileAssignDivision(node) } if !ast.IsFunctionCall(right) { return errors.New(errors.NotImplemented, f.File, node.Expression.Token.Position) } count := 0 _, err := f.CompileCall(right) if err != nil { return err } return left.EachLeaf(func(leaf *expression.Expression) error { name := leaf.Token.Text(f.File.Bytes) variable := f.VariableByName(name) if variable == nil { return errors.New(&errors.UnknownIdentifier{Name: name}, f.File, left.Token.Position) } f.RegisterRegister(asm.MOVE, variable.Register, f.CPU.Output[count]) f.UseVariable(variable) count++ return nil }) }