Skip to content

Commit

Permalink
Allow else if (#91)
Browse files Browse the repository at this point in the history
* Allow else if

* Add pretty print of else if on same line
  • Loading branch information
ldemailly authored Aug 2, 2024
1 parent bedeb61 commit d8fedc3
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 7 deletions.
25 changes: 18 additions & 7 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,21 +303,32 @@ type IfExpression struct {
Alternative *Statements
}

func (ie IfExpression) handlElse(out *PrintState) {
if out.Compact {
out.Print("else")
} else {
out.Print(" else ")
}
if len(ie.Alternative.Statements) == 1 && ie.Alternative.Statements[0].Value().Type() == token.IF {
// else if
if out.Compact {
out.Print(" ")
}
ie.Alternative.Statements[0].PrettyPrint(out)
return
}
ie.Alternative.PrettyPrint(out)
}

func (ie IfExpression) PrettyPrint(out *PrintState) *PrintState {
out.Print("if ")
ie.Condition.PrettyPrint(out)
if !out.Compact {
out.Print(" ")
}
ie.Consequence.PrettyPrint(out)

if ie.Alternative != nil {
if out.Compact {
out.Print("else")
} else {
out.Print(" else ")
}
ie.Alternative.PrettyPrint(out)
ie.handlElse(out)
}
return out
}
Expand Down
3 changes: 3 additions & 0 deletions eval/eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ func TestIfElseExpressions(t *testing.T) {
{"if (1 > 2) { 10 }", nil},
{"if (1 > 2) { 10 } else { 20 }", 20},
{"if (1 < 2) { 10 } else { 20 }", 10},
{"i=1; if (i>=3) {10} else if (i>=2) {20} else {30}", 30},
{"i=2; if (i>=3) {10} else if (i>=2) {20} else {30}", 20},
{"i=3; if (i>=3) {10} else if (i>=2) {20} else {30}", 10},
}

for _, tt := range tests {
Expand Down
6 changes: 6 additions & 0 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,12 @@ func (p *Parser) parseIfExpression() ast.Node {
if p.peekTokenIs(token.ELSE) {
p.nextToken()

if p.peekTokenIs(token.IF) {
p.nextToken()
expression.Alternative = &ast.Statements{Statements: []ast.Node{p.parseIfExpression()}}
return expression
}

if !p.expectPeek(token.LBRACE) {
return nil
}
Expand Down
13 changes: 13 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,17 @@ d = [4, 5, 6]
e = "f"`,
`m={1:"a","b":2}c=3 d=[4,5,6]e="f"`,
},
{
`if (i>3) {10} else if (i>2) {20} else {30}`,
`if i > 3 {
10
} else if i > 2 {
20
} else {
30
}`,
`if i>3{10}else if i>2{20}else{30}`,
},
}
for i, tt := range tests {
l := lexer.New(tt.input)
Expand All @@ -297,6 +308,8 @@ e = "f"`,
if actual != tt.expected {
t.Errorf("test [%d] failing for long form\n---input---\n%s\n---expected---\n%s\n---actual---\n%s\n---",
i, tt.input, tt.expected, actual)
// sometime differences are tabs or newline so print escaped versions too:
t.Errorf("test [%d] failing for long form expected %q got %q", i, tt.expected, actual)
}
ps := ast.NewPrintState()
ps.Compact = true
Expand Down

0 comments on commit d8fedc3

Please sign in to comment.