From 342e01f5b4c0484528b38e00d08810751aa7c247 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Fri, 4 Dec 2020 16:19:01 +0000 Subject: [PATCH] attempting to support the character literal notation --- hawk/lib/hawk.h | 26 ++++--- hawk/lib/run.c | 176 ++++++++++++++++++++++++++++++++++++++------ hawk/lib/tree-prv.h | 18 +++-- hawk/lib/tree.c | 35 +++++++++ hawk/lib/val-prv.h | 13 +++- hawk/lib/val.c | 56 +++++++++++++- 6 files changed, 284 insertions(+), 40 deletions(-) diff --git a/hawk/lib/hawk.h b/hawk/lib/hawk.h index 86c12c55..77fcb75b 100644 --- a/hawk/lib/hawk.h +++ b/hawk/lib/hawk.h @@ -411,6 +411,7 @@ enum hawk_nde_type_t HAWK_NDE_FNCALL_FNC, HAWK_NDE_FNCALL_FUN, HAWK_NDE_FNCALL_VAR, + HAWK_NDE_CHAR, HAWK_NDE_INT, HAWK_NDE_FLT, HAWK_NDE_STR, @@ -1383,16 +1384,17 @@ enum hawk_val_type_t * must be synchronized with an internal table of the __cmp_val * function in run.c and the __val_type_name in val.c */ HAWK_VAL_NIL = 0, /**< nil */ - HAWK_VAL_INT = 1, /**< integer */ - HAWK_VAL_FLT = 2, /**< floating-pointer number */ - HAWK_VAL_STR = 3, /**< string */ - HAWK_VAL_MBS = 4, /**< byte array */ - HAWK_VAL_FUN = 5, /**< function pointer */ - HAWK_VAL_MAP = 6, /**< map */ - HAWK_VAL_ARR = 7, /**< array */ + HAWK_VAL_CHAR = 1, /**< character */ + HAWK_VAL_INT = 2, /**< integer */ + HAWK_VAL_FLT = 3, /**< floating-pointer number */ + HAWK_VAL_STR = 4, /**< string */ + HAWK_VAL_MBS = 5, /**< byte array */ + HAWK_VAL_FUN = 6, /**< function pointer */ + HAWK_VAL_MAP = 7, /**< map */ + HAWK_VAL_ARR = 8, /**< array */ - HAWK_VAL_REX = 8, /**< regular expression */ - HAWK_VAL_REF = 9 /**< reference to other types */ + HAWK_VAL_REX = 9, /**< regular expression */ + HAWK_VAL_REF = 10 /**< reference to other types */ }; 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_EXPORT hawk_val_t* hawk_rtx_makecharval ( + hawk_rtx_t* rtx, + hawk_ooch_t v +); + /** * The hawk_rtx_makeintval() function creates an integer value. * If \a v is one of -1, 0, 1, this function never fails. diff --git a/hawk/lib/run.c b/hawk/lib/run.c index 3c93137a..c099e82d 100644 --- a/hawk/lib/run.c +++ b/hawk/lib/run.c @@ -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_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 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_flt (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) { hawk_nde_t* p; - hawk_oow_t saved_stack_top; + /*hawk_oow_t saved_stack_top;*/ int n = 0; 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); - saved_stack_top = rtx->stack_top; + /*saved_stack_top = rtx->stack_top;*/ #if defined(DEBUG_RUN) 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_fun, eval_fncall_var, + eval_char, eval_int, eval_flt, 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; } +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) { - 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); } @@ -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) { hawk_int_t v = HAWK_RTX_GETINTFROMVAL(rtx, left); 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) { - hawk_int_t v1 = HAWK_RTX_GETINTFROMVAL(rtx, left); hawk_int_t v2 = HAWK_RTX_GETINTFROMVAL(rtx, right); 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; } +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) { - 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; 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; } +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) { 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) { - hawk_t* hawk = hawk_rtx_gethawk(rtx); hawk_val_str_t* ls, * rs; 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; } +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) { 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); } +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) { 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; } +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) { 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 * 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_int_nil, __cmp_int_int, __cmp_int_flt, __cmp_int_str, __cmp_int_mbs, __cmp_int_fun, __cmp_int_map, - __cmp_flt_nil, __cmp_flt_int, __cmp_flt_flt, __cmp_flt_str, __cmp_flt_mbs, __cmp_flt_fun, __cmp_flt_map, - __cmp_str_nil, __cmp_str_int, __cmp_str_flt, __cmp_str_str, __cmp_str_mbs, __cmp_str_fun, __cmp_str_map, - __cmp_mbs_nil, __cmp_mbs_int, __cmp_mbs_flt, __cmp_mbs_str, __cmp_mbs_mbs, __cmp_mbs_fun, __cmp_mbs_map, - __cmp_fun_nil, __cmp_fun_int, __cmp_fun_flt, __cmp_fun_str, __cmp_fun_mbs, __cmp_fun_fun, __cmp_fun_map, - __cmp_map_nil, __cmp_map_int, __cmp_map_flt, __cmp_map_str, __cmp_map_mbs, __cmp_map_fun, __cmp_map_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_char_nil, __cmp_char_char, __cmp_char_int, __cmp_char_flt, __cmp_char_str, __cmp_char_mbs, __cmp_char_fun, __cmp_char_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_flt_nil, __cmp_flt_char, __cmp_flt_int, __cmp_flt_flt, __cmp_flt_str, __cmp_flt_mbs, __cmp_flt_fun, __cmp_flt_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_mbs_nil, __cmp_mbs_char, __cmp_mbs_int, __cmp_mbs_flt, __cmp_mbs_str, __cmp_mbs_mbs, __cmp_mbs_fun, __cmp_mbs_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); @@ -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: * HAWK_VAL_NIL = 0 - * HAWK_VAL_INT = 1 - * HAWK_VAL_FLT = 2 - * HAWK_VAL_STR = 3 - * HAWK_VAL_MBS = 4 - * HAWK_VAL_FUN = 5 - * HAWK_VAL_MAP = 6 + * HAWK_VAL_CHAR = 1 + * HAWK_VAL_INT = 2 + * HAWK_VAL_FLT = 3 + * HAWK_VAL_STR = 4 + * HAWK_VAL_MBS = 5 + * HAWK_VAL_FUN = 6 + * HAWK_VAL_MAP = 7 * * op_hint indicate the operation in progress when this function is called. * this hint doesn't require the comparison function to compare using this * operation. the comparision function should return 0 if equal, -1 if less, * 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; *ret = n; @@ -5233,6 +5345,10 @@ static int teq_val (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right) n = 1; break; + case HAWK_VAL_CHAR: + n = (HAWK_RTX_GETCHARFROMVAL (rtx, left) == HAWK_RTX_GETCHARFROMVAL (rtx, right)); + break; + case HAWK_VAL_INT: n = (HAWK_RTX_GETINTFROMVAL (rtx, left) == HAWK_RTX_GETINTFROMVAL (rtx, right)); break; @@ -6920,6 +7036,14 @@ oops: 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) { hawk_val_t* val; @@ -8210,6 +8334,11 @@ wp_mod_main: ch_len = 0; break; + case HAWK_VAL_CHAR: + ch = (hawk_ooch_t)HAWK_RTX_GETCHARFROMVAL (rtx, v); + ch_len = 1; + break; + case HAWK_VAL_INT: ch = (hawk_ooch_t)HAWK_RTX_GETINTFROMVAL (rtx, v); ch_len = 1; @@ -9027,6 +9156,11 @@ wp_mod_main: ch_len = 0; 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: ch = (hawk_bch_t)HAWK_RTX_GETINTFROMVAL(rtx, v); ch_len = 1; diff --git a/hawk/lib/tree-prv.h b/hawk/lib/tree-prv.h index ac8d5cf6..bf65c28c 100644 --- a/hawk/lib/tree-prv.h +++ b/hawk/lib/tree-prv.h @@ -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_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_flt_t hawk_nde_flt_t; typedef struct hawk_nde_str_t hawk_nde_str_t; @@ -135,13 +136,20 @@ struct hawk_nde_pos_t hawk_nde_t* val; }; +/* HAWK_NDE_CHAR */ +struct hawk_nde_char_t +{ + HAWK_NDE_HDR; + hawk_ooch_t val; +}; + /* HAWK_NDE_INT */ struct hawk_nde_int_t { HAWK_NDE_HDR; hawk_int_t val; - hawk_ooch_t* str; - hawk_oow_t len; + hawk_ooch_t* str; + hawk_oow_t len; }; /* HAWK_NDE_FLT */ @@ -149,8 +157,8 @@ struct hawk_nde_flt_t { HAWK_NDE_HDR; hawk_flt_t val; - hawk_ooch_t* str; - hawk_oow_t len; + hawk_ooch_t* str; + hawk_oow_t len; }; /* HAWK_NDE_STR */ @@ -158,7 +166,7 @@ struct hawk_nde_str_t { HAWK_NDE_HDR; hawk_ooch_t* ptr; - hawk_oow_t len; + hawk_oow_t len; }; /* HAWK_NDE_MBS */ diff --git a/hawk/lib/tree.c b/hawk/lib/tree.c index c4720e7c..e4e37739 100644 --- a/hawk/lib/tree.c +++ b/hawk/lib/tree.c @@ -303,6 +303,41 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde) 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: { if (((hawk_nde_int_t*)nde)->str) diff --git a/hawk/lib/val-prv.h b/hawk/lib/val-prv.h index 5f300639..d55fe734 100644 --- a/hawk/lib/val-prv.h +++ b/hawk/lib/val-prv.h @@ -77,11 +77,12 @@ struct hawk_val_rchunk_t * * is this a safe assumption? do i have to use memalign or write my own * aligned malloc()? */ -#define HAWK_VTR_NUM_TYPE_BITS 1 -#define HAWK_VTR_MASK_TYPE_BITS 1 +#define HAWK_VTR_NUM_TYPE_BITS 2 /* last 2 bits */ +#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_QUICKINT 1 +#define HAWK_VTR_TYPE_BITS_QUICKCHAR 2 #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. @@ -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_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_QUICKCHAR(p) (HAWK_VTR_TYPE_BITS(p) == HAWK_VTR_TYPE_BITS_QUICKCHAR) #define HAWK_QUICKINT_TO_VTR_POSITIVE(i) \ (((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) \ ((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_ONE ((hawk_val_t*)HAWK_QUICKINT_TO_VTR_POSITIVE(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) \ (((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_GETCHARFROMVAL(rtx, p) (HAWK_VTR_TO_QUICKCHAR(p)) #define HAWK_VAL_ZERO HAWK_VTR_ZERO diff --git a/hawk/lib/val.c b/hawk/lib/val.c index 703de92b..ddb41962 100644 --- a/hawk/lib/val.c +++ b/hawk/lib/val.c @@ -484,6 +484,11 @@ hawk_val_t* hawk_rtx_makenilval (hawk_rtx_t* rtx) 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_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 */ HAWK_T("nil"), + HAWK_T("char"), HAWK_T("int"), HAWK_T("flt"), HAWK_T("str"), @@ -1407,7 +1413,13 @@ void hawk_rtx_freeval (hawk_rtx_t* rtx, hawk_val_t* val, int flags) hawk_rtx_freemem (rtx, val); break; } - + + case HAWK_VAL_CHAR: + { + /* this never happens */ + break; + } + case HAWK_VAL_INT: { ((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: return 0; + case HAWK_VAL_CHAR: + return HAWK_RTX_GETCHARFROMVAL(rtx, val) != 0; case HAWK_VAL_INT: return HAWK_RTX_GETINTFROMVAL(rtx, val) != 0; 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: 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: 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; return 0; + case HAWK_VAL_CHAR: + *l = HAWK_RTX_GETCHARFROMVAL(rtx, v); + return 0; /* long */ + case HAWK_VAL_INT: *l = HAWK_RTX_GETINTFROMVAL(rtx, v); return 0; /* long */ @@ -2556,6 +2580,13 @@ hawk_int_t hawk_rtx_hashval (hawk_rtx_t* rtx, hawk_val_t* v) hv = 0; 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: { 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) { case HAWK_VAL_NIL: - hawk_errputstrf (HAWK_T("nil")); + hawk_errputstrf (HAWK_T("@nil")); 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: hawk_errputstrf (HAWK_T("%jd"), (hawk_intmax_t)((hawk_val_int_t*)val)->val); break;