diff --git a/bin/ace b/bin/ace index da2c6ea..ba95b88 100644 Binary files a/bin/ace and b/bin/ace differ diff --git a/src/ace/c/acedef.h b/src/ace/c/acedef.h index b053a5b..a7944c2 100755 --- a/src/ace/c/acedef.h +++ b/src/ace/c/acedef.h @@ -483,6 +483,7 @@ typedef struct symstruct { SHORT no_of_params; /* # of SUB parameters */ int p_type[MAXPARAMS]; /* SUB parameter types */ int p_addr[MAXPARAMS]; /* SUB parameter frame offsets */ + struct symstruct *p_structdef[MAXPARAMS]; /* structdef for struct-typed params */ UBYTE decl; /* forward reference? */ UBYTE *reg; /* lib function regs */ char *libname; /* library name */ diff --git a/src/ace/c/sub.c b/src/ace/c/sub.c index 4a69a27..d5ab885 100755 --- a/src/ace/c/sub.c +++ b/src/ace/c/sub.c @@ -125,6 +125,13 @@ int sub_type=undefined; param_type = sym_to_type(sym); insymbol(); } + else if (sym == ident && exist(id, structdef)) + { + /* struct type identifier -> treat as ADDRESS */ + sub_ptr->p_structdef[param_count] = curr_item; + param_type = longtype; + insymbol(); + } if (sym != ident) _error(7); /* ident expected */ else @@ -285,6 +292,7 @@ SYM *sub_ptr; SHORT param_count=0; int param_type; char addrbuf[40]; +SYM *struct_param_def; /* parse current SUB's formal parameter list */ @@ -306,6 +314,7 @@ char addrbuf[40]; do { param_type=undefined; + struct_param_def=NULL; insymbol(); @@ -316,20 +325,38 @@ char addrbuf[40]; param_type = sym_to_type(sym); insymbol(); } + else if (sym == ident && exist(id, structdef)) + { + /* struct type identifier -> treat as ADDRESS */ + struct_param_def = curr_item; + param_type = longtype; + insymbol(); + } if (sym != ident) _error(7); /* ident expected */ else { - if (!exist(id,variable)) /* treat param's as local variables */ + if (struct_param_def != NULL) + { + /* struct-typed parameter: enter as structure object */ + if (exist(id, structure)) + _error(38); /* duplicate parameter */ + else + { + enter(id, notype, structure, 0); + curr_item->other = struct_param_def; + } + } + else if (!exist(id,variable)) /* treat param's as local variables */ { - /* if type not already specified, take type indicated by ident */ + /* if type not already specified, take type indicated by ident */ if (param_type == undefined) param_type = typ; /* enter parameter as a variable into symbol table */ enter(id,param_type,variable,0); /* string parameter? -> associate with BSS object */ - if (curr_item->type == stringtype) + if (curr_item->type == stringtype) { gen_frame_addr(curr_item->address,addrbuf); gen("move.l",addrbuf,"-(sp)"); /* push value parameter */ @@ -343,6 +370,7 @@ char addrbuf[40]; /* store parameter type and address */ sub_ptr->p_type[param_count]=param_type; sub_ptr->p_addr[param_count]=curr_item->address; + sub_ptr->p_structdef[param_count]=struct_param_def; param_count++; insymbol(); diff --git a/verify/scripts/otherthenamiga/call-on-ustartup b/verify/scripts/otherthenamiga/call-on-ustartup index 1b70ba1..8b13789 100644 --- a/verify/scripts/otherthenamiga/call-on-ustartup +++ b/verify/scripts/otherthenamiga/call-on-ustartup @@ -1 +1 @@ -; nothing to do + diff --git a/verify/tests/cases/syntax/test_struct_sub_param.b b/verify/tests/cases/syntax/test_struct_sub_param.b new file mode 100644 index 0000000..bf3da4f --- /dev/null +++ b/verify/tests/cases/syntax/test_struct_sub_param.b @@ -0,0 +1,13 @@ +STRUCT Vec2D + SINGLE x + SINGLE y +END STRUCT + +SUB PrintVec(Vec2D p) + PRINT p->x; ","; p->y +END SUB + +DECLARE STRUCT Vec2D pt +pt->x = 3.0 +pt->y = 4.0 +PrintVec(pt) diff --git a/verify/tests/expected/test_struct_sub_param.expected b/verify/tests/expected/test_struct_sub_param.expected new file mode 100644 index 0000000..29a9188 --- /dev/null +++ b/verify/tests/expected/test_struct_sub_param.expected @@ -0,0 +1 @@ + 3 , 4