diff --git a/lib/comp.c b/lib/comp.c index 9b9f2c1..7294b7b 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -1979,7 +1979,7 @@ static int compile_break (hcl_t* hcl, hcl_cnode_t* src) hcl_ooi_t i; HCL_ASSERT (hcl, HCL_CNODE_IS_CONS(src)); - HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(HCL_CNODE_CONS_CAR(src), HCL_SYNCODE_BREAK)); + HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(HCL_CNODE_CONS_CAR(src), HCL_SYNCODE_BREAK) || HCL_CNODE_IS_TYPED(HCL_CNODE_CONS_CAR(src), HCL_CNODE_BREAK)); cmd = HCL_CNODE_CONS_CAR(src); obj = HCL_CNODE_CONS_CDR(src); @@ -2094,7 +2094,7 @@ static int compile_continue (hcl_t* hcl, hcl_cnode_t* src) hcl_ooi_t i; HCL_ASSERT (hcl, HCL_CNODE_IS_CONS(src)); - HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(HCL_CNODE_CONS_CAR(src), HCL_SYNCODE_CONTINUE)); + HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(HCL_CNODE_CONS_CAR(src), HCL_SYNCODE_CONTINUE) || HCL_CNODE_IS_TYPED(HCL_CNODE_CONS_CAR(src), HCL_CNODE_CONTINUE)); cmd = HCL_CNODE_CONS_CAR(src); obj = HCL_CNODE_CONS_CDR(src); @@ -2553,7 +2553,7 @@ static int compile_class (hcl_t* hcl, hcl_cnode_t* src, int defclass) } else { - HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(cmd, HCL_SYNCODE_CLASS)); + HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(cmd, HCL_SYNCODE_CLASS) || HCL_CNODE_IS_TYPED(cmd, HCL_CNODE_CLASS)); if (obj && HCL_CNODE_IS_CONS(obj)) { @@ -2827,7 +2827,7 @@ static int compile_fun (hcl_t* hcl, hcl_cnode_t* src, int defun) { /* some inaccurate prior check if 'fun' is followed by an argument list * without a function name. stop-gap measure to support 'fun' in place of 'defun' */ - HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(cmd, HCL_SYNCODE_FUN)); + HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(cmd, HCL_SYNCODE_FUN) || HCL_CNODE_IS_TYPED(cmd, HCL_CNODE_FUN)); args = HCL_CNODE_CONS_CAR(obj); if (!HCL_CNODE_IS_ELIST_CONCODED(args, HCL_CONCODE_XLIST) && !HCL_CNODE_IS_CONS_CONCODED(args, HCL_CONCODE_XLIST)) @@ -2959,7 +2959,7 @@ static int compile_fun (hcl_t* hcl, hcl_cnode_t* src, int defun) } else { - HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(cmd, HCL_SYNCODE_FUN)); + HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(cmd, HCL_SYNCODE_FUN) || HCL_CNODE_IS_TYPED(cmd, HCL_CNODE_FUN)); defun_name = HCL_NULL; } @@ -3756,7 +3756,9 @@ static int compile_while (hcl_t* hcl, hcl_cnode_t* src, int next_cop) HCL_ASSERT (hcl, HCL_CNODE_IS_CONS(src)); HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(HCL_CNODE_CONS_CAR(src), HCL_SYNCODE_UNTIL) || - HCL_CNODE_IS_SYMBOL_SYNCODED(HCL_CNODE_CONS_CAR(src), HCL_SYNCODE_WHILE)); + HCL_CNODE_IS_SYMBOL_SYNCODED(HCL_CNODE_CONS_CAR(src), HCL_SYNCODE_WHILE) || + HCL_CNODE_IS_TYPED(HCL_CNODE_CONS_CAR(src), HCL_CNODE_UNTIL) || + HCL_CNODE_IS_TYPED(HCL_CNODE_CONS_CAR(src), HCL_CNODE_WHILE)); HCL_ASSERT (hcl, next_cop == COP_POST_UNTIL_COND || next_cop == COP_POST_WHILE_COND); cmd = HCL_CNODE_CONS_CAR(src); /* while or until itself */ @@ -3901,34 +3903,58 @@ static int compile_cons_xlist_expression (hcl_t* hcl, hcl_cnode_t* obj, int nret HCL_ASSERT (hcl, HCL_CNODE_IS_CONS_CONCODED(obj, HCL_CONCODE_XLIST)); car = HCL_CNODE_CONS_CAR(obj); - if (HCL_CNODE_IS_TYPED(car, HCL_CNODE_IF)) + switch (HCL_CNODE_GET_TYPE(car)) { - if (compile_if(hcl, obj) <= -1) return -1; + case HCL_CNODE_CLASS: + if (compile_class(hcl, obj, 0) <= -1) return -1; + goto done; + + case HCL_CNODE_FUN: + if (compile_fun(hcl, obj, 0) <= -1) return -1; + goto done; + + case HCL_CNODE_IF: + if (compile_if(hcl, obj) <= -1) return -1; + goto done; + + case HCL_CNODE_ELIF: + hcl_setsynerrbfmt (hcl, HCL_SYNERR_ELSE, HCL_CNODE_GET_LOC(car), HCL_CNODE_GET_TOK(car), "else without if"); + return -1; + + case HCL_CNODE_ELSE: + hcl_setsynerrbfmt (hcl, HCL_SYNERR_ELIF, HCL_CNODE_GET_LOC(car), HCL_CNODE_GET_TOK(car), "elif without if"); + return -1; + + case HCL_CNODE_THROW: + if (compile_throw(hcl, obj) <= -1) return -1; + goto done; + + case HCL_CNODE_TRY: + if (compile_try(hcl, obj) <= -1) return -1; + goto done; + + case HCL_CNODE_CATCH: + hcl_setsynerrbfmt (hcl, HCL_SYNERR_CATCH, HCL_CNODE_GET_LOC(car), HCL_CNODE_GET_TOK(car), "catch without try"); + return -1; + + case HCL_CNODE_BREAK: + if (compile_break(hcl, obj) <= -1) return -1; + goto done; + + case HCL_CNODE_CONTINUE: + if (compile_continue(hcl, obj) <= -1) return -1; + goto done; + + case HCL_CNODE_UNTIL: + if (compile_while(hcl, obj, COP_POST_UNTIL_COND) <= -1) return -1; + goto done; + + case HCL_CNODE_WHILE: + if (compile_while(hcl, obj, COP_POST_WHILE_COND) <= -1) return -1; + goto done; } - else if (HCL_CNODE_IS_TYPED(car, HCL_CNODE_ELIF)) - { - hcl_setsynerrbfmt (hcl, HCL_SYNERR_ELSE, HCL_CNODE_GET_LOC(car), HCL_CNODE_GET_TOK(car), "else without if"); - return -1; - } - else if (HCL_CNODE_IS_TYPED(car, HCL_CNODE_ELSE)) - { - hcl_setsynerrbfmt (hcl, HCL_SYNERR_ELIF, HCL_CNODE_GET_LOC(car), HCL_CNODE_GET_TOK(car), "elif without if"); - return -1; - } - else if (HCL_CNODE_IS_TYPED(car, HCL_CNODE_THROW)) - { - if (compile_throw(hcl, obj) <= -1) return -1; - } - else if (HCL_CNODE_IS_TYPED(car, HCL_CNODE_TRY)) - { - if (compile_try(hcl, obj) <= -1) return -1; - } - else if (HCL_CNODE_IS_TYPED(car, HCL_CNODE_CATCH)) - { - hcl_setsynerrbfmt (hcl, HCL_SYNERR_CATCH, HCL_CNODE_GET_LOC(car), HCL_CNODE_GET_TOK(car), "catch without try"); - return -1; - } - else if (HCL_CNODE_IS_SYMBOL(car) && (syncode = HCL_CNODE_SYMBOL_SYNCODE(car))) + + if (HCL_CNODE_IS_SYMBOL(car) && (syncode = HCL_CNODE_SYMBOL_SYNCODE(car))) { if (nrets > 0) { @@ -4133,6 +4159,7 @@ static int compile_cons_xlist_expression (hcl_t* hcl, hcl_cnode_t* obj, int nret return -1; } +done: return 0; } diff --git a/lib/hcl-prv.h b/lib/hcl-prv.h index e30cc1a..bb775ca 100644 --- a/lib/hcl-prv.h +++ b/lib/hcl-prv.h @@ -301,12 +301,18 @@ enum hcl_tok_type_t HCL_TOK_SELF, HCL_TOK_SUPER, + HCL_TOK_CLASS, + HCL_TOK_FUN, HCL_TOK_IF, HCL_TOK_ELIF, HCL_TOK_ELSE, HCL_TOK_THROW, HCL_TOK_TRY, HCL_TOK_CATCH, + HCL_TOK_BREAK, + HCL_TOK_CONTINUE, + HCL_TOK_UNTIL, + HCL_TOK_WHILE, HCL_TOK_BINOP, HCL_TOK_IDENT, @@ -388,12 +394,19 @@ enum hcl_cnode_type_t HCL_CNODE_FALSE, HCL_CNODE_SELF, HCL_CNODE_SUPER, + + HCL_CNODE_CLASS, + HCL_CNODE_FUN, HCL_CNODE_IF, HCL_CNODE_ELIF, HCL_CNODE_ELSE, HCL_CNODE_THROW, HCL_CNODE_TRY, HCL_CNODE_CATCH, + HCL_CNODE_BREAK, + HCL_CNODE_CONTINUE, + HCL_CNODE_UNTIL, + HCL_CNODE_WHILE, HCL_CNODE_ELLIPSIS, HCL_CNODE_TRPCOLONS, diff --git a/lib/read.c b/lib/read.c index 73dbe4c..991cd84 100644 --- a/lib/read.c +++ b/lib/read.c @@ -58,12 +58,18 @@ static struct voca_t { 4, { 's','e','l','f' } }, { 5, { 's','u','p','e','r' } }, + { 5, { 'c','l','a','s','s' } }, + { 3, { 'f','u','n' } }, { 2, { 'i','f' } }, { 4, { 'e','l','i','f' } }, { 4, { 'e','l','s','e' } }, { 5, { 't','h','r','o','w' } }, { 3, { 't','r','y' } }, { 5, { 'c','a','t','c','h' } }, + { 5, { 'b','r','e','a','k' } }, + { 8, { 'c','o','n','t','i','n','u','e' } }, + { 5, { 'u','n','t','i','l' } }, + { 5, { 'w','h','i','l','e' } }, { 3, { 's','e','t' } }, { 5, { 's','e','t','-','r' } }, @@ -107,12 +113,18 @@ enum voca_id_t VOCA_KW_SELF, VOCA_KW_SUPER, + VOCA_KW_CLASS, + VOCA_KW_FUN, VOCA_KW_IF, VOCA_KW_ELIF, VOCA_KW_ELSE, VOCA_KW_THROW, VOCA_KW_TRY, VOCA_KW_CATCH, + VOCA_KW_BREAK, + VOCA_KW_CONTINUE, + VOCA_KW_UNTIL, + VOCA_KW_WHILE, VOCA_SYM_SET, VOCA_SYM_SET_R, @@ -417,18 +429,24 @@ static hcl_tok_type_t classify_ident_token (hcl_t* hcl, const hcl_oocs_t* v) hcl_tok_type_t type; } tab[] = { - { VOCA_KW_NIL, HCL_TOK_NIL }, - { VOCA_KW_TRUE, HCL_TOK_TRUE }, - { VOCA_KW_FALSE, HCL_TOK_FALSE }, - { VOCA_KW_SELF, HCL_TOK_SELF }, - { VOCA_KW_SUPER, HCL_TOK_SUPER }, + { VOCA_KW_NIL, HCL_TOK_NIL }, + { VOCA_KW_TRUE, HCL_TOK_TRUE }, + { VOCA_KW_FALSE, HCL_TOK_FALSE }, + { VOCA_KW_SELF, HCL_TOK_SELF }, + { VOCA_KW_SUPER, HCL_TOK_SUPER }, - { VOCA_KW_IF, HCL_TOK_IF }, - { VOCA_KW_ELIF, HCL_TOK_ELIF }, - { VOCA_KW_ELSE, HCL_TOK_ELSE }, - { VOCA_KW_THROW, HCL_TOK_THROW }, - { VOCA_KW_TRY, HCL_TOK_TRY }, - { VOCA_KW_CATCH, HCL_TOK_CATCH } + { VOCA_KW_CLASS, HCL_TOK_CLASS }, + { VOCA_KW_FUN, HCL_TOK_FUN }, + { VOCA_KW_IF, HCL_TOK_IF }, + { VOCA_KW_ELIF, HCL_TOK_ELIF }, + { VOCA_KW_ELSE, HCL_TOK_ELSE }, + { VOCA_KW_THROW, HCL_TOK_THROW }, + { VOCA_KW_TRY, HCL_TOK_TRY }, + { VOCA_KW_CATCH, HCL_TOK_CATCH }, + { VOCA_KW_BREAK, HCL_TOK_BREAK }, + { VOCA_KW_CONTINUE, HCL_TOK_CONTINUE }, + { VOCA_KW_UNTIL, HCL_TOK_UNTIL }, + { VOCA_KW_WHILE, HCL_TOK_WHILE } }; for (i = 0; i < HCL_COUNTOF(tab); i++) @@ -823,7 +841,8 @@ static HCL_INLINE int can_colon_list (hcl_t* hcl) * implemented elsewhere because ':' has dual use while '::' or ':*' are * independent tokens */ if (HCL_CNODE_IS_SYMBOL_SYNCODED(HCL_CNODE_CONS_CAR(rstl->head), HCL_SYNCODE_DEFUN) || - HCL_CNODE_IS_SYMBOL_SYNCODED(HCL_CNODE_CONS_CAR(rstl->head), HCL_SYNCODE_FUN)) + HCL_CNODE_IS_SYMBOL_SYNCODED(HCL_CNODE_CONS_CAR(rstl->head), HCL_SYNCODE_FUN) || + HCL_CNODE_IS_TYPED(HCL_CNODE_CONS_CAR(rstl->head), HCL_CNODE_FUN)) { if (rstl->count == 2) return 2; } @@ -1245,12 +1264,18 @@ static hcl_cnode_type_t kw_to_cnode_type (int tok_type) HCL_CNODE_SELF, HCL_CNODE_SUPER, + HCL_CNODE_CLASS, + HCL_CNODE_FUN, HCL_CNODE_IF, HCL_CNODE_ELIF, HCL_CNODE_ELSE, HCL_CNODE_THROW, HCL_CNODE_TRY, HCL_CNODE_CATCH, + HCL_CNODE_BREAK, + HCL_CNODE_CONTINUE, + HCL_CNODE_UNTIL, + HCL_CNODE_WHILE }; return mapping[tok_type - HCL_TOK_NIL]; @@ -1657,12 +1682,19 @@ static int feed_process_token (hcl_t* hcl) case HCL_TOK_FALSE: case HCL_TOK_SELF: case HCL_TOK_SUPER: + + case HCL_TOK_CLASS: + case HCL_TOK_FUN: case HCL_TOK_IF: case HCL_TOK_ELIF: case HCL_TOK_ELSE: case HCL_TOK_THROW: case HCL_TOK_TRY: case HCL_TOK_CATCH: + case HCL_TOK_BREAK: + case HCL_TOK_CONTINUE: + case HCL_TOK_UNTIL: + case HCL_TOK_WHILE: frd->obj = hcl_makecnode(hcl, kw_to_cnode_type(TOKEN_TYPE(hcl)), 0, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); goto auto_xlist;