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.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108package core
import ( "git.urbach.dev/cli/q/src/errors" "git.urbach.dev/cli/q/src/expression" "git.urbach.dev/cli/q/src/ssa" "git.urbach.dev/cli/q/src/token" "git.urbach.dev/cli/q/src/types")
// define gives a value an identifier.func (f *Function) define(left *expression.Expression, right *expression.Expression, isAssign bool) error { rightValue, err := f.evaluateRight(right)
if err != nil { return err }
name := left.String(f.File.Bytes)
if name == "_" { return nil }
root := left.Parent
if isAssign && root.Token.Kind != token.Assign { operator := removeAssign(root.Token.Kind) leftValueDeref, err := f.evaluateRight(left)
if err != nil { return err }
rightValue = f.Append(&ssa.BinaryOp{ Op: operator, Left: leftValueDeref, Right: rightValue, Source: root.Source(), }) }
leftValue, err := f.validateLeft(left, right, name, rightValue.Type(), isAssign)
if err != nil { return err }
call, isCall := rightValue.(*ssa.Call)
if isCall && len(call.Func.Typ.Output) != 1 { return errors.New(&DefinitionCountMismatch{Function: call.Func.String(), Count: 1, ExpectedCount: len(call.Func.Typ.Output)}, f.File, left.Source()) }
// If the value we got was a value that is stored in a variable, // it must have been returned from the optimizer as a cached value. // We want to assure that every named variable creates a copy of // another named variable instead of using the cached value itself // because it could lead to incorrect optimizations. if f.IsIdentified(rightValue) { _, isResource := rightValue.Type().(*types.Resource)
if isResource { f.Block().Unidentify(rightValue) } else { rightValue = f.copy(rightValue, right.Source(), isIdentifierRead(right)) } }
global, isGlobal := leftValue.(*ssa.Global)
if isGlobal { zero := f.Append(&ssa.Int{Int: 0})
memory := &ssa.Memory{ Typ: global.Typ.(*types.Pointer).To, Address: global, Index: zero, Source: global.Source, }
return f.store(memory, rightValue) }
if !isCall { structure, isStructType := rightValue.(*ssa.Struct)
if isStructType { for i, field := range types.Unwrap(structure.Typ).(*types.Struct).Fields { f.Block().Identify(name+"."+field.Name, structure.Arguments[i]) } }
f.Block().Identify(name, rightValue) return nil }
structure, isStructType := types.Unwrap(rightValue.Type()).(*types.Struct)
if !isStructType { f.Block().Identify(name, rightValue) return nil }
composite := f.makeStructFromTuple(rightValue, rightValue.Type(), structure, name, left.Source()) f.Block().Identify(name, composite) return nil}