Skip to content

Commit c9f620e

Browse files
committed
Only allow if on precedence == 0
1 parent bc0ce17 commit c9f620e

File tree

2 files changed

+166
-8
lines changed

2 files changed

+166
-8
lines changed

parser/parser.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ func ParseWithConfig(input string, config *conf.Config) (*Tree, error) {
110110
config: config,
111111
}
112112

113-
node := p.parseExpression(0)
113+
node := p.parseSequenceExpression()
114114

115115
if !p.current.Is(EOF) {
116116
p.error("unexpected token %v", p.current)
@@ -190,7 +190,7 @@ func (p *parser) parseExpression(precedence int) Node {
190190
return p.parseVariableDeclaration()
191191
}
192192

193-
if p.current.Is(Operator, "if") {
193+
if precedence == 0 && p.current.Is(Operator, "if") {
194194
return p.parseConditionalIf()
195195
}
196196

@@ -290,7 +290,7 @@ func (p *parser) parseVariableDeclaration() Node {
290290
p.expect(Operator, "=")
291291
value := p.parseExpression(0)
292292
p.expect(Operator, ";")
293-
node := p.parseExpression(0)
293+
node := p.parseSequenceExpression()
294294
return p.createNode(&VariableDeclaratorNode{
295295
Name: variableName.Value,
296296
Value: value,
@@ -364,7 +364,7 @@ func (p *parser) parsePrimary() Node {
364364

365365
if token.Is(Bracket, "(") {
366366
p.next()
367-
expr := p.parseExpression(0)
367+
expr := p.parseSequenceExpression()
368368
p.expect(Bracket, ")") // "an opened parenthesis is not properly closed"
369369
return p.parsePostfixExpression(expr)
370370
}
@@ -607,17 +607,22 @@ func (p *parser) parseArguments(arguments []Node) []Node {
607607

608608
func (p *parser) parsePredicate() Node {
609609
startToken := p.current
610-
expectClosingBracket := false
610+
withBrackets := false
611611
if p.current.Is(Bracket, "{") {
612612
p.next()
613-
expectClosingBracket = true
613+
withBrackets = true
614614
}
615615

616616
p.depth++
617-
node := p.parseExpression(0)
617+
var node Node
618+
if withBrackets {
619+
node = p.parseSequenceExpression()
620+
} else {
621+
node = p.parseExpression(0)
622+
}
618623
p.depth--
619624

620-
if expectClosingBracket {
625+
if withBrackets {
621626
p.expect(Bracket, "}")
622627
}
623628
predicateNode := p.createNode(&PredicateNode{

parser/parser_test.go

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,29 @@ world`},
659659
Exp1: &BoolNode{Value: true},
660660
Exp2: &IdentifierNode{Value: "x"}},
661661
},
662+
{
663+
"1; 2; 3",
664+
&SequenceNode{
665+
Nodes: []Node{
666+
&IntegerNode{Value: 1},
667+
&IntegerNode{Value: 2},
668+
&IntegerNode{Value: 3},
669+
},
670+
},
671+
},
672+
{
673+
"1; (2; 3)",
674+
&SequenceNode{
675+
Nodes: []Node{
676+
&IntegerNode{Value: 1},
677+
&SequenceNode{
678+
Nodes: []Node{
679+
&IntegerNode{Value: 2},
680+
&IntegerNode{Value: 3}},
681+
},
682+
},
683+
},
684+
},
662685
{
663686
"true ? 1; 2; 3 : 4",
664687
&ConditionalNode{
@@ -707,6 +730,115 @@ world`},
707730
&IntegerNode{Value: 5},
708731
&IntegerNode{Value: 6}}}},
709732
},
733+
{
734+
`all(ls, if true { 1 } else { 2 })`,
735+
&BuiltinNode{
736+
Name: "all",
737+
Arguments: []Node{
738+
&IdentifierNode{Value: "ls"},
739+
&PredicateNode{
740+
Node: &ConditionalNode{
741+
Cond: &BoolNode{Value: true},
742+
Exp1: &IntegerNode{Value: 1},
743+
Exp2: &IntegerNode{Value: 2}}}}},
744+
},
745+
{
746+
`let x = if true { 1 } else { 2 }; x`,
747+
&VariableDeclaratorNode{
748+
Name: "x",
749+
Value: &ConditionalNode{
750+
Cond: &BoolNode{Value: true},
751+
Exp1: &IntegerNode{Value: 1},
752+
Exp2: &IntegerNode{Value: 2}},
753+
Expr: &IdentifierNode{Value: "x"}},
754+
},
755+
{
756+
`call(if true { 1 } else { 2 })`,
757+
&CallNode{
758+
Callee: &IdentifierNode{Value: "call"},
759+
Arguments: []Node{
760+
&ConditionalNode{
761+
Cond: &BoolNode{Value: true},
762+
Exp1: &IntegerNode{Value: 1},
763+
Exp2: &IntegerNode{Value: 2}}}},
764+
},
765+
{
766+
`[if true { 1 } else { 2 }]`,
767+
&ArrayNode{
768+
Nodes: []Node{
769+
&ConditionalNode{
770+
Cond: &BoolNode{Value: true},
771+
Exp1: &IntegerNode{Value: 1},
772+
Exp2: &IntegerNode{Value: 2}}}},
773+
},
774+
{
775+
`map(ls, { 1; 2; 3 })`,
776+
&BuiltinNode{
777+
Name: "map",
778+
Arguments: []Node{
779+
&IdentifierNode{Value: "ls"},
780+
&PredicateNode{
781+
Node: &SequenceNode{
782+
Nodes: []Node{
783+
&IntegerNode{Value: 1},
784+
&IntegerNode{Value: 2},
785+
&IntegerNode{Value: 3},
786+
},
787+
},
788+
},
789+
}},
790+
},
791+
{
792+
`let x = 1; 2; 3 + x`,
793+
&VariableDeclaratorNode{
794+
Name: "x",
795+
Value: &IntegerNode{Value: 1},
796+
Expr: &SequenceNode{
797+
Nodes: []Node{
798+
&IntegerNode{Value: 2},
799+
&BinaryNode{
800+
Operator: "+",
801+
Left: &IntegerNode{Value: 3},
802+
Right: &IdentifierNode{Value: "x"},
803+
},
804+
},
805+
},
806+
},
807+
},
808+
{
809+
`let x = 1; let y = 2; 3; 4; x + y`,
810+
&VariableDeclaratorNode{
811+
Name: "x",
812+
Value: &IntegerNode{Value: 1},
813+
Expr: &VariableDeclaratorNode{
814+
Name: "y",
815+
Value: &IntegerNode{Value: 2},
816+
Expr: &SequenceNode{
817+
Nodes: []Node{
818+
&IntegerNode{Value: 3},
819+
&IntegerNode{Value: 4},
820+
&BinaryNode{
821+
Operator: "+",
822+
Left: &IdentifierNode{Value: "x"},
823+
Right: &IdentifierNode{Value: "y"},
824+
},
825+
},
826+
}}},
827+
},
828+
{
829+
`let x = (1; 2; 3); x`,
830+
&VariableDeclaratorNode{
831+
Name: "x",
832+
Value: &SequenceNode{
833+
Nodes: []Node{
834+
&IntegerNode{Value: 1},
835+
&IntegerNode{Value: 2},
836+
&IntegerNode{Value: 3},
837+
},
838+
},
839+
Expr: &IdentifierNode{Value: "x"},
840+
},
841+
},
710842
}
711843
for _, test := range tests {
712844
t.Run(test.input, func(t *testing.T) {
@@ -788,6 +920,27 @@ func TestParse_error(t *testing.T) {
788920
{`1 not == [1, 2, 5]`, `unexpected token Operator("==") (1:7)
789921
| 1 not == [1, 2, 5]
790922
| ......^`},
923+
{`foo(1; 2; 3)`, `unexpected token Operator(";") (1:6)
924+
| foo(1; 2; 3)
925+
| .....^`},
926+
{
927+
`map(ls, 1; 2; 3)`,
928+
`unexpected token Operator(";") (1:10)
929+
| map(ls, 1; 2; 3)
930+
| .........^`,
931+
},
932+
{
933+
`[1; 2; 3]`,
934+
`unexpected token Operator(";") (1:3)
935+
| [1; 2; 3]
936+
| ..^`,
937+
},
938+
{
939+
`1 + if true { 2 } else { 3 }`,
940+
`unexpected token Operator("if") (1:5)
941+
| 1 + if true { 2 } else { 3 }
942+
| ....^`,
943+
},
791944
}
792945

793946
for _, test := range tests {

0 commit comments

Comments
 (0)