fixed the push_ivar instruction not pushing a value
This commit is contained in:
31
README.md
31
README.md
@ -87,39 +87,34 @@ do { | k | set k 20; printf "k=%d\n" k; };
|
|||||||
## Defining a function
|
## Defining a function
|
||||||
|
|
||||||
```
|
```
|
||||||
(fun function-name (arguments)
|
fun function-name(arguments) {
|
||||||
| local variables |
|
| local variables |
|
||||||
function body
|
function body
|
||||||
)
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
(set function-name (lambda (arguments)
|
set function-name (fun(arguments) {
|
||||||
| local variables |
|
| local variables |
|
||||||
function body
|
function body
|
||||||
)
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
## Class
|
## Class
|
||||||
|
|
||||||
```
|
```
|
||||||
(class T
|
class[attributes] Name: Superclass (ivars (cvars)) {
|
||||||
:: | A B C | ## class variables
|
ivar ivar1
|
||||||
|
cvar cvar1
|
||||||
|
|
||||||
(printf "initializing....\n")
|
set cvar1 20
|
||||||
|
|
||||||
(fun :: dump()
|
fun[attributes] name(arguments) {
|
||||||
(printf "%d %d %d\n" A B C)
|
| local variables |
|
||||||
)
|
function body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(set A 10)
|
|
||||||
(set B 20)
|
|
||||||
(set C 30)
|
|
||||||
|
|
||||||
(printf "initialization done....\n")
|
|
||||||
)
|
|
||||||
|
|
||||||
(:T dump)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Redefining a primitive function
|
## Redefining a primitive function
|
||||||
|
32
lib/comp.c
32
lib/comp.c
@ -3010,7 +3010,7 @@ static HAK_INLINE int compile_class_p1 (hak_t* hak)
|
|||||||
/* the position of the CLASS_ENTER instruction */
|
/* the position of the CLASS_ENTER instruction */
|
||||||
hak->c->clsblk.info[hak->c->clsblk.depth].class_enter_inst_pos = hak->code.bc.len;
|
hak->c->clsblk.info[hak->c->clsblk.depth].class_enter_inst_pos = hak->code.bc.len;
|
||||||
|
|
||||||
/* class_enter nsuperclasses, nivars, ncvars */
|
/* class_enter nsuperclasses, nivars, ncvars, spec/selfspec, indexed_type */
|
||||||
if (emit_byte_instruction(hak, HAK_CODE_CLASS_ENTER, &cf->u._class.start_loc) <= -1) goto oops;
|
if (emit_byte_instruction(hak, HAK_CODE_CLASS_ENTER, &cf->u._class.start_loc) <= -1) goto oops;
|
||||||
if (emit_long_param(hak, cf->u._class.nsuperclasses) <= -1) goto oops;
|
if (emit_long_param(hak, cf->u._class.nsuperclasses) <= -1) goto oops;
|
||||||
if (emit_long_param(hak, vardcl.nivars) <= -1) goto oops;
|
if (emit_long_param(hak, vardcl.nivars) <= -1) goto oops;
|
||||||
@ -3426,8 +3426,9 @@ static int compile_fun (hak_t* hak, hak_cnode_t* src)
|
|||||||
{
|
{
|
||||||
/* TODO: it must allow as rvalue..
|
/* TODO: it must allow as rvalue..
|
||||||
* class X {
|
* class X {
|
||||||
* b := (fun() {}) ## this is allowed <- TODO: not supported yet
|
* b := (fun() {}) ## this is prohibited in the previous if check
|
||||||
* fun() {} ## this is prohibited
|
* (fun() {}) ## this is prohibited in the previous if check as well
|
||||||
|
* fun() {} ## this is prohibited in this if check
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
hak_setsynerrbfmt(
|
hak_setsynerrbfmt(
|
||||||
@ -3478,11 +3479,14 @@ static int compile_fun (hak_t* hak, hak_cnode_t* src)
|
|||||||
{
|
{
|
||||||
if (is_in_class_init_scope(hak) || class_name)
|
if (is_in_class_init_scope(hak) || class_name)
|
||||||
{
|
{
|
||||||
/* TODO: */
|
/* NOTE
|
||||||
/* TODO: THIS IS ALSO WRONG.
|
* checking simply with is_in_class_init_scope() isn't sufficient for code like this:
|
||||||
* class X {
|
* class X {
|
||||||
* a := (fun x(){}) ## this context is also class_init_scope. so the check above isn't good enough
|
* a := (fun[#ci] x(){})
|
||||||
* } */
|
* }
|
||||||
|
* but the prior checks prevents the function definition itself in that context.
|
||||||
|
* so the simple check is just ok.
|
||||||
|
*/
|
||||||
if (check_fun_attr_list(hak, attr_list, &fun_type, cmd, class_name, fun_name) <= -1) return -1;
|
if (check_fun_attr_list(hak, attr_list, &fun_type, cmd, class_name, fun_name) <= -1) return -1;
|
||||||
if (class_name) fun_type |= 0x100; /* defined in `fun class:xxx` style outside class */
|
if (class_name) fun_type |= 0x100; /* defined in `fun class:xxx` style outside class */
|
||||||
}
|
}
|
||||||
@ -3520,7 +3524,7 @@ static int compile_fun (hak_t* hak, hak_cnode_t* src)
|
|||||||
nrvars = 0;
|
nrvars = 0;
|
||||||
|
|
||||||
HAK_ASSERT(hak, HAK_CNODE_IS_ELIST_CONCODED(arg_list, HAK_CONCODE_XLIST) ||
|
HAK_ASSERT(hak, HAK_CNODE_IS_ELIST_CONCODED(arg_list, HAK_CONCODE_XLIST) ||
|
||||||
HAK_CNODE_IS_CONS_CONCODED(arg_list, HAK_CONCODE_XLIST));
|
HAK_CNODE_IS_CONS_CONCODED(arg_list, HAK_CONCODE_XLIST));
|
||||||
if (HAK_CNODE_IS_ELIST_CONCODED(arg_list, HAK_CONCODE_XLIST))
|
if (HAK_CNODE_IS_ELIST_CONCODED(arg_list, HAK_CONCODE_XLIST))
|
||||||
{
|
{
|
||||||
/* empty list - no argument - fun () {+ 10 20} */
|
/* empty list - no argument - fun () {+ 10 20} */
|
||||||
@ -3720,7 +3724,7 @@ static int check_var_attr_list (hak_t* hak, hak_cnode_t* attr_list, unsigned int
|
|||||||
|
|
||||||
HAK_ASSERT(hak, attr_list != HAK_NULL);
|
HAK_ASSERT(hak, attr_list != HAK_NULL);
|
||||||
HAK_ASSERT(hak, HAK_CNODE_IS_CONS_CONCODED(attr_list, HAK_CONCODE_XLIST) ||
|
HAK_ASSERT(hak, HAK_CNODE_IS_CONS_CONCODED(attr_list, HAK_CONCODE_XLIST) ||
|
||||||
HAK_CNODE_IS_ELIST_CONCODED(attr_list, HAK_CONCODE_XLIST));
|
HAK_CNODE_IS_ELIST_CONCODED(attr_list, HAK_CONCODE_XLIST));
|
||||||
|
|
||||||
if (HAK_CNODE_IS_ELIST_CONCODED(attr_list, HAK_CONCODE_XLIST))
|
if (HAK_CNODE_IS_ELIST_CONCODED(attr_list, HAK_CONCODE_XLIST))
|
||||||
{
|
{
|
||||||
@ -3933,7 +3937,7 @@ static int compile_return (hak_t* hak, hak_cnode_t* src, int ret_from_home)
|
|||||||
|
|
||||||
HAK_ASSERT(hak, HAK_CNODE_IS_CONS(src));
|
HAK_ASSERT(hak, HAK_CNODE_IS_CONS(src));
|
||||||
HAK_ASSERT(hak, HAK_CNODE_IS_TYPED(HAK_CNODE_CONS_CAR(src), HAK_CNODE_RETURN) ||
|
HAK_ASSERT(hak, HAK_CNODE_IS_TYPED(HAK_CNODE_CONS_CAR(src), HAK_CNODE_RETURN) ||
|
||||||
HAK_CNODE_IS_TYPED(HAK_CNODE_CONS_CAR(src), HAK_CNODE_REVERT));
|
HAK_CNODE_IS_TYPED(HAK_CNODE_CONS_CAR(src), HAK_CNODE_REVERT));
|
||||||
|
|
||||||
fbi = &hak->c->funblk.info[hak->c->funblk.depth];
|
fbi = &hak->c->funblk.info[hak->c->funblk.depth];
|
||||||
obj = HAK_CNODE_CONS_CDR(src);
|
obj = HAK_CNODE_CONS_CDR(src);
|
||||||
@ -4398,7 +4402,7 @@ static HAK_INLINE int compile_catch (hak_t* hak)
|
|||||||
* if 'exarg' is the first variable in the variable string, there is no preceding space.
|
* if 'exarg' is the first variable in the variable string, there is no preceding space.
|
||||||
* if it is not, there is a preceding space. */
|
* if it is not, there is a preceding space. */
|
||||||
HAK_ASSERT(hak, (hak->c->tv.s.len == HAK_CNODE_GET_TOKLEN(exarg) && fbi->tmprlen == hak->c->tv.s.len - HAK_CNODE_GET_TOKLEN(exarg)) || /* first */
|
HAK_ASSERT(hak, (hak->c->tv.s.len == HAK_CNODE_GET_TOKLEN(exarg) && fbi->tmprlen == hak->c->tv.s.len - HAK_CNODE_GET_TOKLEN(exarg)) || /* first */
|
||||||
(hak->c->tv.s.len > HAK_CNODE_GET_TOKLEN(exarg) && fbi->tmprlen == hak->c->tv.s.len - HAK_CNODE_GET_TOKLEN(exarg) - 1)); /* not first */
|
(hak->c->tv.s.len > HAK_CNODE_GET_TOKLEN(exarg) && fbi->tmprlen == hak->c->tv.s.len - HAK_CNODE_GET_TOKLEN(exarg) - 1)); /* not first */
|
||||||
HAK_ASSERT(hak, fbi->tmprcnt == vi.index_in_ctx + par_tmprcnt);
|
HAK_ASSERT(hak, fbi->tmprcnt == vi.index_in_ctx + par_tmprcnt);
|
||||||
fbi->tmprlen = hak->c->tv.s.len;
|
fbi->tmprlen = hak->c->tv.s.len;
|
||||||
fbi->tmprcnt = hak->c->tv.wcount;
|
fbi->tmprcnt = hak->c->tv.wcount;
|
||||||
@ -4531,7 +4535,7 @@ static int compile_while (hak_t* hak, hak_cnode_t* src, int next_cop)
|
|||||||
|
|
||||||
HAK_ASSERT(hak, HAK_CNODE_IS_CONS(src));
|
HAK_ASSERT(hak, HAK_CNODE_IS_CONS(src));
|
||||||
HAK_ASSERT(hak, HAK_CNODE_IS_TYPED(HAK_CNODE_CONS_CAR(src), HAK_CNODE_UNTIL) ||
|
HAK_ASSERT(hak, HAK_CNODE_IS_TYPED(HAK_CNODE_CONS_CAR(src), HAK_CNODE_UNTIL) ||
|
||||||
HAK_CNODE_IS_TYPED(HAK_CNODE_CONS_CAR(src), HAK_CNODE_WHILE));
|
HAK_CNODE_IS_TYPED(HAK_CNODE_CONS_CAR(src), HAK_CNODE_WHILE));
|
||||||
HAK_ASSERT(hak, next_cop == COP_POST_UNTIL_COND || next_cop == COP_POST_WHILE_COND);
|
HAK_ASSERT(hak, next_cop == COP_POST_UNTIL_COND || next_cop == COP_POST_WHILE_COND);
|
||||||
|
|
||||||
cmd = HAK_CNODE_CONS_CAR(src); /* while or until itself */
|
cmd = HAK_CNODE_CONS_CAR(src); /* while or until itself */
|
||||||
@ -5006,7 +5010,7 @@ static int compile_cons_mlist_expression (hak_t* hak, hak_cnode_t* obj, int nret
|
|||||||
* (<receiver> <binop> <operand>
|
* (<receiver> <binop> <operand>
|
||||||
*/
|
*/
|
||||||
HAK_ASSERT(hak, HAK_CNODE_IS_CONS_CONCODED(obj, HAK_CONCODE_BLIST) ||
|
HAK_ASSERT(hak, HAK_CNODE_IS_CONS_CONCODED(obj, HAK_CONCODE_BLIST) ||
|
||||||
HAK_CNODE_IS_CONS_CONCODED(obj, HAK_CONCODE_MLIST));
|
HAK_CNODE_IS_CONS_CONCODED(obj, HAK_CONCODE_MLIST));
|
||||||
|
|
||||||
car = HAK_CNODE_CONS_CAR(obj);
|
car = HAK_CNODE_CONS_CAR(obj);
|
||||||
|
|
||||||
|
@ -3356,7 +3356,7 @@ static hak_oop_t fetch_numeric_rcv_slot (hak_t* hak, hak_oop_t rcv, hak_oow_t b1
|
|||||||
hak_obj_type_t rcv_type;
|
hak_obj_type_t rcv_type;
|
||||||
|
|
||||||
rcv_type = (hak_obj_type_t)HAK_OBJ_GET_FLAGS_TYPE(rcv);
|
rcv_type = (hak_obj_type_t)HAK_OBJ_GET_FLAGS_TYPE(rcv);
|
||||||
switch (HAK_LIKELY(rcv_type))
|
switch (rcv_type)
|
||||||
{
|
{
|
||||||
case HAK_OBJ_TYPE_CHAR:
|
case HAK_OBJ_TYPE_CHAR:
|
||||||
w = ((hak_oop_char_t)rcv)->slot[b1];
|
w = ((hak_oop_char_t)rcv)->slot[b1];
|
||||||
@ -3389,7 +3389,7 @@ static int store_into_numeric_rcv_slot (hak_t* hak, hak_oop_t rcv, hak_oow_t b1,
|
|||||||
else if (hak_inttooow(hak, v, &w) <= -1) return -1;
|
else if (hak_inttooow(hak, v, &w) <= -1) return -1;
|
||||||
|
|
||||||
rcv_type = (hak_obj_type_t)HAK_OBJ_GET_FLAGS_TYPE(rcv);
|
rcv_type = (hak_obj_type_t)HAK_OBJ_GET_FLAGS_TYPE(rcv);
|
||||||
switch (HAK_LIKELY(rcv_type))
|
switch (rcv_type)
|
||||||
{
|
{
|
||||||
case HAK_OBJ_TYPE_CHAR:
|
case HAK_OBJ_TYPE_CHAR:
|
||||||
((hak_oop_char_t)rcv)->slot[b1] = w;
|
((hak_oop_char_t)rcv)->slot[b1] = w;
|
||||||
@ -3542,12 +3542,16 @@ static int execute (hak_t* hak)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
hak_oop_t v;
|
hak_oop_t v;
|
||||||
|
|
||||||
v = fetch_numeric_rcv_slot(hak, rcv, b1);
|
v = fetch_numeric_rcv_slot(hak, rcv, b1);
|
||||||
|
|
||||||
if (HAK_UNLIKELY(!v))
|
if (HAK_UNLIKELY(!v))
|
||||||
{
|
{
|
||||||
if (do_throw_with_internal_errmsg(hak, fetched_instruction_pointer) >= 0) break;
|
if (do_throw_with_internal_errmsg(hak, fetched_instruction_pointer) >= 0) break;
|
||||||
goto oops_with_errmsg_supplement;
|
goto oops_with_errmsg_supplement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HAK_STACK_PUSH(hak, v);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
10
lib/fmt.c
10
lib/fmt.c
@ -317,9 +317,8 @@ static hak_bch_t* sprintn_lower (hak_bch_t* nbuf, hak_uintmax_t num, int base, h
|
|||||||
{
|
{
|
||||||
hak_bch_t* p;
|
hak_bch_t* p;
|
||||||
|
|
||||||
p = nbuf;
|
p = nbuf; *p = '\0';
|
||||||
*p = '\0';
|
do {*++p = hex2ascii_lower[num % base]; } while (num /= base);
|
||||||
do { *++p = hex2ascii_lower[num % base]; } while (num /= base);
|
|
||||||
|
|
||||||
if (lenp) *lenp = p - nbuf;
|
if (lenp) *lenp = p - nbuf;
|
||||||
return p; /* returns the end */
|
return p; /* returns the end */
|
||||||
@ -329,8 +328,7 @@ static hak_bch_t* sprintn_upper (hak_bch_t* nbuf, hak_uintmax_t num, int base, h
|
|||||||
{
|
{
|
||||||
hak_bch_t* p;
|
hak_bch_t* p;
|
||||||
|
|
||||||
p = nbuf;
|
p = nbuf; *p = '\0';
|
||||||
*p = '\0';
|
|
||||||
do { *++p = hex2ascii_upper[num % base]; } while (num /= base);
|
do { *++p = hex2ascii_upper[num % base]; } while (num /= base);
|
||||||
|
|
||||||
if (lenp) *lenp = p - nbuf;
|
if (lenp) *lenp = p - nbuf;
|
||||||
@ -512,7 +510,7 @@ static int fmt_outv (hak_t* hak, hak_fmtout_t* fmtout, va_list ap)
|
|||||||
handle_percent:
|
handle_percent:
|
||||||
padc = ' ';
|
padc = ' ';
|
||||||
width = 0; precision = 0; neg = 0; sign = 0;
|
width = 0; precision = 0; neg = 0; sign = 0;
|
||||||
lm_flag = 0; lm_dflag = 0; flagc = 0;
|
lm_flag = 0; lm_dflag = 0; flagc = 0; base = 10;
|
||||||
sprintn = sprintn_lower;
|
sprintn = sprintn_lower;
|
||||||
|
|
||||||
reswitch:
|
reswitch:
|
||||||
|
Reference in New Issue
Block a user