[INTERPRETER]

* BUG: Fix maximum number of array declaration in the same class.
* NEW: Array and Collection constructor operator [ ... ] now can take any 
  number of arguments. It is only limited by the maximum function size, 
  which leads for example to about 32000 elements for a short array.


git-svn-id: svn://localhost/gambas/trunk@6110 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2014-01-27 23:46:37 +00:00
parent 3bece35d9b
commit 2daefc5fa0
12 changed files with 187 additions and 121 deletions

View File

@ -268,7 +268,7 @@ static void trans_subr(int subr, short nparam)
else if (nparam > info->max_param)
THROW("Too many arguments to &1()", info->name);
CODE_subr(info->opcode, nparam, info->optype, FALSE /* output */, (info->max_param == info->min_param));
CODE_subr(info->opcode, nparam, info->optype, info->max_param == info->min_param);
}

View File

@ -68,7 +68,13 @@ static void trans_subr(int subr, int nparam)
ERROR_panic("Unknown intern subroutine: %s", tsi->name);
}
CODE_subr(tsi->info->opcode, nparam, tsi->info->optype, FALSE, tsi->info->min_param == tsi->info->max_param);
if (subr == TS_SUBR_ARRAY && nparam == 0)
CODE_subr(tsi->info->opcode, MAX_PARAM_OP + 1, 0, TRUE);
else if (subr == TS_SUBR_COLLECTION && nparam == 0)
CODE_subr(tsi->info->opcode, MAX_PARAM_OP, 0, TRUE);
else
CODE_subr(tsi->info->opcode, nparam, tsi->info->optype, tsi->info->min_param == tsi->info->max_param);
}
@ -979,4 +985,3 @@ void TRANS_subr(int subr, int nparam)
trans_subr(subr, nparam);
}

View File

@ -45,11 +45,16 @@ static void analyze_expr(short priority, short op_main);
static void analyze_array();
static void THROW_EXPR_TOO_COMPLEX()
{
THROW("Expression too complex");
}
static void inc_level()
{
level++;
if (level > MAX_EXPR_LEVEL)
THROW("Expression too complex");
THROW_EXPR_TOO_COMPLEX();
}
@ -58,11 +63,6 @@ static void dec_level()
level--;
}
static void THROW_EXPR_TOO_COMPLEX()
{
THROW("Expression too complex");
}
#define add_pattern(_pattern) \
do { \
if (tree_length >= MAX_EXPR_PATTERN) \
@ -244,8 +244,8 @@ static void analyze_make_array()
for(;;)
{
n++;
if (n > MAX_PARAM_OP)
THROW("Too many arguments");
/*if (n > MAX_PARAM_OP)
THROW("Too many arguments");*/
analyze_expr(0, RS_NONE);
if (!checked)
@ -260,14 +260,31 @@ static void analyze_make_array()
THROW(E_MISSING, "':'");
current++;
n++;
if (n > MAX_PARAM_OP)
THROW("Too many arguments");
/*if (n > MAX_PARAM_OP)
THROW("Too many arguments");*/
analyze_expr(0, RS_NONE);
}
if (!PATTERN_is(*current, RS_COMMA))
break;
current++;
if (collection)
{
if (n == (MAX_PARAM_OP - 1))
{
add_operator(RS_COLON, 0);
n = 0;
}
}
else
{
if (n == MAX_PARAM_OP)
{
add_operator(RS_RSQR, 0);
n = 0;
}
}
}
}

View File

@ -654,14 +654,10 @@ BEGIN_METHOD(Array_Extract, GB_INTEGER start; GB_INTEGER length)
END_METHOD
BEGIN_METHOD(Array_Resize, GB_INTEGER size)
int size = VARG(size);
void CARRAY_resize(CARRAY *_object, int size)
{
int count = THIS->count;
if (check_not_multi(THIS))
return;
if (size > count)
{
ARRAY_add_many_void(&THIS->data, size - count);
@ -673,6 +669,17 @@ BEGIN_METHOD(Array_Resize, GB_INTEGER size)
}
THIS->count = size;
}
BEGIN_METHOD(Array_Resize, GB_INTEGER size)
int size = VARG(size);
if (check_not_multi(THIS))
return;
CARRAY_resize(THIS, size);
END_METHOD

View File

