Skip to content

Commit ce727bc

Browse files
committed
Add Ternary field to ConditionalNode and update tests and printing logic
1 parent 5052a11 commit ce727bc

5 files changed

Lines changed: 60 additions & 33 deletions

File tree

ast/node.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,13 @@ type PointerNode struct {
200200
Name string // Name of the pointer. Like "index" in "#index".
201201
}
202202

203-
// ConditionalNode represents a ternary operator.
203+
// ConditionalNode represents a ternary operator or if/else operator.
204204
type ConditionalNode struct {
205205
base
206-
Cond Node // Condition of the ternary operator. Like "foo" in "foo ? bar : baz".
207-
Exp1 Node // Expression 1 of the ternary operator. Like "bar" in "foo ? bar : baz".
208-
Exp2 Node // Expression 2 of the ternary operator. Like "baz" in "foo ? bar : baz".
206+
Ternary bool // Is it ternary or if/else operator?
207+
Cond Node // Condition
208+
Exp1 Node // Expression 1
209+
Exp2 Node // Expression 2
209210
}
210211

211212
// VariableDeclaratorNode represents a variable declaration.

ast/print.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,16 @@ func (n *SequenceNode) String() string {
207207
}
208208

209209
func (n *ConditionalNode) String() string {
210+
if !n.Ternary {
211+
cond := n.Cond.String()
212+
exp1 := n.Exp1.String()
213+
if c2, ok := n.Exp2.(*ConditionalNode); ok && !c2.Ternary {
214+
return fmt.Sprintf("if %s { %s } else %s", cond, exp1, c2.String())
215+
}
216+
exp2 := n.Exp2.String()
217+
return fmt.Sprintf("if %s { %s } else { %s }", cond, exp1, exp2)
218+
}
219+
210220
var cond, exp1, exp2 string
211221
if _, ok := n.Cond.(*ConditionalNode); ok {
212222
cond = fmt.Sprintf("(%s)", n.Cond.String())

ast/print_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ func TestPrint(t *testing.T) {
8383
{`(2 ** 2) ** 3`, `(2 ** 2) ** 3`},
8484
{`(3 + 5) / (5 % 3)`, `(3 + 5) / (5 % 3)`},
8585
{`(-(1+1)) == 2`, `-(1 + 1) == 2`},
86-
{`if true { 1 } else { 2 }`, `true ? 1 : 2`},
87-
{`if true { 1 } else if false { 2 } else { 3 }`, `true ? 1 : (false ? 2 : 3)`},
86+
{`if true { 1 } else { 2 }`, `if true { 1 } else { 2 }`},
87+
{`if true { 1 } else if false { 2 } else { 3 }`, `if true { 1 } else if false { 2 } else { 3 }`},
8888
}
8989

9090
for _, tt := range tests {

parser/parser.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,9 +368,10 @@ func (p *Parser) parseConditional(node Node) Node {
368368
}
369369

370370
node = p.createNode(&ConditionalNode{
371-
Cond: node,
372-
Exp1: expr1,
373-
Exp2: expr2,
371+
Ternary: true,
372+
Cond: node,
373+
Exp1: expr1,
374+
Exp2: expr2,
374375
}, p.current.Location)
375376
if node == nil {
376377
return nil

parser/parser_test.go

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,19 @@ world`},
197197
},
198198
{
199199
"true ? true : false",
200-
&ConditionalNode{Cond: &BoolNode{Value: true},
201-
Exp1: &BoolNode{Value: true},
202-
Exp2: &BoolNode{}},
200+
&ConditionalNode{
201+
Ternary: true,
202+
Cond: &BoolNode{Value: true},
203+
Exp1: &BoolNode{Value: true},
204+
Exp2: &BoolNode{}},
203205
},
204206
{
205207
"a?[b]:c",
206-
&ConditionalNode{Cond: &IdentifierNode{Value: "a"},
207-
Exp1: &ArrayNode{Nodes: []Node{&IdentifierNode{Value: "b"}}},
208-
Exp2: &IdentifierNode{Value: "c"}},
208+
&ConditionalNode{
209+
Ternary: true,
210+
Cond: &IdentifierNode{Value: "a"},
211+
Exp1: &ArrayNode{Nodes: []Node{&IdentifierNode{Value: "b"}}},
212+
Exp2: &IdentifierNode{Value: "c"}},
209213
},
210214
{
211215
"a.b().c().d[33]",
@@ -396,6 +400,7 @@ world`},
396400
{
397401
"2==2 ? false : 3 not in [1, 2, 5]",
398402
&ConditionalNode{
403+
Ternary: true,
399404
Cond: &BinaryNode{
400405
Operator: "==",
401406
Left: &IntegerNode{Value: 2},
@@ -710,9 +715,10 @@ world`},
710715
&SequenceNode{
711716
Nodes: []Node{
712717
&ConditionalNode{
713-
Cond: &BoolNode{Value: true},
714-
Exp1: &IntegerNode{Value: 1},
715-
Exp2: &IntegerNode{Value: 2}},
718+
Ternary: true,
719+
Cond: &BoolNode{Value: true},
720+
Exp1: &IntegerNode{Value: 1},
721+
Exp2: &IntegerNode{Value: 2}},
716722
&IntegerNode{Value: 3},
717723
&IntegerNode{Value: 4},
718724
},
@@ -721,8 +727,9 @@ world`},
721727
{
722728
"true ? 1 : ( 2; 3; 4 )",
723729
&ConditionalNode{
724-
Cond: &BoolNode{Value: true},
725-
Exp1: &IntegerNode{Value: 1},
730+
Ternary: true,
731+
Cond: &BoolNode{Value: true},
732+
Exp1: &IntegerNode{Value: 1},
726733
Exp2: &SequenceNode{
727734
Nodes: []Node{
728735
&IntegerNode{Value: 2},
@@ -737,9 +744,10 @@ world`},
737744
&SequenceNode{
738745
Nodes: []Node{
739746
&ConditionalNode{
740-
Cond: &BoolNode{Value: true},
741-
Exp1: &BoolNode{Value: true},
742-
Exp2: &IntegerNode{Value: 1}},
747+
Ternary: true,
748+
Cond: &BoolNode{Value: true},
749+
Exp1: &BoolNode{Value: true},
750+
Exp2: &IntegerNode{Value: 1}},
743751
&IntegerNode{Value: 2},
744752
&IntegerNode{Value: 3},
745753
},
@@ -750,18 +758,20 @@ world`},
750758
&VariableDeclaratorNode{
751759
Name: "x",
752760
Value: &ConditionalNode{
753-
Cond: &BoolNode{Value: true},
754-
Exp1: &IntegerNode{Value: 1},
755-
Exp2: &IntegerNode{Value: 2}},
761+
Ternary: true,
762+
Cond: &BoolNode{Value: true},
763+
Exp1: &IntegerNode{Value: 1},
764+
Exp2: &IntegerNode{Value: 2}},
756765
Expr: &IdentifierNode{Value: "x"}},
757766
},
758767
{
759768
"let x = true ? 1 : ( 2; 3; 4 ); x",
760769
&VariableDeclaratorNode{
761770
Name: "x",
762771
Value: &ConditionalNode{
763-
Cond: &BoolNode{Value: true},
764-
Exp1: &IntegerNode{Value: 1},
772+
Ternary: true,
773+
Cond: &BoolNode{Value: true},
774+
Exp1: &IntegerNode{Value: 1},
765775
Exp2: &SequenceNode{
766776
Nodes: []Node{
767777
&IntegerNode{Value: 2},
@@ -785,7 +795,8 @@ world`},
785795
Nodes: []Node{
786796
&IntegerNode{Value: 4},
787797
&IntegerNode{Value: 5},
788-
&IntegerNode{Value: 6}}}},
798+
&IntegerNode{Value: 6}}},
799+
},
789800
},
790801
{
791802
`all(ls, if true { 1 } else { 2 })`,
@@ -797,7 +808,8 @@ world`},
797808
Node: &ConditionalNode{
798809
Cond: &BoolNode{Value: true},
799810
Exp1: &IntegerNode{Value: 1},
800-
Exp2: &IntegerNode{Value: 2}}}}},
811+
Exp2: &IntegerNode{Value: 2},
812+
}}}},
801813
},
802814
{
803815
`let x = if true { 1 } else { 2 }; x`,
@@ -806,7 +818,8 @@ world`},
806818
Value: &ConditionalNode{
807819
Cond: &BoolNode{Value: true},
808820
Exp1: &IntegerNode{Value: 1},
809-
Exp2: &IntegerNode{Value: 2}},
821+
Exp2: &IntegerNode{Value: 2},
822+
},
810823
Expr: &IdentifierNode{Value: "x"}},
811824
},
812825
{
@@ -817,7 +830,8 @@ world`},
817830
&ConditionalNode{
818831
Cond: &BoolNode{Value: true},
819832
Exp1: &IntegerNode{Value: 1},
820-
Exp2: &IntegerNode{Value: 2}}}},
833+
Exp2: &IntegerNode{Value: 2},
834+
}}},
821835
},
822836
{
823837
`[if true { 1 } else { 2 }]`,
@@ -826,7 +840,8 @@ world`},
826840
&ConditionalNode{
827841
Cond: &BoolNode{Value: true},
828842
Exp1: &IntegerNode{Value: 1},
829-
Exp2: &IntegerNode{Value: 2}}}},
843+
Exp2: &IntegerNode{Value: 2},
844+
}}},
830845
},
831846
{
832847
`map(ls, { 1; 2; 3 })`,

0 commit comments

Comments
 (0)