diff --git a/src/snc/analysis.c b/src/snc/analysis.c index f31dee5b4de3badb8474edb46317130013be1bdf..f615113701655113c61c7863d424af4901a7b3a6 100644 --- a/src/snc/analysis.c +++ b/src/snc/analysis.c @@ -1203,14 +1203,18 @@ static uint connect_states(SymTable st, Expr *prog) foreach (tp, sp->state_whens) { - Expr *next_sp = (Expr *)sym_table_lookup(st, tp->value, ssp); + Expr *next_sp = 0; - if (!next_sp) + if (tp->value) { - error_at_expr(tp, - "a state with name '%s' does not " - "exist in state set '%s'\n", - tp->value, ssp->value); + next_sp = (Expr *)sym_table_lookup(st, tp->value, ssp); + if (!next_sp) + { + error_at_expr(tp, + "a state with name '%s' does not " + "exist in state set '%s'\n", + tp->value, ssp->value); + } } tp->extra.e_when->next_state = next_sp; assert(!next_sp || strcmp(tp->value,next_sp->value) == 0); diff --git a/src/snc/gen_ss_code.c b/src/snc/gen_ss_code.c index 828d4567ed0577e2fbf3dea45ac403a35b621036..11d5dd31360a266f87d17b7eb3a5513f3833dbbf 100644 --- a/src/snc/gen_ss_code.c +++ b/src/snc/gen_ss_code.c @@ -458,11 +458,18 @@ static void gen_event_body(Expr *xp) indent(level); printf("{\n"); next_sp = tp->extra.e_when->next_state; - /* NULL at this point would have been an error in analysis phase */ - assert(next_sp != 0); - indent(level+1); - printf("*pNextState = %d;\n", next_sp->extra.e_state->index); - indent(level+1); printf("*pTransNum = %d;\n", trans_num); + if (!next_sp) + { + /* "when(...) {...} exit" -> exit from program */ + indent(level+1); + printf("seq_pvExit(ssId);\n"); + } + else + { + indent(level+1); + printf("*pNextState = %d;\n", next_sp->extra.e_state->index); + } + indent(level+1);printf("*pTransNum = %d;\n", trans_num); indent(level+1); printf("return TRUE;\n"); indent(level); printf("}\n"); trans_num++; diff --git a/src/snc/snl.lem b/src/snc/snl.lem index c204e24126a8ff973450128ac969484f9db39da0..5459415c93b7992b26dfeebcdb51e7ada25b18a3 100644 --- a/src/snc/snl.lem +++ b/src/snc/snl.lem @@ -260,6 +260,11 @@ when(p) ::= WHEN(t) LPAREN opt_expr(c) RPAREN block(b) STATE NAME(n). { p = expr(D_WHEN, t, c, b.left, b.right); } +when(p) ::= WHEN(t) LPAREN opt_expr(c) RPAREN block(b) EXIT. { + t.str = 0; + p = expr(D_WHEN, t, c, b.left, b.right); +} + %type block {ExprPair} block(p) ::= LBRACE block_defns(ds) statements(xs) RBRACE. { p = (ExprPair){ds,xs};