attempting to support the character literal notation

This commit is contained in:
hyung-hwan 2020-12-04 16:19:01 +00:00
parent 672a9a248d
commit 342e01f5b4
6 changed files with 284 additions and 40 deletions

View File

@ -411,6 +411,7 @@ enum hawk_nde_type_t
HAWK_NDE_FNCALL_FNC, HAWK_NDE_FNCALL_FNC,
HAWK_NDE_FNCALL_FUN, HAWK_NDE_FNCALL_FUN,
HAWK_NDE_FNCALL_VAR, HAWK_NDE_FNCALL_VAR,
HAWK_NDE_CHAR,
HAWK_NDE_INT, HAWK_NDE_INT,
HAWK_NDE_FLT, HAWK_NDE_FLT,
HAWK_NDE_STR, HAWK_NDE_STR,
@ -1383,16 +1384,17 @@ enum hawk_val_type_t
* must be synchronized with an internal table of the __cmp_val * must be synchronized with an internal table of the __cmp_val
* function in run.c and the __val_type_name in val.c */ * function in run.c and the __val_type_name in val.c */
HAWK_VAL_NIL = 0, /**< nil */ HAWK_VAL_NIL = 0, /**< nil */
HAWK_VAL_INT = 1, /**< integer */ HAWK_VAL_CHAR = 1, /**< character */
HAWK_VAL_FLT = 2, /**< floating-pointer number */ HAWK_VAL_INT = 2, /**< integer */
HAWK_VAL_STR = 3, /**< string */ HAWK_VAL_FLT = 3, /**< floating-pointer number */
HAWK_VAL_MBS = 4, /**< byte array */ HAWK_VAL_STR = 4, /**< string */
HAWK_VAL_FUN = 5, /**< function pointer */ HAWK_VAL_MBS = 5, /**< byte array */
HAWK_VAL_MAP = 6, /**< map */ HAWK_VAL_FUN = 6, /**< function pointer */
HAWK_VAL_ARR = 7, /**< array */ HAWK_VAL_MAP = 7, /**< map */
HAWK_VAL_ARR = 8, /**< array */
HAWK_VAL_REX = 8, /**< regular expression */ HAWK_VAL_REX = 9, /**< regular expression */
HAWK_VAL_REF = 9 /**< reference to other types */ HAWK_VAL_REF = 10 /**< reference to other types */
}; };
typedef enum hawk_val_type_t hawk_val_type_t; typedef enum hawk_val_type_t hawk_val_type_t;
@ -2662,6 +2664,12 @@ HAWK_EXPORT hawk_val_t* hawk_rtx_makenilval (
hawk_rtx_t* rtx hawk_rtx_t* rtx
); );
HAWK_EXPORT hawk_val_t* hawk_rtx_makecharval (
hawk_rtx_t* rtx,
hawk_ooch_t v
);
/** /**
* The hawk_rtx_makeintval() function creates an integer value. * The hawk_rtx_makeintval() function creates an integer value.
* If \a v is one of -1, 0, 1, this function never fails. * If \a v is one of -1, 0, 1, this function never fails.

View File

@ -153,10 +153,10 @@ static hawk_val_t* eval_fncall_fnc (hawk_rtx_t* rtx, hawk_nde_t* nde);
static hawk_val_t* eval_fncall_fun (hawk_rtx_t* rtx, hawk_nde_t* nde); static hawk_val_t* eval_fncall_fun (hawk_rtx_t* rtx, hawk_nde_t* nde);
static hawk_val_t* eval_fncall_var (hawk_rtx_t* rtx, hawk_nde_t* nde); static hawk_val_t* eval_fncall_var (hawk_rtx_t* rtx, hawk_nde_t* nde);
static int get_reference (hawk_rtx_t* rtx, hawk_nde_t* nde, hawk_val_t*** ref); static int get_reference (hawk_rtx_t* rtx, hawk_nde_t* nde, hawk_val_t*** ref);
static hawk_val_t** get_reference_indexed (hawk_rtx_t* rtx, hawk_nde_var_t* var); static hawk_val_t** get_reference_indexed (hawk_rtx_t* rtx, hawk_nde_var_t* var);
static hawk_val_t* eval_char (hawk_rtx_t* rtx, hawk_nde_t* nde);
static hawk_val_t* eval_int (hawk_rtx_t* rtx, hawk_nde_t* nde); static hawk_val_t* eval_int (hawk_rtx_t* rtx, hawk_nde_t* nde);
static hawk_val_t* eval_flt (hawk_rtx_t* rtx, hawk_nde_t* nde); static hawk_val_t* eval_flt (hawk_rtx_t* rtx, hawk_nde_t* nde);
static hawk_val_t* eval_str (hawk_rtx_t* rtx, hawk_nde_t* nde); static hawk_val_t* eval_str (hawk_rtx_t* rtx, hawk_nde_t* nde);
@ -2063,7 +2063,7 @@ static int run_pblock (hawk_rtx_t* rtx, hawk_chain_t* cha, hawk_oow_t bno)
static HAWK_INLINE int run_block0 (hawk_rtx_t* rtx, hawk_nde_blk_t* nde) static HAWK_INLINE int run_block0 (hawk_rtx_t* rtx, hawk_nde_blk_t* nde)
{ {
hawk_nde_t* p; hawk_nde_t* p;
hawk_oow_t saved_stack_top; /*hawk_oow_t saved_stack_top;*/
int n = 0; int n = 0;
if (nde == HAWK_NULL) if (nde == HAWK_NULL)
@ -2092,7 +2092,7 @@ static HAWK_INLINE int run_block0 (hawk_rtx_t* rtx, hawk_nde_blk_t* nde)
} }
HAWK_ASSERT (nde->type == HAWK_NDE_BLK); HAWK_ASSERT (nde->type == HAWK_NDE_BLK);
saved_stack_top = rtx->stack_top; /*saved_stack_top = rtx->stack_top;*/
#if defined(DEBUG_RUN) #if defined(DEBUG_RUN)
hawk_logfmt (hawk_rtx_gethawk(rtx), HAWK_T("securing space for local variables nlcls = %d\n"), (int)nde->nlcls); hawk_logfmt (hawk_rtx_gethawk(rtx), HAWK_T("securing space for local variables nlcls = %d\n"), (int)nde->nlcls);
@ -3647,6 +3647,7 @@ static hawk_val_t* eval_expression0 (hawk_rtx_t* rtx, hawk_nde_t* nde)
eval_fncall_fnc, eval_fncall_fnc,
eval_fncall_fun, eval_fncall_fun,
eval_fncall_var, eval_fncall_var,
eval_char,
eval_int, eval_int,
eval_flt, eval_flt,
eval_str, eval_str,
@ -4633,9 +4634,15 @@ static HAWK_INLINE int __cmp_nil_nil (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
return 0; return 0;
} }
static HAWK_INLINE int __cmp_nil_char (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{
hawk_ooch_t v = HAWK_RTX_GETCHARFROMVAL(rtx, right);
return (v < 0)? 1: ((v > 0)? -1: 0);
}
static HAWK_INLINE int __cmp_nil_int (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint) static HAWK_INLINE int __cmp_nil_int (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{ {
hawk_int_t v = HAWK_RTX_GETINTFROMVAL (rtx, right); hawk_int_t v = HAWK_RTX_GETINTFROMVAL(rtx, right);
return (v < 0)? 1: ((v > 0)? -1: 0); return (v < 0)? 1: ((v > 0)? -1: 0);
} }
@ -4669,15 +4676,82 @@ static HAWK_INLINE int __cmp_nil_map (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
static HAWK_INLINE int __cmp_char_nil (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{
hawk_ooch_t v = HAWK_RTX_GETCHARFROMVAL(rtx, left);
return (v > 0)? 1: ((v < 0)? -1: 0);
}
static HAWK_INLINE int __cmp_char_char (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{
hawk_ooch_t v1 = HAWK_RTX_GETCHARFROMVAL(rtx, left);
hawk_ooch_t v2 = HAWK_RTX_GETCHARFROMVAL(rtx, right);
return (v1 > v2)? 1: ((v1 < v2)? -1: 0);
}
static HAWK_INLINE int __cmp_char_int (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{
hawk_ooch_t v1 = HAWK_RTX_GETCHARFROMVAL(rtx, left);
hawk_ooch_t v2 = HAWK_RTX_GETCHARFROMVAL(rtx, right);
return (v1 > v2)? 1: ((v1 < v2)? -1: 0);
}
static HAWK_INLINE int __cmp_char_flt (
hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{
hawk_ooch_t v1 = HAWK_RTX_GETCHARFROMVAL(rtx, left);
if (v1 > ((hawk_val_flt_t*)right)->val) return 1;
if (v1 < ((hawk_val_flt_t*)right)->val) return -1;
return 0;
}
static HAWK_INLINE int __cmp_char_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{
hawk_ooch_t v1 = HAWK_RTX_GETCHARFROMVAL(rtx, left);
return hawk_comp_oochars(&v1, 1, ((hawk_val_str_t*)right)->val.ptr, ((hawk_val_str_t*)right)->val.len, rtx->gbl.ignorecase);
}
static HAWK_INLINE int __cmp_char_mbs (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{
hawk_ooch_t v1 = HAWK_RTX_GETCHARFROMVAL(rtx, left);
hawk_bch_t bc;
if (v1 > 0xFF) return 1;
bc = v1;
return hawk_comp_bchars(&bc, 1, ((hawk_val_mbs_t*)right)->val.ptr, ((hawk_val_mbs_t*)right)->val.len, rtx->gbl.ignorecase);
}
static HAWK_INLINE int __cmp_char_fun (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{
return __cmp_ensure_not_equal(rtx, op_hint);
}
static HAWK_INLINE int __cmp_char_map (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{
/* compare an integer and the size of a map */
hawk_ooch_t v1 = HAWK_RTX_GETCHARFROMVAL(rtx, left);
hawk_int_t v2 = HAWK_HTB_SIZE(((hawk_val_map_t*)right)->map);
if (v1 > v2) return 1;
if (v1 < v2) return -1;
return 0;
}
/* -------------------------------------------------------------------- */
static HAWK_INLINE int __cmp_int_nil (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint) static HAWK_INLINE int __cmp_int_nil (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{ {
hawk_int_t v = HAWK_RTX_GETINTFROMVAL(rtx, left); hawk_int_t v = HAWK_RTX_GETINTFROMVAL(rtx, left);
return (v > 0)? 1: ((v < 0)? -1: 0); return (v > 0)? 1: ((v < 0)? -1: 0);
} }
static HAWK_INLINE int __cmp_int_char (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{
hawk_int_t v1 = HAWK_RTX_GETINTFROMVAL(rtx, left);
hawk_ooch_t v2 = HAWK_RTX_GETCHARFROMVAL(rtx, right);
return (v1 > v2)? 1: ((v1 < v2)? -1: 0);
}
static HAWK_INLINE int __cmp_int_int (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint) static HAWK_INLINE int __cmp_int_int (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{ {
hawk_int_t v1 = HAWK_RTX_GETINTFROMVAL(rtx, left); hawk_int_t v1 = HAWK_RTX_GETINTFROMVAL(rtx, left);
hawk_int_t v2 = HAWK_RTX_GETINTFROMVAL(rtx, right); hawk_int_t v2 = HAWK_RTX_GETINTFROMVAL(rtx, right);
return (v1 > v2)? 1: ((v1 < v2)? -1: 0); return (v1 > v2)? 1: ((v1 < v2)? -1: 0);
@ -4797,9 +4871,17 @@ static HAWK_INLINE int __cmp_flt_nil (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
return 0; return 0;
} }
static HAWK_INLINE int __cmp_flt_char (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{
hawk_ooch_t v2 = HAWK_RTX_GETCHARFROMVAL(rtx, right);
if (((hawk_val_flt_t*)left)->val > v2) return 1;
if (((hawk_val_flt_t*)left)->val < v2) return -1;
return 0;
}
static HAWK_INLINE int __cmp_flt_int (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint) static HAWK_INLINE int __cmp_flt_int (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{ {
hawk_int_t v2 = HAWK_RTX_GETINTFROMVAL (rtx, right); hawk_int_t v2 = HAWK_RTX_GETINTFROMVAL(rtx, right);
if (((hawk_val_flt_t*)left)->val > v2) return 1; if (((hawk_val_flt_t*)left)->val > v2) return 1;
if (((hawk_val_flt_t*)left)->val < v2) return -1; if (((hawk_val_flt_t*)left)->val < v2) return -1;
return 0; return 0;
@ -4892,6 +4974,14 @@ static HAWK_INLINE int __cmp_str_nil (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
return (((hawk_val_str_t*)left)->val.len == 0)? 0: 1; return (((hawk_val_str_t*)left)->val.len == 0)? 0: 1;
} }
static HAWK_INLINE int __cmp_str_char (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{
int n;
n = __cmp_char_str(rtx, right, left, inverse_cmp_op(op_hint));
if (n == CMP_ERROR) return CMP_ERROR;
return -n;
}
static HAWK_INLINE int __cmp_str_int (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint) static HAWK_INLINE int __cmp_str_int (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{ {
int n; int n;
@ -4910,7 +5000,6 @@ static HAWK_INLINE int __cmp_str_flt (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint) static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{ {
hawk_t* hawk = hawk_rtx_gethawk(rtx);
hawk_val_str_t* ls, * rs; hawk_val_str_t* ls, * rs;
int stripspc; int stripspc;
@ -5024,6 +5113,14 @@ static HAWK_INLINE int __cmp_mbs_nil (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
return (((hawk_val_mbs_t*)left)->val.len == 0)? 0: 1; return (((hawk_val_mbs_t*)left)->val.len == 0)? 0: 1;
} }
static HAWK_INLINE int __cmp_mbs_char (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{
int n;
n = __cmp_char_mbs(rtx, right, left, inverse_cmp_op(op_hint));
if (n == CMP_ERROR) return CMP_ERROR;
return -n;
}
static HAWK_INLINE int __cmp_mbs_int (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint) static HAWK_INLINE int __cmp_mbs_int (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{ {
int n; int n;
@ -5075,6 +5172,11 @@ static HAWK_INLINE int __cmp_fun_nil (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
return __cmp_ensure_not_equal(rtx, op_hint); return __cmp_ensure_not_equal(rtx, op_hint);
} }
static HAWK_INLINE int __cmp_fun_char (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{
return __cmp_ensure_not_equal(rtx, op_hint);
}
static HAWK_INLINE int __cmp_fun_int (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint) static HAWK_INLINE int __cmp_fun_int (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{ {
return __cmp_ensure_not_equal(rtx, op_hint); return __cmp_ensure_not_equal(rtx, op_hint);
@ -5115,6 +5217,14 @@ static HAWK_INLINE int __cmp_map_nil (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
return -n; return -n;
} }
static HAWK_INLINE int __cmp_map_char (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{
int n;
n = __cmp_char_map(rtx, right, left, inverse_cmp_op(op_hint));
if (n == CMP_ERROR) return CMP_ERROR;
return -n;
}
static HAWK_INLINE int __cmp_map_int (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint) static HAWK_INLINE int __cmp_map_int (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right, cmp_op_t op_hint)
{ {
int n; int n;
@ -5165,13 +5275,14 @@ static HAWK_INLINE int __cmp_val (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t*
{ {
/* this table must be synchronized with /* this table must be synchronized with
* the HAWK_VAL_XXX values in hawk.h */ * the HAWK_VAL_XXX values in hawk.h */
__cmp_nil_nil, __cmp_nil_int, __cmp_nil_flt, __cmp_nil_str, __cmp_nil_mbs, __cmp_nil_fun, __cmp_nil_map, __cmp_nil_nil, __cmp_nil_char, __cmp_nil_int, __cmp_nil_flt, __cmp_nil_str, __cmp_nil_mbs, __cmp_nil_fun, __cmp_nil_map,
__cmp_int_nil, __cmp_int_int, __cmp_int_flt, __cmp_int_str, __cmp_int_mbs, __cmp_int_fun, __cmp_int_map, __cmp_char_nil, __cmp_char_char, __cmp_char_int, __cmp_char_flt, __cmp_char_str, __cmp_char_mbs, __cmp_char_fun, __cmp_char_map,
__cmp_flt_nil, __cmp_flt_int, __cmp_flt_flt, __cmp_flt_str, __cmp_flt_mbs, __cmp_flt_fun, __cmp_flt_map, __cmp_int_nil, __cmp_int_char, __cmp_int_int, __cmp_int_flt, __cmp_int_str, __cmp_int_mbs, __cmp_int_fun, __cmp_int_map,
__cmp_str_nil, __cmp_str_int, __cmp_str_flt, __cmp_str_str, __cmp_str_mbs, __cmp_str_fun, __cmp_str_map, __cmp_flt_nil, __cmp_flt_char, __cmp_flt_int, __cmp_flt_flt, __cmp_flt_str, __cmp_flt_mbs, __cmp_flt_fun, __cmp_flt_map,
__cmp_mbs_nil, __cmp_mbs_int, __cmp_mbs_flt, __cmp_mbs_str, __cmp_mbs_mbs, __cmp_mbs_fun, __cmp_mbs_map, __cmp_str_nil, __cmp_str_char, __cmp_str_int, __cmp_str_flt, __cmp_str_str, __cmp_str_mbs, __cmp_str_fun, __cmp_str_map,
__cmp_fun_nil, __cmp_fun_int, __cmp_fun_flt, __cmp_fun_str, __cmp_fun_mbs, __cmp_fun_fun, __cmp_fun_map, __cmp_mbs_nil, __cmp_mbs_char, __cmp_mbs_int, __cmp_mbs_flt, __cmp_mbs_str, __cmp_mbs_mbs, __cmp_mbs_fun, __cmp_mbs_map,
__cmp_map_nil, __cmp_map_int, __cmp_map_flt, __cmp_map_str, __cmp_map_mbs, __cmp_map_fun, __cmp_map_map __cmp_fun_nil, __cmp_fun_char, __cmp_fun_int, __cmp_fun_flt, __cmp_fun_str, __cmp_fun_mbs, __cmp_fun_fun, __cmp_fun_map,
__cmp_map_nil, __cmp_map_char, __cmp_map_int, __cmp_map_flt, __cmp_map_str, __cmp_map_mbs, __cmp_map_fun, __cmp_map_map
}; };
lvtype = HAWK_RTX_GETVALTYPE(rtx, left); lvtype = HAWK_RTX_GETVALTYPE(rtx, left);
@ -5189,19 +5300,20 @@ static HAWK_INLINE int __cmp_val (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t*
/* mapping fomula and table layout assume: /* mapping fomula and table layout assume:
* HAWK_VAL_NIL = 0 * HAWK_VAL_NIL = 0
* HAWK_VAL_INT = 1 * HAWK_VAL_CHAR = 1
* HAWK_VAL_FLT = 2 * HAWK_VAL_INT = 2
* HAWK_VAL_STR = 3 * HAWK_VAL_FLT = 3
* HAWK_VAL_MBS = 4 * HAWK_VAL_STR = 4
* HAWK_VAL_FUN = 5 * HAWK_VAL_MBS = 5
* HAWK_VAL_MAP = 6 * HAWK_VAL_FUN = 6
* HAWK_VAL_MAP = 7
* *
* op_hint indicate the operation in progress when this function is called. * op_hint indicate the operation in progress when this function is called.
* this hint doesn't require the comparison function to compare using this * this hint doesn't require the comparison function to compare using this
* operation. the comparision function should return 0 if equal, -1 if less, * operation. the comparision function should return 0 if equal, -1 if less,
* 1 if greater, CMP_ERROR upon error regardless of this hint. * 1 if greater, CMP_ERROR upon error regardless of this hint.
*/ */
n = func[lvtype * 7 + rvtype](rtx, left, right, op_hint); n = func[lvtype * 8 + rvtype](rtx, left, right, op_hint);
if (n == CMP_ERROR) return -1; if (n == CMP_ERROR) return -1;
*ret = n; *ret = n;
@ -5233,6 +5345,10 @@ static int teq_val (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right)
n = 1; n = 1;
break; break;
case HAWK_VAL_CHAR:
n = (HAWK_RTX_GETCHARFROMVAL (rtx, left) == HAWK_RTX_GETCHARFROMVAL (rtx, right));
break;
case HAWK_VAL_INT: case HAWK_VAL_INT:
n = (HAWK_RTX_GETINTFROMVAL (rtx, left) == HAWK_RTX_GETINTFROMVAL (rtx, right)); n = (HAWK_RTX_GETINTFROMVAL (rtx, left) == HAWK_RTX_GETINTFROMVAL (rtx, right));
break; break;
@ -6920,6 +7036,14 @@ oops:
return HAWK_NULL; return HAWK_NULL;
} }
static hawk_val_t* eval_char (hawk_rtx_t* rtx, hawk_nde_t* nde)
{
hawk_val_t* val;
val = hawk_rtx_makecharval(rtx, ((hawk_nde_char_t*)nde)->val);
if (HAWK_UNLIKELY(!val)) ADJERR_LOC (rtx, &nde->loc);
return val;
}
static hawk_val_t* eval_int (hawk_rtx_t* rtx, hawk_nde_t* nde) static hawk_val_t* eval_int (hawk_rtx_t* rtx, hawk_nde_t* nde)
{ {
hawk_val_t* val; hawk_val_t* val;
@ -8210,6 +8334,11 @@ wp_mod_main:
ch_len = 0; ch_len = 0;
break; break;
case HAWK_VAL_CHAR:
ch = (hawk_ooch_t)HAWK_RTX_GETCHARFROMVAL (rtx, v);
ch_len = 1;
break;
case HAWK_VAL_INT: case HAWK_VAL_INT:
ch = (hawk_ooch_t)HAWK_RTX_GETINTFROMVAL (rtx, v); ch = (hawk_ooch_t)HAWK_RTX_GETINTFROMVAL (rtx, v);
ch_len = 1; ch_len = 1;
@ -9027,6 +9156,11 @@ wp_mod_main:
ch_len = 0; ch_len = 0;
break; break;
case HAWK_VAL_CHAR:
ch = (hawk_bch_t)HAWK_RTX_GETCHARFROMVAL(rtx, v); /* the value may get truncated */
ch_len = 1;
break;
case HAWK_VAL_INT: case HAWK_VAL_INT:
ch = (hawk_bch_t)HAWK_RTX_GETINTFROMVAL(rtx, v); ch = (hawk_bch_t)HAWK_RTX_GETINTFROMVAL(rtx, v);
ch_len = 1; ch_len = 1;

View File

@ -57,6 +57,7 @@ typedef struct hawk_nde_exp_t hawk_nde_exp_t;
typedef struct hawk_nde_cnd_t hawk_nde_cnd_t; typedef struct hawk_nde_cnd_t hawk_nde_cnd_t;
typedef struct hawk_nde_pos_t hawk_nde_pos_t; typedef struct hawk_nde_pos_t hawk_nde_pos_t;
typedef struct hawk_nde_char_t hawk_nde_char_t;
typedef struct hawk_nde_int_t hawk_nde_int_t; typedef struct hawk_nde_int_t hawk_nde_int_t;
typedef struct hawk_nde_flt_t hawk_nde_flt_t; typedef struct hawk_nde_flt_t hawk_nde_flt_t;
typedef struct hawk_nde_str_t hawk_nde_str_t; typedef struct hawk_nde_str_t hawk_nde_str_t;
@ -135,6 +136,13 @@ struct hawk_nde_pos_t
hawk_nde_t* val; hawk_nde_t* val;
}; };
/* HAWK_NDE_CHAR */
struct hawk_nde_char_t
{
HAWK_NDE_HDR;
hawk_ooch_t val;
};
/* HAWK_NDE_INT */ /* HAWK_NDE_INT */
struct hawk_nde_int_t struct hawk_nde_int_t
{ {

View File

@ -303,6 +303,41 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde)
break; break;
} }
case HAWK_NDE_CHAR:
{
hawk_ooch_t tmp = ((hawk_nde_char_t*)nde)->val;
hawk_ooch_t buf[16];
PUT_SRCSTR (hawk, HAWK_T("\'"));
if (tmp == '\0')
PUT_SRCSTR (hawk, HAWK_T("\\0"));
else if (tmp == '\'')
PUT_SRCSTR (hawk, HAWK_T("\\'"));
else if (hawk_is_ooch_print(tmp))
PUT_SRCSTRN (hawk, &tmp, 1);
#if defined(HAWK_OOCH_IS_UCH)
else if (tmp <= 0xFFFF)
{
hawk_fmttooocstr (hawk, buf, HAWK_COUNTOF(buf), HAWK_T("\\u%04x"), tmp);
PUT_SRCSTR (hawk, buf);
}
else
{
hawk_fmttooocstr (hawk, buf, HAWK_COUNTOF(buf), HAWK_T("\\U%08x"), tmp);
PUT_SRCSTR (hawk, buf);
}
#else
else
{
hawk_fmttooocstr (hawk, buf, HAWK_COUNTOF(buf), HAWK_T("\\x%02x"), tmp);
PUT_SRCSTR (hawk, buf);
}
#endif
PUT_SRCSTR (hawk, HAWK_T("\'"));
break;
}
case HAWK_NDE_INT: case HAWK_NDE_INT:
{ {
if (((hawk_nde_int_t*)nde)->str) if (((hawk_nde_int_t*)nde)->str)

View File

@ -77,11 +77,12 @@ struct hawk_val_rchunk_t
* *
* is this a safe assumption? do i have to use memalign or write my own * is this a safe assumption? do i have to use memalign or write my own
* aligned malloc()? */ * aligned malloc()? */
#define HAWK_VTR_NUM_TYPE_BITS 1 #define HAWK_VTR_NUM_TYPE_BITS 2 /* last 2 bits */
#define HAWK_VTR_MASK_TYPE_BITS 1 #define HAWK_VTR_MASK_TYPE_BITS 3 /* all 1's in the last 2 bits */
#define HAWK_VTR_TYPE_BITS_POINTER 0 #define HAWK_VTR_TYPE_BITS_POINTER 0
#define HAWK_VTR_TYPE_BITS_QUICKINT 1 #define HAWK_VTR_TYPE_BITS_QUICKINT 1
#define HAWK_VTR_TYPE_BITS_QUICKCHAR 2
#define HAWK_VTR_SIGN_BIT ((hawk_uintptr_t)1 << (HAWK_SIZEOF_UINTPTR_T * 8 - 1)) #define HAWK_VTR_SIGN_BIT ((hawk_uintptr_t)1 << (HAWK_SIZEOF_UINTPTR_T * 8 - 1))
/* shrink the bit range by 1 more bit to ease signbit handling. /* shrink the bit range by 1 more bit to ease signbit handling.
@ -95,6 +96,7 @@ struct hawk_val_rchunk_t
#define HAWK_VTR_TYPE_BITS(p) (((hawk_uintptr_t)(p)) & HAWK_VTR_MASK_TYPE_BITS) #define HAWK_VTR_TYPE_BITS(p) (((hawk_uintptr_t)(p)) & HAWK_VTR_MASK_TYPE_BITS)
#define HAWK_VTR_IS_POINTER(p) (HAWK_VTR_TYPE_BITS(p) == HAWK_VTR_TYPE_BITS_POINTER) #define HAWK_VTR_IS_POINTER(p) (HAWK_VTR_TYPE_BITS(p) == HAWK_VTR_TYPE_BITS_POINTER)
#define HAWK_VTR_IS_QUICKINT(p) (HAWK_VTR_TYPE_BITS(p) == HAWK_VTR_TYPE_BITS_QUICKINT) #define HAWK_VTR_IS_QUICKINT(p) (HAWK_VTR_TYPE_BITS(p) == HAWK_VTR_TYPE_BITS_QUICKINT)
#define HAWK_VTR_IS_QUICKCHAR(p) (HAWK_VTR_TYPE_BITS(p) == HAWK_VTR_TYPE_BITS_QUICKCHAR)
#define HAWK_QUICKINT_TO_VTR_POSITIVE(i) \ #define HAWK_QUICKINT_TO_VTR_POSITIVE(i) \
(((hawk_uintptr_t)(i) << HAWK_VTR_NUM_TYPE_BITS) | HAWK_VTR_TYPE_BITS_QUICKINT) (((hawk_uintptr_t)(i) << HAWK_VTR_NUM_TYPE_BITS) | HAWK_VTR_TYPE_BITS_QUICKINT)
@ -105,6 +107,8 @@ struct hawk_val_rchunk_t
#define HAWK_QUICKINT_TO_VTR(i) \ #define HAWK_QUICKINT_TO_VTR(i) \
((hawk_val_t*)(((i) < 0)? HAWK_QUICKINT_TO_VTR_NEGATIVE(i): HAWK_QUICKINT_TO_VTR_POSITIVE(i))) ((hawk_val_t*)(((i) < 0)? HAWK_QUICKINT_TO_VTR_NEGATIVE(i): HAWK_QUICKINT_TO_VTR_POSITIVE(i)))
#define HAWK_QUICKCHAR_TO_VTR(i) (((hawk_uintptr_t)(i) << HAWK_VTR_NUM_TYPE_BITS) | HAWK_VTR_TYPE_BITS_QUICKCHAR)
#define HAWK_VTR_ZERO ((hawk_val_t*)HAWK_QUICKINT_TO_VTR_POSITIVE(0)) #define HAWK_VTR_ZERO ((hawk_val_t*)HAWK_QUICKINT_TO_VTR_POSITIVE(0))
#define HAWK_VTR_ONE ((hawk_val_t*)HAWK_QUICKINT_TO_VTR_POSITIVE(1)) #define HAWK_VTR_ONE ((hawk_val_t*)HAWK_QUICKINT_TO_VTR_POSITIVE(1))
#define HAWK_VTR_NEGONE ((hawk_val_t*)HAWK_QUICKINT_TO_VTR_NEGATIVE(-1)) #define HAWK_VTR_NEGONE ((hawk_val_t*)HAWK_QUICKINT_TO_VTR_NEGATIVE(-1))
@ -119,9 +123,12 @@ struct hawk_val_rchunk_t
#define HAWK_VTR_TO_QUICKINT(p) \ #define HAWK_VTR_TO_QUICKINT(p) \
(((hawk_uintptr_t)(p) & HAWK_VTR_SIGN_BIT)? HAWK_VTR_TO_QUICKINT_NEGATIVE(p): HAWK_VTR_TO_QUICKINT_POSITIVE(p)) (((hawk_uintptr_t)(p) & HAWK_VTR_SIGN_BIT)? HAWK_VTR_TO_QUICKINT_NEGATIVE(p): HAWK_VTR_TO_QUICKINT_POSITIVE(p))
#define HAWK_VTR_TO_QUICKCHAR(p) ((hawk_ooch_t)((hawk_uintptr_t)(p) >> HAWK_VTR_NUM_TYPE_BITS))
#define HAWK_RTX_GETVALTYPE(rtx,p) (HAWK_VTR_IS_QUICKINT(p)? HAWK_VAL_INT: (p)->v_type) #define HAWK_RTX_GETVALTYPE(rtx,p) (HAWK_VTR_IS_QUICKINT(p)? HAWK_VAL_INT: \
HAWK_VTR_IS_QUICKCHAR(p)? HAWK_VAL_CHAR: (p)->v_type)
#define HAWK_RTX_GETINTFROMVAL(rtx,p) ((HAWK_VTR_IS_QUICKINT(p)? (hawk_int_t)HAWK_VTR_TO_QUICKINT(p): ((hawk_val_int_t*)(p))->i_val)) #define HAWK_RTX_GETINTFROMVAL(rtx,p) ((HAWK_VTR_IS_QUICKINT(p)? (hawk_int_t)HAWK_VTR_TO_QUICKINT(p): ((hawk_val_int_t*)(p))->i_val))
#define HAWK_RTX_GETCHARFROMVAL(rtx, p) (HAWK_VTR_TO_QUICKCHAR(p))
#define HAWK_VAL_ZERO HAWK_VTR_ZERO #define HAWK_VAL_ZERO HAWK_VTR_ZERO

View File

@ -484,6 +484,11 @@ hawk_val_t* hawk_rtx_makenilval (hawk_rtx_t* rtx)
return (hawk_val_t*)&hawk_nil; return (hawk_val_t*)&hawk_nil;
} }
hawk_val_t* hawk_rtx_makecharval (hawk_rtx_t* rtx, hawk_ooch_t v)
{
return HAWK_QUICKCHAR_TO_VTR(v);
}
hawk_val_t* hawk_rtx_makeintval (hawk_rtx_t* rtx, hawk_int_t v) hawk_val_t* hawk_rtx_makeintval (hawk_rtx_t* rtx, hawk_int_t v)
{ {
hawk_val_int_t* val; hawk_val_int_t* val;
@ -1368,6 +1373,7 @@ const hawk_ooch_t* hawk_rtx_getvaltypename(hawk_rtx_t* rtx, hawk_val_t* val)
{ {
/* synchronize this table with enum hawk_val_type_t in hawk.h */ /* synchronize this table with enum hawk_val_type_t in hawk.h */
HAWK_T("nil"), HAWK_T("nil"),
HAWK_T("char"),
HAWK_T("int"), HAWK_T("int"),
HAWK_T("flt"), HAWK_T("flt"),
HAWK_T("str"), HAWK_T("str"),
@ -1408,6 +1414,12 @@ void hawk_rtx_freeval (hawk_rtx_t* rtx, hawk_val_t* val, int flags)
break; break;
} }
case HAWK_VAL_CHAR:
{
/* this never happens */
break;
}
case HAWK_VAL_INT: case HAWK_VAL_INT:
{ {
((hawk_val_int_t*)val)->nde = (hawk_nde_int_t*)rtx->vmgr.ifree; ((hawk_val_int_t*)val)->nde = (hawk_nde_int_t*)rtx->vmgr.ifree;
@ -1650,6 +1662,8 @@ int hawk_rtx_valtobool (hawk_rtx_t* rtx, const hawk_val_t* val)
{ {
case HAWK_VAL_NIL: case HAWK_VAL_NIL:
return 0; return 0;
case HAWK_VAL_CHAR:
return HAWK_RTX_GETCHARFROMVAL(rtx, val) != 0;
case HAWK_VAL_INT: case HAWK_VAL_INT:
return HAWK_RTX_GETINTFROMVAL(rtx, val) != 0; return HAWK_RTX_GETINTFROMVAL(rtx, val) != 0;
case HAWK_VAL_FLT: case HAWK_VAL_FLT:
@ -2068,6 +2082,12 @@ int hawk_rtx_valtostr (hawk_rtx_t* rtx, const hawk_val_t* v, hawk_rtx_valtostr_o
case HAWK_VAL_NIL: case HAWK_VAL_NIL:
return str_to_str(rtx, HAWK_T(""), 0, out); return str_to_str(rtx, HAWK_T(""), 0, out);
case HAWK_VAL_CHAR:
{
hawk_ooch_t tmp = HAWK_RTX_GETCHARFROMVAL(rtx, v);
return str_to_str(rtx, &tmp, 1, out);
}
case HAWK_VAL_INT: case HAWK_VAL_INT:
return val_int_to_str(rtx, (hawk_val_int_t*)v, out); return val_int_to_str(rtx, (hawk_val_int_t*)v, out);
@ -2415,6 +2435,10 @@ int hawk_rtx_valtonum (hawk_rtx_t* rtx, const hawk_val_t* v, hawk_int_t* l, hawk
*l = 0; *l = 0;
return 0; return 0;
case HAWK_VAL_CHAR:
*l = HAWK_RTX_GETCHARFROMVAL(rtx, v);
return 0; /* long */
case HAWK_VAL_INT: case HAWK_VAL_INT:
*l = HAWK_RTX_GETINTFROMVAL(rtx, v); *l = HAWK_RTX_GETINTFROMVAL(rtx, v);
return 0; /* long */ return 0; /* long */
@ -2556,6 +2580,13 @@ hawk_int_t hawk_rtx_hashval (hawk_rtx_t* rtx, hawk_val_t* v)
hv = 0; hv = 0;
break; break;
case HAWK_VAL_CHAR:
{
hawk_ooch_t tmp = HAWK_RTX_GETCHARFROMVAL(rtx, v);
hv = (hawk_int_t)hash((hawk_uint8_t*)&tmp, HAWK_SIZEOF(tmp));
break;
}
case HAWK_VAL_INT: case HAWK_VAL_INT:
{ {
hawk_int_t tmp = HAWK_RTX_GETINTFROMVAL(rtx, v); hawk_int_t tmp = HAWK_RTX_GETINTFROMVAL(rtx, v);
@ -2860,9 +2891,30 @@ void hawk_dprintval (hawk_rtx_t* run, hawk_val_t* val)
switch (val->type) switch (val->type)
{ {
case HAWK_VAL_NIL: case HAWK_VAL_NIL:
hawk_errputstrf (HAWK_T("nil")); hawk_errputstrf (HAWK_T("@nil"));
break; break;
case HAWK_VAL_NIL:
{
hawk_ooch_t tmp = HAWK_RTX_GETCHARFROMVAL(rtx, val);
if (tmp == '\'')
hawk_errputstrf (HAWK_T("'\\%c'"), tmp);
else if (tmp == '\0')
hawk_errputstrf (HAWK_T("'\\0'"));
else if (hawk_is_ooch_print(tmp))
hawk_errputstrf (HAWK_T("'%jc'"), tmp);
#if defined(HAWK_OOCH_IS_UCH)
else if (tmp <= 0xFFFF)
hawk_errputstrf (HAWK_T("'\\u%04x'"), tmp);
else
hawk_errputstrf (HAWK_T("'\\U%08x'"), tmp);
#else
else
hawk_errputstrf (HAWK_T("'\\x%02x'"), tmp);
#endif
break;
}
case HAWK_VAL_INT: case HAWK_VAL_INT:
hawk_errputstrf (HAWK_T("%jd"), (hawk_intmax_t)((hawk_val_int_t*)val)->val); hawk_errputstrf (HAWK_T("%jd"), (hawk_intmax_t)((hawk_val_int_t*)val)->val);
break; break;