From 039572060e641f2f0a82ae28a48208c0792f8651 Mon Sep 17 00:00:00 2001 From: David Anderson <dvander@alliedmods.net> Date: Sat, 8 Nov 2014 02:48:13 -0800 Subject: [PATCH] Add new dynamic array syntax. --- sourcepawn/compiler/sc1.cpp | 40 +++++++++++++++++-- sourcepawn/compiler/sc5-in.scp | 1 + .../tests/fail-dynamic-array-bad-type.sp | 4 ++ .../tests/fail-dynamic-array-bad-type.txt | 1 + .../tests/ok-new-dynamic-array-syntax.sp | 10 +++++ 5 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 sourcepawn/compiler/tests/fail-dynamic-array-bad-type.sp create mode 100644 sourcepawn/compiler/tests/fail-dynamic-array-bad-type.txt create mode 100644 sourcepawn/compiler/tests/ok-new-dynamic-array-syntax.sp diff --git a/sourcepawn/compiler/sc1.cpp b/sourcepawn/compiler/sc1.cpp index 81e121b9..07c9bea1 100644 --- a/sourcepawn/compiler/sc1.cpp +++ b/sourcepawn/compiler/sc1.cpp @@ -157,6 +157,7 @@ static void inst_datetime_defines(void); static void inst_binary_name(char *binfname); static int operatorname(char *name); static int parse_new_typename(const token_t *tok); +static bool parse_new_typename(const token_t *tok, int *outp); static int parse_new_decl(declinfo_t *decl, const token_t *first, int flags); static int reparse_old_decl(declinfo_t *decl, int flags); static int reparse_new_decl(declinfo_t *decl, int flags); @@ -2184,6 +2185,30 @@ static void declloc(int tokid) genarray(1, false); ldconst((cur_lit + glb_declared) * sizeof(cell), sPRI); copyarray(sym, cells * sizeof(cell)); + } else if (matchtoken(tNEW)) { + int tag = 0; + if (parse_new_typename(NULL, &tag)) { + if (tag != type->tag) + error(164, pc_typename(tag), pc_typename(type->tag)); + } + + for (int i = 0; i < type->numdim; i++) { + if (!needtoken('[')) + break; + + value val; + symbol *child; + int ident = doexpr2( + TRUE, FALSE, TRUE, FALSE, + &type->idxtag[i], + &child, 0, &val); + pushreg(sPRI); + + if (!needtoken(']')) + break; + } + + genarray(type->numdim, true); } else if (lexpeek('{')) { // Dynamic array with fixed initializer. error(160); @@ -3064,6 +3089,16 @@ static int parse_new_typename(const token_t *tok) return -1; } +static bool parse_new_typename(const token_t *tok, int *tagp) +{ + int tag = parse_new_typename(tok); + if (tag >= 0) + *tagp = tag; + else + *tagp = 0; + return true; +} + static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags) { token_t tok; @@ -3080,8 +3115,7 @@ static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags) lextok(&tok); } - type->tag = parse_new_typename(&tok); - if (type->tag == -1) + if (!parse_new_typename(&tok, &type->tag)) goto err_out; // Note: we could have already filled in the prefix array bits, so we check @@ -4224,7 +4258,7 @@ static void parse_function_type(functag_t *type) int lparen = matchtoken('('); needtoken(tFUNCTION); - type->ret_tag = parse_new_typename(NULL); + parse_new_typename(NULL, &type->ret_tag); type->usage = uPUBLIC; needtoken('('); diff --git a/sourcepawn/compiler/sc5-in.scp b/sourcepawn/compiler/sc5-in.scp index ddc69650..e099541f 100644 --- a/sourcepawn/compiler/sc5-in.scp +++ b/sourcepawn/compiler/sc5-in.scp @@ -207,6 +207,7 @@ static const char *errmsg[] = { /*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", /*163*/ "indeterminate array size in \"sizeof\" expression (symbol \"%s\")\n", +/*164*/ "allocated array type '%s' doesn't match original type '%s'\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", diff --git a/sourcepawn/compiler/tests/fail-dynamic-array-bad-type.sp b/sourcepawn/compiler/tests/fail-dynamic-array-bad-type.sp new file mode 100644 index 00000000..14a53f54 --- /dev/null +++ b/sourcepawn/compiler/tests/fail-dynamic-array-bad-type.sp @@ -0,0 +1,4 @@ +public main() +{ + int[] x = new float[3]; +} diff --git a/sourcepawn/compiler/tests/fail-dynamic-array-bad-type.txt b/sourcepawn/compiler/tests/fail-dynamic-array-bad-type.txt new file mode 100644 index 00000000..d2e8545a --- /dev/null +++ b/sourcepawn/compiler/tests/fail-dynamic-array-bad-type.txt @@ -0,0 +1 @@ +(3) : error 164: allocated array type 'float' doesn't match original type 'int' diff --git a/sourcepawn/compiler/tests/ok-new-dynamic-array-syntax.sp b/sourcepawn/compiler/tests/ok-new-dynamic-array-syntax.sp new file mode 100644 index 00000000..ef3f8ac4 --- /dev/null +++ b/sourcepawn/compiler/tests/ok-new-dynamic-array-syntax.sp @@ -0,0 +1,10 @@ +native printnum(num); + +public main() +{ + new x = 4; + new y = 8; + int[][] v = new int[4][8]; + v[2][3] = 9; + printnum(v[2][3]); +}