Define post-fix arrays as determinate and pre-fix arrays as indeterminate.

This commit is contained in:
David Anderson 2014-11-07 22:39:00 -08:00
parent a8796543af
commit 70e095f320
9 changed files with 109 additions and 28 deletions

View File

@ -70,7 +70,7 @@ native void WritePackFloat(Handle pack, float val);
* @noreturn
* @error Invalid handle.
*/
native void WritePackString(Handle pack, const char str[]);
native void WritePackString(Handle pack, const char[] str);
/**
* Packs a function pointer into a data pack.
@ -109,7 +109,7 @@ native float ReadPackFloat(Handle pack);
* @noreturn
* @error Invalid handle, or bounds error.
*/
native void ReadPackString(Handle pack, char buffer[], maxlen);
native void ReadPackString(Handle pack, char[] buffer, maxlen);
/**
* Reads a function pointer from a data pack.

View File

@ -614,6 +614,17 @@ static void inst_datetime_defines(void)
insert_subst("__TIME__", ltime, 8);
}
const char *pc_typename(int tag)
{
if (tag == 0)
return "int";
if (tag == sc_rationaltag)
return "float";
if (tag == pc_tag_string)
return "char";
return pc_tagname(tag);
}
const char *pc_tagname(int tag)
{
constvalue *ptr=tagname_tab.next;
@ -1985,6 +1996,11 @@ static void declglb(declinfo_t *decl,int fpublic,int fstatic,int fstock)
litidx=0; /* global initial data is dumped, so restart at zero */
} /* if */
assert(litidx==0); /* literal queue should be empty (again) */
if (type->ident == iREFARRAY) {
// Dynamc array in global scope.
assert(type->is_new);
error(162);
}
initials3(decl);
if (type->tag == pc_tag_string && type->numdim == 1 && !type->dim[type->numdim - 1]) {
slength = glbstringread;
@ -2038,6 +2054,25 @@ static void declglb(declinfo_t *decl,int fpublic,int fstatic,int fstock)
needtoken(tTERM); /* if not comma, must be semicolumn */
}
static bool parse_local_array_initializer(typeinfo_t *type, int *curlit, int *slength)
{
if (sc_alignnext) {
aligndata(sc_dataalign);
sc_alignnext=FALSE;
} /* if */
*curlit = litidx; /* save current index in the literal table */
if (type->numdim && !type->dim[type->numdim-1])
type->size = 0;
initials(type->ident,type->tag,&type->size,type->dim,type->numdim,type->enumroot);
if (type->tag == pc_tag_string && type->numdim == 1 && !type->dim[type->numdim - 1])
*slength = glbstringread;
if (type->size == 0)
return false;
if (type->numdim == 1)
type->dim[0] = type->size;
return true;
}
/* declloc - declare local symbols
*
* Declare local (automatic) variables. Since these variables are relative
@ -2092,20 +2127,8 @@ static void declloc(int tokid)
slength = fix_char_size(&decl);
if (type->ident == iARRAY || fstatic) {
if (sc_alignnext) {
aligndata(sc_dataalign);
sc_alignnext=FALSE;
} /* if */
cur_lit=litidx; /* save current index in the literal table */
if (type->numdim && !type->dim[type->numdim-1])
type->size = 0;
initials(type->ident,type->tag,&type->size,type->dim,type->numdim,type->enumroot);
if (type->tag == pc_tag_string && type->numdim == 1 && !type->dim[type->numdim - 1])
slength = glbstringread;
if (type->size == 0)
if (!parse_local_array_initializer(type, &cur_lit, &slength))
return;
if (type->numdim == 1)
type->dim[0] = type->size;
}
/* reserve memory (on the stack) for the variable */
if (fstatic) {
@ -2132,6 +2155,17 @@ static void declloc(int tokid)
if (curfunc->x.stacksize<declared+1)
curfunc->x.stacksize=declared+1; /* +1 for PROC opcode */
} else if (type->ident == iREFARRAY) {
if (matchtoken('=')) {
if (lexpeek('{')) {
// Dynamic array with fixed initializer.
error(160);
// Parse just to clear the tokens. First give '=' back.
lexpush();
if (!parse_local_array_initializer(type, &cur_lit, &slength))
return;
}
}
declared+=1; /* one cell for address */
sym=addvariable(decl.name,-declared*sizeof(cell),type->ident,sLOCAL,type->tag,type->dim,type->numdim,type->idxtag);
//markexpr(sLDECL,name,-declared*sizeof(cell)); /* mark for better optimization */
@ -3035,7 +3069,7 @@ static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags)
goto err_out;
}
} while (matchtoken('['));
type->ident = iARRAY;
type->ident = iREFARRAY;
type->size = 0;
}
@ -3146,6 +3180,10 @@ static void parse_old_array_dims(declinfo_t *decl, int flags)
genarray(type->numdim, autozero);
type->ident = iREFARRAY;
type->size = 0;
if (type->is_new) {
// Fixed array with dynamic size.
error(161, pc_typename(type->tag));
}
}
stgout(staging_index);
@ -3301,6 +3339,8 @@ static int parse_new_decl(declinfo_t *decl, const token_t *first, int flags)
}
}
decl->type.is_new = TRUE;
if (flags & DECLMASK_NAMED_DECL) {
if (matchtoken('[')) {
if (decl->type.numdim == 0)
@ -3310,7 +3350,6 @@ static int parse_new_decl(declinfo_t *decl, const token_t *first, int flags)
}
}
decl->type.is_new = TRUE;
return TRUE;
}
@ -5606,6 +5645,9 @@ static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, argi
int slength=0;
typeinfo_t *type = &decl->type;
// Otherwise we get very weird line number ranges, anything to the current fline.
errorset(sEXPRMARK,0);
strcpy(arg->name, decl->name);
arg->hasdefault=FALSE; /* preset (most common case) */
arg->defvalue.val=0; /* clear */
@ -5641,6 +5683,10 @@ static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, argi
}
}
} else {
if (type->is_new && !type->has_postdims && lexpeek('{')) {
// Dynamic array with fixed initializer.
error(160);
}
initials2(type->ident, type->tags[0], &type->size, arg->dim, arg->numdim, type->enumroot, 1, 0);
assert(type->size >= litidx);
/* allocate memory to hold the initial values */
@ -5660,7 +5706,17 @@ static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, argi
} /* if */
litidx=0; /* reset */
}
} /* if */
} else {
if (type->is_new && type->has_postdims) {
for (int i = 0; i < type->numdim; i++) {
if (type->dim[i] <= 0) {
// Fixed-array with unknown size.
error(159);
break;
}
}
}
}
} else {
if (matchtoken('=')) {
unsigned char size_tag_token;
@ -5729,6 +5785,8 @@ static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, argi
if (type->usage & uCONST)
argsym->usage|=uCONST;
} /* if */
errorset(sEXPRRELEASE,0);
}
static int count_referrers(symbol *entry)

