From 2daefc5fa0816dc3206bbfbbc6b20c73de880315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Minisini?= Date: Mon, 27 Jan 2014 23:46:37 +0000 Subject: [PATCH] [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 --- main/gbc/gbc_trans_expr.c | 2 +- main/gbc/gbc_trans_subr.c | 9 ++- main/gbc/gbc_trans_tree.c | 37 ++++++++--- main/gbx/gbx_c_array.c | 19 ++++-- main/gbx/gbx_c_array.h | 1 + main/gbx/gbx_subr_misc.c | 108 +++++++++++++++++++++++++------- main/lib/eval/eval_trans.h | 2 +- main/lib/eval/eval_trans_expr.c | 20 +++--- main/lib/eval/eval_trans_tree.c | 88 +++++++++----------------- main/share/gb_code.h | 4 +- main/share/gb_code_temp.h | 16 ++--- main/share/gb_limit.h | 2 +- 12 files changed, 187 insertions(+), 121 deletions(-) diff --git a/main/gbc/gbc_trans_expr.c b/main/gbc/gbc_trans_expr.c index 3870209c9..2b4d874ce 100644 --- a/main/gbc/gbc_trans_expr.c +++ b/main/gbc/gbc_trans_expr.c @@ -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); } diff --git a/main/gbc/gbc_trans_subr.c b/main/gbc/gbc_trans_subr.c index bd1dd9dea..577e42568 100644 --- a/main/gbc/gbc_trans_subr.c +++ b/main/gbc/gbc_trans_subr.c @@ -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); } - diff --git a/main/gbc/gbc_trans_tree.c b/main/gbc/gbc_trans_tree.c index 481aad81b..a7432d141 100644 --- a/main/gbc/gbc_trans_tree.c +++ b/main/gbc/gbc_trans_tree.c @@ -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; + } + } } } diff --git a/main/gbx/gbx_c_array.c b/main/gbx/gbx_c_array.c index 58f79a98e..46524ec80 100644 --- a/main/gbx/gbx_c_array.c +++ b/main/gbx/gbx_c_array.c @@ -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 diff --git a/main/gbx/gbx_c_array.h b/main/gbx/gbx_c_array.h index 8c113985b..ce39a376f 100644 --- a/main/gbx/gbx_c_array.h +++ b/main/gbx/gbx_c_array.h @@ -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); diff --git a/main/gbx/gbx_subr_misc.c b/main/gbx/gbx_subr_misc.c index 38a6f4a0a..5c57b40cf 100644 --- a/main/gbx/gbx_subr_misc.c +++ b/main/gbx/gbx_subr_misc.c @@ -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; } diff --git a/main/lib/eval/eval_trans.h b/main/lib/eval/eval_trans.h index f797d4942..d679e04bc 100644 --- a/main/lib/eval/eval_trans.h +++ b/main/lib/eval/eval_trans.h @@ -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 */ diff --git a/main/lib/eval/eval_trans_expr.c b/main/lib/eval/eval_trans_expr.c index 7dae4b5dd..355115357 100644 --- a/main/lib/eval/eval_trans_expr.c +++ b/main/lib/eval/eval_trans_expr.c @@ -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); } } } diff --git a/main/lib/eval/eval_trans_tree.c b/main/lib/eval/eval_trans_tree.c index aea9eef31..3ca666c75 100644 --- a/main/lib/eval/eval_trans_tree.c +++ b/main/lib/eval/eval_trans_tree.c @@ -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 } diff --git a/main/share/gb_code.h b/main/share/gb_code.h index 30ff7578a..0c1d93758 100644 --- a/main/share/gb_code.h +++ b/main/share/gb_code.h @@ -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); diff --git a/main/share/gb_code_temp.h b/main/share/gb_code_temp.h index 21296c28e..96139986d 100644 --- a/main/share/gb_code_temp.h +++ b/main/share/gb_code_temp.h @@ -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) diff --git a/main/share/gb_limit.h b/main/share/gb_limit.h index 876407a22..70105a3ab 100644 --- a/main/share/gb_limit.h +++ b/main/share/gb_limit.h @@ -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