Skip to content

Commit 344fbb1

Browse files
committed
split operator evaluators from call dispatch runtime
1 parent d6bedc5 commit 344fbb1

2 files changed

Lines changed: 128 additions & 127 deletions

File tree

vibes/execution_calls.go

Lines changed: 0 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -151,133 +151,6 @@ func (exec *Execution) callFunction(fn *ScriptFunction, receiver Value, args []V
151151
return val, nil
152152
}
153153

154-
func (exec *Execution) evalUnaryExpr(e *UnaryExpr, env *Env) (Value, error) {
155-
right, err := exec.evalExpressionWithAuto(e.Right, env, true)
156-
if err != nil {
157-
return NewNil(), err
158-
}
159-
if err := exec.checkMemoryWith(right); err != nil {
160-
return NewNil(), err
161-
}
162-
switch e.Operator {
163-
case tokenMinus:
164-
switch right.Kind() {
165-
case KindInt:
166-
return NewInt(-right.Int()), nil
167-
case KindFloat:
168-
return NewFloat(-right.Float()), nil
169-
default:
170-
return NewNil(), exec.errorAt(e.Pos(), "unsupported unary - operand")
171-
}
172-
case tokenBang:
173-
return NewBool(!right.Truthy()), nil
174-
default:
175-
return NewNil(), exec.errorAt(e.Pos(), "unsupported unary operator")
176-
}
177-
}
178-
179-
func (exec *Execution) evalIndexExpr(e *IndexExpr, env *Env) (Value, error) {
180-
obj, err := exec.evalExpressionWithAuto(e.Object, env, true)
181-
if err != nil {
182-
return NewNil(), err
183-
}
184-
if err := exec.checkMemoryWith(obj); err != nil {
185-
return NewNil(), err
186-
}
187-
idx, err := exec.evalExpressionWithAuto(e.Index, env, true)
188-
if err != nil {
189-
return NewNil(), err
190-
}
191-
if err := exec.checkMemoryWith(idx); err != nil {
192-
return NewNil(), err
193-
}
194-
switch obj.Kind() {
195-
case KindString:
196-
i, err := valueToInt(idx)
197-
if err != nil {
198-
return NewNil(), exec.errorAt(e.Index.Pos(), "%s", err.Error())
199-
}
200-
runes := []rune(obj.String())
201-
if i < 0 || i >= len(runes) {
202-
return NewNil(), exec.errorAt(e.Index.Pos(), "string index out of bounds")
203-
}
204-
return NewString(string(runes[i])), nil
205-
case KindArray:
206-
i, err := valueToInt(idx)
207-
if err != nil {
208-
return NewNil(), exec.errorAt(e.Index.Pos(), "%s", err.Error())
209-
}
210-
arr := obj.Array()
211-
if i < 0 || i >= len(arr) {
212-
return NewNil(), exec.errorAt(e.Index.Pos(), "array index out of bounds")
213-
}
214-
return arr[i], nil
215-
case KindHash, KindObject:
216-
key, err := valueToHashKey(idx)
217-
if err != nil {
218-
return NewNil(), exec.errorAt(e.Index.Pos(), "%s", err.Error())
219-
}
220-
val, ok := obj.Hash()[key]
221-
if !ok {
222-
return NewNil(), nil
223-
}
224-
return val, nil
225-
default:
226-
return NewNil(), exec.errorAt(e.Object.Pos(), "cannot index %s", obj.Kind())
227-
}
228-
}
229-
230-
func (exec *Execution) evalBinaryExpr(expr *BinaryExpr, env *Env) (Value, error) {
231-
left, err := exec.evalExpression(expr.Left, env)
232-
if err != nil {
233-
return NewNil(), err
234-
}
235-
right, err := exec.evalExpression(expr.Right, env)
236-
if err != nil {
237-
return NewNil(), err
238-
}
239-
if err := exec.checkMemoryWith(left, right); err != nil {
240-
return NewNil(), err
241-
}
242-
243-
var result Value
244-
switch expr.Operator {
245-
case tokenPlus:
246-
result, err = addValues(left, right)
247-
case tokenMinus:
248-
result, err = subtractValues(left, right)
249-
case tokenAsterisk:
250-
result, err = multiplyValues(left, right)
251-
case tokenSlash:
252-
result, err = divideValues(left, right)
253-
case tokenPercent:
254-
result, err = moduloValues(left, right)
255-
case tokenEQ:
256-
return NewBool(left.Equal(right)), nil
257-
case tokenNotEQ:
258-
return NewBool(!left.Equal(right)), nil
259-
case tokenLT:
260-
return compareValues(expr, left, right, func(c int) bool { return c < 0 })
261-
case tokenLTE:
262-
return compareValues(expr, left, right, func(c int) bool { return c <= 0 })
263-
case tokenGT:
264-
return compareValues(expr, left, right, func(c int) bool { return c > 0 })
265-
case tokenGTE:
266-
return compareValues(expr, left, right, func(c int) bool { return c >= 0 })
267-
case tokenAnd:
268-
return NewBool(left.Truthy() && right.Truthy()), nil
269-
case tokenOr:
270-
return NewBool(left.Truthy() || right.Truthy()), nil
271-
default:
272-
return NewNil(), exec.errorAt(expr.Pos(), "unsupported operator")
273-
}
274-
275-
if err != nil {
276-
return NewNil(), exec.wrapError(err, expr.Pos())
277-
}
278-
return result, nil
279-
}
280-
281154
func (exec *Execution) evalCallTarget(call *CallExpr, env *Env) (Value, Value, error) {
282155
if member, ok := call.Callee.(*MemberExpr); ok {
283156
receiver, err := exec.evalExpression(member.Object, env)

vibes/execution_operators.go

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package vibes
2+
3+
func (exec *Execution) evalUnaryExpr(e *UnaryExpr, env *Env) (Value, error) {
4+
right, err := exec.evalExpressionWithAuto(e.Right, env, true)
5+
if err != nil {
6+
return NewNil(), err
7+
}
8+
if err := exec.checkMemoryWith(right); err != nil {
9+
return NewNil(), err
10+
}
11+
switch e.Operator {
12+
case tokenMinus:
13+
switch right.Kind() {
14+
case KindInt:
15+
return NewInt(-right.Int()), nil
16+
case KindFloat:
17+
return NewFloat(-right.Float()), nil
18+
default:
19+
return NewNil(), exec.errorAt(e.Pos(), "unsupported unary - operand")
20+
}
21+
case tokenBang:
22+
return NewBool(!right.Truthy()), nil
23+
default:
24+
return NewNil(), exec.errorAt(e.Pos(), "unsupported unary operator")
25+
}
26+
}
27+
28+
func (exec *Execution) evalIndexExpr(e *IndexExpr, env *Env) (Value, error) {
29+
obj, err := exec.evalExpressionWithAuto(e.Object, env, true)
30+
if err != nil {
31+
return NewNil(), err
32+
}
33+
if err := exec.checkMemoryWith(obj); err != nil {
34+
return NewNil(), err
35+
}
36+
idx, err := exec.evalExpressionWithAuto(e.Index, env, true)
37+
if err != nil {
38+
return NewNil(), err
39+
}
40+
if err := exec.checkMemoryWith(idx); err != nil {
41+
return NewNil(), err
42+
}
43+
switch obj.Kind() {
44+
case KindString:
45+
i, err := valueToInt(idx)
46+
if err != nil {
47+
return NewNil(), exec.errorAt(e.Index.Pos(), "%s", err.Error())
48+
}
49+
runes := []rune(obj.String())
50+
if i < 0 || i >= len(runes) {
51+
return NewNil(), exec.errorAt(e.Index.Pos(), "string index out of bounds")
52+
}
53+
return NewString(string(runes[i])), nil
54+
case KindArray:
55+
i, err := valueToInt(idx)
56+
if err != nil {
57+
return NewNil(), exec.errorAt(e.Index.Pos(), "%s", err.Error())
58+
}
59+
arr := obj.Array()
60+
if i < 0 || i >= len(arr) {
61+
return NewNil(), exec.errorAt(e.Index.Pos(), "array index out of bounds")
62+
}
63+
return arr[i], nil
64+
case KindHash, KindObject:
65+
key, err := valueToHashKey(idx)
66+
if err != nil {
67+
return NewNil(), exec.errorAt(e.Index.Pos(), "%s", err.Error())
68+
}
69+
val, ok := obj.Hash()[key]
70+
if !ok {
71+
return NewNil(), nil
72+
}
73+
return val, nil
74+
default:
75+
return NewNil(), exec.errorAt(e.Object.Pos(), "cannot index %s", obj.Kind())
76+
}
77+
}
78+
79+
func (exec *Execution) evalBinaryExpr(expr *BinaryExpr, env *Env) (Value, error) {
80+
left, err := exec.evalExpression(expr.Left, env)
81+
if err != nil {
82+
return NewNil(), err
83+
}
84+
right, err := exec.evalExpression(expr.Right, env)
85+
if err != nil {
86+
return NewNil(), err
87+
}
88+
if err := exec.checkMemoryWith(left, right); err != nil {
89+
return NewNil(), err
90+
}
91+
92+
var result Value
93+
switch expr.Operator {
94+
case tokenPlus:
95+
result, err = addValues(left, right)
96+
case tokenMinus:
97+
result, err = subtractValues(left, right)
98+
case tokenAsterisk:
99+
result, err = multiplyValues(left, right)
100+
case tokenSlash:
101+
result, err = divideValues(left, right)
102+
case tokenPercent:
103+
result, err = moduloValues(left, right)
104+
case tokenEQ:
105+
return NewBool(left.Equal(right)), nil
106+
case tokenNotEQ:
107+
return NewBool(!left.Equal(right)), nil
108+
case tokenLT:
109+
return compareValues(expr, left, right, func(c int) bool { return c < 0 })
110+
case tokenLTE:
111+
return compareValues(expr, left, right, func(c int) bool { return c <= 0 })
112+
case tokenGT:
113+
return compareValues(expr, left, right, func(c int) bool { return c > 0 })
114+
case tokenGTE:
115+
return compareValues(expr, left, right, func(c int) bool { return c >= 0 })
116+
case tokenAnd:
117+
return NewBool(left.Truthy() && right.Truthy()), nil
118+
case tokenOr:
119+
return NewBool(left.Truthy() || right.Truthy()), nil
120+
default:
121+
return NewNil(), exec.errorAt(expr.Pos(), "unsupported operator")
122+
}
123+
124+
if err != nil {
125+
return NewNil(), exec.wrapError(err, expr.Pos())
126+
}
127+
return result, nil
128+
}

0 commit comments

Comments
 (0)