View File

@ -202,6 +202,10 @@ static const char *errmsg[] = {
/*156*/ "unused156\n",
/*157*/ "'%s' is a reserved keyword\n",
/*158*/ "multi-tags are no longer supported\n",
/*159*/ "brackets after variable name indicate a fixed-size array, but size could not be determined - either specify sizes, an array initializer, or use dynamic syntax (such as 'char[] x')\n",
/*160*/ "brackets in between type and variable name indicate a dynamic-size array, but a fixed-size initializer was given\n",
/*161*/ "brackets after variable name indicate a fixed-size array, but a dynamic size was given - did you mean to use 'new %s[size]' syntax?\n",
/*162*/ "cannot create dynamic arrays in global scope - did you mean to create a fixed-length array with brackets after the variable name?\n",
#else
"\315e\306\227\266k\217:\235\277bu\201fo\220\204\223\012",
"\202l\224\250s\205g\346\356e\233\201(\243\315\214\267\202) \253 f\255low ea\305 \042c\353e\042\012",

View File

@ -0,0 +1,16 @@
int[] gInvalid = {1};
public OnPluginStart()
{
int v = 10;
int invalid1[v];
int[] invalid2 = {1};
}
void invalid_arg1(int invalid[])
{
}
void invalid_arg2(int[] invalid = {1, 2, 3})
{
}

View File

@ -0,0 +1,6 @@
(1) : error 162: cannot create dynamic arrays in global scope - did you mean to create a fixed-length array with brackets after the variable name?
(6) : error 161: brackets after variable name indicate a fixed-size array, but a dynamic size was given - did you mean to use 'new int[size]' syntax?
(7) : error 160: brackets in between type and variable name indicate a dynamic-size array, but a fixed-size initializer was given
(10) : error 159: brackets after variable name indicate a fixed-size array, but size could not be determined - either specify sizes, an array initializer, or use dynamic syntax (such as 'char[] x')
(14) : error 160: brackets in between type and variable name indicate a dynamic-size array, but a fixed-size initializer was given

View File

@ -1,13 +1,15 @@
native int[] egg6();
forward float[] egg7();
new void crab4;
int[] yam1 = {1,2,3}, yam2[] = {3,4,5};
void bad(int[] yam[] = {1})
{
}
forward void OnPluginStart();
public int OnPluginStart()
{
}

View File

@ -1,5 +1,5 @@
(1) : error 141: natives, forwards, and public functions cannot return arrays
(2) : error 141: natives, forwards, and public functions cannot return arrays
(3) : error 143: new-style declarations should not have "new"
(4) : error 121: cannot specify array dimensions on both type and name
(6) : error 025: function heading differs from prototype
(5) : error 121: cannot specify array dimensions on both type and name
(9) : error 025: function heading differs from prototype

View File

@ -2,7 +2,7 @@ stock A(int n)
{
}
stock B(int n[])
stock B(int n[10])
{
}

View File

@ -9,10 +9,8 @@ new crab2 = 5;
bool crab3 = true;
int crab4 = 6;
new crab5[] = {1, 2, 3};
bool[] crab6 = {true, false, false, true}
bool crab7[] = {false, true, true}
char crab8[] = "hello"
char[] crab9 = "bye"
native float operator*(float oper1, float oper2) = FloatMul;
@ -41,7 +39,6 @@ new Float:ham, bool:ham2;
int cram, cram2, cram3;
new cram4[] = {1, 2}, cram5[] = {3, 4, 7}
int cram6[] = {1, 2}, cram7[] = {3, 4, 7}
int[] cram8 = {3, 4}, cram9 = {4, 8, 10}
public OnPluginStart()
{
@ -50,6 +47,4 @@ public OnPluginStart()
cram4[0] = 2
cram5[2] = 2
cram7[2] = 2
cram8[1] = 5
cram9[2] = 5
}