diff --git a/lib/cnode.c b/lib/cnode.c new file mode 100644 index 0000000..eadfb80 --- /dev/null +++ b/lib/cnode.c @@ -0,0 +1,81 @@ +/* + * $Id$ + * + Copyright (c) 2016-2018 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +static hcl_cnode_t* make_cnode (hcl_t* hcl, hcl_cnode_type_t type, const hcl_ioloc_t* loc, hcl_oow_t extra_space) +{ + hcl_cnode_t* cnode; + + cnode = hcl_allocmem(hcl, HCL_SIZEOF(*cnode) + extra_space); + if (HCL_UNLIKELY(!cnode)) return HCL_NULL; + + cnode->type = type; + cnode->loc = *loc; + return cnode; +} + +hcl_cnode_t* hcl_makecnodenil (hcl_t* hcl, const hcl_ioloc_t* loc) +{ + return make_cnode(hcl, HCL_CNODE_NIL, loc, 0); +} + +hcl_cnode_t* hcl_makecnodetrue (hcl_t* hcl, const hcl_ioloc_t* loc) +{ + return make_cnode(hcl, HCL_CNODE_TRUE, loc, 0); +} + +hcl_cnode_t* hcl_makecnodefalse (hcl_t* hcl, const hcl_ioloc_t* loc) +{ + return make_cnode(hcl, HCL_CNODE_FALSE, loc, 0); +} + +hcl_cnode_t* hcl_makecnodecharlit (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_ooch_t ch) +{ + hcl_cnode_t* c = make_cnode(hcl, HCL_CNODE_CHARLIT, loc, 0); + if (HCL_UNLIKELY(!c)) return HCL_NULL; + c->u.charlit.v = ch; + return c; +} + +hcl_cnode_t* hcl_makecnodestrlit (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_ooch_t* ptr, hcl_oow_t len) +{ + hcl_cnode_t* c = make_cnode(hcl, HCL_CNODE_STRLIT, loc, HCL_SIZEOF(*ptr) * (len + 1)); + if (HCL_UNLIKELY(!c)) return HCL_NULL; + + c->u.strlit.ptr = (hawk_ooch_t*)(c + 1); + c->u.strlit.len = len; + hawk_copy_bchars (c->u.strlit.ptr, c->u.strlit.len, ptr, len); + return c; +} + +hcl_cnode_t* hcl_makecnodeerrlit (hcl_t* hcl, const hcl_ioloc_t* loc, hcl_ooi_t v) +{ + hcl_cnode_t* c = make_cnode(hcl, HCL_CNODE_ERRLIT, loc, HCL_SIZEOF(*ptr) * (len + 1)); + if (HCL_UNLIKELY(!c)) return HCL_NULL; + + c->u.errlit.v = v; + return c; +} + diff --git a/lib/hcl-prv.h b/lib/hcl-prv.h index 6510ec5..ce06fb6 100644 --- a/lib/hcl-prv.h +++ b/lib/hcl-prv.h @@ -140,7 +140,7 @@ enum hcl_iotok_type_t HCL_IOTOK_RADNUMLIT, HCL_IOTOK_FPDECLIT, HCL_IOTOK_SMPTRLIT, - HCL_IOTOK_ERRORLIT, + HCL_IOTOK_ERRLIT, HCL_IOTOK_NIL, HCL_IOTOK_TRUE, HCL_IOTOK_FALSE, @@ -181,7 +181,6 @@ struct hcl_iolink_t hcl_iolink_t* link; }; -typedef enum hcl_concode_t hcl_concode_t; enum hcl_cnode_type_t { HCL_CNODE_CHARLIT, @@ -190,7 +189,7 @@ enum hcl_cnode_type_t HCL_CNODE_RADNUMLIT, HCL_CNODE_FPDECLIT, HCL_CNODE_SMPTRLIT, - HCL_CNODE_ERRORLIT, + HCL_CNODE_ERRLIT, HCL_CNODE_NIL, HCL_CNODE_TRUE, HCL_CNODE_FALSE, @@ -226,11 +225,19 @@ struct hcl_cnode_t union { + struct + { + hcl_ooch_t v; + } charlit; struct { hcl_ooch_t* ptr; hcl_oow_t len; } strlit; + struct + { + hcl_ooi_t v; + } errlit; } u; }; typedef struct hcl_cnode_t hcl_cnode_t; diff --git a/lib/hcl.h b/lib/hcl.h index 35d34b0..a1550a2 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -103,7 +103,7 @@ enum hcl_synerrnum_t HCL_SYNERR_CHARLIT, /* wrong character literal */ HCL_SYNERR_NUMLIT , /* invalid numeric literal */ HCL_SYNERR_NUMRANGE, /* number range error */ - HCL_SYNERR_ERRORLIT, /* wrong error literal */ + HCL_SYNERR_ERRLIT, /* wrong error literal */ HCL_SYNERR_SMPTRLIT, /* wrong smptr literal */ HCL_SYNERR_MSEGIDENT, /* wrong multi-segment identifier */ diff --git a/lib/read.c b/lib/read.c index bddf15f..e5bd6bb 100644 --- a/lib/read.c +++ b/lib/read.c @@ -799,7 +799,7 @@ static int get_sharp_token (hcl_t* hcl) case 'e': if (get_radix_number(hcl, c, 10) <= -1) return -1; - SET_TOKEN_TYPE (hcl, HCL_IOTOK_ERRORLIT); + SET_TOKEN_TYPE (hcl, HCL_IOTOK_ERRLIT); break; case 'p': @@ -2030,7 +2030,7 @@ static int read_object (hcl_t* hcl) break; } - case HCL_IOTOK_ERRORLIT: + case HCL_IOTOK_ERRLIT: { hcl_oow_t i; hcl_ooi_t v = 0; @@ -2043,7 +2043,7 @@ static int read_object (hcl_t* hcl) if (v > HCL_ERROR_MAX) { - hcl_setsynerr (hcl, HCL_SYNERR_ERRORLIT, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); + hcl_setsynerr (hcl, HCL_SYNERR_ERRLIT, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); return -1; } }