From 48a54d61c1752299614dd8e76119aa11a9df7a9e Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 14 Jan 2024 09:48:57 +0900 Subject: [PATCH] updated the reader to forge an outer xlist automatically if the beginning is a complex literal expression like array([]), dictionary(#{}), etc --- bin/main.c | 3 ++- lib/read.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ t/Makefile.am | 4 +++- t/Makefile.in | 4 +++- t/call-01.err | 3 +++ t/var-02.hcl | 24 ++++++++++++++++++++++++ 6 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 t/call-01.err create mode 100644 t/var-02.hcl diff --git a/bin/main.c b/bin/main.c index 8a6dbe5..aae35fd 100644 --- a/bin/main.c +++ b/bin/main.c @@ -582,7 +582,8 @@ oops: return -1; } -#define DEFAULT_HEAPSIZE 512000ul +//#define DEFAULT_HEAPSIZE (512000ul) +#define DEFAULT_HEAPSIZE (0ul) /* don't use the pre-allocated heap */ int main (int argc, char* argv[]) { diff --git a/lib/read.c b/lib/read.c index 92620a6..1bd0a75 100644 --- a/lib/read.c +++ b/lib/read.c @@ -1042,6 +1042,38 @@ static HCL_INLINE int is_at_block_beginning (hcl_t* hcl) return !rstl || (LIST_FLAG_GET_CONCODE(rstl->flagv) == HCL_CONCODE_BLOCK && (hcl->c->feed.rd.flagv & AT_BEGINNING)); } +static int forge_auto_xlist_if_at_block_beginning (hcl_t* hcl, hcl_frd_t* frd) +{ + if (is_at_block_beginning(hcl)) + { + int forged_flagv; + + /* both MLIST and ALIST begin as XLIST and get converted to MLIST + * or ALIST after more tokens are processed. so handling of MLIST + * or ALIST is needed at this phase */ + forged_flagv = AUTO_FORGED; + LIST_FLAG_SET_CONCODE (forged_flagv, HCL_CONCODE_XLIST); + + /* this portion is similar to the code below the start_list label */ + if (frd->level >= HCL_TYPE_MAX(int)) /* the nesting level too deep */ + { + hcl_setsynerr (hcl, HCL_SYNERR_NESTING, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); + return -1; + } + + /* since the actual list opener doesn't exist, the location of the + * first element wil be the location of the list */ + if (enter_list(hcl, TOKEN_LOC(hcl), forged_flagv) <= -1) return -1; + frd->level++; /* level after the forged list has been added */ + /* a new list has been created automatically. unlike normal list creation + * by an explicit symbol such as a left parenthesis, a left brace, etc, + * the first element opens up this new list. so the AT_BEGINNING bit is + * turned off here */ + frd->flagv &= ~AT_BEGINNING; + } + + return 0; +} static int feed_process_token (hcl_t* hcl) { hcl_frd_t* frd = &hcl->c->feed.rd; @@ -1139,26 +1171,36 @@ static int feed_process_token (hcl_t* hcl) } case HCL_TOK_LBRACK: /* [ */ + /* [] is a data list. so let's treat it like other literal + * expressions(e.g. 1, "abc"). when it's placed at the block beginning, + * create the outer XLIST. */ + if (forge_auto_xlist_if_at_block_beginning(hcl, frd) <= -1) goto oops; + frd->flagv = DATA_LIST; LIST_FLAG_SET_CONCODE (frd->flagv, HCL_CONCODE_ARRAY); goto start_list; case HCL_TOK_BAPAREN: /* #[ */ + if (forge_auto_xlist_if_at_block_beginning(hcl, frd) <= -1) goto oops; + frd->flagv = DATA_LIST; LIST_FLAG_SET_CONCODE (frd->flagv, HCL_CONCODE_BYTEARRAY); goto start_list; case HCL_TOK_LBRACE: /* { */ + /* this is a block opener itself. auto xlist forge at the block beginning */ frd->flagv = 0; LIST_FLAG_SET_CONCODE (frd->flagv, HCL_CONCODE_BLOCK); goto start_list; case HCL_TOK_DLPAREN: /* #{ */ + if (forge_auto_xlist_if_at_block_beginning(hcl, frd) <= -1) goto oops; frd->flagv = DATA_LIST; LIST_FLAG_SET_CONCODE (frd->flagv, HCL_CONCODE_DIC); goto start_list; case HCL_TOK_QLPAREN: /* #( */ + if (forge_auto_xlist_if_at_block_beginning(hcl, frd) <= -1) goto oops; frd->flagv = DATA_LIST; LIST_FLAG_SET_CONCODE (frd->flagv, HCL_CONCODE_QLIST); goto start_list; @@ -1458,6 +1500,7 @@ static int feed_process_token (hcl_t* hcl) goto auto_xlist; auto_xlist: + #if 0 if (is_at_block_beginning(hcl)) { int forged_flagv; @@ -1485,6 +1528,9 @@ static int feed_process_token (hcl_t* hcl) * turned off here */ frd->flagv &= ~AT_BEGINNING; } + #else + if (forge_auto_xlist_if_at_block_beginning(hcl, frd) <= -1) goto oops; + #endif break; } diff --git a/t/Makefile.am b/t/Makefile.am index d9880a5..a54c962 100644 --- a/t/Makefile.am +++ b/t/Makefile.am @@ -6,9 +6,11 @@ check_SCRIPTS = \ insta-02.hcl \ ret-01.hcl \ retvar-01.hcl \ - va-01.hcl + va-01.hcl \ + var-02.hcl check_ERRORS = \ + call-01.err \ class-01.err \ do-01.err \ do-02.err \ diff --git a/t/Makefile.in b/t/Makefile.in index 5f6751b..65355a9 100644 --- a/t/Makefile.in +++ b/t/Makefile.in @@ -477,9 +477,11 @@ check_SCRIPTS = \ insta-02.hcl \ ret-01.hcl \ retvar-01.hcl \ - va-01.hcl + va-01.hcl \ + var-01.hcl check_ERRORS = \ + call-01.err \ class-01.err \ do-01.err \ do-02.err \ diff --git a/t/call-01.err b/t/call-01.err new file mode 100644 index 0000000..c8a996d --- /dev/null +++ b/t/call-01.err @@ -0,0 +1,3 @@ +## the expression begins with a dictionary expression. +## it is not a function name and can'be be invoked. +#{100:1, 200: 3}; ##ERROR: syntax error - invalid callable diff --git a/t/var-02.hcl b/t/var-02.hcl new file mode 100644 index 0000000..64977a1 --- /dev/null +++ b/t/var-02.hcl @@ -0,0 +1,24 @@ +defun x (a ::: x y z) { + x := (* a a); + y := (+ a a); + z := (- x y); +}; + +j := 21; + +if (eqv? j 20) { + [a,b,c] := (x 20); + q := (x 20); +} else { + [a,b,c] := (x 30); + q := (x 30); +}; + +if (/= a 900) { print "ERROR: a is not 900\n" } +else { printf "OK: %d\n" a }; + +if (/= b 60) { print "ERROR: b is not 60\n" } +else { printf "OK: %d\n" b }; + +if (/= c 840) { print "ERROR: c is not 840\n" } +else { printf "OK: %d\n" c };