package core import ( "fmt" "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 := f.VariableByName(name) if variable != nil { f.UseVariable(variable) f.MemoryRegister(asm.STORE, memory, variable.Register) return types.Pointer, nil } uniqueName := fmt.Sprintf("%s.%s", f.Package, name) _, exists := f.Functions[uniqueName] if exists { f.MemoryLabel(asm.STORE, memory, uniqueName) return types.Pointer, 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 }