added some code to handle local variable declaration
This commit is contained in:
parent
55a5d2c3c6
commit
bdfc72d48d
165
lib/comp.c
165
lib/comp.c
@ -29,7 +29,7 @@
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
VAR_NAMED,
|
VAR_NAMED,
|
||||||
VAR_ARGUMENT
|
VAR_INDEXED
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TV_BUFFER_ALIGN 256
|
#define TV_BUFFER_ALIGN 256
|
||||||
@ -185,16 +185,12 @@ static int emit_single_param_instruction (hcl_t* hcl, int cmd, hcl_oow_t param_1
|
|||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
case BCODE_PUSH_INSTVAR_0:
|
case BCODE_PUSH_INSTVAR_0:
|
||||||
case BCODE_STORE_INTO_INSTVAR_0:
|
case BCODE_STORE_INTO_INSTVAR_0:
|
||||||
case BCODE_POP_INTO_INSTVAR_0:
|
case BCODE_POP_INTO_INSTVAR_0:
|
||||||
#endif
|
|
||||||
case HCL_CODE_PUSH_TEMPVAR_0:
|
case HCL_CODE_PUSH_TEMPVAR_0:
|
||||||
#if 0
|
case HCL_CODE_STORE_INTO_TEMPVAR_0:
|
||||||
case BCODE_STORE_INTO_TEMPVAR_0:
|
|
||||||
case BCODE_POP_INTO_TEMPVAR_0:
|
case BCODE_POP_INTO_TEMPVAR_0:
|
||||||
#endif
|
|
||||||
if (param_1 < 8)
|
if (param_1 < 8)
|
||||||
{
|
{
|
||||||
/* low 3 bits to hold the parameter */
|
/* low 3 bits to hold the parameter */
|
||||||
@ -232,10 +228,8 @@ static int emit_single_param_instruction (hcl_t* hcl, int cmd, hcl_oow_t param_1
|
|||||||
case BCODE_POP_INTO_OBJECT_0:
|
case BCODE_POP_INTO_OBJECT_0:
|
||||||
case HCL_CODE_JUMP_FORWARD_0:
|
case HCL_CODE_JUMP_FORWARD_0:
|
||||||
case HCL_CODE_JUMP_BACKWARD_0:
|
case HCL_CODE_JUMP_BACKWARD_0:
|
||||||
#if 0
|
case BCODE_JUMP_IF_TRUE_0:
|
||||||
case HCL_CODE_JUMP_IF_TRUE_0:
|
case BCODE_JUMP_IF_FALSE_0:
|
||||||
case HCL_CODE_JUMP_IF_FALSE_0:
|
|
||||||
#endif
|
|
||||||
case HCL_CODE_CALL_0:
|
case HCL_CODE_CALL_0:
|
||||||
if (param_1 < 4)
|
if (param_1 < 4)
|
||||||
{
|
{
|
||||||
@ -310,15 +304,13 @@ static int emit_double_param_instruction (hcl_t* hcl, int cmd, hcl_oow_t param_1
|
|||||||
{
|
{
|
||||||
|
|
||||||
case HCL_CODE_STORE_INTO_CTXTEMPVAR_0:
|
case HCL_CODE_STORE_INTO_CTXTEMPVAR_0:
|
||||||
/*case BCODE_POP_INTO_CTXTEMPVAR_0:*/
|
case BCODE_POP_INTO_CTXTEMPVAR_0:
|
||||||
case HCL_CODE_PUSH_CTXTEMPVAR_0:
|
case HCL_CODE_PUSH_CTXTEMPVAR_0:
|
||||||
#if 0
|
case BCODE_PUSH_OBJVAR_0:
|
||||||
case HCL_CODE_PUSH_OBJVAR_0:
|
case BCODE_STORE_INTO_OBJVAR_0:
|
||||||
case HCL_CODE_STORE_INTO_OBJVAR_0:
|
|
||||||
case BCODE_POP_INTO_OBJVAR_0:
|
case BCODE_POP_INTO_OBJVAR_0:
|
||||||
case HCL_CODE_SEND_MESSAGE_0:
|
case BCODE_SEND_MESSAGE_0:
|
||||||
case HCL_CODE_SEND_MESSAGE_TO_SUPER_0:
|
case BCODE_SEND_MESSAGE_TO_SUPER_0:
|
||||||
#endif
|
|
||||||
if (param_1 < 4 && param_2 < 0xFF)
|
if (param_1 < 4 && param_2 < 0xFF)
|
||||||
{
|
{
|
||||||
/* low 2 bits of the instruction code is the first parameter */
|
/* low 2 bits of the instruction code is the first parameter */
|
||||||
@ -547,10 +539,10 @@ enum
|
|||||||
static int compile_lambda (hcl_t* hcl, hcl_oop_t src)
|
static int compile_lambda (hcl_t* hcl, hcl_oop_t src)
|
||||||
{
|
{
|
||||||
hcl_cframe_t* cf;
|
hcl_cframe_t* cf;
|
||||||
hcl_oop_t obj, args, arg, ptr;
|
hcl_oop_t obj, args;
|
||||||
hcl_oow_t nargs, ntmprs;
|
hcl_oow_t nargs, ntmprs;
|
||||||
hcl_oow_t jump_inst_pos;
|
hcl_oow_t jump_inst_pos;
|
||||||
hcl_oow_t saved_tv_count;
|
hcl_oow_t saved_tv_count, tv_dup_start;
|
||||||
|
|
||||||
HCL_ASSERT (HCL_BRANDOF(hcl,src) == HCL_BRAND_CONS);
|
HCL_ASSERT (HCL_BRANDOF(hcl,src) == HCL_BRAND_CONS);
|
||||||
HCL_ASSERT (HCL_CONS_CAR(src) == hcl->_lambda);
|
HCL_ASSERT (HCL_CONS_CAR(src) == hcl->_lambda);
|
||||||
@ -579,7 +571,8 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hcl_oow_t tv_dup_start;
|
hcl_oop_t arg, ptr;
|
||||||
|
|
||||||
if (HCL_BRANDOF(hcl, args) != HCL_BRAND_CONS)
|
if (HCL_BRANDOF(hcl, args) != HCL_BRAND_CONS)
|
||||||
{
|
{
|
||||||
HCL_DEBUG1 (hcl, "Syntax error - not a lambda argument list - %O\n", args);
|
HCL_DEBUG1 (hcl, "Syntax error - not a lambda argument list - %O\n", args);
|
||||||
@ -607,8 +600,7 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src)
|
|||||||
if (hcl->errnum == HCL_EEXIST)
|
if (hcl->errnum == HCL_EEXIST)
|
||||||
{
|
{
|
||||||
HCL_DEBUG1 (hcl, "Syntax error - lambda argument duplicate - %O\n", arg);
|
HCL_DEBUG1 (hcl, "Syntax error - lambda argument duplicate - %O\n", arg);
|
||||||
hcl_setsynerr (hcl, HCL_SYNERR_ARGNAME, HCL_NULL, HCL_NULL); /* TODO: error location */
|
hcl_setsynerr (hcl, HCL_SYNERR_ARGNAMEDUP, HCL_NULL, HCL_NULL); /* TODO: error location */
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -629,9 +621,6 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src)
|
|||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ntmprs = nargs;
|
|
||||||
/* TODO: handle local temporary variables */
|
|
||||||
|
|
||||||
HCL_ASSERT (nargs == hcl->c->tv.size - saved_tv_count);
|
HCL_ASSERT (nargs == hcl->c->tv.size - saved_tv_count);
|
||||||
if (nargs > MAX_CODE_NBLKARGS) /*TODO: change this limit to max call argument count */
|
if (nargs > MAX_CODE_NBLKARGS) /*TODO: change this limit to max call argument count */
|
||||||
{
|
{
|
||||||
@ -644,17 +633,49 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
ntmprs = nargs;
|
||||||
/* TODO: block local temporary variables... */
|
obj = HCL_CONS_CDR(obj);
|
||||||
|
|
||||||
|
tv_dup_start = hcl->c->tv.size;
|
||||||
|
while (HCL_IS_CONS(hcl, obj))
|
||||||
|
{
|
||||||
|
hcl_oop_t dcl;
|
||||||
|
|
||||||
|
dcl = HCL_CONS_CAR(obj);
|
||||||
|
if (HCL_IS_SYMBOL_ARRAY(hcl, dcl))
|
||||||
|
{
|
||||||
|
hcl_oow_t i, sz;
|
||||||
|
|
||||||
|
sz = HCL_OBJ_GET_SIZE(dcl);
|
||||||
|
for (i = 0; i < sz; i++)
|
||||||
|
{
|
||||||
|
if (add_temporary_variable (hcl, ((hcl_oop_oop_t)dcl)->slot[i], tv_dup_start) <= -1)
|
||||||
|
{
|
||||||
|
if (hcl->errnum == HCL_EEXIST)
|
||||||
|
{
|
||||||
|
HCL_DEBUG1 (hcl, "Syntax error - local variable duplicate - %O\n", ((hcl_oop_oop_t)dcl)->slot[i]);
|
||||||
|
hcl_setsynerr (hcl, HCL_SYNERR_VARNAMEDUP, HCL_NULL, HCL_NULL); /* TODO: error location */
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ntmprs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj = HCL_CONS_CDR(obj);
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
/* ntmprs: number of temporary variables including arguments */
|
/* ntmprs: number of temporary variables including arguments */
|
||||||
HCL_ASSERT (ntmprs == hcl->c->tv.size - saved_tv_count);
|
HCL_ASSERT (ntmprs == hcl->c->tv.size - saved_tv_count);
|
||||||
if (ntmprs > MAX_CODE_NBLKTMPRS)
|
if (ntmprs > MAX_CODE_NBLKTMPRS)
|
||||||
{
|
{
|
||||||
HCL_DEBUG1 (hcl, "Syntax error - too many local temporary variables - %O\n", args);
|
HCL_DEBUG1 (hcl, "Syntax error - too many variables - %O\n", args);
|
||||||
hcl_setsynerr (hcl, HCL_SYNERR_BLKTMPRFLOOD, HCL_NULL, HCL_NULL);
|
hcl_setsynerr (hcl, HCL_SYNERR_VARFLOOD, HCL_NULL, HCL_NULL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (hcl->c->blk.depth == HCL_TYPE_MAX(hcl_ooi_t))
|
if (hcl->c->blk.depth == HCL_TYPE_MAX(hcl_ooi_t))
|
||||||
{
|
{
|
||||||
@ -672,7 +693,7 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src)
|
|||||||
jump_inst_pos = hcl->code.bc.len;
|
jump_inst_pos = hcl->code.bc.len;
|
||||||
if (emit_single_param_instruction (hcl, HCL_CODE_JUMP_FORWARD_0, MAX_CODE_JUMP) <= -1) return -1;
|
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));
|
SWITCH_TOP_CFRAME (hcl, COP_COMPILE_OBJECT_LIST, obj);
|
||||||
|
|
||||||
PUSH_SUBCFRAME (hcl, COP_EMIT_LAMBDA, hcl->_nil); /* operand field is not used for COP_EMIT_LAMBDA */
|
PUSH_SUBCFRAME (hcl, COP_EMIT_LAMBDA, hcl->_nil); /* operand field is not used for COP_EMIT_LAMBDA */
|
||||||
cf = GET_SUBCFRAME (hcl); /* modify the EMIT_LAMBDA frame */
|
cf = GET_SUBCFRAME (hcl); /* modify the EMIT_LAMBDA frame */
|
||||||
@ -687,6 +708,7 @@ static int compile_set (hcl_t* hcl, hcl_oop_t src)
|
|||||||
{
|
{
|
||||||
hcl_cframe_t* cf;
|
hcl_cframe_t* cf;
|
||||||
hcl_oop_t obj, var, val;
|
hcl_oop_t obj, var, val;
|
||||||
|
hcl_oow_t index;
|
||||||
|
|
||||||
obj = HCL_CONS_CDR(src);
|
obj = HCL_CONS_CDR(src);
|
||||||
|
|
||||||
@ -740,9 +762,22 @@ static int compile_set (hcl_t* hcl, hcl_oop_t src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_TOP_CFRAME (hcl, COP_COMPILE_OBJECT, val);
|
SWITCH_TOP_CFRAME (hcl, COP_COMPILE_OBJECT, val);
|
||||||
|
|
||||||
|
if (find_temporary_variable_backward (hcl, var, &index) <= -1)
|
||||||
|
{
|
||||||
PUSH_SUBCFRAME (hcl, COP_EMIT_SET, var); /* set doesn't evaluate the variable name */
|
PUSH_SUBCFRAME (hcl, COP_EMIT_SET, var); /* set doesn't evaluate the variable name */
|
||||||
cf = GET_SUBCFRAME (hcl);
|
cf = GET_SUBCFRAME (hcl);
|
||||||
cf->u.set.var_type = VAR_NAMED;
|
cf->u.set.var_type = VAR_NAMED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* the check in compile_lambda() must ensure this condition */
|
||||||
|
HCL_ASSERT (index <= HCL_SMOOI_MAX);
|
||||||
|
|
||||||
|
PUSH_SUBCFRAME (hcl, COP_EMIT_SET, HCL_SMOOI_TO_OOP(index));
|
||||||
|
cf = GET_SUBCFRAME (hcl);
|
||||||
|
cf->u.set.var_type = VAR_INDEXED;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -842,22 +877,9 @@ static int compile_cons (hcl_t* hcl, hcl_oop_t obj)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HCL_INLINE int compile_symbol (hcl_t* hcl, hcl_oop_t obj)
|
static int emit_indexed_variable_access (hcl_t* hcl, hcl_oow_t index, hcl_oob_t baseinst1, hcl_oob_t baseinst2)
|
||||||
{
|
{
|
||||||
hcl_oow_t index;
|
#if defined(HCL_USE_CTXTEMPVAR)
|
||||||
|
|
||||||
HCL_ASSERT (HCL_BRANDOF(hcl,obj) == HCL_BRAND_SYMBOL);
|
|
||||||
|
|
||||||
/* check if a symbol is a local variable */
|
|
||||||
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)
|
if (hcl->c->blk.depth >= 0)
|
||||||
{
|
{
|
||||||
hcl_oow_t i;
|
hcl_oow_t i;
|
||||||
@ -877,18 +899,38 @@ static HCL_INLINE int compile_symbol (hcl_t* hcl, hcl_oop_t obj)
|
|||||||
* 2 means current->home->home.
|
* 2 means current->home->home.
|
||||||
* index_in_ctx is a relative index within the context found.
|
* 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;
|
if (emit_double_param_instruction(hcl, baseinst1, ctx_offset, index_in_ctx) <= -1) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* TODO: top-level... verify this. this will vary depending on how i implement the top-level and global variables... */
|
/* 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;
|
if (emit_single_param_instruction (hcl, baseinst2, index) <= -1) return -1;
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HCL_INLINE int compile_symbol (hcl_t* hcl, hcl_oop_t obj)
|
||||||
|
{
|
||||||
|
hcl_oow_t index;
|
||||||
|
|
||||||
|
HCL_ASSERT (HCL_BRANDOF(hcl,obj) == HCL_BRAND_SYMBOL);
|
||||||
|
|
||||||
|
/* check if a symbol is a local variable */
|
||||||
|
if (find_temporary_variable_backward (hcl, obj, &index) <= -1)
|
||||||
|
{
|
||||||
|
/* TODO: if i require all variables to be declared, this part is not needed and should handle it as an error */
|
||||||
|
/* global variable */
|
||||||
|
if (add_literal(hcl, obj, &index) <= -1 ||
|
||||||
|
emit_single_param_instruction (hcl, HCL_CODE_PUSH_OBJECT_0, index) <= -1) return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return emit_indexed_variable_access (hcl, index, HCL_CODE_PUSH_CTXTEMPVAR_0, HCL_CODE_PUSH_TEMPVAR_0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int compile_object (hcl_t* hcl)
|
static int compile_object (hcl_t* hcl)
|
||||||
@ -922,6 +964,11 @@ static int compile_object (hcl_t* hcl)
|
|||||||
if (compile_cons (hcl, cf->operand) <= -1) return -1;
|
if (compile_cons (hcl, cf->operand) <= -1) return -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case HCL_BRAND_SYMBOL_ARRAY:
|
||||||
|
HCL_DEBUG1 (hcl, "Syntax error - variable declartion disallowed - %O\n", cf->operand);
|
||||||
|
hcl_setsynerr (hcl, HCL_SYNERR_VARDCLBANNED, HCL_NULL, HCL_NULL); /* TODO: error location */
|
||||||
|
return -1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
goto literal;
|
goto literal;
|
||||||
}
|
}
|
||||||
@ -1080,26 +1127,30 @@ static HCL_INLINE int emit_set (hcl_t* hcl)
|
|||||||
|
|
||||||
cf = GET_TOP_CFRAME(hcl);
|
cf = GET_TOP_CFRAME(hcl);
|
||||||
HCL_ASSERT (cf->opcode == COP_EMIT_SET);
|
HCL_ASSERT (cf->opcode == COP_EMIT_SET);
|
||||||
HCL_ASSERT (HCL_IS_SYMBOL(hcl, cf->operand));
|
|
||||||
|
|
||||||
if (cf->u.set.var_type == VAR_NAMED)
|
if (cf->u.set.var_type == VAR_NAMED)
|
||||||
{
|
{
|
||||||
hcl_oow_t index;
|
hcl_oow_t index;
|
||||||
|
|
||||||
|
HCL_ASSERT (HCL_IS_SYMBOL(hcl, cf->operand));
|
||||||
|
|
||||||
if (add_literal(hcl, cf->operand, &index) <= -1 ||
|
if (add_literal(hcl, cf->operand, &index) <= -1 ||
|
||||||
emit_single_param_instruction(hcl, HCL_CODE_STORE_INTO_OBJECT_0, index) <= -1) return -1;
|
emit_single_param_instruction(hcl, HCL_CODE_STORE_INTO_OBJECT_0, index) <= -1) return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* TODO: */
|
hcl_oow_t index;
|
||||||
HCL_DEBUG0 (hcl, "EMIT SET NOT IMPLEMENTED YET\n");
|
HCL_ASSERT (cf->u.set.var_type == VAR_INDEXED);
|
||||||
hcl->errnum = HCL_ENOIMPL;
|
HCL_ASSERT (HCL_OOP_IS_SMOOI(cf->operand));
|
||||||
return -1;
|
|
||||||
|
index = (hcl_oow_t)HCL_OOP_TO_SMOOI(cf->operand);
|
||||||
|
if (emit_indexed_variable_access (hcl, index, HCL_CODE_STORE_INTO_CTXTEMPVAR_0, HCL_CODE_STORE_INTO_TEMPVAR_0) <= -1) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
POP_CFRAME (hcl);
|
POP_CFRAME (hcl);
|
||||||
return 0;
|
return 0;
|
||||||
};
|
}
|
||||||
|
|
||||||
int hcl_compile (hcl_t* hcl, hcl_oop_t obj)
|
int hcl_compile (hcl_t* hcl, hcl_oop_t obj)
|
||||||
{
|
{
|
||||||
@ -1176,6 +1227,6 @@ oops:
|
|||||||
hcl->code.lit.len = saved_lit_len;
|
hcl->code.lit.len = saved_lit_len;
|
||||||
|
|
||||||
hcl->c->tv.size = 0;
|
hcl->c->tv.size = 0;
|
||||||
hcl->c->blk.depth = 0;
|
hcl->c->blk.depth = -1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
2
lib/gc.c
2
lib/gc.c
@ -34,7 +34,7 @@ static struct
|
|||||||
hcl_oow_t offset;
|
hcl_oow_t offset;
|
||||||
} syminfo[] =
|
} syminfo[] =
|
||||||
{
|
{
|
||||||
{ 6, { 'b', 'e', 'g', 'i', 'n' }, HCL_SYNCODE_BEGIN, HCL_OFFSETOF(hcl_t,_begin) },
|
{ 5, { 'b', 'e', 'g', 'i', 'n' }, HCL_SYNCODE_BEGIN, HCL_OFFSETOF(hcl_t,_begin) },
|
||||||
{ 5, { 'd', 'e', 'f', 'u', 'n' }, HCL_SYNCODE_DEFUN, HCL_OFFSETOF(hcl_t,_defun) },
|
{ 5, { 'd', 'e', 'f', 'u', 'n' }, HCL_SYNCODE_DEFUN, HCL_OFFSETOF(hcl_t,_defun) },
|
||||||
{ 2, { 'i', 'f' }, HCL_SYNCODE_IF, HCL_OFFSETOF(hcl_t,_if) },
|
{ 2, { 'i', 'f' }, HCL_SYNCODE_IF, HCL_OFFSETOF(hcl_t,_if) },
|
||||||
{ 6, { 'l', 'a', 'm', 'b', 'd', 'a' }, HCL_SYNCODE_LAMBDA, HCL_OFFSETOF(hcl_t,_lambda) },
|
{ 6, { 'l', 'a', 'm', 'b', 'd', 'a' }, HCL_SYNCODE_LAMBDA, HCL_OFFSETOF(hcl_t,_lambda) },
|
||||||
|
@ -435,7 +435,16 @@ struct hcl_ntime_t
|
|||||||
#define HCL_GETBITS(type,value,offset,length) \
|
#define HCL_GETBITS(type,value,offset,length) \
|
||||||
((((type)(value)) >> (offset)) & HCL_LBMASK(type,length))
|
((((type)(value)) >> (offset)) & HCL_LBMASK(type,length))
|
||||||
|
|
||||||
|
#define HCL_CLEARBITS(type,value,offset,length) \
|
||||||
|
(((type)(value)) & ~(HCL_LBMASK(type,length) << (offset)))
|
||||||
|
|
||||||
#define HCL_SETBITS(type,value,offset,length,bits) \
|
#define HCL_SETBITS(type,value,offset,length,bits) \
|
||||||
|
(value = (HCL_CLEARBITS(type,value,offset,length) | (((bits) & HCL_LBMASK(type,length)) << (offset))))
|
||||||
|
|
||||||
|
#define HCL_FLIPBITS(type,value,offset,length) \
|
||||||
|
(((type)(value)) ^ (HCL_LBMASK(type,length) << (offset)))
|
||||||
|
|
||||||
|
#define HCL_ORBITS(type,value,offset,length,bits) \
|
||||||
(value = (((type)(value)) | (((bits) & HCL_LBMASK(type,length)) << (offset))))
|
(value = (((type)(value)) | (((bits) & HCL_LBMASK(type,length)) << (offset))))
|
||||||
|
|
||||||
|
|
||||||
|
@ -255,6 +255,7 @@ struct hcl_iotok_t
|
|||||||
HCL_IOTOK_BAPAREN,
|
HCL_IOTOK_BAPAREN,
|
||||||
HCL_IOTOK_LBRACK,
|
HCL_IOTOK_LBRACK,
|
||||||
HCL_IOTOK_RBRACK,
|
HCL_IOTOK_RBRACK,
|
||||||
|
HCL_IOTOK_VBAR,
|
||||||
|
|
||||||
HCL_IOTOK_INCLUDE
|
HCL_IOTOK_INCLUDE
|
||||||
} type;
|
} type;
|
||||||
@ -337,9 +338,19 @@ struct hcl_compiler_t
|
|||||||
hcl_oop_t s; /* stack for reading */
|
hcl_oop_t s; /* stack for reading */
|
||||||
hcl_oop_t e; /* last object read */
|
hcl_oop_t e; /* last object read */
|
||||||
|
|
||||||
hcl_oow_t balit_capa;
|
struct
|
||||||
hcl_oow_t balit_count;
|
{
|
||||||
hcl_oob_t* balit;
|
hcl_oob_t* ptr;
|
||||||
|
hcl_oow_t size;
|
||||||
|
hcl_oow_t capa;
|
||||||
|
} balit;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
hcl_oop_t* ptr;
|
||||||
|
hcl_oow_t size;
|
||||||
|
hcl_oow_t capa;
|
||||||
|
} salit;
|
||||||
} r; /* reading */
|
} r; /* reading */
|
||||||
/* == END READER == */
|
/* == END READER == */
|
||||||
|
|
||||||
|
19
lib/hcl.h
19
lib/hcl.h
@ -80,21 +80,27 @@ enum hcl_synerrnum_t
|
|||||||
HCL_SYNERR_LPAREN, /* ( expected */
|
HCL_SYNERR_LPAREN, /* ( expected */
|
||||||
HCL_SYNERR_RPAREN, /* ) expected */
|
HCL_SYNERR_RPAREN, /* ) expected */
|
||||||
HCL_SYNERR_RBRACK, /* ] expected */
|
HCL_SYNERR_RBRACK, /* ] expected */
|
||||||
|
HCL_SYNERR_VBAR, /* | expected */
|
||||||
|
|
||||||
HCL_SYNERR_STRING, /* string expected */
|
HCL_SYNERR_STRING, /* string expected */
|
||||||
HCL_SYNERR_BYTERANGE, /* byte too small or too large */
|
HCL_SYNERR_BYTERANGE, /* byte too small or too large */
|
||||||
HCL_SYNERR_NESTING, /* nesting level too deep */
|
HCL_SYNERR_NESTING, /* nesting level too deep */
|
||||||
|
|
||||||
|
HCL_SYNERR_VBARBANNED, /* | disallowed */
|
||||||
HCL_SYNERR_DOTBANNED, /* . disallowed */
|
HCL_SYNERR_DOTBANNED, /* . disallowed */
|
||||||
HCL_SYNERR_INCLUDE, /* #include error */
|
HCL_SYNERR_INCLUDE, /* #include error */
|
||||||
|
|
||||||
HCL_SYNERR_ARGNAMELIST, /* argument name list expected */
|
|
||||||
HCL_SYNERR_ARGNAME, /* argument name expected */
|
|
||||||
HCL_SYNERR_BLKFLOOD, /* lambda block too big */
|
HCL_SYNERR_BLKFLOOD, /* lambda block too big */
|
||||||
HCL_SYNERR_BLKDEPTH, /* lambda block too deep */
|
HCL_SYNERR_BLKDEPTH, /* lambda block too deep */
|
||||||
|
HCL_SYNERR_ARGNAMELIST, /* argument name list expected */
|
||||||
|
HCL_SYNERR_ARGNAME, /* argument name expected */
|
||||||
|
HCL_SYNERR_ARGNAMEDUP, /* duplicate argument name */
|
||||||
HCL_SYNERR_VARNAME, /* variable name expected */
|
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 */
|
HCL_SYNERR_ARGFLOOD, /* too many arguments defined */
|
||||||
|
HCL_SYNERR_VARFLOOD, /* too many variables defined */
|
||||||
|
HCL_SYNERR_VARDCLBANNED, /* variable declaration disallowed */
|
||||||
|
HCL_SYNERR_VARNAMEDUP /* duplicate variable name */
|
||||||
};
|
};
|
||||||
typedef enum hcl_synerrnum_t hcl_synerrnum_t;
|
typedef enum hcl_synerrnum_t hcl_synerrnum_t;
|
||||||
|
|
||||||
@ -1038,6 +1044,7 @@ enum
|
|||||||
HCL_BRAND_CONS,
|
HCL_BRAND_CONS,
|
||||||
HCL_BRAND_ARRAY,
|
HCL_BRAND_ARRAY,
|
||||||
HCL_BRAND_BYTE_ARRAY,
|
HCL_BRAND_BYTE_ARRAY,
|
||||||
|
HCL_BRAND_SYMBOL_ARRAY, /* special. internal use only */
|
||||||
HCL_BRAND_SYMBOL,
|
HCL_BRAND_SYMBOL,
|
||||||
HCL_BRAND_STRING,
|
HCL_BRAND_STRING,
|
||||||
HCL_BRAND_SET,
|
HCL_BRAND_SET,
|
||||||
@ -1056,7 +1063,7 @@ enum
|
|||||||
HCL_SYNCODE_IF,
|
HCL_SYNCODE_IF,
|
||||||
HCL_SYNCODE_LAMBDA,
|
HCL_SYNCODE_LAMBDA,
|
||||||
HCL_SYNCODE_QUOTE,
|
HCL_SYNCODE_QUOTE,
|
||||||
HCL_SYNCODE_SET,
|
HCL_SYNCODE_SET
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hcl_cons_t
|
struct hcl_cons_t
|
||||||
@ -1070,6 +1077,8 @@ typedef struct hcl_cons_t* hcl_oop_cons_t;
|
|||||||
|
|
||||||
#define HCL_IS_NIL(hcl,v) (v == (hcl)->_nil)
|
#define HCL_IS_NIL(hcl,v) (v == (hcl)->_nil)
|
||||||
#define HCL_IS_SYMBOL(hcl,v) (HCL_OOP_IS_POINTER(v) && HCL_OBJ_GET_FLAGS_BRAND(v) == HCL_BRAND_SYMBOL)
|
#define HCL_IS_SYMBOL(hcl,v) (HCL_OOP_IS_POINTER(v) && HCL_OBJ_GET_FLAGS_BRAND(v) == HCL_BRAND_SYMBOL)
|
||||||
|
#define HCL_IS_SYMBOL_ARRAY(hcl,v) (HCL_OOP_IS_POINTER(v) && HCL_OBJ_GET_FLAGS_BRAND(v) == HCL_BRAND_SYMBOL_ARRAY)
|
||||||
|
#define HCL_IS_CONS(hcl,v) (HCL_OOP_IS_POINTER(v) && HCL_OBJ_GET_FLAGS_BRAND(v) == HCL_BRAND_CONS)
|
||||||
|
|
||||||
#define HCL_CONS_CAR(v) (((hcl_cons_t*)(v))->car)
|
#define HCL_CONS_CAR(v) (((hcl_cons_t*)(v))->car)
|
||||||
#define HCL_CONS_CDR(v) (((hcl_cons_t*)(v))->cdr)
|
#define HCL_CONS_CDR(v) (((hcl_cons_t*)(v))->cdr)
|
||||||
@ -1274,9 +1283,7 @@ HCL_EXPORT void hcl_setsynerr (
|
|||||||
const hcl_oocs_t* tgt
|
const hcl_oocs_t* tgt
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/* Memory allocation/deallocation functions using hcl's MMGR */
|
/* Memory allocation/deallocation functions using hcl's MMGR */
|
||||||
|
|
||||||
HCL_EXPORT void* hcl_allocmem (
|
HCL_EXPORT void* hcl_allocmem (
|
||||||
hcl_t* hcl,
|
hcl_t* hcl,
|
||||||
hcl_oow_t size
|
hcl_oow_t size
|
||||||
|
28
lib/main.c
28
lib/main.c
@ -436,21 +436,27 @@ static char* syntax_error_msg[] =
|
|||||||
"( expected",
|
"( expected",
|
||||||
") expected",
|
") expected",
|
||||||
"] expected",
|
"] expected",
|
||||||
|
"| expected",
|
||||||
|
|
||||||
"string expected",
|
"string expected",
|
||||||
"byte too small or too large",
|
"byte too small or too large",
|
||||||
"nesting level too deep",
|
"nesting level too deep",
|
||||||
|
|
||||||
|
"| disallowed",
|
||||||
". disallowed",
|
". disallowed",
|
||||||
"#include error",
|
"#include error",
|
||||||
|
|
||||||
"argument name list expected",
|
|
||||||
"argument name expected",
|
|
||||||
"lambda block too big",
|
"lambda block too big",
|
||||||
"lambda block too deep",
|
"lambda block too deep",
|
||||||
|
"argument name list expected",
|
||||||
|
"argument name expected",
|
||||||
|
"duplicate argument name",
|
||||||
"variable name expected",
|
"variable name expected",
|
||||||
"wrong number of arguments",
|
"wrong number of arguments",
|
||||||
"too many arguments defined"
|
"too many arguments defined",
|
||||||
|
"too many variables defined",
|
||||||
|
"variable declaration disallowed",
|
||||||
|
"duplicate variable name"
|
||||||
};
|
};
|
||||||
|
|
||||||
static void print_synerr (hcl_t* hcl)
|
static void print_synerr (hcl_t* hcl)
|
||||||
@ -499,7 +505,6 @@ hcl_ooch_t str_hcl[] = { 'S', 't', 'i', 'x' };
|
|||||||
hcl_ooch_t str_my_object[] = { 'M', 'y', 'O', 'b','j','e','c','t' };
|
hcl_ooch_t str_my_object[] = { 'M', 'y', 'O', 'b','j','e','c','t' };
|
||||||
hcl_ooch_t str_main[] = { 'm', 'a', 'i', 'n' };
|
hcl_ooch_t str_main[] = { 'm', 'a', 'i', 'n' };
|
||||||
|
|
||||||
|
|
||||||
int main (int argc, char* argv[])
|
int main (int argc, char* argv[])
|
||||||
{
|
{
|
||||||
hcl_t* hcl;
|
hcl_t* hcl;
|
||||||
@ -514,7 +519,6 @@ int main (int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
memset (&vmprim, 0, HCL_SIZEOF(vmprim));
|
memset (&vmprim, 0, HCL_SIZEOF(vmprim));
|
||||||
vmprim.log_write = log_write;
|
vmprim.log_write = log_write;
|
||||||
|
|
||||||
@ -601,7 +605,19 @@ int main (int argc, char* argv[])
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
hcl_print (hcl, HCL_CHAR_TO_OOP('\n'));
|
hcl_print (hcl, HCL_CHAR_TO_OOP('\n'));
|
||||||
hcl_compile (hcl, obj); /* TODO: error handling */
|
if (hcl_compile (hcl, obj) <= -1)
|
||||||
|
{
|
||||||
|
if (hcl->errnum == HCL_ESYNERR)
|
||||||
|
{
|
||||||
|
print_synerr (hcl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf ("ERROR: cannot compile object - %d\n", hcl_geterrnum(hcl));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* carry on? */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
69
lib/print.c
69
lib/print.c
@ -52,7 +52,7 @@ do { \
|
|||||||
#define OUTPUT_CHAR(pr,ch) do { \
|
#define OUTPUT_CHAR(pr,ch) do { \
|
||||||
hcl_ooch_t tmp = ch; \
|
hcl_ooch_t tmp = ch; \
|
||||||
OUTPUT_STRX (pr, &tmp, 1); \
|
OUTPUT_STRX (pr, &tmp, 1); \
|
||||||
} while(0);
|
} while(0)
|
||||||
|
|
||||||
#define PRINT_STACK_ARRAY_END 0
|
#define PRINT_STACK_ARRAY_END 0
|
||||||
#define PRINT_STACK_CONS 1
|
#define PRINT_STACK_CONS 1
|
||||||
@ -193,6 +193,7 @@ static int print_object (printer_t* pr, hcl_oop_t obj)
|
|||||||
hcl_t* hcl;
|
hcl_t* hcl;
|
||||||
hcl_oop_t cur;
|
hcl_oop_t cur;
|
||||||
print_stack_t ps;
|
print_stack_t ps;
|
||||||
|
int brand;
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
@ -219,7 +220,7 @@ next:
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (HCL_OBJ_GET_FLAGS_BRAND(obj))
|
switch ((brand = HCL_OBJ_GET_FLAGS_BRAND(obj)))
|
||||||
{
|
{
|
||||||
case HCL_BRAND_NIL:
|
case HCL_BRAND_NIL:
|
||||||
OUTPUT_STRX (pr, word[0].ptr, word[0].len);
|
OUTPUT_STRX (pr, word[0].ptr, word[0].len);
|
||||||
@ -337,18 +338,32 @@ next:
|
|||||||
{
|
{
|
||||||
hcl_oow_t arridx;
|
hcl_oow_t arridx;
|
||||||
|
|
||||||
|
if (brand == HCL_BRAND_ARRAY)
|
||||||
|
{
|
||||||
OUTPUT_CHAR (pr, '#');
|
OUTPUT_CHAR (pr, '#');
|
||||||
OUTPUT_CHAR (pr, '(');
|
OUTPUT_CHAR (pr, '(');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OUTPUT_CHAR (pr, '|');
|
||||||
|
}
|
||||||
|
|
||||||
if (HCL_OBJ_GET_SIZE(obj) <= 0) goto done_array;
|
if (HCL_OBJ_GET_SIZE(obj) <= 0)
|
||||||
|
{
|
||||||
|
if (brand == HCL_BRAND_ARRAY)
|
||||||
|
OUTPUT_CHAR (pr, ')');
|
||||||
|
else
|
||||||
|
OUTPUT_CHAR (pr, '|');
|
||||||
|
break;
|
||||||
|
}
|
||||||
arridx = 0;
|
arridx = 0;
|
||||||
|
ps.type = PRINT_STACK_ARRAY;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
/* Push what to print next on to the stack
|
/* Push what to print next on to the stack */
|
||||||
* the variable p is */
|
|
||||||
ps.idx = arridx + 1;
|
ps.idx = arridx + 1;
|
||||||
if (ps.idx >= HCL_OBJ_GET_SIZE(obj))
|
if (ps.idx >= HCL_OBJ_GET_SIZE(obj))
|
||||||
{
|
{
|
||||||
@ -356,7 +371,7 @@ next:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ps.type = PRINT_STACK_ARRAY;
|
HCL_ASSERT (ps.type == PRINT_STACK_ARRAY);
|
||||||
ps.obj = obj;
|
ps.obj = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,7 +383,7 @@ next:
|
|||||||
/* Jump to the 'next' label so that the object
|
/* Jump to the 'next' label so that the object
|
||||||
* pointed to by 'obj' is printed. Once it
|
* pointed to by 'obj' is printed. Once it
|
||||||
* ends, a jump back to the 'resume' label
|
* ends, a jump back to the 'resume' label
|
||||||
* is made at the at of this function. */
|
* is made at the end of this function. */
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
resume_array:
|
resume_array:
|
||||||
@ -377,9 +392,6 @@ next:
|
|||||||
obj = ps.obj;
|
obj = ps.obj;
|
||||||
}
|
}
|
||||||
while (1);
|
while (1);
|
||||||
|
|
||||||
done_array:
|
|
||||||
OUTPUT_CHAR (pr, ')');
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,6 +411,23 @@ next:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case HCL_BRAND_SYMBOL_ARRAY:
|
||||||
|
{
|
||||||
|
hcl_oow_t i;
|
||||||
|
|
||||||
|
OUTPUT_CHAR (pr, '|');
|
||||||
|
|
||||||
|
for (i = 0; i < HCL_OBJ_GET_SIZE(obj); i++)
|
||||||
|
{
|
||||||
|
hcl_oop_t s;
|
||||||
|
s = ((hcl_oop_oop_t)obj)->slot[i];
|
||||||
|
OUTPUT_CHAR (pr, ' ');
|
||||||
|
OUTPUT_STRX (pr, ((hcl_oop_char_t)s)->slot, HCL_OBJ_GET_SIZE(s));
|
||||||
|
}
|
||||||
|
OUTPUT_CHAR (pr, ' ');
|
||||||
|
OUTPUT_CHAR (pr, '|');
|
||||||
|
break;
|
||||||
|
}
|
||||||
#if 0
|
#if 0
|
||||||
case HCL_BRAND_PROCEDURE:
|
case HCL_BRAND_PROCEDURE:
|
||||||
OUTPUT_STR (pr, "#<PROCEDURE>");
|
OUTPUT_STR (pr, "#<PROCEDURE>");
|
||||||
@ -411,7 +440,7 @@ next:
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
HCL_ASSERT ("Unknown object type" == HCL_NULL);
|
HCL_ASSERT ("Unknown object type" == HCL_NULL);
|
||||||
HCL_DEBUG2 (hcl, "Internal error - unknown object type at %s:%d\n", __FILE__, __LINE__);
|
HCL_DEBUG3 (hcl, "Internal error - unknown object type %d at %s:%d\n", (int)brand, __FILE__, __LINE__);
|
||||||
hcl->errnum = HCL_EINTERN;
|
hcl->errnum = HCL_EINTERN;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -421,12 +450,22 @@ done:
|
|||||||
while (hcl->p.s.size > 0)
|
while (hcl->p.s.size > 0)
|
||||||
{
|
{
|
||||||
pop (hcl, &ps);
|
pop (hcl, &ps);
|
||||||
if (ps.type == PRINT_STACK_CONS) goto resume_cons;
|
switch (ps.type)
|
||||||
else if (ps.type == PRINT_STACK_ARRAY) goto resume_array;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
HCL_ASSERT (ps.type == PRINT_STACK_ARRAY_END);
|
case PRINT_STACK_CONS:
|
||||||
|
goto resume_cons;
|
||||||
|
|
||||||
|
case PRINT_STACK_ARRAY:
|
||||||
|
goto resume_array;
|
||||||
|
|
||||||
|
case PRINT_STACK_ARRAY_END:
|
||||||
OUTPUT_CHAR (pr, ')');
|
OUTPUT_CHAR (pr, ')');
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
HCL_DEBUG3 (hcl, "Internal error - unknown print stack type %d at %s:%d\n", (int)ps.type, __FILE__, __LINE__);
|
||||||
|
hcl->errnum = HCL_EINTERN;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
154
lib/read.c
154
lib/read.c
@ -33,6 +33,7 @@ static int end_include (hcl_t* hcl);
|
|||||||
|
|
||||||
#define BUFFER_ALIGN 128
|
#define BUFFER_ALIGN 128
|
||||||
#define BALIT_BUFFER_ALIGN 128
|
#define BALIT_BUFFER_ALIGN 128
|
||||||
|
#define SALIT_BUFFER_ALIGN 128
|
||||||
#define ARLIT_BUFFER_ALIGN 128
|
#define ARLIT_BUFFER_ALIGN 128
|
||||||
|
|
||||||
#define CHAR_TO_NUM(c,base) \
|
#define CHAR_TO_NUM(c,base) \
|
||||||
@ -218,7 +219,7 @@ static HCL_INLINE int is_alnumchar (hcl_ooci_t c)
|
|||||||
|
|
||||||
static HCL_INLINE int is_delimiter (hcl_ooci_t c)
|
static HCL_INLINE int is_delimiter (hcl_ooci_t c)
|
||||||
{
|
{
|
||||||
return c == '(' || c == ')' || c == '[' || c == ']' || c == '\"' || c == '#' || c == ';' || is_spacechar(c) || c == HCL_UCI_EOF;
|
return c == '(' || c == ')' || c == '[' || c == ']' || c == '\"' || c == '#' || c == ';' || c == '|' || is_spacechar(c) || c == HCL_UCI_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -908,13 +909,13 @@ retry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
case '(':
|
case '(':
|
||||||
SET_TOKEN_TYPE (hcl, HCL_IOTOK_LPAREN);
|
|
||||||
ADD_TOKEN_CHAR(hcl, c);
|
ADD_TOKEN_CHAR(hcl, c);
|
||||||
|
SET_TOKEN_TYPE (hcl, HCL_IOTOK_LPAREN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ')':
|
case ')':
|
||||||
SET_TOKEN_TYPE (hcl, HCL_IOTOK_RPAREN);
|
|
||||||
ADD_TOKEN_CHAR(hcl, c);
|
ADD_TOKEN_CHAR(hcl, c);
|
||||||
|
SET_TOKEN_TYPE (hcl, HCL_IOTOK_RPAREN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '[':
|
case '[':
|
||||||
@ -927,6 +928,11 @@ retry:
|
|||||||
SET_TOKEN_TYPE (hcl, HCL_IOTOK_RBRACK);
|
SET_TOKEN_TYPE (hcl, HCL_IOTOK_RBRACK);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '|':
|
||||||
|
ADD_TOKEN_CHAR (hcl, c);
|
||||||
|
SET_TOKEN_TYPE(hcl, HCL_IOTOK_VBAR);
|
||||||
|
break;
|
||||||
|
|
||||||
case '.':
|
case '.':
|
||||||
SET_TOKEN_TYPE (hcl, HCL_IOTOK_DOT);
|
SET_TOKEN_TYPE (hcl, HCL_IOTOK_DOT);
|
||||||
ADD_TOKEN_CHAR(hcl, c);
|
ADD_TOKEN_CHAR(hcl, c);
|
||||||
@ -1204,12 +1210,14 @@ static HCL_INLINE hcl_oop_t enter_list (hcl_t* hcl, int flagv)
|
|||||||
* nil#2 to store the last element in the list.
|
* nil#2 to store the last element in the list.
|
||||||
* both to be updated in chain_to_list() as items are added.
|
* both to be updated in chain_to_list() as items are added.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* TODO: change to push array of 3 cells instead? or don't use the object memory for stack. use compiler's own memory... */
|
||||||
return (push (hcl, HCL_SMOOI_TO_OOP(flagv)) == HCL_NULL ||
|
return (push (hcl, HCL_SMOOI_TO_OOP(flagv)) == HCL_NULL ||
|
||||||
push (hcl, hcl->_nil) == HCL_NULL ||
|
push (hcl, hcl->_nil) == HCL_NULL ||
|
||||||
push (hcl, hcl->_nil) == HCL_NULL)? HCL_NULL: hcl->c->r.s;
|
push (hcl, hcl->_nil) == HCL_NULL)? HCL_NULL: hcl->c->r.s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HCL_INLINE hcl_oop_t leave_list (hcl_t* hcl, int* flagv)
|
static HCL_INLINE hcl_oop_t leave_list (hcl_t* hcl, int* flagv, int* oldflagv)
|
||||||
{
|
{
|
||||||
hcl_oop_t head;
|
hcl_oop_t head;
|
||||||
int fv;
|
int fv;
|
||||||
@ -1260,6 +1268,7 @@ static HCL_INLINE hcl_oop_t leave_list (hcl_t* hcl, int* flagv)
|
|||||||
head = (hcl_oop_t)arr;
|
head = (hcl_oop_t)arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*oldflagv = fv;
|
||||||
if (HCL_IS_NIL(hcl,hcl->c->r.s))
|
if (HCL_IS_NIL(hcl,hcl->c->r.s))
|
||||||
{
|
{
|
||||||
/* the stack is empty after popping.
|
/* the stack is empty after popping.
|
||||||
@ -1380,21 +1389,21 @@ static HCL_INLINE int is_list_empty (hcl_t* hcl)
|
|||||||
|
|
||||||
static int add_to_byte_array_literal_buffer (hcl_t* hcl, hcl_oob_t b)
|
static int add_to_byte_array_literal_buffer (hcl_t* hcl, hcl_oob_t b)
|
||||||
{
|
{
|
||||||
if (hcl->c->r.balit_count >= hcl->c->r.balit_capa)
|
if (hcl->c->r.balit.size >= hcl->c->r.balit.capa)
|
||||||
{
|
{
|
||||||
hcl_oob_t* tmp;
|
hcl_oob_t* tmp;
|
||||||
hcl_oow_t new_capa;
|
hcl_oow_t new_capa;
|
||||||
|
|
||||||
new_capa = HCL_ALIGN (hcl->c->r.balit_count + 1, BALIT_BUFFER_ALIGN);
|
new_capa = HCL_ALIGN (hcl->c->r.balit.size + 1, BALIT_BUFFER_ALIGN);
|
||||||
tmp = (hcl_oob_t*)hcl_reallocmem (hcl, hcl->c->r.balit, new_capa * HCL_SIZEOF(*tmp));
|
tmp = (hcl_oob_t*)hcl_reallocmem (hcl, hcl->c->r.balit.ptr, new_capa * HCL_SIZEOF(*tmp));
|
||||||
if (!tmp) return -1;
|
if (!tmp) return -1;
|
||||||
|
|
||||||
hcl->c->r.balit_capa = new_capa;
|
hcl->c->r.balit.capa = new_capa;
|
||||||
hcl->c->r.balit = tmp;
|
hcl->c->r.balit.ptr = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: overflow check of hcl->c->r.balit_count itself */
|
/* TODO: overflow check of hcl->c->r.balit.size itself */
|
||||||
hcl->c->r.balit[hcl->c->r.balit_count++] = b;
|
hcl->c->r.balit.ptr[hcl->c->r.balit.size++] = b;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1403,7 +1412,7 @@ static int get_byte_array_literal (hcl_t* hcl, hcl_oop_t* xlit)
|
|||||||
hcl_ooi_t tmp;
|
hcl_ooi_t tmp;
|
||||||
hcl_oop_t ba;
|
hcl_oop_t ba;
|
||||||
|
|
||||||
hcl->c->r.balit_count = 0;
|
HCL_ASSERT (hcl->c->r.balit.size == 0);
|
||||||
|
|
||||||
HCL_ASSERT (TOKEN_TYPE(hcl) == HCL_IOTOK_BAPAREN);
|
HCL_ASSERT (TOKEN_TYPE(hcl) == HCL_IOTOK_BAPAREN);
|
||||||
GET_TOKEN(hcl); /* skip #[ */
|
GET_TOKEN(hcl); /* skip #[ */
|
||||||
@ -1439,14 +1448,81 @@ static int get_byte_array_literal (hcl_t* hcl, hcl_oop_t* xlit)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ba = hcl_makebytearray (hcl, hcl->c->r.balit, hcl->c->r.balit_count);
|
ba = hcl_makebytearray (hcl, hcl->c->r.balit.ptr, hcl->c->r.balit.size);
|
||||||
if (!ba)
|
if (!ba)
|
||||||
{
|
{
|
||||||
hcl->c->r.balit_count = 0; /* reset literal count... */
|
hcl->c->r.balit.size = 0; /* reset literal count... */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*xlit = ba;
|
*xlit = ba;
|
||||||
|
|
||||||
|
hcl->c->r.balit.size = 0; /* reset literal count... */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int add_to_symbol_array_literal_buffer (hcl_t* hcl, hcl_oop_t b)
|
||||||
|
{
|
||||||
|
if (hcl->c->r.salit.size >= hcl->c->r.salit.capa)
|
||||||
|
{
|
||||||
|
hcl_oop_t* tmp;
|
||||||
|
hcl_oow_t new_capa;
|
||||||
|
|
||||||
|
new_capa = HCL_ALIGN (hcl->c->r.salit.size + 1, SALIT_BUFFER_ALIGN);
|
||||||
|
tmp = (hcl_oop_t*)hcl_reallocmem (hcl, hcl->c->r.salit.ptr, new_capa * HCL_SIZEOF(*tmp));
|
||||||
|
if (!tmp) return -1;
|
||||||
|
|
||||||
|
hcl->c->r.salit.capa = new_capa;
|
||||||
|
hcl->c->r.salit.ptr = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: overflow check of hcl->c->r.tvlit_count itself */
|
||||||
|
hcl->c->r.salit.ptr[hcl->c->r.salit.size++] = b;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_symbol_array_literal (hcl_t* hcl, hcl_oop_t* xlit)
|
||||||
|
{
|
||||||
|
hcl_oop_t sa, sym;
|
||||||
|
hcl_oow_t i;
|
||||||
|
|
||||||
|
HCL_ASSERT (hcl->c->r.salit.size == 0);
|
||||||
|
|
||||||
|
HCL_ASSERT (TOKEN_TYPE(hcl) == HCL_IOTOK_VBAR);
|
||||||
|
GET_TOKEN(hcl); /* skip #[ */
|
||||||
|
|
||||||
|
while (TOKEN_TYPE(hcl) == HCL_IOTOK_IDENT)
|
||||||
|
{
|
||||||
|
sym = hcl_makesymbol (hcl, TOKEN_NAME_PTR(hcl), TOKEN_NAME_LEN(hcl));
|
||||||
|
if (!sym) return -1;
|
||||||
|
|
||||||
|
if (add_to_symbol_array_literal_buffer(hcl, sym) <= -1) return -1;
|
||||||
|
GET_TOKEN (hcl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TOKEN_TYPE(hcl) != HCL_IOTOK_VBAR)
|
||||||
|
{
|
||||||
|
hcl_setsynerr (hcl, HCL_SYNERR_VBAR, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sa = hcl_makearray (hcl, hcl->c->r.salit.size);
|
||||||
|
if (!sa)
|
||||||
|
{
|
||||||
|
hcl->c->r.salit.size = 0; /* reset literal count... */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < hcl->c->r.salit.size; i++)
|
||||||
|
((hcl_oop_oop_t)sa)->slot[i] = hcl->c->r.salit.ptr[i];
|
||||||
|
|
||||||
|
/* switch array to symbol array. this is special-purpose. */
|
||||||
|
HCL_OBJ_SET_FLAGS_BRAND (sa, HCL_BRAND_SYMBOL_ARRAY);
|
||||||
|
|
||||||
|
*xlit = sa;
|
||||||
|
|
||||||
|
hcl->c->r.salit.size = 0; /* reset literal count... */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1455,7 +1531,7 @@ static int read_object (hcl_t* hcl)
|
|||||||
/* this function read an s-expression non-recursively
|
/* this function read an s-expression non-recursively
|
||||||
* by manipulating its own stack. */
|
* by manipulating its own stack. */
|
||||||
|
|
||||||
int level = 0, flagv = 0;
|
int level = 0, array_level = 0, flagv = 0;
|
||||||
hcl_oop_t obj;
|
hcl_oop_t obj;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
@ -1521,6 +1597,7 @@ static int read_object (hcl_t* hcl)
|
|||||||
* a list literal or an array literal */
|
* a list literal or an array literal */
|
||||||
if (enter_list (hcl, flagv) == HCL_NULL) return -1;
|
if (enter_list (hcl, flagv) == HCL_NULL) return -1;
|
||||||
level++;
|
level++;
|
||||||
|
if (flagv & ARRAY) array_level++;
|
||||||
|
|
||||||
/* read the next token */
|
/* read the next token */
|
||||||
GET_TOKEN (hcl);
|
GET_TOKEN (hcl);
|
||||||
@ -1541,6 +1618,8 @@ static int read_object (hcl_t* hcl)
|
|||||||
goto redo;
|
goto redo;
|
||||||
|
|
||||||
case HCL_IOTOK_RPAREN:
|
case HCL_IOTOK_RPAREN:
|
||||||
|
{
|
||||||
|
int oldflagv;
|
||||||
if ((flagv & QUOTED) || level <= 0)
|
if ((flagv & QUOTED) || level <= 0)
|
||||||
{
|
{
|
||||||
/* the right parenthesis can never appear while
|
/* the right parenthesis can never appear while
|
||||||
@ -1564,15 +1643,27 @@ static int read_object (hcl_t* hcl)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = leave_list (hcl, &flagv);
|
obj = leave_list (hcl, &flagv, &oldflagv);
|
||||||
|
|
||||||
level--;
|
level--;
|
||||||
|
if (oldflagv & ARRAY) array_level--;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case HCL_IOTOK_BAPAREN:
|
case HCL_IOTOK_BAPAREN:
|
||||||
if (get_byte_array_literal(hcl, &obj) <= -1) return -1;
|
if (get_byte_array_literal(hcl, &obj) <= -1) return -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case HCL_IOTOK_VBAR:
|
||||||
|
/* TODO: think wheter to allow | | inside a quoted list... */
|
||||||
|
if (array_level > 0)
|
||||||
|
{
|
||||||
|
hcl_setsynerr (hcl, HCL_SYNERR_VBARBANNED, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (get_symbol_array_literal (hcl, &obj) <= -1) return -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case HCL_IOTOK_NIL:
|
case HCL_IOTOK_NIL:
|
||||||
obj = hcl->_nil;
|
obj = hcl->_nil;
|
||||||
break;
|
break;
|
||||||
@ -1622,6 +1713,8 @@ static int read_object (hcl_t* hcl)
|
|||||||
/* check if the element is read for a quoted list */
|
/* check if the element is read for a quoted list */
|
||||||
while (flagv & QUOTED)
|
while (flagv & QUOTED)
|
||||||
{
|
{
|
||||||
|
int oldflagv;
|
||||||
|
|
||||||
HCL_ASSERT (level > 0);
|
HCL_ASSERT (level > 0);
|
||||||
|
|
||||||
/* if so, append the element read into the quote list */
|
/* if so, append the element read into the quote list */
|
||||||
@ -1629,10 +1722,11 @@ static int read_object (hcl_t* hcl)
|
|||||||
|
|
||||||
/* exit out of the quoted list. the quoted list can have
|
/* exit out of the quoted list. the quoted list can have
|
||||||
* one element only. */
|
* one element only. */
|
||||||
obj = leave_list (hcl, &flagv);
|
obj = leave_list (hcl, &flagv, &oldflagv);
|
||||||
|
|
||||||
/* one level up toward the top */
|
/* one level up toward the top */
|
||||||
level--;
|
level--;
|
||||||
|
if (oldflagv & ARRAY) array_level--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if we are at the top level */
|
/* check if we are at the top level */
|
||||||
@ -1648,6 +1742,7 @@ static int read_object (hcl_t* hcl)
|
|||||||
|
|
||||||
/* upon exit, we must be at the top level */
|
/* upon exit, we must be at the top level */
|
||||||
HCL_ASSERT (level == 0);
|
HCL_ASSERT (level == 0);
|
||||||
|
HCL_ASSERT (array_level == 0);
|
||||||
|
|
||||||
hcl->c->r.e = obj;
|
hcl->c->r.e = obj;
|
||||||
return 0;
|
return 0;
|
||||||
@ -1683,6 +1778,7 @@ static void gc_compiler (hcl_t* hcl)
|
|||||||
hcl->c->r.s = hcl_moveoop (hcl, hcl->c->r.s);
|
hcl->c->r.s = hcl_moveoop (hcl, hcl->c->r.s);
|
||||||
hcl->c->r.e = hcl_moveoop (hcl, hcl->c->r.e);
|
hcl->c->r.e = hcl_moveoop (hcl, hcl->c->r.e);
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i <= hcl->c->cfs.top; i++)
|
for (i = 0; i <= hcl->c->cfs.top; i++)
|
||||||
{
|
{
|
||||||
hcl->c->cfs.ptr[i].operand = hcl_moveoop(hcl, hcl->c->cfs.ptr[i].operand);
|
hcl->c->cfs.ptr[i].operand = hcl_moveoop(hcl, hcl->c->cfs.ptr[i].operand);
|
||||||
@ -1692,6 +1788,12 @@ static void gc_compiler (hcl_t* hcl)
|
|||||||
{
|
{
|
||||||
hcl->c->tv.ptr[i] = hcl_moveoop (hcl, hcl->c->tv.ptr[i]);
|
hcl->c->tv.ptr[i] = hcl_moveoop (hcl, hcl->c->tv.ptr[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < hcl->c->r.salit.size; i++)
|
||||||
|
{
|
||||||
|
hcl->c->r.salit.ptr[i] = hcl_moveoop (hcl, hcl->c->r.salit.ptr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fini_compiler (hcl_t* hcl)
|
static void fini_compiler (hcl_t* hcl)
|
||||||
@ -1699,12 +1801,20 @@ static void fini_compiler (hcl_t* hcl)
|
|||||||
/* called before the hcl object is closed */
|
/* called before the hcl object is closed */
|
||||||
if (hcl->c)
|
if (hcl->c)
|
||||||
{
|
{
|
||||||
if (hcl->c->r.balit)
|
if (hcl->c->r.balit.ptr)
|
||||||
{
|
{
|
||||||
hcl_freemem (hcl, hcl->c->r.balit);
|
hcl_freemem (hcl, hcl->c->r.balit.ptr);
|
||||||
hcl->c->r.balit = HCL_NULL;
|
hcl->c->r.balit.ptr = HCL_NULL;
|
||||||
hcl->c->r.balit_count = 0;
|
hcl->c->r.balit.size = 0;
|
||||||
hcl->c->r.balit_capa = 0;
|
hcl->c->r.balit.capa = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hcl->c->r.salit.ptr)
|
||||||
|
{
|
||||||
|
hcl_freemem (hcl, hcl->c->r.salit.ptr);
|
||||||
|
hcl->c->r.salit.ptr = HCL_NULL;
|
||||||
|
hcl->c->r.salit.size = 0;
|
||||||
|
hcl->c->r.salit.capa = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hcl->c->cfs.ptr)
|
if (hcl->c->cfs.ptr)
|
||||||
|
Loading…
Reference in New Issue
Block a user