diff --git a/lib/comp.c b/lib/comp.c index c83fcd5..e7f965d 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -4903,7 +4903,7 @@ redo: lit = HCL_ERROR_TO_OOP(oprnd->u.errlit.v); goto literal; - case HCL_CNODE_SYMBOL: + case HCL_CNODE_SYMBOL: /* symbol. but not a literal. usually a variable */ if (compile_symbol(hcl, oprnd) <= -1) return -1; goto done; diff --git a/lib/gc.c b/lib/gc.c index 30dd1eb..9ce31d3 100644 --- a/lib/gc.c +++ b/lib/gc.c @@ -298,6 +298,18 @@ static kernel_class_info_t kernel_classes[__KCI_MAX__] = HCL_OFFSETOF(hcl_t, c_string) }, + KCI(KCI_STRING) { + "ByteString", + KCI_FIXED_SIZED_COLLECTION, + HCL_BRAND_BYTE_STRING, + 0, + 0, + 0, + HCL_CLASS_SPEC_FLAG_INDEXED, + HCL_OBJ_TYPE_BYTE, + HCL_OFFSETOF(hcl_t, c_byte_string) + }, + KCI(KCI_SYMBOL) { "Symbol", KCI_STRING, diff --git a/lib/hcl.h b/lib/hcl.h index ce8dccd..e269cd7 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -1713,6 +1713,7 @@ struct hcl_t hcl_oop_class_t c_indexed_collection; /* IndexedCollection */ hcl_oop_class_t c_fixed_sized_collection; /* FixedSizedCollection */ hcl_oop_class_t c_string; /* String */ + hcl_oop_class_t c_byte_string; /* String */ hcl_oop_class_t c_symbol; /* Symbol */ hcl_oop_class_t c_array; /* Array */ hcl_oop_class_t c_byte_array; /* ByteArray */ @@ -2007,6 +2008,7 @@ enum hcl_brand_t HCL_BRAND_BYTE_ARRAY, HCL_BRAND_SYMBOL, HCL_BRAND_STRING, + HCL_BRAND_BYTE_STRING, HCL_BRAND_DIC, HCL_BRAND_FPDEC, /* fixed-point decimal */ diff --git a/lib/obj.c b/lib/obj.c index b0f182c..cee6efb 100644 --- a/lib/obj.c +++ b/lib/obj.c @@ -360,7 +360,7 @@ hcl_oop_t hcl_makebytestringwithbytes (hcl_t* hcl, const hcl_oob_t* ptr, hcl_oow hcl_oow_t i; hcl_oob_t v; - b = (hcl_oop_byte_t)alloc_numeric_array(hcl, HCL_BRAND_BYTE_ARRAY, ptr, len, HCL_OBJ_TYPE_BYTE, HCL_SIZEOF(hcl_oob_t), 1, ngc); + b = (hcl_oop_byte_t)alloc_numeric_array(hcl, HCL_BRAND_BYTE_STRING, ptr, len, HCL_OBJ_TYPE_BYTE, HCL_SIZEOF(hcl_oob_t), 1, ngc); if (HCL_UNLIKELY(!b)) { const hcl_ooch_t* orgmsg = hcl_backuperrmsg(hcl); @@ -374,7 +374,7 @@ hcl_oop_t hcl_makebytestringwithbytes (hcl_t* hcl, const hcl_oob_t* ptr, hcl_oow HCL_OBJ_SET_BYTE_VAL(b, i, v); } - HCL_OBJ_SET_CLASS (b, (hcl_oop_t)hcl->c_byte_array); + HCL_OBJ_SET_CLASS (b, (hcl_oop_t)hcl->c_byte_string); } return (hcl_oop_t)b; @@ -391,7 +391,7 @@ hcl_oop_t hcl_makebytestring (hcl_t* hcl, const hcl_ooch_t* ptr, hcl_oow_t len, hcl_oow_t i; hcl_oob_t v; - b = (hcl_oop_byte_t)alloc_numeric_array(hcl, HCL_BRAND_BYTE_ARRAY, HCL_NULL, len, HCL_OBJ_TYPE_BYTE, HCL_SIZEOF(hcl_oob_t), 1, ngc); + b = (hcl_oop_byte_t)alloc_numeric_array(hcl, HCL_BRAND_BYTE_STRING, HCL_NULL, len, HCL_OBJ_TYPE_BYTE, HCL_SIZEOF(hcl_oob_t), 1, ngc); if (HCL_UNLIKELY(!b)) { const hcl_ooch_t* orgmsg = hcl_backuperrmsg(hcl); @@ -405,7 +405,7 @@ hcl_oop_t hcl_makebytestring (hcl_t* hcl, const hcl_ooch_t* ptr, hcl_oow_t len, HCL_OBJ_SET_BYTE_VAL(b, i, v); } - HCL_OBJ_SET_CLASS (b, (hcl_oop_t)hcl->c_byte_array); + HCL_OBJ_SET_CLASS (b, (hcl_oop_t)hcl->c_byte_string); } return (hcl_oop_t)b; diff --git a/lib/print.c b/lib/print.c index fa39f42..c33d4f0 100644 --- a/lib/print.c +++ b/lib/print.c @@ -202,6 +202,69 @@ static HCL_INLINE int print_single_char (hcl_t* hcl, hcl_fmtout_t* fmtout, hcl_o return 0; } +static HCL_INLINE int print_single_byte_char (hcl_t* hcl, hcl_fmtout_t* fmtout, hcl_bch_t ch) +{ + hcl_bchu_t chu = (hcl_bchu_t)ch; + if (chu == '\\' || chu == '\"') + { + if (hcl_bfmt_out(hcl, fmtout, "\\%hc", chu) <= -1) return -1; + } +#if defined(HCL_OOCH_IS_UCH) + else if (chu < ' ') +#else + else if (chu < ' ' || chu >= 0x80) +#endif + { + hcl_bchu_t escaped; + + switch (chu) + { + case '\0': + escaped = '0'; + break; + case '\n': + escaped = 'n'; + break; + case '\r': + escaped = 'r'; + break; + case '\t': + escaped = 't'; + break; + case '\f': + escaped = 'f'; + break; + case '\b': + escaped = 'b'; + break; + case '\v': + escaped = 'v'; + break; + case '\a': + escaped = 'a'; + break; + default: + escaped = chu; + break; + } + + if (escaped == chu) + { + if (hcl_bfmt_out(hcl, fmtout, "\\x%02X", chu) <= -1) return -1; + } + else + { + if (hcl_bfmt_out(hcl, fmtout, "\\%hc", escaped) <= -1) return -1; + } + } + else + { + if (hcl_bfmt_out(hcl, fmtout, "%hc", ch) <= -1) return -1; + } + + return 0; +} + int hcl_fmt_object (hcl_t* hcl, hcl_fmtout_t* fmtout, hcl_oop_t obj) { hcl_oop_t cur; @@ -385,7 +448,8 @@ next: * I simply treat the syntax symbol as a normal symbol * for printing currently. */ /* TODO: escaping if needed */ - if (hcl_bfmt_out(hcl, fmtout, "#\"%.*js\"", HCL_OBJ_GET_SIZE(obj), HCL_OBJ_GET_CHAR_SLOT(obj)) <= -1) return -1; + /*if (hcl_bfmt_out(hcl, fmtout, "#\"%.*js\"", HCL_OBJ_GET_SIZE(obj), HCL_OBJ_GET_CHAR_SLOT(obj)) <= -1) return -1;*/ + if (hcl_bfmt_out(hcl, fmtout, "%.*js", HCL_OBJ_GET_SIZE(obj), HCL_OBJ_GET_CHAR_SLOT(obj)) <= -1) return -1; break; case HCL_BRAND_STRING: @@ -421,6 +485,40 @@ next: break; } + case HCL_BRAND_BYTE_STRING: + { + hcl_bch_t ch; + hcl_oow_t i; + int escape = 0; + + for (i = 0; i < HCL_OBJ_GET_SIZE(obj); i++) + { + ch = ((hcl_oop_byte_t)obj)->slot[i]; + if (ch < ' ' || ch == '\"' || ch == '\\') + { + escape = 1; + break; + } + } + + if (escape) + { + if (hcl_bfmt_out(hcl, fmtout, "b\"") <= -1) return -1; + for (i = 0; i < HCL_OBJ_GET_SIZE(obj); i++) + { + ch = ((hcl_oop_byte_t)obj)->slot[i]; + if (print_single_byte_char(hcl, fmtout, ch) <= -1) return -1; + } + if (hcl_bfmt_out(hcl, fmtout, "\"") <= -1) return -1; + } + else + { + if (hcl_bfmt_out(hcl, fmtout, "b\"%.*hs\"", HCL_OBJ_GET_SIZE(obj), HCL_OBJ_GET_BYTE_SLOT(obj)) <= -1) return -1; + } + break; + } + + case HCL_BRAND_CONS: { int concode;