Implemented array storage
This commit is contained in:
@ -79,6 +79,10 @@ func TestParse(t *testing.T) {
|
||||
{"Function calls 27", "sum(a,b)*2+15*4", "(+ (* (λ sum a b) 2) (* 15 4))"},
|
||||
{"Package function calls", "math.sum(a,b)", "(λ (. math sum) a b)"},
|
||||
{"Package function calls 2", "generic.math.sum(a,b)", "(λ (. (. generic math) sum) a b)"},
|
||||
{"Array access", "a[0]", "(@ a 0)"},
|
||||
{"Array access 2", "a[b+c]", "(@ a (+ b c))"},
|
||||
{"Array access 3", "a.b[c]", "(@ (. a b) c)"},
|
||||
{"Array access 4", "a.b[c+d]", "(@ (. a b) (+ c d))"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
@ -18,6 +18,7 @@ type Operator struct {
|
||||
var Operators = map[string]*Operator{
|
||||
".": {".", 13, 2},
|
||||
"λ": {"λ", 12, 1},
|
||||
"@": {"@", 12, 2},
|
||||
"!": {"!", 11, 1},
|
||||
"*": {"*", 10, 2},
|
||||
"/": {"/", 10, 2},
|
||||
|
@ -6,7 +6,10 @@ import (
|
||||
"git.akyoto.dev/cli/q/src/build/token"
|
||||
)
|
||||
|
||||
var call = []byte("λ")
|
||||
var (
|
||||
call = []byte("λ")
|
||||
array = []byte("@")
|
||||
)
|
||||
|
||||
// Parse generates an expression tree from tokens.
|
||||
func Parse(tokens token.List) *Expression {
|
||||
@ -18,7 +21,7 @@ func Parse(tokens token.List) *Expression {
|
||||
)
|
||||
|
||||
for i, t := range tokens {
|
||||
if t.Kind == token.GroupStart {
|
||||
if t.Kind == token.GroupStart || t.Kind == token.ArrayStart {
|
||||
groupLevel++
|
||||
|
||||
if groupLevel == 1 {
|
||||
@ -28,23 +31,30 @@ func Parse(tokens token.List) *Expression {
|
||||
continue
|
||||
}
|
||||
|
||||
if t.Kind == token.GroupEnd {
|
||||
if t.Kind == token.GroupEnd || t.Kind == token.ArrayEnd {
|
||||
groupLevel--
|
||||
|
||||
if groupLevel != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
isFunctionCall := isComplete(cursor)
|
||||
|
||||
if isFunctionCall {
|
||||
// Function call or array access
|
||||
if isComplete(cursor) {
|
||||
parameters := NewList(tokens[groupPosition:i])
|
||||
|
||||
node := New()
|
||||
node.Token.Kind = token.Operator
|
||||
node.Token.Position = tokens[groupPosition].Position
|
||||
node.Token.Bytes = call
|
||||
node.Precedence = precedence("λ")
|
||||
|
||||
switch t.Kind {
|
||||
case token.GroupEnd:
|
||||
node.Token.Bytes = call
|
||||
node.Precedence = precedence("λ")
|
||||
|
||||
case token.ArrayEnd:
|
||||
node.Token.Bytes = array
|
||||
node.Precedence = precedence("@")
|
||||
}
|
||||
|
||||
if cursor.Token.Kind == token.Operator && node.Precedence > cursor.Precedence {
|
||||
cursor.LastChild().Replace(node)
|
||||
|
Reference in New Issue
Block a user