Something went wrong. Try again.
🌱 A minimal programming language and compiler. git.urbach.dev/cli/q
high-performance programming-language compiler
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101package core
import ( "git.urbach.dev/cli/q/src/ast" "git.urbach.dev/cli/q/src/errors" "git.urbach.dev/cli/q/src/ssa" "git.urbach.dev/cli/q/src/token" "git.urbach.dev/cli/q/src/types")
// compileStoreField compiles an assignment to a struct field.func (f *Function) compileStoreField(node *ast.Assign) error { right := node.Expression.Children[1] rightValue, err := f.evaluateRight(right)
if err != nil { return err }
left := node.Expression.Children[0]
if len(left.Children) == 1 { return errors.NewAt(MissingFieldName, f.File, left.Source().End()) }
address := left.Children[0]
if address.Token.Kind == token.Invalid { return errors.NewAt(MissingObject, f.File, left.Source().Start()) }
fieldExpr := left.Children[1] fieldName := fieldExpr.String(f.File.Bytes) addressValue, err := f.evaluate(address)
if err != nil { return err }
_, isResource := rightValue.Type().(*types.Resource)
if isResource { f.Block().Unidentify(rightValue) }
if node.Expression.Token.Kind != token.Assign { leftValue, err := f.evaluateRight(left)
if err != nil { return err }
rightValue = f.Append(&ssa.BinaryOp{ Op: removeAssign(node.Expression.Token.Kind), Left: leftValue, Right: rightValue, Source: node.Expression.Source(), }) }
switch addressType := types.Unwrap(addressValue.Type()).(type) { case *types.Pointer: structType, isStructType := addressType.To.(*types.Struct)
if !isStructType { return errors.New(&NotDataStruct{TypeName: addressType.To.Name()}, f.File, address.Source()) }
field := structType.FieldByName(fieldName)
if field == nil { return errors.New(&UnknownStructField{StructName: structType.Name(), FieldName: fieldName}, f.File, fieldExpr.Source()) }
if !types.Is(rightValue.Type(), field.Type) { return errors.New(&TypeMismatch{Encountered: rightValue.Type().Name(), Expected: field.Type.Name()}, f.File, right.Source()) }
memory := f.structField(addressValue, field) return f.store(memory, rightValue) case *types.Struct: field := addressType.FieldByName(fieldName)
if field == nil { return errors.New(&UnknownStructField{StructName: addressType.Name(), FieldName: fieldName}, f.File, fieldExpr.Source()) }
structure, isStruct := addressValue.(*ssa.Struct)
if isStruct { name := address.SourceString(f.File.Bytes) f.updateStruct(structure, field, name, rightValue) return nil }
memory := f.structField(addressValue, field) return f.store(memory, rightValue) default: return errors.New(&NotDataStruct{TypeName: addressType.Name()}, f.File, address.Source()) }}