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.
7.5 kB 路 169 lines
Go
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169package expression_test
import ( "testing"
"git.urbach.dev/cli/q/src/expression" "git.urbach.dev/cli/q/src/token" "git.urbach.dev/go/assert")
func TestParse(t *testing.T) { tests := []struct { Name string Expression string Result string }{ {"Identity", "1", "1"}, {"Basic calculation", "1+2", "(+ 1 2)"},
{"Same operator", "1+2+3", "(+ (+ 1 2) 3)"}, {"Same operator 2", "1+2+3+4", "(+ (+ (+ 1 2) 3) 4)"},
{"Different operator", "1+2-3", "(- (+ 1 2) 3)"}, {"Different operator 2", "1+2-3+4", "(+ (- (+ 1 2) 3) 4)"}, {"Different operator 3", "1+2-3+4-5", "(- (+ (- (+ 1 2) 3) 4) 5)"},
{"Grouped identity", "(1)", "1"}, {"Grouped identity 2", "((1))", "1"}, {"Grouped identity 3", "(((1)))", "1"},
{"Adding identity", "(1)+(2)", "(+ 1 2)"}, {"Adding identity 2", "(1)+(2)+(3)", "(+ (+ 1 2) 3)"}, {"Adding identity 3", "(1)+(2)+(3)+(4)", "(+ (+ (+ 1 2) 3) 4)"},
{"Grouping", "(1+2)", "(+ 1 2)"}, {"Grouping 2", "(1+2+3)", "(+ (+ 1 2) 3)"}, {"Grouping 3", "((1)+(2)+(3))", "(+ (+ 1 2) 3)"}, {"Grouping left", "(1+2)*3", "(* (+ 1 2) 3)"}, {"Grouping right", "1*(2+3)", "(* 1 (+ 2 3))"}, {"Grouping same operator", "1+(2+3)", "(+ 1 (+ 2 3))"}, {"Grouping same operator 2", "1+(2+3)+(4+5)", "(+ (+ 1 (+ 2 3)) (+ 4 5))"}, {"Grouping error", "(", ""},
{"Two groups", "(1+2)*(3+4)", "(* (+ 1 2) (+ 3 4))"}, {"Two groups 2", "(1+2-3)*(3+4-5)", "(* (- (+ 1 2) 3) (- (+ 3 4) 5))"}, {"Two groups 3", "(1+2)*(3+4-5)", "(* (+ 1 2) (- (+ 3 4) 5))"},
{"Operator priority", "1+2*3", "(+ 1 (* 2 3))"}, {"Operator priority 2", "1*2+3", "(+ (* 1 2) 3)"}, {"Operator priority 3", "1+2*3+4", "(+ (+ 1 (* 2 3)) 4)"}, {"Operator priority 4", "1+2*(3+4)+5", "(+ (+ 1 (* 2 (+ 3 4))) 5)"}, {"Operator priority 5", "1+2*3*4", "(+ 1 (* (* 2 3) 4))"}, {"Operator priority 6", "1+2*3+4*5", "(+ (+ 1 (* 2 3)) (* 4 5))"}, {"Operator priority 7", "1+2*3*4*5*6", "(+ 1 (* (* (* (* 2 3) 4) 5) 6))"}, {"Operator priority 8", "1*2*3+4*5*6", "(+ (* (* 1 2) 3) (* (* 4 5) 6))"},
{"Complex", "(1+2-3*4)*(5+6-7*8)", "(* (- (+ 1 2) (* 3 4)) (- (+ 5 6) (* 7 8)))"}, {"Complex 2", "(1+2*3-4)*(5+6*7-8)", "(* (- (+ 1 (* 2 3)) 4) (- (+ 5 (* 6 7)) 8))"}, {"Complex 3", "(1+2*3-4)*(5+6*7-8)+9-10*11", "(- (+ (* (- (+ 1 (* 2 3)) 4) (- (+ 5 (* 6 7)) 8)) 9) (* 10 11))"},
{"Unary not", "!", "!"}, {"Unary not 2", "!a", "(! a)"}, {"Unary not 3", "!!a", "(! (! a))"}, {"Unary not 4", "!!!a", "(! (! (! a)))"}, {"Unary not 5", "!(!a)", "(! (! a))"}, {"Unary not 6", "!(a||b)", "(! (|| a b))"}, {"Unary not 7", "a || !b", "(|| a (! b))"},
{"Unary minus", "-", "-"}, {"Unary minus 2", "-a", "(- a)"}, {"Unary minus 3", "--a", "(- (- a))"}, {"Unary minus 4", "---a", "(- (- (- a)))"}, {"Unary minus 5", "-(-a)", "(- (- a))"}, {"Unary minus 6", "-a+b", "(+ (- a) b)"}, {"Unary minus 7", "-(a+b)", "(- (+ a b))"}, {"Unary minus 8", "a + -b", "(+ a (- b))"}, {"Unary minus 9", "-a + -b", "(+ (- a) (- b))"},
{"Assign bitwise operation", "a|=b", "(|= a b)"}, {"Assign bitwise operation 2", "a|=b<<c", "(|= a (<< b c))"},
{"Function calls", "a()", "(位 a)"}, {"Function calls 2", "a(1)", "(位 a 1)"}, {"Function calls 3", "a(1)+1", "(+ (位 a 1) 1)"}, {"Function calls 4", "1+a(1)", "(+ 1 (位 a 1))"}, {"Function calls 5", "a(1,2)", "(位 a 1 2)"}, {"Function calls 6", "a(1,2,3)", "(位 a 1 2 3)"}, {"Function calls 7", "a(1,2+2,3)", "(位 a 1 (+ 2 2) 3)"}, {"Function calls 8", "a(1,2+2,3+3)", "(位 a 1 (+ 2 2) (+ 3 3))"}, {"Function calls 9", "a(1+1,2,3)", "(位 a (+ 1 1) 2 3)"}, {"Function calls 10", "a(1+1,2+2,3+3)", "(位 a (+ 1 1) (+ 2 2) (+ 3 3))"}, {"Function calls 11", "a(b())", "(位 a (位 b))"}, {"Function calls 12", "a(b(),c())", "(位 a (位 b) (位 c))"}, {"Function calls 13", "a(b(),c(),d())", "(位 a (位 b) (位 c) (位 d))"}, {"Function calls 14", "a(b(1))", "(位 a (位 b 1))"}, {"Function calls 15", "a(b(1),c(2),d(3))", "(位 a (位 b 1) (位 c 2) (位 d 3))"}, {"Function calls 16", "a(b(1)+1)", "(位 a (+ (位 b 1) 1))"}, {"Function calls 17", "a(b(1)+1,c(2),d(3))", "(位 a (+ (位 b 1) 1) (位 c 2) (位 d 3))"}, {"Function calls 18", "a(b(1)*c(2))", "(位 a (* (位 b 1) (位 c 2)))"}, {"Function calls 19", "a(b(1)*c(2),d(3)+e(4),f(5)/f(6))", "(位 a (* (位 b 1) (位 c 2)) (+ (位 d 3) (位 e 4)) (/ (位 f 5) (位 f 6)))"}, {"Function calls 20", "a(b(1,2)+c(3,4)*d(5,6))", "(位 a (+ (位 b 1 2) (* (位 c 3 4) (位 d 5 6))))"}, {"Function calls 21", "a((b(1,2)+c(3,4))*d(5,6))", "(位 a (* (+ (位 b 1 2) (位 c 3 4)) (位 d 5 6)))"}, {"Function calls 22", "a((b(1,2)+c(3,4))*d(5,6),e())", "(位 a (* (+ (位 b 1 2) (位 c 3 4)) (位 d 5 6)) (位 e))"}, {"Function calls 23", "a((b(1,2)+c(3,4))*d(5,6),e(7+8,9-10*11,12))", "(位 a (* (+ (位 b 1 2) (位 c 3 4)) (位 d 5 6)) (位 e (+ 7 8) (- 9 (* 10 11)) 12))"}, {"Function calls 24", "a((b(1,2,bb())+c(3,4,cc(0)))*d(5,6,dd(0)),e(7+8,9-10*11,12,ee(0)))", "(位 a (* (+ (位 b 1 2 (位 bb)) (位 c 3 4 (位 cc 0))) (位 d 5 6 (位 dd 0))) (位 e (+ 7 8) (- 9 (* 10 11)) 12 (位 ee 0)))"}, {"Function calls 25", "a(1-2*3)", "(位 a (- 1 (* 2 3)))"}, {"Function calls 26", "1+2*a()+4", "(+ (+ 1 (* 2 (位 a))) 4)"}, {"Function calls 27", "a(b,c)*2+15*4", "(+ (* (位 a b c) 2) (* 15 4))"}, {"Function calls 28", "a(,)", "(位 a )"},
{"New", "new(int)", "(位 new int)"}, {"New array", "new(int, 10)", "(位 new int 10)"},
{"Member access", "a.b", "(. a b)"}, {"Member access 2", "a.", "(. a)"}, {"Member access 3", ".b", "(. b)"}, {"Member access 4", "a.b(c)", "(位 (. a b) c)"}, {"Member access 5", "a.b(c,d)", "(位 (. a b) c d)"}, {"Member access 6", "a.b.c(d,e)", "(位 (. (. a b) c) d e)"},
{"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))"}, {"Array access 5", "a()[b]", "(@ (位 a) b)"}, {"Array access 6", "a.b()[c]", "(@ (位 (. a b)) c)"}, {"Array access 7", "a.b(c)[d]", "(@ (位 (. a b) c) d)"}, {"Array access 8", "a.b(c)[d][e]", "(@ (@ (位 (. a b) c) d) e)"}, {"Array access 9", "a[0](1)[2](3)", "(位 (@ (位 (@ a 0) 1) 2) 3)"},
{"Dereferencing", "[a]", "(@ a)"}, {"Dereferencing 2", "[a+b]", "(@ (+ a b))"}, {"Dereferencing 3", "[a]=b", "(= (@ a) b)"}, {"Dereferencing 4", "[a+b]=c", "(= (@ (+ a b)) c)"}, {"Dereferencing 5", "[a+b]=c+d", "(= (@ (+ a b)) (+ c d))"}, {"Dereferencing 6", "a=[b]", "(= a (@ b))"}, {"Dereferencing 7", "a=[b].x", "(= a (. (@ b) x))"},
{"Structs", "a{}", "($ a)"}, {"Structs 2", "a{b:c}", "($ a (: b c))"}, {"Structs 3", "a{b:c,d:e}", "($ a (: b c) (: d e))"}, {"Structs 4", "a{}.f", "(. ($ a) f)"}, {"Structs 5", "a{b:c}.f", "(. ($ a (: b c)) f)"}, {"Structs 6", "a{}[0]", "(@ ($ a) 0)"}, {"Structs 7", "a{b:c}[0]", "(@ ($ a (: b c)) 0)"}, {"Structs 8", "a{}(f)", "(位 ($ a) f)"}, {"Structs 9", "a{b:c}(f)", "(位 ($ a (: b c)) f)"},
{"Slices", "a[..]", "(@ a ..)"}, {"Slices 2", "a[b..]", "(@ a (.. b))"}, {"Slices 3", "a[..c]", "(@ a (.. c))"}, {"Slices 4", "a[b..c]", "(@ a (.. b c))"},
{"Type cast", "a as b", "(as a b)"}, {"Type cast 2", "a as *b", "(as a *b)"}, {"Type cast 3", "(a as b).c", "(. (as a b) c)"}, }
for _, test := range tests { t.Run(test.Name, func(t *testing.T) { src := []byte(test.Expression) tokens := token.Tokenize(src) expr := expression.Parse(tokens) defer expr.Reset() assert.NotNil(t, expr) assert.Equal(t, expr.String(src), test.Result) }) }}