@ -78,6 +78,7 @@ void *CARRAY_get_data_multi(CARRAY *_object, GB_INTEGER *arg, int nparam);
void *CARRAY_out_of_bound();
CLASS *CARRAY_get_array_class(CLASS *class, CTYPE ctype);
int *CARRAY_get_array_bounds(CARRAY *_object);
void CARRAY_resize(CARRAY *_object, int size);
CARRAY *CARRAY_create_static(CLASS *class, void *ref, CLASS_ARRAY *desc, void *data);
int CARRAY_get_static_count(CLASS_ARRAY *desc);

View File

@ -290,45 +290,101 @@ _FREE:
void SUBR_array(ushort code)
{
static bool reuse = FALSE;
TYPE type;
int i;
GB_ARRAY array;
int i, j;
CARRAY *array;
bool next_reuse;
SUBR_ENTER();
type = SUBR_check_good_type(PARAM, NPARAM);
if (type == T_NULL)
type = T_OBJECT;
for (i = 0; i < NPARAM; i++)
VALUE_conv(&PARAM[i], type);
GB_ArrayNew(&array, type, NPARAM);
OBJECT_REF(array);
if (NPARAM == 0)
{
NPARAM = MAX_PARAM_OP;
PARAM -= NPARAM;
next_reuse = TRUE;
}
else
next_reuse = FALSE;
if (reuse)
{
array = (CARRAY *)(PARAM[-1]._object.object);
type = array->type;
}
else
{
type = SUBR_check_good_type(PARAM, NPARAM);
if (type == T_NULL)
type = T_OBJECT;
}
for (i = 0; i < NPARAM; i++)
VALUE_conv(&PARAM[i], type);
if (reuse)
{
GB_Store(type, (GB_VALUE *)&PARAM[i], GB_ArrayGet(array, i));
j = array->count;
CARRAY_resize(array, j + NPARAM);
}
else
{
j = 0;
GB_ArrayNew(POINTER(&array), type, NPARAM);
OBJECT_REF(array);
}
for (i = 0; i < NPARAM; i++, j++)
{
GB_Store(type, (GB_VALUE *)&PARAM[i], GB_ArrayGet(array, j));
RELEASE(&PARAM[i]);
}
PARAM->_object.class = OBJECT_class(array); //CLASS_Array;
PARAM->_object.object = array;
SP = PARAM + 1;
if (reuse)
{
SP = PARAM;
}
else
{
PARAM->_object.class = OBJECT_class(array); //CLASS_Array;
PARAM->_object.object = array;
SP = PARAM + 1;
}
reuse = next_reuse;
}
void SUBR_collection(ushort code)
{
static bool reuse = FALSE;
int i;
GB_COLLECTION col;
char *key;
int len;
VALUE *vkey, *vval;
bool next_reuse;
SUBR_ENTER();
GB_CollectionNew(&col, GB_COMP_BINARY);
if (NPARAM == 0)
{
NPARAM = MAX_PARAM_OP - 1;
PARAM -= NPARAM;
next_reuse = TRUE;
}
else
next_reuse = FALSE;
if (reuse)
col = (GB_COLLECTION)(PARAM[-1]._object.object);
else
{
GB_CollectionNew(&col, GB_COMP_BINARY);
OBJECT_REF(col);
}
for (i = 0; i < NPARAM; i += 2)
{
@ -345,10 +401,18 @@ void SUBR_collection(ushort code)
RELEASE(&PARAM[i + 1]);
}
OBJECT_REF(col);
PARAM->_object.class = OBJECT_class(col); //CLASS_Array;
PARAM->_object.object = col;
SP = PARAM + 1;
if (reuse)
{
SP = PARAM;
}
else
{
PARAM->_object.class = OBJECT_class(col); //CLASS_Array;
PARAM->_object.object = col;
SP = PARAM + 1;
}
reuse = next_reuse;
}

View File

@ -60,7 +60,7 @@ bool TRANS_get_number(int index, TRANS_NUMBER *result);
void TRANS_expression(void);
bool TRANS_affectation(void);
void TRANS_operation(short op, short nparam, bool output, PATTERN previous);
void TRANS_operation(short op, short nparam, PATTERN previous);
/* eval_trans_tree.c */

View File

