-
Notifications
You must be signed in to change notification settings - Fork 0
/
statement.go
83 lines (63 loc) · 2.25 KB
/
statement.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package executor
import (
"github.com/peter-mount/go-script/errors"
"github.com/peter-mount/go-script/script"
)
// Statements executes a Statements block.
// Within this it runs with its own variable scope which is automatically closed when it completes
func (e *executor) Statements(statements *script.Statements) error {
// Do nothing if it's an empty block
if statements == nil || len(statements.Statements) == 0 {
return nil
}
e.state.NewScope()
defer e.state.EndScope()
s := statements.Statements[0]
for s != nil {
if err := e.Statement(s); err != nil {
return errors.Error(s.Pos, err)
}
s = s.Next
}
return nil
}
func (e *executor) Statement(statement *script.Statement) error {
if statement == nil || statement.Empty {
return nil
}
switch {
case statement.Block != nil:
return errors.Error(statement.Pos, e.Statements(statement.Block))
case statement.Expression != nil:
// Wrap visit to Expression, so we don't leak return values on the stack
_, _, err := e.calculator.Calculate(func() error {
return errors.Error(statement.Pos, e.Expression(statement.Expression))
})
return err
case statement.For != nil:
return errors.Error(statement.Pos, e.forStatement(statement.For))
case statement.ForRange != nil:
return errors.Error(statement.Pos, e.forRange(statement.ForRange))
case statement.IfStmt != nil:
return errors.Error(statement.Pos, e.ifStatement(statement.IfStmt))
case statement.DoWhile != nil:
return errors.Error(statement.Pos, e.doWhile(statement.DoWhile))
case statement.Repeat != nil:
return errors.Error(statement.Pos, e.repeatUntil(statement.Repeat))
case statement.While != nil:
return errors.Error(statement.Pos, e.while(statement.While))
case statement.Return != nil:
return errors.Error(statement.Pos, e.returnStatement(statement.Return))
case statement.Break:
return errors.Break()
case statement.Continue:
return errors.Continue()
case statement.Switch != nil:
return errors.Error(statement.Pos, e.switchStatement(statement.Switch))
case statement.Try != nil:
return errors.Error(statement.Pos, e.try(statement.Try))
default:
// This will fail if we add a new statement, but it's not yet implemented.
return errors.Errorf(statement.Pos, "unimplemented statement reached")
}
}