diff --git a/lib/exec.c b/lib/exec.c index 22739b0..f94fd31 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -377,11 +377,12 @@ static void vm_checkbc (hak_t* hak, hak_oob_t bcode) static HAK_INLINE hak_oop_context_t make_context (hak_t* hak, hak_ooi_t ntmprs) { hak_oop_context_t ctx; + HAK_ASSERT(hak, ntmprs >= 0); /*return (hak_oop_context_t)hak_allocoopobj(hak, HAK_BRAND_CONTEXT, HAK_CONTEXT_NAMED_INSTVARS + (hak_oow_t)ntmprs);*/ ctx = (hak_oop_context_t)hak_instantiate(hak, hak->c_block_context, HAK_NULL, ntmprs); - /* TODO: a good way to initialize smooi field to 0 in hak_insstantiate()? + /* TODO: a good way to initialize smooi field to 0 in hak_instantiate()? * for this, there must be a way to specify the type of the member variables... * it's error-prone to initialize the numeric value to nil where 0 is necessary */ @@ -5134,12 +5135,18 @@ hak_oop_t hak_execute (hak_t* hak) #endif } - /* create a virtual function object that holds the byte code generated plus the literal frame */ + /* create a virtual function object that holds the byte code generated plus the literal frame. + * when hcl_execute() is called repeatedly, especially in the interactive mode, functions and + * methods defined in the previous call refers to data in the previous virtual function. the + * instruction pointers and literal frame indicies, if such functions are called, don't reference + * data in this new function. */ funcobj = make_function(hak, hak->code.lit.len, hak->code.bc.ptr, hak->code.bc.len, hak->code.dbgi); if (HAK_UNLIKELY(!funcobj)) return HAK_NULL; /* pass nil for the home context of the initial function */ - fill_function_data(hak, funcobj, ENCODE_BLK_MASK(0,0,0,0,hak->code.ngtmprs), HAK_TYPE_MAX(hak_oow_t), (hak_oop_context_t)hak->_nil, hak->code.lit.arr->slot, hak->code.lit.len); + fill_function_data( + hak, funcobj, ENCODE_BLK_MASK(0,0,0,0,hak->code.ngtmprs), HAK_TYPE_MAX(hak_oow_t), + (hak_oop_context_t)hak->_nil, hak->code.lit.arr->slot, hak->code.lit.len); hak->initial_function = funcobj; /* the initial function is ready */ diff --git a/lib/hak-prv.h b/lib/hak-prv.h index e07c5f1..91b4fef 100644 --- a/lib/hak-prv.h +++ b/lib/hak-prv.h @@ -821,6 +821,7 @@ struct hak_flx_pi_t hak_oow_t seg_len; hak_oow_t non_ident_seg_count; hak_tok_type_t last_non_ident_type; + hak_oow_t last_non_ident_seg; int is_cla; /* class-level accrssor. prefixed with self/super */ }; @@ -2050,6 +2051,11 @@ int hak_is_binop_char (hak_ooci_t c); int hak_class_responds_to (hak_t* hak, hak_oop_t rcv, hak_oop_t msg); int hak_inst_responds_to (hak_t* hak, hak_oop_t rcv, hak_oop_t msg); +hak_pfrc_t hak_pf_number_add (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs); +hak_pfrc_t hak_pf_number_sub (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs); +hak_pfrc_t hak_pf_number_mul (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs); +hak_pfrc_t hak_pf_number_div (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs); + hak_pfrc_t hak_pf_process_current (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs); hak_pfrc_t hak_pf_process_fork (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs); hak_pfrc_t hak_pf_process_resume (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs); diff --git a/lib/prim.c b/lib/prim.c index 373d063..b6a34a7 100644 --- a/lib/prim.c +++ b/lib/prim.c @@ -810,7 +810,7 @@ static hak_pfrc_t pf_or (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs) /* ------------------------------------------------------------------------- */ -static hak_pfrc_t pf_number_add (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs) +hak_pfrc_t hak_pf_number_add (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs) { hak_ooi_t i; hak_oop_t arg, ret; @@ -828,7 +828,7 @@ static hak_pfrc_t pf_number_add (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs) return HAK_PF_SUCCESS; } -static hak_pfrc_t pf_number_sub (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs) +hak_pfrc_t hak_pf_number_sub (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs) { hak_ooi_t i; hak_oop_t arg, ret; @@ -846,7 +846,7 @@ static hak_pfrc_t pf_number_sub (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs) return HAK_PF_SUCCESS; } -static hak_pfrc_t pf_number_mul (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs) +hak_pfrc_t hak_pf_number_mul (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs) { hak_ooi_t i; hak_oop_t arg, ret; @@ -881,7 +881,7 @@ static hak_pfrc_t pf_number_mlt (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs) return HAK_PF_SUCCESS; } -static hak_pfrc_t pf_number_div (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs) +hak_pfrc_t hak_pf_number_div (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs) { hak_ooi_t i; hak_oop_t arg, ret; @@ -1316,11 +1316,11 @@ static pf_t builtin_prims[] = { 1, 1, pf_is_object, 7, { 'o','b','j','e','c','t','?' } }, - { 1, HAK_TYPE_MAX(hak_oow_t), pf_number_add, 1, { '+' } }, - { 1, HAK_TYPE_MAX(hak_oow_t), pf_number_sub, 1, { '-' } }, - { 1, HAK_TYPE_MAX(hak_oow_t), pf_number_mul, 1, { '*' } }, + { 1, HAK_TYPE_MAX(hak_oow_t), hak_pf_number_add, 1, { '+' } }, + { 1, HAK_TYPE_MAX(hak_oow_t), hak_pf_number_sub, 1, { '-' } }, + { 1, HAK_TYPE_MAX(hak_oow_t), hak_pf_number_mul, 1, { '*' } }, { 1, HAK_TYPE_MAX(hak_oow_t), pf_number_mlt, 3, { 'm','l','t' } }, - { 1, HAK_TYPE_MAX(hak_oow_t), pf_number_div, 1, { '/' } }, + { 1, HAK_TYPE_MAX(hak_oow_t), hak_pf_number_div, 1, { '/' } }, { 1, 1, pf_number_sqrt, 4, { 's','q','r','t' } }, { 1, 1, pf_number_abs, 3, { 'a','b','s' } }, diff --git a/lib/read.c b/lib/read.c index ee9cca3..2a44c26 100644 --- a/lib/read.c +++ b/lib/read.c @@ -312,6 +312,7 @@ static HAK_INLINE int is_pure_lead_ident_char (hak_ooci_t c) static HAK_INLINE int is_pure_ident_char (hak_ooci_t c) { + /* ? is still allowed at the back. see classify_ident_token() */ return hak_is_ooch_alnum(c) || c == '_' || c == '-'; } @@ -322,10 +323,6 @@ static HAK_INLINE int is_lead_ident_char (hak_ooci_t c) static HAK_INLINE int is_ident_char (hak_ooci_t c) { - /* [NOTE] - * '-' is prohibited as the last character of an identifier or an identifier segment. - * see flx_plain_ident(). - */ return hak_is_ooch_alnum(c) || c == '_' || c == '-' || c == '?' || is_binop_char(c); } @@ -3052,6 +3049,7 @@ static int flx_plain_ident (hak_t* hak, hak_ooci_t c) /* identifier */ /* for example, if.if.abc - flag the error after having consumed all the segments */ pi->non_ident_seg_count++; pi->last_non_ident_type = tok_type; + pi->last_non_ident_seg = pi->seg_count; } } @@ -3074,6 +3072,12 @@ static int flx_plain_ident (hak_t* hak, hak_ooci_t c) /* identifier */ FEED_WRAP_UP(hak, pi->last_non_ident_type); goto not_consumed; } + else if (!pi->is_cla && pi->seg_count == pi->last_non_ident_seg + 1 && pi->last_non_ident_type == HAK_TOK_BINOP) + { + /* allow it if the last segment is binop and not prefixed with self. or super. */ + /* for example, core.+ */ + /* do nothing */ + } else { hak_setsynerrbfmt(hak, HAK_SYNERR_ILTOK, TOKEN_LOC(hak), TOKEN_NAME(hak), "wrong multi-segment identifier"); @@ -3082,7 +3086,7 @@ static int flx_plain_ident (hak_t* hak, hak_ooci_t c) /* identifier */ } /* if single-segmented, perform classification(call classify_ident_token()) again - * bcause self and super as the first segment have not been marked as a non-identifier above */ + * because self and super as the first segment have not been marked as a non-identifier above */ if (pi->seg_count == 1) { if (classify_ident_token(hak, TOKEN_NAME(hak), TOKEN_LOC(hak), &tok_type) <= -1) return -1; diff --git a/mod/core.c b/mod/core.c index d27fb77..4e2fad9 100644 --- a/mod/core.c +++ b/mod/core.c @@ -483,6 +483,11 @@ static hak_pfrc_t pf_core_smooi_to_char (hak_t* hak, hak_mod_t* mod, hak_ooi_t n static hak_pfinfo_t pfinfos[] = { + { "*", { HAK_PFBASE_FUNC, hak_pf_number_mul, 1, HAK_TYPE_MAX(hak_oow_t) } }, + { "+", { HAK_PFBASE_FUNC, hak_pf_number_add, 1, HAK_TYPE_MAX(hak_oow_t) } }, + { "-", { HAK_PFBASE_FUNC, hak_pf_number_sub, 1, HAK_TYPE_MAX(hak_oow_t) } }, + { "/", { HAK_PFBASE_FUNC, hak_pf_number_div, 1, HAK_TYPE_MAX(hak_oow_t) } }, +/* TODO: add more builtin primitives here... */ { "basicAt", { HAK_PFBASE_FUNC, pf_core_basic_at, 2, 2 } }, { "basicAtPut", { HAK_PFBASE_FUNC, pf_core_basic_at_put, 3, 3 } }, { "basicNew", { HAK_PFBASE_FUNC, pf_core_basic_new, 2, 2 } }, diff --git a/t/feed-5001.err b/t/feed-5001.err index 58f999d..06b469c 100644 --- a/t/feed-5001.err +++ b/t/feed-5001.err @@ -138,6 +138,10 @@ printf if; ##ERROR: syntax error - 'if' prohibited in this context --- +#234 ##ERROR: syntax error - '2' prohibited as first character of symbol + +--- + abc- := 20 ##ERROR: syntax error - illegal identifier 'abc-' --- @@ -160,7 +164,6 @@ abc. := 20 ##ERROR: syntax error - blank segment after 'abc.' abc.? := 20 ##ERROR: syntax error - wrong multi-segment identifier - abc.? - --- - := 20 ##ERROR: syntax error - bad lvalue - invalid identifier - - diff --git a/t/va-01.hak b/t/va-01.hak index a372792..a1204a0 100644 --- a/t/va-01.hak +++ b/t/va-01.hak @@ -55,17 +55,26 @@ if (~= c 30) { printf "OK: %d\n" c } -## TODO: make the below line work... -##set prim-plus + ## this is not allowed currently... -##fun plus (a b ...) { -## | sum vac i | -## sum := (prim-plus a b) -## vac := (va-count) -## i := 0; -## while (< i vac) { -## sum := (prim-plus sum (va-get i)) -## i := (prim-plus i 1) -## } -## sum := (prim-plus sum 9999) -##} -##printf "%d\n" (plus 10 20 30) +## Redefine the plus function. core.+ still can refer to the built-in +## numeric plus primitive. +## [NOTE] Don't add other test cases below this test case +## as the + function has been manipulated for testing purpose +## Add new cases above here. +fun + (a b ...) { + | sum vac i | + sum := (core.+ a b) + vac := (va-count) + i := 0; + while (< i vac) { + sum := (core.+ sum (va-get i)) + i := (core.+ i 1) + } + sum := (core.+ sum 9999) + return sum +} +c := (+ 10 20 30) +if (~= c 10059) { + printf "ERROR: c is not 30\n" +} else { + printf "OK: %d\n" c +}