Skip to content

Commit 6838cad

Browse files
Check for mismatched scope begin/end in typecheck
1 parent 66ac669 commit 6838cad

File tree

1 file changed

+26
-21
lines changed

1 file changed

+26
-21
lines changed

src/typecheck.js

Lines changed: 26 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,22 @@ 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);
667672
} else if (a.op == "tryend") {
668-
scopepop(a.pos);
673+
scopepop(a, "catch", "catcherr");
669674
} else if (a.op == "throw") {
670675
} else if (a.op == "comment") {
671676
//pass
672677
} else {
673678
}
674679
}
675-
scopepop(a.pos);
680+
scopepop({ pos: a.pos, op: "EOF" }, "global");
676681
// console.log(scope.length)
677682
// console.dir(signature,{maxArrayLength:null,depth:null})
678683

0 commit comments

Comments
 (0)