shithub: scc

Download patch

ref: d7f2425b01e1c9643b82d5c565d73a0aee04384c
parent: bd985d9e0ba924bfb73ff0abb5004f1be04ffa34
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Aug 28 15:45:41 EDT 2012

Added control about nesting levels

If we don't want have a stack colition with the heap, we should check the
nesting level, because in other case the recursion will be controlled by the
user, and this is dangerous. It is also important not only check the deep
level, and write why we nest (while, do, for, switch), because this
information will be used later for break, continue, case and default.

--- a/flow.c
+++ b/flow.c
@@ -1,12 +1,33 @@
 
+#include <assert.h>
 #include <stdio.h>
 
 #include "symbol.h"
 #include "tokens.h"
 #include "syntax.h"
+#include "sizes.h"
 
 static struct node *stmt(void);
 
+
+static unsigned char blocks[NR_BLOCK];
+static unsigned char *blockp = blocks;
+
+static void
+push(register unsigned char b)
+{
+	if (blockp == &blocks[NR_BLOCK])
+		error("Too much nesting levels");
+	*blockp++ = b;
+}
+
+static void
+pop(void)
+{
+	assert(blockp >= blocks);
+	--blockp;
+}
+
 static struct node *
 _goto(void)
 {
@@ -25,19 +46,22 @@
 static struct node *
 _while(void)
 {
-	register struct node *cond;
+	register struct node *cond, *np;
 
 	expect(WHILE);
 	expect('(');
 	cond = expr();
 	expect(')');
-	return node2(OWHILE, cond, stmt());
+	push(OWHILE);
+	np = node2(OWHILE, cond, stmt());
+	pop();
+	return np;
 }
 
 static struct node *
 _do(void)
 {
-	register struct node *cond, *body;
+	register struct node *cond, *body, *np;
 
 	expect(DO);
 	body = stmt();
@@ -47,7 +71,10 @@
 	expect(')');
 	expect(';');
 
-	return node2(ODO, body, cond);
+	push(ODO);
+	np = node2(ODO, body, cond);
+	pop();
+	return np;
 }
 
 static struct node *
@@ -54,6 +81,7 @@
 _for(void)
 {
 	register struct node *exp1, *exp2, *exp3;
+	struct node *np;
 
 	expect(FOR);
 	expect('(');
@@ -63,8 +91,11 @@
 	expect(';');
 	exp3 = (yytoken != ')') ? expr() : NULL;
 	expect(')');
-	
-	return node2(OFOR, node3(OFEXP, exp1, exp2, exp3), stmt());
+
+	push(OFOR);
+	np = node2(OFOR, node3(OFEXP, exp1, exp2, exp3), stmt());
+	pop();
+	return np;
 }
 
 static struct node *
@@ -84,13 +115,17 @@
 static struct node *
 _switch(void)
 {
-	register struct node *cond;
+	register struct node *cond, *np;
 
 	expect(SWITCH);
 	expect('(');
 	cond = expr();
 	expect(')');
-	return node2(OSWITCH, cond, stmt());
+
+	push(OSWITCH);
+	np = node2(OSWITCH, cond, stmt());
+	pop();
+	return np;
 }
 
 static struct node *