Skip to content

Commit

Permalink
Merge pull request #83 from skx/allow-raw-line-for-if
Browse files Browse the repository at this point in the history
Allow omitting GOTO for IF-tests.
  • Loading branch information
skx authored Jan 24, 2019
2 parents 111d7d3 + 5b0232e commit 8b4a675
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
25 changes: 25 additions & 0 deletions eval/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ func New(stream *tokenizer.Tokenizer) (*Interpreter, error) {
//
t.fns = make(map[string]userFunction)

//
// The previous token we've seen, if any.
//
var prevToken token.Token

//
// Save the tokens that our program consists of, one by one,
// until we hit the end.
Expand Down Expand Up @@ -169,9 +174,29 @@ func New(stream *tokenizer.Tokenizer) (*Interpreter, error) {
// sequential. Or at least going-backwards.
}

//
// If the previous token was a "THEN" or "ELSE", and the
// current token is an integer then we add in the implicit
// GOTO.
//
// This allows the following two programs to be identical:
//
// IF 1 < 2 THEN 300 ELSE 400
//
// IF 1 < 2 THEN GOTO 300 ELSE GOTO 400
//
if prevToken.Type == token.THEN || prevToken.Type == token.ELSE {
if tok.Type == token.INT {
t.program = append(t.program,
token.Token{Type: token.GOTO, Literal: "GOTO"})
}
}

// Regardless append the token to our array
t.program = append(t.program, tok)

// Continue - recording the previous token too.
prevToken = tok
offset++
}

Expand Down
66 changes: 66 additions & 0 deletions eval/eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,72 @@ func TestIF(t *testing.T) {
t.Errorf("The error we found was not what we expected: %s", err.Error())
}

//
// Now some simple tests of "GOTO" in IF
//
// The first with a `GOTO` token, the second without.
//
test1 := `
10 IF 2 < 10 THEN GOTO 40
20 LET a = 3
30 END
40 LET a = 33
50 END
`
test2 := `
10 IF 2 < 10 THEN 40 ELSE 99
20 LET a = 2
30 END
40 LET a = 313
50 END
`
//
// test1
//
e, err = FromString(test1)
if err != nil {
t.Errorf("Failed to parse program")
}

err = e.Run()
if err != nil {
t.Errorf("Didn't expect a runtime-error, received one %s", err.Error())
}
cur := e.GetVariable("a")
if cur.Type() == object.ERROR {
t.Errorf("Variable 'a' does not exist for %s", test1)
}
if cur.Type() != object.NUMBER {
t.Errorf("Variable 'a' had wrong type: %s", cur.String())
}
out := cur.(*object.NumberObject).Value
if out != 33 {
t.Errorf("Expected 'a' to be %d, got %f", 33, out)
}

//
// test2
//
e, err = FromString(test2)
if err != nil {
t.Errorf("Failed to parse program")
}

err = e.Run()
if err != nil {
t.Errorf("Didn't expect a runtime-error, received one %s", err.Error())
}
cur = e.GetVariable("a")
if cur.Type() == object.ERROR {
t.Errorf("Variable 'a' does not exist for %s", test2)
}
if cur.Type() != object.NUMBER {
t.Errorf("Variable 'a' had wrong type: %s", cur.String())
}
out = cur.(*object.NumberObject).Value
if out != 313 {
t.Errorf("Expected 'a' to be %d, got %f", 313, out)
}
}

// TestINPUT performs testing of our INPUT implementation.
Expand Down

0 comments on commit 8b4a675

Please sign in to comment.