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.
2.1 kB · 111 lines
Go
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111package expression
import ( "git.urbach.dev/cli/q/src/token")
// Parse generates an expression tree from tokens.func Parse(tokens token.List) *Expression { var ( cursor *Expression root *Expression i uint )
loop: for i < uint(len(tokens)) { t := tokens[i]
if startsType(t.Kind) { j, isType := parseType(tokens, i)
if isType { typeToken := makeTypeToken(tokens[i:j]) root, cursor = handleLiteral(root, cursor, typeToken) i = j t = tokens[i] } }
switch t.Kind { case token.GroupStart, token.ArrayStart, token.BlockStart: i++ groupLevel := 1 groupPosition := i
for i < uint(len(tokens)) { t = tokens[i]
switch t.Kind { case token.GroupStart, token.ArrayStart, token.BlockStart: groupLevel++ case token.GroupEnd, token.ArrayEnd, token.BlockEnd: groupLevel--
if groupLevel == 0 { root, cursor = handleGroupEnd(tokens, root, cursor, groupPosition, i, t) i++ continue loop } }
i++ }
break loop }
switch { case cursor != nil && cursor.Token.Kind == token.Cast && len(cursor.Children) < 2: typ := tokens[i:]
if len(typ) > 0 { typeToken := makeTypeToken(typ) cursor.AddChild(newLeaf(typeToken)) }
return root case t.Kind.IsLiteral(): root, cursor = handleLiteral(root, cursor, t) case t.Kind.IsKeyword(): leaf := newLeaf(t) leaf.Token.Kind = token.Invalid
if cursor == nil { cursor = leaf root = leaf } else { cursor.AddChild(leaf) cursor = leaf } case !t.Kind.IsOperator(): // do nothing case cursor == nil: cursor = newLeaf(t) cursor.precedence = precedence(t.Kind) root = cursor default: node := newLeaf(t) node.precedence = precedence(t.Kind)
if cursor.Token.Kind.IsOperator() { root = handleOperator(root, cursor, node) } else { node.AddChild(cursor) root = node }
if !cursor.Token.Kind.IsUnaryOperator() || !node.Token.Kind.IsUnaryOperator() { cursor = node } }
i++ }
if root == nil { root = New() }
return root}