package core import ( "fmt" "math" "git.urbach.dev/cli/q/src/asm" "git.urbach.dev/cli/q/src/errors" "git.urbach.dev/cli/q/src/eval" "git.urbach.dev/cli/q/src/expression" "git.urbach.dev/cli/q/src/types" ) // EvaluateDot evaluates an access with the dot operator. func (f *Function) EvaluateDot(expr *expression.Expression) (eval.Value, error) { left := expr.Children[0] right := expr.Children[1] leftText := left.Token.Text(f.File.Bytes) rightText := right.Token.Text(f.File.Bytes) variable := f.VariableByName(leftText) if variable != nil { field := variable.Value.Typ.(*types.Pointer).To.(*types.Struct).FieldByName(rightText) value := eval.Memory{ Typ: field.Type, Memory: asm.Memory{ Base: variable.Value.Register, Offset: int8(field.Offset), OffsetRegister: math.MaxUint8, Length: byte(field.Type.Size()), }, } return value, nil } constant, isConst := f.All.Constants[f.Package+"."+leftText+"."+rightText] if isConst { number, err := ToNumber(constant.Token, constant.File) if err != nil { return nil, err } value := eval.Number{ Typ: types.AnyInt, Number: number, } return value, nil } uniqueName := fmt.Sprintf("%s.%s", leftText, rightText) function, exists := f.All.Functions[uniqueName] if exists { f.File.Imports[leftText].Used = true value := eval.Label{ Typ: types.AnyPointer, Label: function.UniqueName, } return value, nil } return nil, errors.New(&errors.UnknownIdentifier{Name: uniqueName}, f.File, left.Token.Position) }