Skip to content

Commit 99b25fd

Browse files
committed
Handle Ignore mode from 'run', not from handlers
1 parent 65203fa commit 99b25fd

3 files changed

Lines changed: 36 additions & 82 deletions

File tree

src/runtime/evaluate.ts

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -705,14 +705,11 @@ handlerMap.set(SyntaxKind.INDEXING_EXPR, (frame) => {
705705
if (index.payload < 0 || index.payload >= array.elements.length) {
706706
throw new E604_IndexError("Index out of bounds");
707707
}
708-
if (frame.mode === Mode.GetValue) {
709-
return array.elements[Number(index.payload)];
710-
}
711-
else if (frame.mode === Mode.GetCell) {
708+
if (frame.mode === Mode.GetCell) {
712709
return new ArrayElementCell(array, Number(index.payload));
713710
}
714-
else { // Mode.Ignore
715-
return new NoneValue();
711+
else {
712+
return array.elements[Number(index.payload)];
716713
}
717714
}
718715
}
@@ -814,25 +811,19 @@ handlerMap.set(SyntaxKind.CALL_EXPR, (frame) => {
814811
handlerMap.set(SyntaxKind.INT_LIT_EXPR, (frame) => {
815812
assertNotAssignable(frame);
816813
let payload = intLitExprValue(frame.node).payload as bigint;
817-
return frame.mode === Mode.Ignore
818-
? new NoneValue()
819-
: new IntValue(payload);
814+
return new IntValue(payload);
820815
});
821816

822817
handlerMap.set(SyntaxKind.STR_LIT_EXPR, (frame) => {
823818
assertNotAssignable(frame);
824819
let payload = strLitExprValue(frame.node).payload as string;
825-
return frame.mode === Mode.Ignore
826-
? new NoneValue()
827-
: new StrValue(payload);
820+
return new StrValue(payload);
828821
});
829822

830823
handlerMap.set(SyntaxKind.BOOL_LIT_EXPR, (frame) => {
831824
assertNotAssignable(frame);
832825
let payload = boolLitExprValue(frame.node).payload as boolean;
833-
return frame.mode === Mode.Ignore
834-
? new NoneValue()
835-
: new BoolValue(payload);
826+
return new BoolValue(payload);
836827
});
837828

838829
handlerMap.set(SyntaxKind.NONE_LIT_EXPR, (frame) => {
@@ -868,9 +859,7 @@ handlerMap.set(SyntaxKind.ARRAY_INITIALIZER_EXPR, (frame) => {
868859
return recurse(frame, 1, { node: elements[frame.index] });
869860
}
870861
else {
871-
return frame.mode === Mode.Ignore
872-
? new NoneValue()
873-
: new ArrayValue(frame.vv);
862+
return new ArrayValue(frame.vv);
874863
}
875864
}
876865
case 1: {
@@ -883,20 +872,16 @@ handlerMap.set(SyntaxKind.ARRAY_INITIALIZER_EXPR, (frame) => {
883872

884873
handlerMap.set(SyntaxKind.VAR_REF_EXPR, (frame) => {
885874
let name = varRefExprName(frame.node).payload as string;
886-
if (frame.mode === Mode.GetValue) {
887-
let value = lookup(frame.env, name);
888-
return value;
889-
}
890-
else if (frame.mode === Mode.GetCell) {
875+
if (frame.mode === Mode.GetCell) {
891876
let [mutable, varEnv] = findEnvOfName(frame.env, name);
892877
if (!mutable) {
893878
throw new E608_ReadonlyError(`Binding '${name}' is readonly`);
894879
}
895880
return new VarCell(varEnv, name);
896881
}
897-
else { // Mode.Ignore
898-
/* ignore */ lookup(frame.env, name);
899-
return new NoneValue();
882+
else {
883+
let value = lookup(frame.env, name);
884+
return value;
900885
}
901886
});
902887

@@ -949,10 +934,7 @@ handlerMap.set(SyntaxKind.QUOTE_EXPR, (frame) => {
949934
);
950935
}
951936
else {
952-
if (frame.mode === Mode.Ignore) {
953-
return new NoneValue();
954-
}
955-
else if (statements.length === 1
937+
if (statements.length === 1
956938
&& isExprStatement(statements[0])) {
957939
return (frame.vv[0] as SyntaxNodeValue).children[0];
958940
}
@@ -1111,7 +1093,7 @@ function step(frame: Frame, staticEnvs: Map<SyntaxNode, Env>): Frame | Value {
11111093
let handler = handlerMap.get(frame.node.kind);
11121094
if (handler === undefined) {
11131095
throw new E000_InternalError(
1114-
`Missing handler for ${frame.node.constructor.name}`
1096+
`Missing handler for ${frame.node.kind.name}`
11151097
);
11161098
}
11171099
return handler(frame);
@@ -1124,13 +1106,17 @@ function run(
11241106
fuel: number = Infinity,
11251107
): Value {
11261108
while (true) {
1109+
if (frame === rootFrame) {
1110+
return frame.value;
1111+
}
11271112
let result = step(frame, staticEnvs);
11281113
if (result instanceof Frame) {
1129-
if (result === rootFrame) {
1130-
return result.value;
1131-
}
11321114
frame = result;
11331115
}
1116+
else if (frame.mode === Mode.Ignore) {
1117+
frame = frame.tail!;
1118+
frame.value = new NoneValue();
1119+
}
11341120
else if (result instanceof Cell) {
11351121
frame = frame.tail!;
11361122
frame.cell = result;

src/runtime/infix.ts

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import {
3131
import {
3232
BoolValue,
3333
IntValue,
34-
NoneValue,
3534
StrValue,
3635
Value,
3736
} from "./value";
@@ -61,9 +60,7 @@ infixOpMap.set("+", (frame) => {
6160
if (!(right instanceof IntValue)) {
6261
throw new E603_TypeError("Expected Int as rhs of +");
6362
}
64-
return frame.mode === Mode.Ignore
65-
? new NoneValue()
66-
: new IntValue(left.payload + right.payload);
63+
return new IntValue(left.payload + right.payload);
6764
}
6865
}
6966
throw new E000_InternalError("Unreachable state");
@@ -91,9 +88,7 @@ infixOpMap.set("-", (frame) => {
9188
if (!(right instanceof IntValue)) {
9289
throw new E603_TypeError("Expected Int as rhs of +");
9390
}
94-
return frame.mode === Mode.Ignore
95-
? new NoneValue()
96-
: new IntValue(left.payload - right.payload);
91+
return new IntValue(left.payload - right.payload);
9792
}
9893
}
9994
throw new E000_InternalError("Unreachable state");
@@ -121,9 +116,7 @@ infixOpMap.set("*", (frame) => {
121116
if (!(right instanceof IntValue)) {
122117
throw new E603_TypeError("Expected Int as rhs of +");
123118
}
124-
return frame.mode === Mode.Ignore
125-
? new NoneValue()
126-
: new IntValue(left.payload * right.payload);
119+
return new IntValue(left.payload * right.payload);
127120
}
128121
}
129122
throw new E000_InternalError("Unreachable state");
@@ -157,9 +150,7 @@ infixOpMap.set("//", (frame) => {
157150
let negative = left.payload < 0n !== right.payload < 0n;
158151
let nonZeroMod = left.payload % right.payload !== 0n;
159152
let diff = negative && nonZeroMod ? 1n : 0n;
160-
return frame.mode === Mode.Ignore
161-
? new NoneValue()
162-
: new IntValue(left.payload / right.payload - diff);
153+
return new IntValue(left.payload / right.payload - diff);
163154
}
164155
}
165156
throw new E000_InternalError("Unreachable state");
@@ -190,9 +181,7 @@ infixOpMap.set("%", (frame) => {
190181
if (right.payload === 0n) {
191182
throw new E601_ZeroDivisionError("Division by 0");
192183
}
193-
return frame.mode === Mode.Ignore
194-
? new NoneValue()
195-
: new IntValue(left.payload % right.payload);
184+
return new IntValue(left.payload % right.payload);
196185
}
197186
}
198187
throw new E000_InternalError("Unreachable state");
@@ -216,9 +205,7 @@ infixOpMap.set("~", (frame) => {
216205
let strLeft = frame.v1 as StrValue;
217206
let right = frame.value;
218207
let strRight = stringify(right);
219-
return frame.mode === Mode.Ignore
220-
? new NoneValue()
221-
: new StrValue(strLeft.payload + strRight.payload);
208+
return new StrValue(strLeft.payload + strRight.payload);
222209
}
223210
}
224211
throw new E000_InternalError("Unreachable state");
@@ -238,9 +225,7 @@ infixOpMap.set("&&", (frame) => {
238225
return tailRecurse(frame, { node: rhs });
239226
}
240227
else {
241-
return frame.mode === Mode.Ignore
242-
? new NoneValue()
243-
: left;
228+
return left;
244229
}
245230
}
246231
}
@@ -258,9 +243,7 @@ infixOpMap.set("||", (frame) => {
258243
let left = frame.value;
259244
let rhs = infixOpExprRhs(frame.node);
260245
if (boolify(left)) {
261-
return frame.mode === Mode.Ignore
262-
? new NoneValue()
263-
: left;
246+
return left;
264247
}
265248
else {
266249
return tailRecurse(frame, { node: rhs });
@@ -319,14 +302,11 @@ infixOpMap.set("=", (frame) => {
319302
let cell = frame.cell!;
320303
let value = frame.value;
321304
assign(cell, value);
322-
if (frame.mode === Mode.GetValue) {
323-
return value;
324-
}
325-
else if (frame.mode === Mode.GetCell) {
305+
if (frame.mode === Mode.GetCell) {
326306
return cell;
327307
}
328-
else { // Mode.Ignore
329-
return new NoneValue();
308+
else {
309+
return value;
330310
}
331311
}
332312
}

src/runtime/prefix.ts

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
} from "./error";
1111
import {
1212
Frame,
13-
Mode,
1413
recurse,
1514
} from "./frame";
1615
import {
@@ -19,7 +18,6 @@ import {
1918
import {
2019
BoolValue,
2120
IntValue,
22-
NoneValue,
2321
Value,
2422
} from "./value";
2523

@@ -37,9 +35,7 @@ prefixOpMap.set("+", (frame) => {
3735
if (!(value instanceof IntValue)) {
3836
throw new E603_TypeError("Expected Int as operand of +");
3937
}
40-
return frame.mode === Mode.Ignore
41-
? new NoneValue()
42-
: new IntValue(value.payload);
38+
return new IntValue(value.payload);
4339
}
4440
}
4541
throw new E000_InternalError("Unreachable state");
@@ -56,9 +52,7 @@ prefixOpMap.set("-", (frame) => {
5652
if (!(value instanceof IntValue)) {
5753
throw new E603_TypeError("Expected Int as operand of -");
5854
}
59-
return frame.mode === Mode.Ignore
60-
? new NoneValue()
61-
: new IntValue(-value.payload);
55+
return new IntValue(-value.payload);
6256
}
6357
}
6458
throw new E000_InternalError("Unreachable state");
@@ -72,9 +66,7 @@ prefixOpMap.set("~", (frame) => {
7266
}
7367
case 1: {
7468
let value = frame.value;
75-
return frame.mode === Mode.Ignore
76-
? new NoneValue()
77-
: stringify(value);
69+
return stringify(value);
7870
}
7971
}
8072
throw new E000_InternalError("Unreachable state");
@@ -88,9 +80,7 @@ prefixOpMap.set("?", (frame) => {
8880
}
8981
case 1: {
9082
let value = frame.value;
91-
return frame.mode === Mode.Ignore
92-
? new NoneValue()
93-
: new BoolValue(boolify(value));
83+
return new BoolValue(boolify(value));
9484
}
9585
}
9686
throw new E000_InternalError("Unreachable state");
@@ -104,9 +94,7 @@ prefixOpMap.set("!", (frame) => {
10494
}
10595
case 1: {
10696
let value = frame.value;
107-
return frame.mode === Mode.Ignore
108-
? new NoneValue()
109-
: new BoolValue(!boolify(value));
97+
return new BoolValue(!boolify(value));
11098
}
11199
}
112100
throw new E000_InternalError("Unreachable state");

0 commit comments

Comments
 (0)