Add unstaged changes.

This commit is contained in:
David Anderson 2014-06-30 20:11:18 -07:00
parent 6f3b08bbae
commit beb557aa56
3 changed files with 160 additions and 164 deletions

View File

@ -1,3 +1,4 @@
// vim: set sts=2 ts=8 sw=2 tw=99 et:
/* Pawn compiler /* Pawn compiler
* *
* Drafted after the Small-C compiler Version 2.01, originally created * Drafted after the Small-C compiler Version 2.01, originally created
@ -272,6 +273,7 @@ typedef struct {
int numdim; int numdim;
int dim[sDIMEN_MAX]; int dim[sDIMEN_MAX];
int idxtag[sDIMEN_MAX]; int idxtag[sDIMEN_MAX];
cell array_size;
constvalue *enumroot; constvalue *enumroot;
// Type information. // Type information.

View File

@ -121,8 +121,7 @@ static void attachstatelist(symbol *sym, int state_id);
static symbol *funcstub(int fnative, const funcstub_setup_t *setup); static symbol *funcstub(int fnative, const funcstub_setup_t *setup);
static int newfunc(const funcstub_setup_t *setup,int fpublic,int fstatic,int stock,symbol **symp); static int newfunc(const funcstub_setup_t *setup,int fpublic,int fstatic,int stock,symbol **symp);
static int declargs(symbol *sym, int chkshadow, const int *thistag); static int declargs(symbol *sym, int chkshadow, const int *thistag);
static void doarg(char *name,int ident,int offset,int tags[],int numtags, static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, arginfo *arg);
int fpublic,int fconst,int chkshadow,arginfo *arg);
static void make_report(symbol *root,FILE *log,char *sourcefile); static void make_report(symbol *root,FILE *log,char *sourcefile);
static void reduce_referrers(symbol *root); static void reduce_referrers(symbol *root);
static long max_stacksize(symbol *root,int *recursion); static long max_stacksize(symbol *root,int *recursion);
@ -3271,14 +3270,16 @@ static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags)
else else
lextok(&tok); lextok(&tok);
type->ident = iVARIABLE;
if (tok.id == tCONST) { if (tok.id == tCONST) {
if (type->usage & uCONST)
error(138);
type->usage |= uCONST; type->usage |= uCONST;
lextok(&tok); lextok(&tok);
} }
if (tok.id == '[') { // Note: we could have already filled in the prefix array bits below, so we
// check that ident != iARRAY before looking for an open bracket.
if (type->ident != iARRAY && tok.id == '[') {
// Not yet supported for return vals. This is allowed with old decls, but // Not yet supported for return vals. This is allowed with old decls, but
// it's a huge hack. For now we forbid it in new code until it works right. // it's a huge hack. For now we forbid it in new code until it works right.
if (flags & TYPEFLAG_RETURN) if (flags & TYPEFLAG_RETURN)
@ -3291,7 +3292,7 @@ static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags)
} }
type->dim[type->numdim++] = 0; type->dim[type->numdim++] = 0;
if (!needtoken(']')) if (!needtoken(']'))
return FALSE; goto err_out;
lextok(&tok); lextok(&tok);
} }
type->ident = iARRAY; type->ident = iARRAY;
@ -3330,14 +3331,14 @@ static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags)
break; break;
default: default:
error(122); error(122);
return FALSE; goto err_out;
} }
if (flags & TYPEFLAG_ARGUMENT) { if (flags & TYPEFLAG_ARGUMENT) {
if (matchtoken('&')) { if (matchtoken('&')) {
if (type->ident == iARRAY) { if (type->ident == iARRAY) {
error(137); error(137);
return FALSE; goto err_out;
} }
type->ident = iREFERENCE; type->ident = iREFERENCE;
} }
@ -3346,6 +3347,11 @@ static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags)
type->tags[0] = type->tag; type->tags[0] = type->tag;
type->numtags = 1; type->numtags = 1;
return TRUE; return TRUE;
err_out:
type->tags[0] = type->tag;
type->numtags = 1;
return FALSE;
} }
static void parse_old_array_dims(declinfo_t *decl, int flags) static void parse_old_array_dims(declinfo_t *decl, int flags)
@ -3370,11 +3376,11 @@ static void parse_old_array_dims(declinfo_t *decl, int flags)
return; return;
} }
size = needsub(&type->idxtag[type->numdim], enumrootp); type->array_size = needsub(&type->idxtag[type->numdim], enumrootp);
if (size > INT_MAX) if (type->array_size > INT_MAX)
error(165); error(165);
type->dim[type->numdim++] = (int)size; type->dim[type->numdim++] = type->array_size;
} while (matchtoken('[')); } while (matchtoken('['));
type->ident = iARRAY; type->ident = iARRAY;
@ -3385,10 +3391,11 @@ static int parse_old_decl(declinfo_t *decl, int flags)
token_t tok; token_t tok;
typeinfo_t *type = &decl->type; typeinfo_t *type = &decl->type;
type->ident = iVARIABLE; if (matchtoken(tCONST)) {
if (type->usage & uCONST)
if (matchtoken(tCONST)) error(138);
type->usage |= uCONST; type->usage |= uCONST;
}
if (flags & TYPEFLAG_ARGUMENT) { if (flags & TYPEFLAG_ARGUMENT) {
if (matchtoken('&')) if (matchtoken('&'))
@ -3413,9 +3420,22 @@ static int parse_old_decl(declinfo_t *decl, int flags)
} }
needtoken(':'); needtoken(':');
} }
} else { }
if (type->numtags == 0) {
if (matchtoken2(tLABEL, &tok)) if (matchtoken2(tLABEL, &tok))
type->tags[type->numtags++] = pc_addtag(tok.str); type->tags[type->numtags++] = pc_addtag(tok.str);
else
type->tags[type->numtags++] = 0;
}
// All finished with tag stuff.
type->tag = type->tags[0];
// Look for varargs and end early.
if (matchtoken(tELLIPS)) {
type->ident = iVARARGS;
return TRUE;
} }
if (flags & TYPEMASK_NAMED_DECL) { if (flags & TYPEMASK_NAMED_DECL) {
@ -3430,15 +3450,14 @@ static int parse_old_decl(declinfo_t *decl, int flags)
parse_old_array_dims(decl, flags); parse_old_array_dims(decl, flags);
} }
type->tag = type->tags[0];
return TRUE; return TRUE;
} }
static int parse_new_decl(declinfo_t *decl, int flags) static int parse_new_decl(declinfo_t *decl, const token_t *first, int flags)
{ {
token_t tok; token_t tok;
if (!parse_new_typeexpr(&decl->type, NULL, flags)) if (!parse_new_typeexpr(&decl->type, first, flags))
return FALSE; return FALSE;
if (!expecttoken(tSYMBOL, &tok)) if (!expecttoken(tSYMBOL, &tok))
return FALSE; return FALSE;
@ -3465,9 +3484,16 @@ static int parse_new_decl(declinfo_t *decl, int flags)
int parse_decl(declinfo_t *decl, int flags) int parse_decl(declinfo_t *decl, int flags)
{ {
token_t tok; token_t tok;
token_ident_t ident;
memset(decl, 0, sizeof(*decl)); memset(decl, 0, sizeof(*decl));
decl->type.ident = iVARIABLE;
// Must attempt to match const first, since it's a common prefix.
if (matchtoken(tCONST))
decl->type.usage |= uCONST;
// If parsing an argument, there are two simple checks for whether this is a // If parsing an argument, there are two simple checks for whether this is a
// new or old-style declaration. // new or old-style declaration.
if ((flags & TYPEFLAG_ARGUMENT) && (lexpeek('&') || lexpeek('{'))) if ((flags & TYPEFLAG_ARGUMENT) && (lexpeek('&') || lexpeek('{')))
@ -3478,22 +3504,51 @@ int parse_decl(declinfo_t *decl, int flags)
return parse_old_decl(decl, flags); return parse_old_decl(decl, flags);
// Otherwise, we have to eat a symbol to tell. // Otherwise, we have to eat a symbol to tell.
if (lextok(&tok) == tSYMBOL) { if (matchsymbol(&ident)) {
if (lexpeek('[') || lexpeek(tSYMBOL)) { if (lexpeek(tSYMBOL)) {
// A new-style declaration only allows array dims or a symbol name, so // A new-style declaration only allows array dims or a symbol name, so
// this is a new-style declaration. Make sure to push back the first // this is a new-style declaration. Make sure to push back the first
// symbol. // symbol.
lexpush(); return parse_new_decl(decl, &ident.tok, flags);
return parse_new_decl(decl, flags);
} }
// Push the symbol back, we've got an old-style decl. if ((flags & TYPEMASK_NAMED_DECL) && matchtoken('[')) {
// If we're not allowing postdims here, then it must be a newdecl.
if (flags & TYPEFLAG_NO_POSTDIMS) {
// Give the '[' and symbol back, since we're going to parse from the start.
lexpush();
lexpush();
return parse_new_decl(decl, NULL, flags);
}
// Oh no - we have to parse array dims before we can tell what kind of
// declarator this is. It could be either:
// "x[] y" (new-style), or
// "y[]," (old-style)
parse_old_array_dims(decl, flags);
if (matchtoken(tSYMBOL) || matchtoken('&')) {
// This must be a newdecl, "x[] y" or "x[] &y", the latter of which
// is illegal, but we flow it through the right path anyway.
lexpush();
return parse_new_decl(decl, &ident.tok, flags);
}
// The most basic - "x[]" and that's it. Well, we know it has no tag and
// we know its name. We might as well just complete the entire decl.
strcpy(decl->name, ident.name);
decl->type.tags[decl->type.numtags++] = 0;
decl->type.tag = decl->type.tags[0];
return TRUE;
}
// Give the symbol back to the lexer. This is an old decl.
lexpush(); lexpush();
return parse_old_decl(decl, flags); return parse_old_decl(decl, flags);
} }
// All else has failed. Probably got a type keyword. New-style. // All else has failed. Probably got a type keyword. New-style.
return parse_new_decl(decl, flags); return parse_new_decl(decl, NULL, flags);
} }
void define_constructor(methodmap_t *map, methodmap_method_t *method) void define_constructor(methodmap_t *map, methodmap_method_t *method)
@ -5318,11 +5373,11 @@ static int argcompare(arginfo *a1,arginfo *a2)
static int declargs(symbol *sym, int chkshadow, const int *thistag) static int declargs(symbol *sym, int chkshadow, const int *thistag)
{ {
char *ptr; char *ptr;
int argcnt,oldargcnt,tok,tags[MAXTAGS],numtags; int argcnt,oldargcnt,tok;
cell val; cell val;
arginfo arg, *arglist; arginfo arg, *arglist;
char name[sNAMEMAX+1]; char name[sNAMEMAX+1];
int ident,fpublic,fconst; int ident,fpublic;
int idx; int idx;
/* if the function is already defined earlier, get the number of arguments /* if the function is already defined earlier, get the number of arguments
@ -5333,9 +5388,6 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
while (sym->dim.arglist[oldargcnt].ident!=0) while (sym->dim.arglist[oldargcnt].ident!=0)
oldargcnt++; oldargcnt++;
argcnt=0; /* zero aruments up to now */ argcnt=0; /* zero aruments up to now */
ident=iVARIABLE;
numtags=0;
fconst=FALSE;
fpublic = (sym->usage & (uPUBLIC|uSTOCK))!=0; fpublic = (sym->usage & (uPUBLIC|uSTOCK))!=0;
if (thistag && *thistag != -1) { if (thistag && *thistag != -1) {
@ -5370,52 +5422,43 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
/* the '(' parantheses has already been parsed */ /* the '(' parantheses has already been parsed */
if (!matchtoken(')')){ if (!matchtoken(')')){
do { /* there are arguments; process them */ do { /* there are arguments; process them */
/* any legal name increases argument count (and stack offset) */ declinfo_t decl;
tok=lex(&val,&ptr); parse_decl(&decl, TYPEFLAG_ARGUMENT|TYPEFLAG_ENUMROOT);
switch (tok) { assert(decl.type.numtags > 0);
case 0:
/* nothing */ if (decl.type.ident == iVARARGS) {
break; assert(decl.type.numtags > 0);
case '&': if ((sym->usage & uPROTOTYPED)==0) {
if (ident!=iVARIABLE || numtags>0) /* redimension the argument list, add the entry iVARARGS */
error(1,"-identifier-","&"); sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo));
ident=iREFERENCE; if (sym->dim.arglist==0)
break; error(163); /* insufficient memory */
case tCONST: memset(&sym->dim.arglist[argcnt+1],0,sizeof(arginfo)); /* keep the list terminated */
if (ident!=iVARIABLE || numtags>0) sym->dim.arglist[argcnt].ident=iVARARGS;
error(1,"-identifier-","const"); sym->dim.arglist[argcnt].hasdefault=FALSE;
fconst=TRUE; sym->dim.arglist[argcnt].defvalue.val=0;
break; sym->dim.arglist[argcnt].defvalue_tag=0;
case tLABEL: sym->dim.arglist[argcnt].numtags=decl.type.numtags;
if (numtags>0) sym->dim.arglist[argcnt].tags=(int*)malloc(decl.type.numtags*sizeof decl.type.tags[0]);
error(1,"-identifier-","-tagname-"); if (sym->dim.arglist[argcnt].tags==NULL)
tags[0]=pc_addtag(ptr); error(163); /* insufficient memory */
numtags=1; memcpy(sym->dim.arglist[argcnt].tags,decl.type.tags,decl.type.numtags*sizeof decl.type.tags[0]);
break; } else {
case '{': if (argcnt>oldargcnt || sym->dim.arglist[argcnt].ident!=iVARARGS)
if (numtags>0) error(25); /* function definition does not match prototype */
error(1,"-identifier-","-tagname-"); } /* if */
numtags=0; argcnt++;
while (numtags<MAXTAGS) { continue;
if (!matchtoken('_') && !needtoken(tSYMBOL)) }
break;
tokeninfo(&val,&ptr); if (argcnt>=sMAXARGS)
tags[numtags++]=pc_addtag(ptr); error(45);
if (matchtoken('}')) if (decl.name[0] == PUBLIC_CHAR)
break; error(56,name); /* function arguments cannot be public */
needtoken(',');
} /* for */ if (1) {
needtoken(':'); if (decl.type.ident == iARRAY)
tok=tLABEL; /* for outer loop: flag that we have seen a tagname */ decl.type.ident = iREFARRAY;
break;
case tSYMBOL:
if (argcnt>=sMAXARGS)
error(45); /* too many function arguments */
strcpy(name,ptr); /* save symbol name */
if (name[0]==PUBLIC_CHAR)
error(56,name); /* function arguments cannot be public */
if (numtags==0)
tags[numtags++]=0; /* default tag */
/* Stack layout: /* Stack layout:
* base + 0*sizeof(cell) == previous "base" * base + 0*sizeof(cell) == previous "base"
* base + 1*sizeof(cell) == function return address * base + 1*sizeof(cell) == function return address
@ -5423,10 +5466,11 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
* base + 3*sizeof(cell) == first argument of the function * base + 3*sizeof(cell) == first argument of the function
* So the offset of each argument is "(argcnt+3) * sizeof(cell)". * So the offset of each argument is "(argcnt+3) * sizeof(cell)".
*/ */
doarg(name,ident,(argcnt+3)*sizeof(cell),tags,numtags,fpublic,fconst,chkshadow,&arg); doarg(&decl,(argcnt+3)*sizeof(cell),fpublic,chkshadow,&arg);
/* :TODO: fix this so stocks that are func pointers can't have default arguments? */
if ((sym->usage & uPUBLIC) && arg.hasdefault) if ((sym->usage & uPUBLIC) && arg.hasdefault)
error(59,name); /* arguments of a public function may not have a default value */ error(59,name); /* arguments of a public function may not have a default value */
if ((sym->usage & uPROTOTYPED)==0) { if ((sym->usage & uPROTOTYPED)==0) {
/* redimension the argument list, add the entry */ /* redimension the argument list, add the entry */
sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo)); sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo));
@ -5447,41 +5491,8 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
free(arg.tags); free(arg.tags);
} /* if */ } /* if */
argcnt++; argcnt++;
ident=iVARIABLE; }
numtags=0; } while (matchtoken(','));
fconst=FALSE;
break;
case tELLIPS:
if (ident!=iVARIABLE)
error(10); /* illegal function or declaration */
if (numtags==0)
tags[numtags++]=0; /* default tag */
if ((sym->usage & uPROTOTYPED)==0) {
/* redimension the argument list, add the entry iVARARGS */
sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo));
if (sym->dim.arglist==0)
error(163); /* insufficient memory */
memset(&sym->dim.arglist[argcnt+1],0,sizeof(arginfo)); /* keep the list terminated */
sym->dim.arglist[argcnt].ident=iVARARGS;
sym->dim.arglist[argcnt].hasdefault=FALSE;
sym->dim.arglist[argcnt].defvalue.val=0;
sym->dim.arglist[argcnt].defvalue_tag=0;
sym->dim.arglist[argcnt].numtags=numtags;
sym->dim.arglist[argcnt].tags=(int*)malloc(numtags*sizeof tags[0]);
if (sym->dim.arglist[argcnt].tags==NULL)
error(163); /* insufficient memory */
memcpy(sym->dim.arglist[argcnt].tags,tags,numtags*sizeof tags[0]);
} else {
if (argcnt>oldargcnt || sym->dim.arglist[argcnt].ident!=iVARARGS)
error(25); /* function definition does not match prototype */
} /* if */
argcnt++;
break;
default:
error(10); /* illegal function or declaration */
} /* switch */
} while (tok=='&' || tok==tLABEL || tok==tCONST
|| (tok!=tELLIPS && matchtoken(','))); /* more? */
/* if the next token is not ",", it should be ")" */ /* if the next token is not ",", it should be ")" */
needtoken(')'); needtoken(')');
} /* if */ } /* if */
@ -5540,50 +5551,29 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
* "fpublic" indicates whether the function for this argument list is public. * "fpublic" indicates whether the function for this argument list is public.
* The arguments themselves are never public. * The arguments themselves are never public.
*/ */
static void doarg(char *name,int ident,int offset,int tags[],int numtags, static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, arginfo *arg)
int fpublic,int fconst,int chkshadow,arginfo *arg)
{ {
symbol *argsym; symbol *argsym;
constvalue *enumroot; constvalue *enumroot;
cell size;
int slength=0; int slength=0;
typeinfo_t *type = &decl->type;
strcpy(arg->name,name); strcpy(arg->name, decl->name);
arg->hasdefault=FALSE; /* preset (most common case) */ arg->hasdefault=FALSE; /* preset (most common case) */
arg->defvalue.val=0; /* clear */ arg->defvalue.val=0; /* clear */
arg->defvalue_tag=0; arg->defvalue_tag=0;
arg->numdim=0; arg->numdim=0;
if (matchtoken('[')) { if (type->ident == iREFARRAY) {
if (ident==iREFERENCE) arg->numdim = type->numdim;
error(67,name); /* illegal declaration ("&name[]" is unsupported) */ memcpy(arg->dim, type->dim, sizeof(int) * type->numdim);
do { memcpy(arg->idxtag, type->idxtag, sizeof(int) * type->numdim);
if (arg->numdim == sDIMEN_MAX) { assert(type->numtags > 0);
error(53); /* exceeding maximum number of dimensions */ if (type->tags[0] == pc_tag_string) {
return;
} /* if */
size=needsub(&arg->idxtag[arg->numdim],&enumroot);/* may be zero here, it is a pointer anyway */
#if INT_MAX < LONG_MAX
if (size > INT_MAX)
error(165); /* overflow, exceeding capacity */
#endif
arg->dim[arg->numdim]=(int)size;
arg->numdim+=1;
} while (matchtoken('['));
ident=iREFARRAY; /* "reference to array" (is a pointer) */
#if 0 /* For SM, multiple tags including string don't make sense,
so just check the first tag. Done manually so the string
tag isn't matched with the any tag. */
if (checktag(tags, numtags, pc_tag_string)) {
#endif
assert(tags!=0);
assert(numtags>0);
if (tags[0] == pc_tag_string) {
slength = arg->dim[arg->numdim - 1]; slength = arg->dim[arg->numdim - 1];
arg->dim[arg->numdim - 1] = (size + sizeof(cell) - 1) / sizeof(cell); arg->dim[arg->numdim - 1] = (type->array_size + sizeof(cell) - 1) / sizeof(cell);
} }
if (matchtoken('=')) { if (matchtoken('=')) {
assert(litidx==0); /* at the start of a function, this is reset */ assert(litidx==0); /* at the start of a function, this is reset */
assert(numtags>0);
/* Check if there is a symbol */ /* Check if there is a symbol */
if (matchtoken(tSYMBOL)) { if (matchtoken(tSYMBOL)) {
symbol *sym; symbol *sym;
@ -5603,8 +5593,8 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
} }
} }
} else { } else {
initials2(ident,tags[0],&size,arg->dim,arg->numdim,enumroot, 1, 0); initials2(type->ident, type->tags[0], &type->array_size, arg->dim, arg->numdim, type->enumroot, 1, 0);
assert(size>=litidx); assert(type->array_size >= litidx);
/* allocate memory to hold the initial values */ /* allocate memory to hold the initial values */
arg->defvalue.array.data=(cell *)malloc(litidx*sizeof(cell)); arg->defvalue.array.data=(cell *)malloc(litidx*sizeof(cell));
if (arg->defvalue.array.data!=NULL) { if (arg->defvalue.array.data!=NULL) {
@ -5626,7 +5616,7 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
} else { } else {
if (matchtoken('=')) { if (matchtoken('=')) {
unsigned char size_tag_token; unsigned char size_tag_token;
assert(ident==iVARIABLE || ident==iREFERENCE); assert(type->ident==iVARIABLE || type->ident==iREFERENCE);
arg->hasdefault=TRUE; /* argument has a default value */ arg->hasdefault=TRUE; /* argument has a default value */
size_tag_token=(unsigned char)(matchtoken(tSIZEOF) ? uSIZEOF : 0); size_tag_token=(unsigned char)(matchtoken(tSIZEOF) ? uSIZEOF : 0);
if (size_tag_token==0) if (size_tag_token==0)
@ -5635,8 +5625,8 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
size_tag_token=(unsigned char)(matchtoken(tCELLSOF) ? uCOUNTOF : 0); size_tag_token=(unsigned char)(matchtoken(tCELLSOF) ? uCOUNTOF : 0);
if (size_tag_token!=0) { if (size_tag_token!=0) {
int paranthese; int paranthese;
if (ident==iREFERENCE) if (type->ident==iREFERENCE)
error(66,name); /* argument may not be a reference */ error(66, decl->name); /* argument may not be a reference */
paranthese=0; paranthese=0;
while (matchtoken('(')) while (matchtoken('('))
paranthese++; paranthese++;
@ -5654,41 +5644,41 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
needtoken(']'); needtoken(']');
} /* while */ } /* while */
} /* if */ } /* if */
if (ident==iVARIABLE) /* make sure we set this only if not a reference */ if (type->ident==iVARIABLE) /* make sure we set this only if not a reference */
arg->hasdefault |= size_tag_token; /* uSIZEOF or uTAGOF */ arg->hasdefault |= size_tag_token; /* uSIZEOF or uTAGOF */
} /* if */ } /* if */
while (paranthese--) while (paranthese--)
needtoken(')'); needtoken(')');
} else { } else {
constexpr(&arg->defvalue.val,&arg->defvalue_tag,NULL); constexpr(&arg->defvalue.val,&arg->defvalue_tag,NULL);
assert(numtags>0); assert(type->numtags > 0);
matchtag(tags[0],arg->defvalue_tag,TRUE); matchtag(type->tags[0], arg->defvalue_tag, TRUE);
} /* if */ } /* if */
} /* if */ } /* if */
} /* if */ } /* if */
arg->ident=(char)ident; arg->ident=(char)type->ident;
arg->usage=(char)(fconst ? uCONST : 0); arg->usage=type->usage;
arg->numtags=numtags; arg->numtags=type->numtags;
arg->tags=(int*)malloc(numtags*sizeof tags[0]); arg->tags=(int*)malloc(type->numtags * sizeof(type->tags[0]));
if (arg->tags==NULL) if (arg->tags==NULL)
error(163); /* insufficient memory */ error(163); /* insufficient memory */
memcpy(arg->tags,tags,numtags*sizeof tags[0]); memcpy(arg->tags, type->tags, type->numtags * sizeof(type->tags[0]));
argsym=findloc(name); argsym=findloc(decl->name);
if (argsym!=NULL) { if (argsym!=NULL) {
error(21,name); /* symbol already defined */ error(21, decl->name); /* symbol already defined */
} else { } else {
if (chkshadow && (argsym=findglb(name,sSTATEVAR))!=NULL && argsym->ident!=iFUNCTN) if (chkshadow && (argsym=findglb(decl->name,sSTATEVAR))!=NULL && argsym->ident!=iFUNCTN)
error(219,name); /* variable shadows another symbol */ error(219, decl->name); /* variable shadows another symbol */
/* add details of type and address */ /* add details of type and address */
assert(numtags>0); assert(type->numtags > 0);
argsym=addvariable2(name,offset,ident,sLOCAL,tags[0], argsym=addvariable2(decl->name,offset,type->ident,sLOCAL,type->tags[0],
arg->dim,arg->numdim,arg->idxtag,slength); arg->dim,arg->numdim,arg->idxtag,slength);
argsym->compound=0; argsym->compound=0;
if (ident==iREFERENCE) if (type->ident==iREFERENCE)
argsym->usage|=uREAD; /* because references are passed back */ argsym->usage|=uREAD; /* because references are passed back */
if (fpublic) if (fpublic)
argsym->usage|=uREAD; /* arguments of public functions are always "used" */ argsym->usage|=uREAD; /* arguments of public functions are always "used" */
if (fconst) if (type->usage & uCONST)
argsym->usage|=uCONST; argsym->usage|=uCONST;
} /* if */ } /* if */
} }

View File

@ -75,6 +75,10 @@ static short lastfile;
char *msg,*pre; char *msg,*pre;
va_list argptr; va_list argptr;
if (number == 47) {
printf("EGG\n");
}
// sErrLine is used to temporarily change the line number of reported errors. // sErrLine is used to temporarily change the line number of reported errors.
// Pawn has an upstream bug where this is not reset on early-return, which // Pawn has an upstream bug where this is not reset on early-return, which
// can lead to broken line numbers in error messages. // can lead to broken line numbers in error messages.