diff --git a/lib/err.c b/lib/err.c index 9f9bf3c..34c2500 100644 --- a/lib/err.c +++ b/lib/err.c @@ -161,6 +161,7 @@ static char* synerrstr[] = "unbalanced key/value pair", "unbalanced parenthesis/brace/bracket", "unexpected semicolon", + "stray backslash", "block expression expected", "block expression disallowed", "invalid lvalue" diff --git a/lib/hcl-prv.h b/lib/hcl-prv.h index f8d1c7f..bd94d21 100644 --- a/lib/hcl-prv.h +++ b/lib/hcl-prv.h @@ -635,6 +635,7 @@ struct hcl_flx_st_t enum hcl_flx_state_t { HCL_FLX_START, + HCL_FLX_BACKSLASHED, HCL_FLX_COMMENT, HCL_FLX_DELIM_TOKEN, HCL_FLX_HMARKED_TOKEN, /* hash-marked token */ diff --git a/lib/hcl.h b/lib/hcl.h index 732e070..61e9d50 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -165,6 +165,7 @@ enum hcl_synerrnum_t HCL_SYNERR_UNBALKV, /* unbalanced key/value pair */ HCL_SYNERR_UNBALPBB, /* unbalanced parenthesis/brace/bracket */ HCL_SYNERR_SEMICOLON, /* unexpected semicolon */ + HCL_SYNERR_BACKSLASH, /* stray backslash */ HCL_SYNERR_BLOCK, /* block expression expected */ HCL_SYNERR_BLOCKBANNED, /* block expression disallowed */ HCL_SYNERR_LVALUE /* invalid lvalue */ diff --git a/lib/read.c b/lib/read.c index cb81e65..fe9c5dc 100644 --- a/lib/read.c +++ b/lib/read.c @@ -1833,6 +1833,14 @@ static int flx_start (hcl_t* hcl, hcl_ooci_t c) FEED_WRAP_UP_WITH_CHARS (hcl, vocas[VOCA_EOF].str, vocas[VOCA_EOF].len, HCL_TOK_EOF); goto consumed; + case '\\': + FEED_CONTINUE_WITH_CHAR (hcl, c, HCL_FLX_BACKSLASHED); + goto consumed; + + case '\n': /* specify all linebreak chars */ + FEED_WRAP_UP_WITH_CHAR (hcl, c, HCL_TOK_SEMICOLON); + goto consumed; + /* this part is never hit because the semicolon sign is part of delim_tok_tab{} TODO: remove this part once the language spec is finalized to not require this case ';': @@ -1880,6 +1888,18 @@ not_consumed: return 0; } +static int flx_backslashed (hcl_t* hcl, hcl_ooci_t c) +{ + if (is_linebreak(c)) + { + FEED_CONTINUE (hcl, HCL_FLX_START); + return 1; /* consumed */ + } + + hcl_setsynerrbfmt (hcl, HCL_SYNERR_BACKSLASH, TOKEN_LOC(hcl), TOKEN_NAME(hcl), "stray backslash"); + return -1; +} + static int flx_comment (hcl_t* hcl, hcl_ooci_t c) { if (is_linebreak(c)) FEED_CONTINUE (hcl, HCL_FLX_START); @@ -2574,6 +2594,7 @@ static int feed_char (hcl_t* hcl, hcl_ooci_t c) switch (FLX_STATE(hcl)) { case HCL_FLX_START: return flx_start(hcl, c); + case HCL_FLX_BACKSLASHED: return flx_backslashed(hcl, c); case HCL_FLX_COMMENT: return flx_comment(hcl, c); case HCL_FLX_DELIM_TOKEN: return flx_delim_token(hcl, c); case HCL_FLX_HMARKED_TOKEN: return flx_hmarked_token(hcl, c); diff --git a/t/insta-01.hcl b/t/insta-01.hcl index 1274916..ee6c55f 100644 --- a/t/insta-01.hcl +++ b/t/insta-01.hcl @@ -30,22 +30,22 @@ defclass B ::: A | d e f | { }; set a ((B:newInstance 1 2 3):sum); -if (/= a 18) { printf "ERROR: a must be 18\n"; } +if (/= a 18) { printf "ERROR: a must be 18\n"; } \ else { printf "OK %d\n" a; }; set b (B:newInstance 2 3 4); set a (b:get-a); -if (/= a 4) {printf "ERROR: a must be 4\n" } +if (/= a 4) {printf "ERROR: a must be 4\n" } \ else { printf "OK %d\n" a }; set a (b:get-b); -if (/= a 6) { printf "ERROR: a must be 6\n" } +if (/= a 6) { printf "ERROR: a must be 6\n" } \ else { printf "OK %d\n" a }; set a (b:get-c); -if (/= a 8) { printf "ERROR: a must be 8\n" } +if (/= a 8) { printf "ERROR: a must be 8\n" } \ else {printf "OK %d\n" a }; set a (b:sum); -if (/= a 27) { printf "ERROR: a must be 27\n" } +if (/= a 27) { printf "ERROR: a must be 27\n" } \ else { printf "OK %d\n" a }; diff --git a/t/insta-02.hcl b/t/insta-02.hcl index fc90212..3152f1f 100644 --- a/t/insta-02.hcl +++ b/t/insta-02.hcl @@ -7,20 +7,20 @@ set t ( set X t; -if (nqv? t X) { printf "ERROR: t must point to X\n" } +if (nqv? t X) { printf "ERROR: t must point to X\n" } \ else { printf "OK: t points to X\n" }; set t ((t:make):get-x); -if (nqv? t 1234) { printf "ERROR: t must be 1234\n" } +if (nqv? t 1234) { printf "ERROR: t must be 1234\n" } \ else { printf "OK: t is %d\n" t }; set j #{ ((X:make):get-x): 9999, 4512: ((X: make): get-x) }; set v (dic.get j 1234); -if (nqv? v 9999) { printf "ERROR: v is not 9999\n" } +if (nqv? v 9999) { printf "ERROR: v is not 9999\n" } \ else { printf "OK: value is %d\n" v }; set v (dic.get j 4512); -if (nqv? v 1234) { printf "ERROR: v is not 1234\n" } +if (nqv? v 1234) { printf "ERROR: v is not 1234\n" } \ else { printf "OK: value is %d\n" v }; diff --git a/t/ret-01.hcl b/t/ret-01.hcl index 18eeef1..1a8100f 100644 --- a/t/ret-01.hcl +++ b/t/ret-01.hcl @@ -15,11 +15,11 @@ defun test-non-local-ret-1(k) { }; set a (test-non-local-ret-1 20); -if (/= a 28) { printf "ERROR: a must be 28\n" } +if (/= a 28) { printf "ERROR: a must be 28\n" } \ else { printf "OK %d\n" a }; set a (test-non-local-ret-1 21); -if (/= a 41) { printf "ERROR: a must be 41\n" } +if (/= a 41) { printf "ERROR: a must be 41\n" } \ else { printf "OK %d\n" a }; @@ -27,7 +27,7 @@ defun ff() { return 999 }; ## test a normal block return set a (ff); -if (/= a 999) { printf "ERROR: a must be 999\n" } +if (/= a 999) { printf "ERROR: a must be 999\n" } \ else { printf "OK %d\n" a }; ## return from top-level