@@ -33,6 +33,7 @@ class StackChecker {
3333 StackCell[] stack;
3434 string [] identifiers;
3535 string [][string ] structs;
36+ size_t [] whileStacks;
3637
3738 this () {
3839 structs[" Array" ] = [" length" , " memberSize" , " elements" ];
@@ -207,7 +208,8 @@ class StackChecker {
207208 Evaluate(node.condition);
208209 Pop(node.condition[$ - 1 ], 1 );
209210
210- size_t oldSize = stack.length;
211+ size_t oldSize = stack.length;
212+ whileStacks ~= stack.length;
211213 Evaluate(node.doWhile);
212214
213215 if (oldSize != stack.length) {
@@ -222,6 +224,19 @@ class StackChecker {
222224 stack = oldStack;
223225 }
224226
227+ void EvaluateBreakContinue (WordNode node) {
228+ if (whileStacks.length == 0 ) {
229+ Error(node.error, " Not in while loops" );
230+ }
231+
232+ if (stack.length > whileStacks[$ - 1 ]) {
233+ StackOverflow(node, whileStacks[$ - 1 ]);
234+ }
235+ else if (stack.length < whileStacks[$ - 1 ]) {
236+ Error(node.error, " Stack underflow" );
237+ }
238+ }
239+
225240 void EvaluateDef (LetNode node) {
226241 identifiers ~= node.name;
227242 }
@@ -233,6 +248,10 @@ class StackChecker {
233248 void EvaluateExtern (ExternNode node) {
234249 string name = node.asName == " " ? node.func : node.asName;
235250
251+ if (name in words) {
252+ Error(node.error, " Word '%s' already exists" , name);
253+ }
254+
236255 if (node.externType == ExternType.C) {
237256 words[name] = Word(
238257 Effect(node.retType == " void" ? 0 : 1 , node.types.length)
@@ -318,8 +337,8 @@ class StackChecker {
318337
319338 switch (wnode.name) {
320339 case " return" : Pop(node, 1 ); break ;
321- case " continue" : break ;
322- case " break" : break ;
340+ case " continue" : EvaluateBreakContinue(wnode); break ;
341+ case " break" : EvaluateBreakContinue(wnode); break ;
323342 case " call" : Error(node.error, " Call is unsafe" ); break ;
324343 case " throw" : Pop(node, 1 ); break ;
325344 case " error" : Error(node.error, " Error thrown by code" ); break ;
0 commit comments