Skip to content

Commit 65ab2b0

Browse files
authored
Merge pull request #496 from statementreply/strengthen-scope-check
Check for mismatched scope begin/end in typecheck
2 parents 66ac669 + 6dcba72 commit 65ab2b0

File tree

4 files changed

+34
-24
lines changed

4 files changed

+34
-24
lines changed

lib/js/位經.wy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@
3535

3636
疏曰「「位變。同犀之~x也。」」
3737
今有一術。名之曰「位變」。欲行是術。必先得一數。曰「甲」。乃行是術曰。
38-
施「(x=>y=>(~x))」於「甲」。名之曰「乙」。乃得「乙」。
38+
施「(x=>(~x))」於「甲」。名之曰「乙」。乃得「乙」。
3939
是謂「位變」之術也。

lib/列經.wy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
今有一術。名之曰「擷取」。欲行是術。必先得一列。曰「甲」。二數。曰「乙」曰「丙」。乃行是術曰。
8787
吾有一列。名之曰「丁」。
8888
吾有一數。曰「乙」。名之曰「戊」。
89-
若「丙」小於零者。夫「甲」之長。加其以「丙」。昔之「丙」者。今其是矣。
89+
若「丙」小於零者。夫「甲」之長。加其以「丙」。昔之「丙」者。今其是矣。云云。
9090

9191
恆為是。若「戊」大於「丙」者乃止也。
9292
夫「甲」之「戊」。充「丁」以其。

lib/曆法.wy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@
149149
夫「乙」之「「商」」。加其以一。夫「數字」之其。加其以「「十」」。昔之「數」者。今其是矣。云云。
150150
夫「乙」之「「餘」」。若其大於零者。
151151
夫「乙」之「「餘」」。加其以一。夫「數字」之其。加「數」以其。昔之「數」者。今其是矣。云云。
152-
乃得「數」
152+
乃得「數」。
153153
是謂「言百內數」之術也。
154154

155155
吾有一術。名之曰「言年月日」。欲行是術。必先得一數。曰「積日」。乃行是術曰。
@@ -173,6 +173,7 @@
173173
夫「年」。取一以施「言百內數」。加其以「「年」」。加「年月日」以其。昔之「年月日」者。今其是矣。
174174
若非。
175175
夫「年」。取一以施「言序數」。加其以「「年」」。加「年月日」以其。昔之「年月日」者。今其是矣。
176+
云云。
176177
減一於「積年」。除其以十。所餘幾何。加其以一。夫「天干」之其。加「年月日」以其。昔之「年月日」者。今其是矣。
177178
減一於「積年」。除其以十二。所餘幾何。加其以一。夫「地支」之其。加「年月日」以其。昔之「年月日」者。今其是矣。
178179
加「年月日」以「「年」」。昔之「年月日」者。今其是矣。
@@ -183,6 +184,7 @@
183184
加「年月日」以「「正月」」。昔之「年月日」者。今其是矣。
184185
若非。
185186
夫「月」。取一以施「言百內數」。加其以「「月」」。加「年月日」以其。昔之「年月日」者。今其是矣。
187+
云云。
186188

187189
若「日」不大於十者。
188190
加「年月日」以「「初」」。昔之「年月日」者。今其是矣。云云。

src/typecheck.js

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ function typecheck(
7878
let imported = [];
7979
let strayvar = [];
8080
let scope = [{}];
81-
let scopestarts = [0];
81+
let scopestarts = [{ pos: 0, op: "global" }];
8282
let signature = [];
8383
let funstack = [];
8484
let funretcnt = [];
@@ -178,15 +178,20 @@ function typecheck(
178178
return t.fields[x];
179179
}
180180

181-
function scopepush(pos) {
181+
function scopepush(tok) {
182182
scope.push({});
183-
scopestarts.push(pos);
183+
scopestarts.push(tok);
184184
}
185185

186-
function scopepop(pos) {
186+
function scopepop(tok, ...acceptScopeStartOps) {
187187
let ss = scopestarts.pop();
188188
let s = scope.pop();
189-
signature.push([[ss, pos, scope.length], s]);
189+
assert(
190+
`[Type] Unexpected '${tok.op}' in '${ss.op}' block`,
191+
tok.pos,
192+
acceptScopeStartOps.indexOf(ss.op) >= 0
193+
);
194+
signature.push([[ss.pos, tok.pos, scope.length], s]);
190195
}
191196

192197
function logscope() {
@@ -303,11 +308,11 @@ function typecheck(
303308
let ptr = scope[scope.length - 1][funstack[funstack.length - 1]];
304309
ptr.in = inittype("nil");
305310
}
306-
scopepush(a.pos);
311+
scopepush(a);
307312
} else if (a.op == "funend") {
308313
var f = funstack.pop();
309314
var n = funretcnt.pop();
310-
scopepop(a.pos);
315+
scopepop(a, "funbody");
311316

312317
if (n == 0) {
313318
var ptr = scope[scope.length - 1][f];
@@ -325,12 +330,12 @@ function typecheck(
325330
a.type
326331
);
327332
} else if (a.op == "end") {
328-
scopepop(a.pos);
333+
scopepop(a, "if", "else", "for", "whiletrue", "whilen");
329334
} else if (a.op == "if") {
330-
scopepush(a.pos);
335+
scopepush(a);
331336
} else if (a.op == "else") {
332-
scopepop(a.pos);
333-
scopepush(a.pos);
337+
scopepop(a, "if");
338+
scopepush(a);
334339
} else if (a.op == "return") {
335340
funretcnt[funretcnt.length - 1]++;
336341
let ptr;
@@ -536,14 +541,14 @@ function typecheck(
536541

537542
gettype(a.container).element = Object.assign({}, typ);
538543
} else if (a.op == "for") {
539-
scopepush(a.pos);
544+
scopepush(a);
540545
typeassert(`For-each LHS`, [inittype("arr")], a.container, a.pos);
541546
scope[scope.length - 1][a.iterator] =
542547
gettype(a.container).element || inittype("any");
543548
} else if (a.op == "whiletrue") {
544-
scopepush(a.pos);
549+
scopepush(a);
545550
} else if (a.op == "whilen") {
546-
scopepush(a.pos);
551+
scopepush(a);
547552
} else if (a.op == "break") {
548553
//pass
549554
} else if (a.op == "not") {
@@ -657,22 +662,25 @@ function typecheck(
657662
} else if (a.op == "import") {
658663
imported = imported.concat(a.iden);
659664
} else if (a.op == "try") {
660-
scopepush(a.pos);
665+
scopepush(a);
661666
} else if (a.op == "catch") {
662-
scopepop(a.pos);
663-
scopepush(a.pos);
667+
scopepop(a, "try");
668+
scopepush(a);
664669
} else if (a.op == "catcherr") {
665-
scopepop(a.pos);
666-
scopepush(a.pos);
670+
scopepop(a, "catch", "catcherr");
671+
scopepush(a);
672+
if (a.error === undefined) {
673+
strayvar.push(inittype("str"));
674+
}
667675
} else if (a.op == "tryend") {
668-
scopepop(a.pos);
676+
scopepop(a, "catch", "catcherr");
669677
} else if (a.op == "throw") {
670678
} else if (a.op == "comment") {
671679
//pass
672680
} else {
673681
}
674682
}
675-
scopepop(a.pos);
683+
scopepop({ pos: a.pos, op: "EOF" }, "global");
676684
// console.log(scope.length)
677685
// console.dir(signature,{maxArrayLength:null,depth:null})
678686

0 commit comments

Comments
 (0)