@ -181,7 +181,7 @@ static void trans_identifier(int index, bool first, bool point)
}
static void trans_subr(int subr, short nparam, bool output)
static void trans_subr(int subr, short nparam)
{
SUBR_INFO *info = &COMP_subr_info[subr];
@ -192,11 +192,11 @@ static void trans_subr(int subr, short nparam, bool output)
else if (nparam > info->max_param)
THROW2("Too many arguments to &1()", info->name);
CODE_subr(info->opcode, nparam, info->optype, output, (info->max_param == info->min_param));
CODE_subr(info->opcode, nparam, info->optype, info->max_param == info->min_param);
}
void TRANS_operation(short op, short nparam, bool output, PATTERN previous)
void TRANS_operation(short op, short nparam, PATTERN previous)
{
COMP_INFO *info = &COMP_res_info[op];
@ -221,12 +221,18 @@ void TRANS_operation(short op, short nparam, bool output, PATTERN previous)
case OP_RSQR:
find_subr(&subr_array_index, ".Array");
trans_subr(subr_array_index, nparam, FALSE);
if (nparam)
trans_subr(subr_array_index, nparam);
else
CODE_subr(COMP_subr_info[subr_array_index].opcode, MAX_PARAM_OP + 1, 0, TRUE);
break;
case OP_COLON:
find_subr(&subr_collection_index, ".Collection");
trans_subr(subr_collection_index, nparam, FALSE);
if (nparam)
trans_subr(subr_collection_index, nparam);
else
CODE_subr(COMP_subr_info[subr_collection_index].opcode, MAX_PARAM_OP, 0, TRUE);
break;
case OP_LBRA:
@ -284,7 +290,7 @@ static void trans_expr_from_tree(PATTERN *tree)
else if (PATTERN_is_subr(pattern))
{
nparam = get_nparam(tree, &i);
trans_subr(PATTERN_index(pattern), nparam, PATTERN_is_output(pattern));
trans_subr(PATTERN_index(pattern), nparam);
}
else if (PATTERN_is_reserved(pattern))
@ -349,7 +355,7 @@ static void trans_expr_from_tree(PATTERN *tree)
else
{
nparam = get_nparam(tree, &i);
TRANS_operation((short)PATTERN_index(pattern), nparam, PATTERN_is_output(pattern), prev_pattern);
TRANS_operation((short)PATTERN_index(pattern), nparam, prev_pattern);
}
}
}

View File

