Skip to content
Snippets Groups Projects
Commit e632939c authored by benjamin.franksen's avatar benjamin.franksen
Browse files

snc: simplified parsing and code generation for blocks

parent 443e2d60
No related branches found
No related tags found
No related merge requests found
......@@ -169,11 +169,6 @@ VarList **pvar_list_from_scope(Expr *scope)
case D_STATE:
assert(scope->extra.e_state); /* invariant */
return &scope->extra.e_state->var_list;
case D_WHEN:
assert(scope->extra.e_when); /* invariant */
return &scope->extra.e_when->var_list;
case D_ENTEX:
return &scope->extra.e_entex;
case S_CMPND:
return &scope->extra.e_cmpnd;
default:
......@@ -194,10 +189,6 @@ Expr *defn_list_from_scope(Expr *scope)
return scope->ss_defns;
case D_STATE:
return scope->state_defns;
case D_WHEN:
return scope->when_defns;
case D_ENTEX:
return scope->entex_defns;
case S_CMPND:
return scope->cmpnd_defns;
default:
......
......@@ -182,23 +182,30 @@ static void gen_state_func(
{
gen_code("\n/* %s function for state \"%s\" in state set \"%s\" */\n",
title, state_name, ss_name);
gen_code("static %s %s_%s_%d_%s(SS_ID " NM_SS ", SEQ_VARS *const " NM_VARS_ARG "%s)\n{\n",
gen_code("static %s %s_%s_%d_%s(SS_ID " NM_SS ", SEQ_VARS *const " NM_VARS_ARG "%s)\n",
rettype, prefix, ss_name, ss_num, state_name, extra_args);
gen_body(xp, context);
gen_code("}\n");
}
static void gen_entex_body(Expr *xp, int context)
static void gen_block(Expr *xp, int context, int level)
{
Expr *ep;
Expr *cxp;
assert(xp->type == D_ENTEX);
gen_local_var_decls(xp, context, 1);
gen_defn_c_code(xp, 1);
foreach (ep, xp->entex_stmts)
assert(xp->type == S_CMPND);
gen_code("{\n");
gen_local_var_decls(xp, context, level+1);
gen_defn_c_code(xp, level+1);
foreach (cxp, xp->cmpnd_stmts)
{
gen_expr(context, ep, 1);
gen_expr(context, cxp, level+1);
}
indent(level); gen_code("}\n");
}
static void gen_entex_body(Expr *xp, int context)
{
assert(xp->type == D_ENTEX);
gen_block(xp->entex_block, context, 0);
}
/* Generate action processing functions:
......@@ -210,6 +217,7 @@ static void gen_action_body(Expr *xp, int context)
int trans_num;
const int level = 1;
gen_code("{\n");
/* "switch" statment based on the transition number */
indent(level); gen_code("switch(" NM_TRN ")\n");
indent(level); gen_code("{\n");
......@@ -218,33 +226,18 @@ static void gen_action_body(Expr *xp, int context)
/* For each transition ("when" statement) ... */
foreach (tp, xp)
{
Expr *ap;
assert(tp->type == D_WHEN);
/* one case for each transition */
indent(level); gen_code("case %d:\n", trans_num);
/* block within case permits local variables */
indent(level+1); gen_code("{\n");
/* for each definition insert corresponding code */
gen_local_var_decls(tp, context, level+2);
gen_defn_c_code(tp, level+2);
if (tp->when_defns)
gen_code("\n");
/* for each action statement insert action code */
foreach (ap, tp->when_stmts)
{
gen_expr(C_TRANS, ap, level+2);
}
/* end of block */
indent(level+1); gen_code("}\n");
indent(level); gen_code("case %d: ", trans_num);
gen_block(tp->when_block, context, level+1);
/* end of case */
indent(level+1); gen_code("return;\n");
trans_num++;
}
/* end of switch stmt */
indent(level); gen_code("}\n");
/* end of function */
gen_code("}\n");
}
/* Generate a C function that checks events for a particular state */
......@@ -254,6 +247,7 @@ static void gen_event_body(Expr *xp, int context)
int trans_num;
const int level = 1;
gen_code("{\n");
trans_num = 0;
/* For each transition generate an "if" statement ... */
foreach (tp, xp)
......@@ -289,6 +283,8 @@ static void gen_event_body(Expr *xp, int context)
trans_num++;
}
indent(level); gen_code("return FALSE;\n");
/* end of function */
gen_code("}\n");
}
static void gen_var_access(Var *vp)
......@@ -352,16 +348,7 @@ static void gen_expr(
{
/* Statements */
case S_CMPND:
indent(level);
gen_code("{\n");
gen_local_var_decls(ep, context, level+1);
gen_defn_c_code(ep, level+1);
foreach (cep, ep->cmpnd_stmts)
{
gen_expr(context, cep, level+1);
}
indent(level);
gen_code("}\n");
gen_block(ep, context, level+1);
break;
case S_STMT:
gen_line_marker(ep);
......@@ -869,8 +856,7 @@ static void gen_prog_func(
{
assert(prog->type == D_PROG);
gen_code("\n/* Program %s func */\n", doc);
gen_code("static void %s(PROG_ID "NM_PROG
", SEQ_VARS *const "NM_VARS_ARG")\n{\n",
gen_code("static void %s(PROG_ID "NM_PROG", SEQ_VARS *const "NM_VARS_ARG")\n{\n",
name);
gen_body(prog);
gen_code("}\n");
......@@ -885,10 +871,9 @@ static void gen_prog_entex_func(
{
assert(prog->type == D_PROG);
gen_code("\n/* Program %s func */\n", doc);
gen_code("static void %s(SS_ID " NM_SS ", SEQ_VARS *const " NM_VARS_ARG ")\n{\n",
gen_code("static void %s(SS_ID " NM_SS ", SEQ_VARS *const " NM_VARS_ARG ")\n",
name);
if (prog && gen_body) gen_body(prog);
gen_code("}\n");
gen_body(prog);
}
static void gen_prog_init_body(Expr *prog)
......@@ -900,11 +885,11 @@ static void gen_prog_init_body(Expr *prog)
static void gen_prog_entry_body(Expr *prog)
{
assert(prog->type == D_PROG);
if (prog->prog_entry) gen_entex_body(prog->prog_entry, C_SS);
gen_entex_body(prog->prog_entry, C_SS);
}
static void gen_prog_exit_body(Expr *prog)
{
assert(prog->type == D_PROG);
if (prog->prog_exit) gen_entex_body(prog->prog_exit, C_SS);
gen_entex_body(prog->prog_exit, C_SS);
}
......@@ -305,10 +305,10 @@ state_defn(p) ::= syncq(x). { p = x; }
state_defn(p) ::= declaration(x). { p = x; }
state_defn(p) ::= option(x). { p = x; }
entry(p) ::= ENTRY(t) block(b). { p = expr(D_ENTEX, t, b.left, b.right); }
entry(p) ::= ENTRY(t) block(b). { p = expr(D_ENTEX, t, b); }
entry(p) ::= . { p = 0; }
exit(p) ::= EXIT(t) block(b). { p = expr(D_ENTEX, t, b.left, b.right); }
exit(p) ::= EXIT(t) block(b). { p = expr(D_ENTEX, t, b); }
exit(p) ::= . { p = 0; }
transitions(p) ::= transitions(xs) transition(x).{ p = link_expr(xs, x); }
......@@ -316,21 +316,20 @@ transitions(p) ::= transition(x). { p = x; }
transition(p) ::= WHEN(t) LPAREN opt_expr(c) RPAREN block(b) STATE NAME(n). {
t.str = n.str;
p = expr(D_WHEN, t, c, b.left, b.right);
p = expr(D_WHEN, t, c, b);
}
transition(p) ::= WHEN(t) LPAREN opt_expr(c) RPAREN block(b) EXIT. {
t.str = 0;
p = expr(D_WHEN, t, c, b.left, b.right);
p = expr(D_WHEN, t, c, b);
}
transition(p) ::= WHEN(t) LPAREN opt_expr(c) RPAREN block(b) error. {
t.str = 0;
p = expr(D_WHEN, t, c, b.left, b.right);
p = expr(D_WHEN, t, c, b);
report("expected 'state' or 'exit'\n");
}
%type block {ExprPair}
block(p) ::= LBRACE block_defns(ds) statements(xs) RBRACE. {
p.left = ds; p.right = xs;
block(p) ::= LBRACE(t) block_defns(ds) statements(xs) RBRACE. {
p = expr(S_CMPND, t, ds, xs);
}
block_defns(p) ::= block_defns(ds) block_defn(d). {
......@@ -350,8 +349,7 @@ statement(p) ::= BREAK(t) SEMICOLON. { p = expr(S_JUMP, t); }
statement(p) ::= CONTINUE(t) SEMICOLON. { p = expr(S_JUMP, t); }
statement(p) ::= STATE NAME(t) SEMICOLON. { p = expr(S_CHANGE, t); }
statement(p) ::= c_code(x). { p = x; }
statement(p) ::= LBRACE(t) block_defns(ds) statements(xs) RBRACE.
{ p = expr(S_CMPND, t, ds, xs); }
statement(p) ::= block(x). { p = x; }
statement(p) ::= IF(t) LPAREN comma_expr(c) RPAREN statement(th).
{ p = expr(S_IF, t, c, th, 0); }
statement(p) ::= IF(t) LPAREN comma_expr(c) RPAREN statement(th) ELSE statement(el).
......
......@@ -40,7 +40,6 @@ typedef struct variable Var;
typedef struct chan_list ChanList;
typedef struct sync_queue_list SyncQList;
typedef struct var_list VarList;
typedef struct expr_pair ExprPair;
typedef struct func_symbol FuncSym;
typedef struct const_symbol ConstSym;
......@@ -94,7 +93,6 @@ struct token /* for the lexer and parser */
struct when /* extra data for when clauses */
{
Expr *next_state; /* declaration of target state */
VarList *var_list; /* list of local variables */
};
struct state /* extra data for state clauses */
......@@ -130,7 +128,6 @@ struct expression /* generic syntax node */
State *e_state; /* state data */
When *e_when; /* transition data */
Expr *e_change; /* declaration of target state */
VarList *e_entex; /* local declarations */
VarList *e_cmpnd; /* block local definitions */
FuncSym *e_builtin; /* builtin function */
ConstSym *e_const; /* builtin constant */
......@@ -211,11 +208,6 @@ struct var_list
Expr *parent_scope; /* next surrounding scope */
};
struct expr_pair
{
Expr *left, *right;
};
struct program
{
/* result of parsing phase */
......@@ -246,8 +238,7 @@ struct program
/* Expression types that are scopes. By definition, a scope is an expression
that allows variable declarations as (immediate) subexpressions. */
#define scope_mask ( bit(D_PROG) | bit(D_SS) | bit(D_STATE)\
| bit(D_ENTEX) | bit(D_WHEN) | bit(S_CMPND) )
#define scope_mask ( bit(D_PROG) | bit(D_SS) | bit(D_STATE) | bit(S_CMPND) )
/* Whether an expression is a scope */
#define is_scope(e) ((bit((e)->type) & scope_mask) != 0)
......@@ -278,7 +269,7 @@ enum expr_type /* description [child expressions...] */
{
D_ASSIGN, /* assign statement [subscr,pvs] */
D_DECL, /* variable declaration [init] */
D_ENTEX, /* entry or exit statement [defns,stmts] */
D_ENTEX, /* entry or exit statement [block] */
D_MONITOR, /* monitor statement [subscr] */
D_OPTION, /* option definition [] */
D_PROG, /* whole program [param,defns,entry,statesets,exit,ccode] */
......@@ -286,7 +277,7 @@ enum expr_type /* description [child expressions...] */
D_STATE, /* state statement [defns,entry,whens,exit] */
D_SYNC, /* sync statement [subscr,evflag] */
D_SYNCQ, /* syncq statement [subscr,evflag,maxqsize] */
D_WHEN, /* when statement [cond,defns,stmts] */
D_WHEN, /* when statement [cond,block] */
E_BINOP, /* binary operator [left,right] */
E_BUILTIN, /* builtin function [] */
......@@ -332,8 +323,7 @@ STATIC_ASSERT(NUM_EXPR_TYPES <= 8*sizeof(TypeMask));
#define cmpnd_defns children[0]
#define cmpnd_stmts children[1]
#define decl_init children[0]
#define entex_defns children[0]
#define entex_stmts children[1]
#define entex_block children[0]
#define for_init children[0]
#define for_cond children[1]
#define for_iter children[2]
......@@ -374,8 +364,7 @@ STATIC_ASSERT(NUM_EXPR_TYPES <= 8*sizeof(TypeMask));
#define ternop_then children[1]
#define ternop_else children[2]
#define when_cond children[0]
#define when_defns children[1]
#define when_stmts children[2]
#define when_block children[1]
#define while_cond children[0]
#define while_stmt children[1]
......@@ -383,8 +372,6 @@ STATIC_ASSERT(NUM_EXPR_TYPES <= 8*sizeof(TypeMask));
#define prog_var_list extra.e_prog
#define ss_var_list extra.e_ss->var_list
#define state_var_list extra.e_state->var_list
#define when_var_list extra.e_when->var_list
#define entex_var_list extra.e_entex;
#define cmpnd_var_list extra.e_cmpnd;
#ifndef expr_type_GLOBAL
......@@ -400,7 +387,7 @@ expr_type_info[]
= {
{ "D_ASSIGN", 2 },
{ "D_DECL", 1 },
{ "D_ENTEX", 2 },
{ "D_ENTEX", 1 },
{ "D_MONITOR", 1 },
{ "D_OPTION", 0 },
{ "D_PROG", 6 },
......@@ -408,7 +395,7 @@ expr_type_info[]
{ "D_STATE", 4 },
{ "D_SYNC", 2 },
{ "D_SYNCQ", 3 },
{ "D_WHEN", 3 },
{ "D_WHEN", 2 },
{ "E_BINOP", 2 },
{ "E_BUILTIN", 0 },
{ "E_CAST", 2 },
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment