diff --git a/lib/comp.c b/lib/comp.c index 90da1bd..3c2c3c0 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -32,6 +32,9 @@ enum VAR_ARGUMENT }; +#define TV_BUFFER_ALIGN 256 +#define BLK_TMPRCNT_BUFFER_ALIGN 128 + #define EMIT_BYTE_INSTRUCTION(hcl,code) \ do { if (emit_byte_instruction(hcl,code) <= -1) return -1; } while(0) @@ -72,6 +75,82 @@ static int add_literal (hcl_t* hcl, hcl_oop_t obj, hcl_oow_t* index) return 0; } +static int add_temporary_variable (hcl_t* hcl, hcl_oop_t name, hcl_oow_t dup_check_start) +{ + hcl_oow_t i; + + HCL_ASSERT (HCL_IS_SYMBOL (hcl, name)); + + for (i = dup_check_start; i < hcl->c->tv.size; i++) + { + HCL_ASSERT (HCL_IS_SYMBOL (hcl, hcl->c->tv.ptr[i])); + if (hcl->c->tv.ptr[i] == name) + { + hcl->errnum = HCL_EEXIST; + return -1; + } + } + + if (hcl->c->tv.size >= hcl->c->tv.capa) + { + hcl_oop_t* tmp; + hcl_oow_t newcapa; + + newcapa = HCL_ALIGN (hcl->c->tv.capa + 1, TV_BUFFER_ALIGN); /* TODO: set a better resizing policy */ + tmp = hcl_reallocmem (hcl, hcl->c->tv.ptr, newcapa); + if (!tmp) return -1; + + hcl->c->tv.capa = newcapa; + hcl->c->tv.ptr = tmp; + } + + hcl->c->tv.ptr[hcl->c->tv.size++] = name; + return 0; +} + +static int find_temporary_variable_backward (hcl_t* hcl, hcl_oop_t name, hcl_oow_t* index) +{ + hcl_oow_t i; + + HCL_ASSERT (HCL_IS_SYMBOL (hcl, name)); + for (i = hcl->c->tv.size; i > 0; ) + { + --i; + HCL_ASSERT (HCL_IS_SYMBOL (hcl, hcl->c->tv.ptr[i])); + if (hcl->c->tv.ptr[i] == name) + { + *index = i; + return 0; + } + } + + hcl->errnum = HCL_ENOENT; + return -1; +} + +static int store_temporary_variable_count_for_block (hcl_t* hcl, hcl_oow_t tmpr_count) +{ + HCL_ASSERT (hcl->c->blk.depth >= 0); + + if (hcl->c->blk.depth >= hcl->c->blk.tmprcnt_capa) + { + hcl_oow_t* tmp; + hcl_oow_t newcapa; + + newcapa = HCL_ALIGN (hcl->c->blk.depth + 1, BLK_TMPRCNT_BUFFER_ALIGN); + tmp = (hcl_oow_t*)hcl_reallocmem (hcl, hcl->c->blk.tmprcnt, newcapa * HCL_SIZEOF(*tmp)); + if (!tmp) return -1; + + hcl->c->blk.tmprcnt_capa = newcapa; + hcl->c->blk.tmprcnt = tmp; + } + + hcl->c->blk.tmprcnt[hcl->c->blk.depth] = tmpr_count; + return 0; +} + +/* ========================================================================= */ + static HCL_INLINE void patch_instruction (hcl_t* hcl, hcl_oow_t index, hcl_oob_t bc) { HCL_ASSERT (index < hcl->code.bc.len); @@ -150,7 +229,7 @@ static int emit_single_param_instruction (hcl_t* hcl, int cmd, hcl_oow_t param_1 case HCL_CODE_PUSH_OBJECT_0: case HCL_CODE_STORE_INTO_OBJECT_0: - case HCL_CODE_POP_INTO_OBJECT_0: + case BCODE_POP_INTO_OBJECT_0: case HCL_CODE_JUMP_FORWARD_0: case HCL_CODE_JUMP_BACKWARD_0: #if 0 @@ -229,15 +308,17 @@ static int emit_double_param_instruction (hcl_t* hcl, int cmd, hcl_oow_t param_1 switch (cmd) { -#if 0 + case HCL_CODE_STORE_INTO_CTXTEMPVAR_0: - case HCL_CODE_POP_INTO_CTXTEMPVAR_0: + /*case BCODE_POP_INTO_CTXTEMPVAR_0:*/ case HCL_CODE_PUSH_CTXTEMPVAR_0: +#if 0 case HCL_CODE_PUSH_OBJVAR_0: case HCL_CODE_STORE_INTO_OBJVAR_0: - case HCL_CODE_POP_INTO_OBJVAR_0: + case BCODE_POP_INTO_OBJVAR_0: case HCL_CODE_SEND_MESSAGE_0: case HCL_CODE_SEND_MESSAGE_TO_SUPER_0: +#endif if (param_1 < 4 && param_2 < 0xFF) { /* low 2 bits of the instruction code is the first parameter */ @@ -247,10 +328,10 @@ static int emit_double_param_instruction (hcl_t* hcl, int cmd, hcl_oow_t param_1 else { /* convert the code to a long version */ - bc = cmd | 0x80; + bc = cmd | 0x80; goto write_long; } -#endif + case HCL_CODE_MAKE_BLOCK: bc = cmd; @@ -469,10 +550,12 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src) hcl_oop_t obj, args, arg, ptr; hcl_oow_t nargs, ntmprs; hcl_oow_t jump_inst_pos; + hcl_oow_t saved_tv_count; HCL_ASSERT (HCL_BRANDOF(hcl,src) == HCL_BRAND_CONS); HCL_ASSERT (HCL_CONS_CAR(src) == hcl->_lambda); + saved_tv_count = hcl->c->tv.size; obj = HCL_CONS_CDR(src); if (HCL_IS_NIL(hcl, obj)) @@ -496,6 +579,7 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src) } else { + hcl_oow_t tv_dup_start; if (HCL_BRANDOF(hcl, args) != HCL_BRAND_CONS) { HCL_DEBUG1 (hcl, "Syntax error - not a lambda argument list - %O\n", args); @@ -503,6 +587,7 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src) return -1; } + tv_dup_start = hcl->c->tv.size; nargs = 0; ptr = args; do @@ -510,12 +595,23 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src) arg = HCL_CONS_CAR(ptr); if (HCL_BRANDOF(hcl, arg) != HCL_BRAND_SYMBOL) { - HCL_DEBUG1 (hcl, "Syntax error - ldamba argument not a symbol - %O\n", arg); + HCL_DEBUG1 (hcl, "Syntax error - lambda argument not a symbol - %O\n", arg); hcl_setsynerr (hcl, HCL_SYNERR_ARGNAME, HCL_NULL, HCL_NULL); /* TODO: error location */ return -1; } /* TODO: check duplicates within only the argument list. duplicates against outer-scope are ok. * is this check necessary? */ + + if (add_temporary_variable (hcl, arg, tv_dup_start) <= -1) + { + if (hcl->errnum == HCL_EEXIST) + { + HCL_DEBUG1 (hcl, "Syntax error - lambda argument duplicate - %O\n", arg); + hcl_setsynerr (hcl, HCL_SYNERR_ARGNAME, HCL_NULL, HCL_NULL); /* TODO: error location */ + return -1; + } + return -1; + } nargs++; ptr = HCL_CONS_CDR(ptr); @@ -533,9 +629,42 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src) while (1); } - ntmprs = nargs; + ntmprs = nargs; /* TODO: handle local temporary variables */ + HCL_ASSERT (nargs == hcl->c->tv.size - saved_tv_count); + if (nargs > MAX_CODE_NBLKARGS) /*TODO: change this limit to max call argument count */ + { + /* while an integer object is pused to indicate the number of + * block arguments, evaluation which is done by message passing + * limits the number of arguments that can be passed. so the + * check is implemented */ + HCL_DEBUG1 (hcl, "Syntax error - too many arguments - %O\n", args); + hcl_setsynerr (hcl, HCL_SYNERR_ARGFLOOD, HCL_NULL, HCL_NULL); + return -1; + } + +#if 0 +/* TODO: block local temporary variables... */ + /* ntmprs: number of temporary variables including arguments */ + HCL_ASSERT (ntmprs == hcl->c->tv.size - saved_tv_count); + if (ntmprs > MAX_CODE_NBLKTMPRS) + { + HCL_DEBUG1 (hcl, "Syntax error - too many local temporary variables - %O\n", args); + hcl_setsynerr (hcl, HCL_SYNERR_BLKTMPRFLOOD, HCL_NULL, HCL_NULL); + return -1; + } +#endif + + if (hcl->c->blk.depth == HCL_TYPE_MAX(hcl_ooi_t)) + { + HCL_DEBUG1 (hcl, "Syntax error - lambda block depth too deep - %O\n", src); + hcl_setsynerr (hcl, HCL_SYNERR_BLKDEPTH, HCL_NULL, HCL_NULL); + return -1; + } + hcl->c->blk.depth++; + if (store_temporary_variable_count_for_block (hcl, hcl->c->tv.size) <= -1) return -1; + if (emit_double_param_instruction (hcl, HCL_CODE_MAKE_BLOCK, nargs, ntmprs) <= -1) return -1; /* specifying MAX_CODE_JUMP causes emit_single_param_instruction() to @@ -544,8 +673,9 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src) if (emit_single_param_instruction (hcl, HCL_CODE_JUMP_FORWARD_0, MAX_CODE_JUMP) <= -1) return -1; SWITCH_TOP_CFRAME (hcl, COP_COMPILE_OBJECT_LIST, HCL_CONS_CDR(obj)); + PUSH_SUBCFRAME (hcl, COP_EMIT_LAMBDA, hcl->_nil); /* operand field is not used for COP_EMIT_LAMBDA */ - cf = GET_SUBCFRAME (hcl); + cf = GET_SUBCFRAME (hcl); /* modify the EMIT_LAMBDA frame */ cf->u.lambda.jip = jump_inst_pos; cf->u.lambda.nargs = nargs; cf->u.lambda.ntmprs = ntmprs; @@ -610,7 +740,7 @@ static int compile_set (hcl_t* hcl, hcl_oop_t src) } SWITCH_TOP_CFRAME (hcl, COP_COMPILE_OBJECT, val); - PUSH_SUBCFRAME (hcl, COP_EMIT_SET, var); + PUSH_SUBCFRAME (hcl, COP_EMIT_SET, var); /* set doesn't evaluate the variable name */ cf = GET_SUBCFRAME (hcl); cf->u.set.var_type = VAR_NAMED; @@ -719,11 +849,44 @@ static HCL_INLINE int compile_symbol (hcl_t* hcl, hcl_oop_t obj) HCL_ASSERT (HCL_BRANDOF(hcl,obj) == HCL_BRAND_SYMBOL); /* check if a symbol is a local variable */ - /*if (emit_single_param_instruction (hcl, HCL_CODE_PUSH_TEMPVAR_0, xxx) <= -1) return -1;*/ + if (find_temporary_variable_backward (hcl, obj, &index) <= -1) + { + /* global variable */ + if (add_literal(hcl, obj, &index) <= -1 || + emit_single_param_instruction (hcl, HCL_CODE_PUSH_OBJECT_0, index) <= -1) return -1; + } + else + { + #if defined(HCL_USE_CTXTEMPVAR) + if (hcl->c->blk.depth >= 0) + { + hcl_oow_t i; - /* global variable */ - if (add_literal(hcl, obj,&index) <= -1 || - emit_single_param_instruction (hcl, HCL_CODE_PUSH_OBJECT_0, index) <= -1) return -1; + /* if a temporary variable is accessed inside a block, + * use a special instruction to indicate it */ + HCL_ASSERT (index < hcl->c->blk.tmprcnt[hcl->c->blk.depth]); + for (i = hcl->c->blk.depth; i > 0; i--) /* excluded the top level -- TODO: change this code depending on global variable handling */ + { + if (index >= hcl->c->blk.tmprcnt[i - 1]) + { + hcl_oow_t ctx_offset, index_in_ctx; + ctx_offset = hcl->c->blk.depth - i; + index_in_ctx = index - hcl->c->blk.tmprcnt[i - 1]; + /* ctx_offset 0 means the current context. + * 1 means current->home. + * 2 means current->home->home. + * index_in_ctx is a relative index within the context found. + */ + if (emit_double_param_instruction(hcl, HCL_CODE_PUSH_CTXTEMPVAR_0, ctx_offset, index_in_ctx) <= -1) return -1; + return 0; + } + } + } + #endif + + /* TODO: top-level... verify this. this will vary depending on how i implement the top-level and global variables... */ + if (emit_single_param_instruction (hcl, HCL_CODE_PUSH_TEMPVAR_0, index) <= -1) return -1; + } return 0; } @@ -832,6 +995,9 @@ static HCL_INLINE int emit_lambda (hcl_t* hcl) HCL_ASSERT (cf->opcode == COP_EMIT_LAMBDA); HCL_ASSERT (HCL_IS_NIL(hcl, cf->operand)); + hcl->c->blk.depth--; + hcl->c->tv.size = hcl->c->blk.tmprcnt[hcl->c->blk.depth]; + /* HCL_CODE_LONG_PARAM_SIZE + 1 => size of the long JUMP_FORWARD instruction */ block_code_size = hcl->code.bc.len - cf->u.lambda.jip - (HCL_BCODE_LONG_PARAM_SIZE + 1); @@ -944,6 +1110,13 @@ int hcl_compile (hcl_t* hcl, hcl_oop_t obj) saved_bc_len = hcl->code.bc.len; saved_lit_len = hcl->code.lit.len; + HCL_ASSERT (hcl->c->tv.size == 0); + HCL_ASSERT (hcl->c->blk.depth == -1); + +/* TODO: in case i implement all global variables as block arguments at the top level... */ + hcl->c->blk.depth++; + if (store_temporary_variable_count_for_block(hcl, hcl->c->tv.size) <= -1) return -1; + PUSH_CFRAME (hcl, COP_COMPILE_OBJECT, obj); while (GET_TOP_CFRAME_INDEX(hcl) >= 0) @@ -990,6 +1163,9 @@ int hcl_compile (hcl_t* hcl, hcl_oop_t obj) done: HCL_ASSERT (GET_TOP_CFRAME_INDEX(hcl) < 0); + HCL_ASSERT (hcl->c->tv.size == 0); + HCL_ASSERT (hcl->c->blk.depth == 0); + hcl->c->blk.depth--; return 0; oops: @@ -999,5 +1175,7 @@ oops: hcl->code.bc.len = saved_bc_len; hcl->code.lit.len = saved_lit_len; + hcl->c->tv.size = 0; + hcl->c->blk.depth = 0; return -1; } diff --git a/lib/decode.c b/lib/decode.c index d673980..46ab1bb 100644 --- a/lib/decode.c +++ b/lib/decode.c @@ -1,4 +1,3 @@ -/* /* * $Id$ * @@ -120,7 +119,7 @@ int hcl_decode (hcl_t* hcl, hcl_oow_t start, hcl_oow_t end) /* ------------------------------------------------- */ case HCL_CODE_PUSH_TEMPVAR_X: - case BCODE_STORE_INTO_TEMPVAR_X: + case HCL_CODE_STORE_INTO_TEMPVAR_X: case BCODE_POP_INTO_TEMPVAR_X: FETCH_PARAM_CODE_TO (hcl, b1); goto handle_tempvar; @@ -133,14 +132,14 @@ int hcl_decode (hcl_t* hcl, hcl_oow_t start, hcl_oow_t end) case HCL_CODE_PUSH_TEMPVAR_5: case HCL_CODE_PUSH_TEMPVAR_6: case HCL_CODE_PUSH_TEMPVAR_7: - case BCODE_STORE_INTO_TEMPVAR_0: - case BCODE_STORE_INTO_TEMPVAR_1: - case BCODE_STORE_INTO_TEMPVAR_2: - case BCODE_STORE_INTO_TEMPVAR_3: - case BCODE_STORE_INTO_TEMPVAR_4: - case BCODE_STORE_INTO_TEMPVAR_5: - case BCODE_STORE_INTO_TEMPVAR_6: - case BCODE_STORE_INTO_TEMPVAR_7: + case HCL_CODE_STORE_INTO_TEMPVAR_0: + case HCL_CODE_STORE_INTO_TEMPVAR_1: + case HCL_CODE_STORE_INTO_TEMPVAR_2: + case HCL_CODE_STORE_INTO_TEMPVAR_3: + case HCL_CODE_STORE_INTO_TEMPVAR_4: + case HCL_CODE_STORE_INTO_TEMPVAR_5: + case HCL_CODE_STORE_INTO_TEMPVAR_6: + case HCL_CODE_STORE_INTO_TEMPVAR_7: case BCODE_POP_INTO_TEMPVAR_0: case BCODE_POP_INTO_TEMPVAR_1: case BCODE_POP_INTO_TEMPVAR_2: @@ -203,7 +202,7 @@ int hcl_decode (hcl_t* hcl, hcl_oow_t start, hcl_oow_t end) /* ------------------------------------------------- */ case HCL_CODE_PUSH_OBJECT_X: case HCL_CODE_STORE_INTO_OBJECT_X: - case HCL_CODE_POP_INTO_OBJECT_X: + case BCODE_POP_INTO_OBJECT_X: FETCH_PARAM_CODE_TO (hcl, b1); goto handle_object; @@ -215,10 +214,10 @@ int hcl_decode (hcl_t* hcl, hcl_oow_t start, hcl_oow_t end) case HCL_CODE_STORE_INTO_OBJECT_1: case HCL_CODE_STORE_INTO_OBJECT_2: case HCL_CODE_STORE_INTO_OBJECT_3: - case HCL_CODE_POP_INTO_OBJECT_0: - case HCL_CODE_POP_INTO_OBJECT_1: - case HCL_CODE_POP_INTO_OBJECT_2: - case HCL_CODE_POP_INTO_OBJECT_3: + case BCODE_POP_INTO_OBJECT_0: + case BCODE_POP_INTO_OBJECT_1: + case BCODE_POP_INTO_OBJECT_2: + case BCODE_POP_INTO_OBJECT_3: b1 = bcode & 0x3; /* low 2 bits */ handle_object: if ((bcode >> 3) & 1) @@ -306,20 +305,20 @@ return -1; /* -------------------------------------------------------- */ - case BCODE_PUSH_CTXTEMPVAR_X: - case BCODE_STORE_INTO_CTXTEMPVAR_X: + case HCL_CODE_PUSH_CTXTEMPVAR_X: + case HCL_CODE_STORE_INTO_CTXTEMPVAR_X: case BCODE_POP_INTO_CTXTEMPVAR_X: FETCH_PARAM_CODE_TO (hcl, b1); FETCH_PARAM_CODE_TO (hcl, b2); goto handle_ctxtempvar; - case BCODE_PUSH_CTXTEMPVAR_0: - case BCODE_PUSH_CTXTEMPVAR_1: - case BCODE_PUSH_CTXTEMPVAR_2: - case BCODE_PUSH_CTXTEMPVAR_3: - case BCODE_STORE_INTO_CTXTEMPVAR_0: - case BCODE_STORE_INTO_CTXTEMPVAR_1: - case BCODE_STORE_INTO_CTXTEMPVAR_2: - case BCODE_STORE_INTO_CTXTEMPVAR_3: + case HCL_CODE_PUSH_CTXTEMPVAR_0: + case HCL_CODE_PUSH_CTXTEMPVAR_1: + case HCL_CODE_PUSH_CTXTEMPVAR_2: + case HCL_CODE_PUSH_CTXTEMPVAR_3: + case HCL_CODE_STORE_INTO_CTXTEMPVAR_0: + case HCL_CODE_STORE_INTO_CTXTEMPVAR_1: + case HCL_CODE_STORE_INTO_CTXTEMPVAR_2: + case HCL_CODE_STORE_INTO_CTXTEMPVAR_3: case BCODE_POP_INTO_CTXTEMPVAR_0: case BCODE_POP_INTO_CTXTEMPVAR_1: case BCODE_POP_INTO_CTXTEMPVAR_2: diff --git a/lib/hcl-prv.h b/lib/hcl-prv.h index e9795a2..e9b4b94 100644 --- a/lib/hcl-prv.h +++ b/lib/hcl-prv.h @@ -351,6 +351,20 @@ struct hcl_compiler_t hcl_oow_t capa; } cfs; /* == END COMPILER STACK == */ + + struct + { + hcl_oop_t* ptr; + hcl_oow_t size; + hcl_oow_t capa; + } tv; /* temporary variables including arguments */ + + struct + { + hcl_ooi_t depth; + hcl_oow_t* tmprcnt; + hcl_oow_t tmprcnt_capa; + } blk; /* lambda block */ }; #endif @@ -489,15 +503,15 @@ enum hcl_bcode_t HCL_CODE_PUSH_TEMPVAR_6 = 0x1E, HCL_CODE_PUSH_TEMPVAR_7 = 0x1F, - BCODE_STORE_INTO_TEMPVAR_0 = 0x20, - BCODE_STORE_INTO_TEMPVAR_1 = 0x21, - BCODE_STORE_INTO_TEMPVAR_2 = 0x22, - BCODE_STORE_INTO_TEMPVAR_3 = 0x23, + HCL_CODE_STORE_INTO_TEMPVAR_0 = 0x20, + HCL_CODE_STORE_INTO_TEMPVAR_1 = 0x21, + HCL_CODE_STORE_INTO_TEMPVAR_2 = 0x22, + HCL_CODE_STORE_INTO_TEMPVAR_3 = 0x23, - BCODE_STORE_INTO_TEMPVAR_4 = 0x24, - BCODE_STORE_INTO_TEMPVAR_5 = 0x25, - BCODE_STORE_INTO_TEMPVAR_6 = 0x26, - BCODE_STORE_INTO_TEMPVAR_7 = 0x27, + HCL_CODE_STORE_INTO_TEMPVAR_4 = 0x24, + HCL_CODE_STORE_INTO_TEMPVAR_5 = 0x25, + HCL_CODE_STORE_INTO_TEMPVAR_6 = 0x26, + HCL_CODE_STORE_INTO_TEMPVAR_7 = 0x27, BCODE_POP_INTO_TEMPVAR_0 = 0x28, BCODE_POP_INTO_TEMPVAR_1 = 0x29, @@ -526,10 +540,10 @@ enum hcl_bcode_t HCL_CODE_STORE_INTO_OBJECT_2 = 0x3A, HCL_CODE_STORE_INTO_OBJECT_3 = 0x3B, - HCL_CODE_POP_INTO_OBJECT_0 = 0x3C, - HCL_CODE_POP_INTO_OBJECT_1 = 0x3D, - HCL_CODE_POP_INTO_OBJECT_2 = 0x3E, - HCL_CODE_POP_INTO_OBJECT_3 = 0x3F, + BCODE_POP_INTO_OBJECT_0 = 0x3C, + BCODE_POP_INTO_OBJECT_1 = 0x3D, + BCODE_POP_INTO_OBJECT_2 = 0x3E, + BCODE_POP_INTO_OBJECT_3 = 0x3F, HCL_CODE_PUSH_OBJECT_0 = 0x40, HCL_CODE_PUSH_OBJECT_1 = 0x41, @@ -561,20 +575,20 @@ enum hcl_bcode_t HCL_CODE_CALL_2 = 0x56, /* 86 */ HCL_CODE_CALL_3 = 0x57, /* 87 */ - BCODE_STORE_INTO_CTXTEMPVAR_0 = 0x58, /* 88 */ - BCODE_STORE_INTO_CTXTEMPVAR_1 = 0x59, /* 89 */ - BCODE_STORE_INTO_CTXTEMPVAR_2 = 0x5A, /* 90 */ - BCODE_STORE_INTO_CTXTEMPVAR_3 = 0x5B, /* 91 */ + HCL_CODE_STORE_INTO_CTXTEMPVAR_0 = 0x58, /* 88 */ + HCL_CODE_STORE_INTO_CTXTEMPVAR_1 = 0x59, /* 89 */ + HCL_CODE_STORE_INTO_CTXTEMPVAR_2 = 0x5A, /* 90 */ + HCL_CODE_STORE_INTO_CTXTEMPVAR_3 = 0x5B, /* 91 */ BCODE_POP_INTO_CTXTEMPVAR_0 = 0x5C, /* 92 */ BCODE_POP_INTO_CTXTEMPVAR_1 = 0x5D, /* 93 */ BCODE_POP_INTO_CTXTEMPVAR_2 = 0x5E, /* 94 */ BCODE_POP_INTO_CTXTEMPVAR_3 = 0x5F, /* 95 */ - BCODE_PUSH_CTXTEMPVAR_0 = 0x60, /* 96 */ - BCODE_PUSH_CTXTEMPVAR_1 = 0x61, /* 97 */ - BCODE_PUSH_CTXTEMPVAR_2 = 0x62, /* 98 */ - BCODE_PUSH_CTXTEMPVAR_3 = 0x63, /* 99 */ + HCL_CODE_PUSH_CTXTEMPVAR_0 = 0x60, /* 96 */ + HCL_CODE_PUSH_CTXTEMPVAR_1 = 0x61, /* 97 */ + HCL_CODE_PUSH_CTXTEMPVAR_2 = 0x62, /* 98 */ + HCL_CODE_PUSH_CTXTEMPVAR_3 = 0x63, /* 99 */ BCODE_PUSH_OBJVAR_0 = 0x64, BCODE_PUSH_OBJVAR_1 = 0x65, @@ -608,7 +622,7 @@ enum hcl_bcode_t BCODE_PUSH_INSTVAR_X = 0x90, /* 144 */ HCL_CODE_PUSH_TEMPVAR_X = 0x98, /* 152 */ - BCODE_STORE_INTO_TEMPVAR_X = 0xA0, /* 160 */ + HCL_CODE_STORE_INTO_TEMPVAR_X = 0xA0, /* 160 */ BCODE_POP_INTO_TEMPVAR_X = 0xA8, /* 168 */ HCL_CODE_PUSH_LITERAL_X = 0xB0, /* 176 */ @@ -616,8 +630,8 @@ enum hcl_bcode_t /* SEE FURTHER DOWN FOR SPECIAL CODES - 0xB2 - 0xB7 */ - HCL_CODE_STORE_INTO_OBJECT_X = 0xB8, /* 184 */ - HCL_CODE_POP_INTO_OBJECT_X = 0xBC, /* 188 */ + HCL_CODE_STORE_INTO_OBJECT_X = 0xB8, /* 184 */ + BCODE_POP_INTO_OBJECT_X = 0xBC, /* 188 */ HCL_CODE_PUSH_OBJECT_X = 0xC0, /* 192 */ HCL_CODE_JUMP_FORWARD_X = 0xC4, /* 196 */ @@ -627,9 +641,9 @@ enum hcl_bcode_t HCL_CODE_CALL_X = 0xD4, /* 212 */ - BCODE_STORE_INTO_CTXTEMPVAR_X = 0xD8, /* 216 */ + HCL_CODE_STORE_INTO_CTXTEMPVAR_X = 0xD8, /* 216 */ BCODE_POP_INTO_CTXTEMPVAR_X = 0xDC, /* 220 */ - BCODE_PUSH_CTXTEMPVAR_X = 0xE0, /* 224 */ + HCL_CODE_PUSH_CTXTEMPVAR_X = 0xE0, /* 224 */ BCODE_PUSH_OBJVAR_X = 0xE4, /* 228 */ BCODE_STORE_INTO_OBJVAR_X = 0xE8, /* 232 */ diff --git a/lib/hcl.h b/lib/hcl.h index 325b1a3..b00beca 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -52,6 +52,7 @@ enum hcl_errnum_t HCL_EPERM, /**< operation not permitted */ HCL_ERANGE, /**< range error. overflow and underflow */ HCL_ENOENT, /**< no matching entry */ + HCL_EEXIST, /**< duplicate entry */ HCL_EDFULL, /**< dictionary full */ HCL_EPFULL, /**< processor full */ HCL_ESHFULL, /**< semaphore heap full */ @@ -90,8 +91,10 @@ enum hcl_synerrnum_t HCL_SYNERR_ARGNAMELIST, /* argument name list expected */ HCL_SYNERR_ARGNAME, /* argument name expected */ HCL_SYNERR_BLKFLOOD, /* lambda block too big */ + HCL_SYNERR_BLKDEPTH, /* lambda block too deep */ HCL_SYNERR_VARNAME, /* variable name expected */ - HCL_SYNERR_ARGCOUNT /* wrong number of arguments */ + HCL_SYNERR_ARGCOUNT, /* wrong number of arguments */ + HCL_SYNERR_ARGFLOOD /* too many arguments defined */ }; typedef enum hcl_synerrnum_t hcl_synerrnum_t; diff --git a/lib/main.c b/lib/main.c index 79b7dbd..4c95e46 100644 --- a/lib/main.c +++ b/lib/main.c @@ -447,8 +447,10 @@ static char* syntax_error_msg[] = "argument name list expected", "argument name expected", "lambda block too big", + "lambda block too deep", "variable name expected", - "wrong number of arguments" + "wrong number of arguments", + "too many arguments defined" }; static void print_synerr (hcl_t* hcl) diff --git a/lib/read.c b/lib/read.c index 4e080fd..1fd50ec 100644 --- a/lib/read.c +++ b/lib/read.c @@ -1687,6 +1687,11 @@ static void gc_compiler (hcl_t* hcl) { hcl->c->cfs.ptr[i].operand = hcl_moveoop(hcl, hcl->c->cfs.ptr[i].operand); } + + for (i = 0; i < hcl->c->tv.size; i++) + { + hcl->c->tv.ptr[i] = hcl_moveoop (hcl, hcl->c->tv.ptr[i]); + } } static void fini_compiler (hcl_t* hcl) @@ -1710,6 +1715,22 @@ static void fini_compiler (hcl_t* hcl) hcl->c->cfs.capa = 0; } + if (hcl->c->tv.ptr) + { + hcl_freemem (hcl, hcl->c->tv.ptr); + hcl->c->tv.ptr = HCL_NULL; + hcl->c->tv.size = 0; + hcl->c->tv.capa = 0; + } + + if (hcl->c->blk.tmprcnt) + { + hcl_freemem (hcl, hcl->c->blk.tmprcnt); + hcl->c->blk.tmprcnt = HCL_NULL; + hcl->c->blk.tmprcnt_capa = 0; + hcl->c->blk.depth = -1; + } + clear_io_names (hcl); if (hcl->c->tok.name.ptr) hcl_freemem (hcl, hcl->c->tok.name.ptr); @@ -1755,6 +1776,7 @@ int hcl_attachio (hcl_t* hcl, hcl_ioimpl_t reader, hcl_ioimpl_t printer) hcl->c->r.e = hcl->_nil; hcl->c->cfs.top = -1; + hcl->c->blk.depth = -1; } else if (hcl->c->reader || hcl->c->printer) {