@ -122,7 +122,7 @@ static void add_reserved_pattern(int reserved)
static void add_operator_output(short op, short nparam, bool has_output)
static void add_operator_output(short op, short nparam)
{
PATTERN pattern;
@ -146,8 +146,8 @@ static void add_operator_output(short op, short nparam, bool has_output)
pattern = PATTERN_make(RT_RESERVED, op);
if (op == RS_LBRA && has_output)
pattern = PATTERN_set_flag(pattern, RT_OUTPUT);
/*if (op == RS_LBRA && has_output)
pattern = PATTERN_set_flag(pattern, RT_OUTPUT);*/
add_pattern(pattern);
@ -158,17 +158,17 @@ static void add_operator_output(short op, short nparam, bool has_output)
static void add_operator(short op, short nparam)
{
add_operator_output(op, nparam, FALSE);
add_operator_output(op, nparam);
}
static void add_subr(PATTERN subr_pattern, short nparam, bool has_output)
static void add_subr(PATTERN subr_pattern, short nparam)
{
PATTERN pattern;
if (has_output)
subr_pattern = PATTERN_set_flag(subr_pattern, RT_OUTPUT);
/*if (has_output)
subr_pattern = PATTERN_set_flag(subr_pattern, RT_OUTPUT);*/
add_pattern(subr_pattern);
@ -188,8 +188,8 @@ static void analyze_make_array()
for(;;)
{
n++;
if (n > MAX_PARAM_OP)
THROW("Too many arguments");
/*if (n > MAX_PARAM_OP)
THROW("Too many arguments");*/
analyze_expr(0, RS_NONE);
if (!checked)
@ -204,14 +204,31 @@ static void analyze_make_array()
THROW("Missing ':'");
current++;
n++;
if (n > MAX_PARAM_OP)
THROW("Too many arguments");
/*if (n > MAX_PARAM_OP)
THROW("Too many arguments");*/
analyze_expr(0, RS_NONE);
}
if (!PATTERN_is(*current, RS_COMMA))
break;
current++;
if (collection)
{
if (n == (MAX_PARAM_OP - 1))
{
add_operator(RS_COLON, 0);
n = 0;
}
}
else
{
if (n == MAX_PARAM_OP)
{
add_operator(RS_RSQR, 0);
n = 0;
}
}
}
}
@ -322,20 +339,12 @@ static void analyze_single(int op)
static void analyze_call()
{
/*static PATTERN *output[MAX_PARAM_OP];*/
int nparam_post = 0;
PATTERN subr_pattern = NULL_PATTERN;
PATTERN last_pattern = get_last_pattern(1);
bool has_output = FALSE;
/*int i;
PATTERN *save_current;*/
SUBR_INFO *info;
bool optional = TRUE;
/*
get_pattern_subr(last_pattern, &subr);
*/
if (PATTERN_is_subr(last_pattern))
{
subr_pattern = last_pattern;
@ -369,19 +378,6 @@ static void analyze_call()
current++;
}
#if 0
if (FALSE) /*(PATTERN_is(*current, RS_AMP))*/
{
current++;
output[nparam_post] = current;
has_output = TRUE;
}
else
{
output[nparam_post] = NULL;
}
#endif
if (optional && (PATTERN_is(*current, RS_COMMA) || PATTERN_is(*current, RS_RBRA)))
{
add_reserved_pattern(RS_OPTIONAL);
@ -412,7 +408,7 @@ static void analyze_call()
*/
if (subr_pattern == NULL_PATTERN)
add_operator_output(RS_LBRA, nparam_post, has_output);
add_operator_output(RS_LBRA, nparam_post);
else
{
info = &COMP_subr_info[PATTERN_index(subr_pattern)];
@ -422,32 +418,8 @@ static void analyze_call()
else if (nparam_post > info->max_param)
THROW2("Too many arguments to &1", info->name);
add_subr(subr_pattern, nparam_post, has_output);
add_subr(subr_pattern, nparam_post);
}
#if 0
if (has_output)
{
save_current = current;
for (i = nparam_post - 1; i >= 0; i--)
{
if (output[i] != NULL)
{
current = output[i];
analyze_expr(0, RS_NONE);
add_reserved_pattern(RS_AT);
}
else
add_reserved_pattern(RS_COMMA); /* Provoque un drop */
}
if (subr_pattern != NULL_PATTERN)
add_reserved_pattern(RS_RBRA); /* Provoque le PUSH RETURN dans le cas d'un call*/
current = save_current;
}
#endif
}

View File

@ -133,8 +133,8 @@ void CODE_return(int return_value);
void CODE_push_char(char car);
void CODE_push_void(void);
void CODE_subr(short subr, short nparam, short optype, bool output, bool fixed);
void CODE_subr_output(short subr, short nparam, int output);
void CODE_subr(short subr, short nparam, short optype, bool fixed);
//void CODE_subr_output(short subr, short nparam, int output);
void CODE_call(short nparam);
void CODE_call_byref(short nparam, uint64_t byref);

View File

@ -1056,26 +1056,20 @@ void CODE_stop_event(void)
#endif
void CODE_subr(short subr, short nparam, short optype, bool output, bool fixed)
void CODE_subr(short subr, short nparam, short optype, bool fixed)
{
LAST_CODE;
if (output)
use_stack(0);
else
use_stack(1 - nparam);
use_stack(1 - nparam);
#ifdef DEBUG
printf("SUBR %s %d (%d)\n", output ? "OUTPUT" : "", subr, nparam);
printf("SUBR %d (%d)\n", subr, nparam);
#endif
if (optype == 0)
{
if (fixed)
nparam = 0;
/*if (output)
nparam |= CODE_CALL_OUTPUT;*/
}
else
{
@ -1087,7 +1081,7 @@ void CODE_subr(short subr, short nparam, short optype, bool output, bool fixed)
}
void CODE_subr_output(short subr, short nparam, int output)
/*void CODE_subr_output(short subr, short nparam, int output)
{
LAST_CODE;
@ -1099,7 +1093,7 @@ void CODE_subr_output(short subr, short nparam, int output)
subr += CODE_FIRST_SUBR;
write_short(((subr & 0xFF) << 8) | (nparam & 0xFF));
}
}*/
void CODE_call(short nparam)

View File

@ -64,7 +64,7 @@
#define MAX_CLASS_UNKNOWN 65536
/* Maximum number of array declarations in the same class - CANNOT CHANGE */
#define MAX_CLASS_ARRAY 32678
#define MAX_CLASS_ARRAY 32768
/* Maximum number of local variables in a function - CANNOT CHANGE */
#define MAX_LOCAL_SYMBOL 127