package core import ( "git.akyoto.dev/cli/q/src/asm" "git.akyoto.dev/cli/q/src/errors" "git.akyoto.dev/cli/q/src/expression" "git.akyoto.dev/cli/q/src/sizeof" "git.akyoto.dev/cli/q/src/token" "git.akyoto.dev/cli/q/src/types" ) // ExpressionToMemory puts the result of an expression into the specified memory address. func (f *Function) ExpressionToMemory(node *expression.Expression, memory asm.Memory) (types.Type, error) { if node.IsLeaf() { if node.Token.Kind == token.Identifier { name := node.Token.Text(f.File.Bytes) variable, function := f.Identifier(name) if variable != nil { f.MemoryRegister(asm.STORE, memory, variable.Register) f.UseVariable(variable) return types.PointerAny, nil } if function != nil { f.MemoryLabel(asm.STORE, memory, function.UniqueName) return types.PointerAny, nil } return nil, errors.New(&errors.UnknownIdentifier{Name: name}, f.File, node.Token.Position) } if node.Token.IsNumeric() { number, err := f.Number(node.Token) if err != nil { return nil, err } size := byte(sizeof.Signed(int64(number))) if size > memory.Length { return nil, errors.New(&errors.NumberExceedsBounds{Number: number, ExpectedSize: memory.Length, Size: size}, f.File, node.Token.Position) } f.MemoryNumber(asm.STORE, memory, number) return types.Int, nil } } typ, register, isTemporary, err := f.Evaluate(node) if err != nil { return nil, err } f.MemoryRegister(asm.STORE, memory, register) if isTemporary { f.FreeRegister(register) } return typ, err }