diff --git a/src/snc/analysis.c b/src/snc/analysis.c index 01e4e10846eb66d2385cc9a12f2a4ce1083083db..34cf14611108eb4cc9a5b425141dd60a3c4f1cb6 100644 --- a/src/snc/analysis.c +++ b/src/snc/analysis.c @@ -20,6 +20,7 @@ in the file LICENSE that is included with this distribution. #include "main.h" #include "expr.h" #include "builtin.h" +#include "gen_code.h" #include "analysis.h" static const int impossible = 0; @@ -97,7 +98,9 @@ static void analyse_funcdefs(Expr *prog) { Expr *d = f->funcdef_decl; Var *var = d->extra.e_decl; + struct function_type *fun_type = &var->type->val.function; Expr *p; + Token t; assert(f->type == D_FUNCDEF); if (var->type->tag != T_FUNCTION) @@ -105,9 +108,9 @@ static void analyse_funcdefs(Expr *prog) error_at_expr(d, "not a function type\n"); continue; } - f->funcdef_params = var->type->val.function.param_decls; - assert(f->funcdef_params); /* invariant enforced by syntax */ - p = f->funcdef_params; + + p = fun_type->param_decls; + assert(p); /* invariant enforced by syntax */ if (p->extra.e_decl->type->tag == T_VOID) { /* no other params should be there */ @@ -120,9 +123,9 @@ static void analyse_funcdefs(Expr *prog) error_at_expr(p, "void parameter should not have a name\n"); } /* void means empty parameter list */ - f->funcdef_params = var->type->val.function.param_decls = 0; + fun_type->param_decls = 0; } - foreach(p, f->funcdef_params) + foreach(p, fun_type->param_decls) { /* check parameter has a name */ if (!p->extra.e_decl->name) @@ -130,6 +133,25 @@ static void analyse_funcdefs(Expr *prog) error_at_expr(p, "function parameter must have a name\n"); } } + /* prepend "SEQ_VARS *const _seq_vars" to parameter list */ + t.str = NM_VARS_ARG; + t.line = d->line_num; + t.file = d->src_file; + p = decl_add_base_type( + decl_create(t), + /* HACK! act as if "SEQ_VARS *const" were an identifier */ + mk_foreign_type(F_TYPENAME, "SEQ_VARS *const") + ); + fun_type->param_decls = link_expr(p, fun_type->param_decls); + /* prepend "SS_ID _seq_ss" to parameter list*/ + t.str = NM_SS; + t.line = d->line_num; + t.file = d->src_file; + p = decl_add_base_type( + decl_create(t), + mk_foreign_type(F_TYPENAME, "SS_ID") + ); + fun_type->param_decls = link_expr(p, fun_type->param_decls); prog->prog_defns = link_expr(prog->prog_defns, d); } } diff --git a/src/snc/gen_code.c b/src/snc/gen_code.c index 64e5a217a3a5758cd641ff17537d2fdae8312b2d..19ea8d0b5ce21d97776546a57393680e02b7d8cc 100644 --- a/src/snc/gen_code.c +++ b/src/snc/gen_code.c @@ -221,23 +221,15 @@ static void gen_user_var(Program *p) } gen_code("};\n"); } + /* function declarations are always global and static */ foreach (vp, p->prog->extra.e_prog->first) { if (vp->decl && vp->type->tag == T_FUNCTION) { - Expr *param_decl; - gen_line_marker(vp->decl); gen_code("static "); - gen_type(vp->type->val.function.return_type, "", vp->name); - gen_code("(SS_ID " NM_SS ", SEQ_VARS *const " NM_VARS_ARG); - foreach (param_decl, vp->type->val.function.param_decls) - { - Var *vp = param_decl->extra.e_decl; - gen_code(", "); - gen_var_decl(vp); - } - gen_code(");\n"); + gen_var_decl(vp); + gen_code(";\n"); } } gen_code("\n"); diff --git a/src/snc/gen_ss_code.c b/src/snc/gen_ss_code.c index 7538ab419758c8446957528571fa7242c8acb297..41be7815635f29b9b8f3af0f928c860251f41f48 100644 --- a/src/snc/gen_ss_code.c +++ b/src/snc/gen_ss_code.c @@ -908,20 +908,12 @@ static void gen_prog_exit_body(Expr *prog) static void gen_funcdef(Expr *fp) { - Expr *param_decl; Var *vp = fp->funcdef_decl->extra.e_decl; assert(fp->type == D_FUNCDEF); gen_line_marker(vp->decl); gen_code("static "); - gen_type(vp->type->val.function.return_type, "", vp->name); - gen_code("(SS_ID " NM_SS ", SEQ_VARS *const " NM_VARS_ARG); - foreach (param_decl, fp->funcdef_params) - { - vp = param_decl->extra.e_decl; - gen_code(", "); - gen_var_decl(vp); - } - gen_code(")\n"); + gen_var_decl(vp); + gen_code("\n"); gen_block(fp->funcdef_block, C_FUNC, 0); } diff --git a/src/snc/snl.lem b/src/snc/snl.lem index f61b7887efb473fcc18c0a6d2d3b3343f4fc65b8..aeb3cd5fa85893287373475f2d2338abb0805bce 100644 --- a/src/snc/snl.lem +++ b/src/snc/snl.lem @@ -480,7 +480,7 @@ functions(p) ::= . { p = 0; } functions(p) ::= functions(fs) function(f). { p = link_expr(fs, f); } function(p) ::= FUNCTION(l) basetype(t) declarator(d) block(b). { - p = expr(D_FUNCDEF, l, decl_add_base_type(d, t), 0, b); + p = expr(D_FUNCDEF, l, decl_add_base_type(d, t), b); } // Literal (C) code diff --git a/src/snc/types.h b/src/snc/types.h index ebedc9e2c303ae246ef0e647531f48d6532577cd..d9738e022ebd2deefa3005c79278010811f99d18 100644 --- a/src/snc/types.h +++ b/src/snc/types.h @@ -271,7 +271,7 @@ enum expr_type /* description [child expressions...] */ D_ASSIGN, /* assign statement [subscr,pvs] */ D_DECL, /* variable declaration [init] */ D_ENTEX, /* entry or exit statement [block] */ - D_FUNCDEF, /* function definition [decl,params,block] */ + D_FUNCDEF, /* function definition [decl,block] */ D_MONITOR, /* monitor statement [subscr] */ D_OPTION, /* option definition [] */ D_PROG, /* whole program [param,defns,entry,statesets,exit,funcdefs,ccode] */ @@ -334,8 +334,7 @@ STATIC_ASSERT(NUM_EXPR_TYPES <= 8*sizeof(TypeMask)); #define func_expr children[0] #define func_args children[1] #define funcdef_decl children[0] -#define funcdef_params children[1] -#define funcdef_block children[2] +#define funcdef_block children[1] #define if_cond children[0] #define if_then children[1] #define if_else children[2] @@ -376,6 +375,8 @@ STATIC_ASSERT(NUM_EXPR_TYPES <= 8*sizeof(TypeMask)); #define while_cond children[0] #define while_stmt children[1] +#define funcdef_params funcdef_decl->extra.e_decl->type->val.function.param_decls + #ifndef expr_type_GLOBAL extern #endif @@ -390,7 +391,7 @@ expr_type_info[] { "D_ASSIGN", 2 }, { "D_DECL", 1 }, { "D_ENTEX", 1 }, - { "D_FUNCDEF", 3 }, + { "D_FUNCDEF", 2 }, { "D_MONITOR", 1 }, { "D_OPTION", 0 }, { "D_PROG", 7 }, diff --git a/src/snc/var_types.c b/src/snc/var_types.c index e22e6839014e0627c3f7a28fbb414d02918787f8..5792d5cb75e1d63e56d528915f5b6a2bfdc9518e 100644 --- a/src/snc/var_types.c +++ b/src/snc/var_types.c @@ -354,12 +354,6 @@ static void gen_array_pointer(Type *t, enum type_tag last_tag, const char *prefi void gen_type(Type *t, const char *prefix, const char *name) { Type *bt = base_type(t); - Type *saved_bt = bt; - - /* DIRTY HACK: overwrite parent pointer so we can use this for the return type of a function */ - if (bt->tag == T_FUNCTION) { - bt = t->parent = bt->parent; - } switch (bt->tag) { case T_EVFLAG: @@ -378,6 +372,4 @@ void gen_type(Type *t, const char *prefix, const char *name) assert(impossible); } gen_array_pointer(bt->parent, T_NONE, prefix, name); - /* DIRTY HACK: restore parent pointer */ - t->parent = saved_bt; }