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 *