package core import ( "git.akyoto.dev/cli/q/src/build/asm" "git.akyoto.dev/cli/q/src/build/ast" "git.akyoto.dev/cli/q/src/build/errors" "git.akyoto.dev/cli/q/src/build/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.Array { name := left.Children[0].Token.Text(f.File.Bytes) variable := f.VariableByName(name) if variable == nil { return errors.New(&errors.UnknownIdentifier{Name: name}, f.File, left.Children[0].Token.Position) } defer f.UseVariable(variable) index := left.Children[1] offset, _, err := f.Number(index.Token) if err != nil { return err } number, size, err := f.Number(right.Token) if err != nil { return err } elementSize := byte(1) if size != elementSize { return errors.New(&errors.NumberExceedsBounds{Number: number, ExpectedSize: elementSize, Size: size}, f.File, right.Token.Position) } f.MemoryNumber(asm.STORE, asm.Memory{Base: variable.Register, Offset: byte(offset), Length: elementSize}, number) return nil } return errors.New(errors.NotImplemented, f.File, left.Token.Position) }