From ed978e6f2d99c1190eb4a9352365a1943531c2b3 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Thu, 3 Oct 2024 17:21:08 +0900 Subject: [PATCH] removed defclass --- lib/comp.c | 149 +++++++++++++++++++++++++---------------------- lib/exec.c | 14 ++--- lib/gc.c | 1 - lib/hcl-prv.h | 14 +++-- lib/hcl.h | 2 - t/Makefile.am | 1 - t/Makefile.in | 1 - t/class-5001.err | 37 ++++++++++++ t/fun-01.hcl | 2 +- t/retvar-01.hcl | 2 +- t/var-5001.err | 2 +- t/var-5003.err | 3 - t/var-5004.err | 8 +-- 13 files changed, 139 insertions(+), 97 deletions(-) delete mode 100644 t/var-5003.err diff --git a/lib/comp.c b/lib/comp.c index b2a2790..51256c0 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -2486,11 +2486,11 @@ static HCL_INLINE int compile_else (hcl_t* hcl) /* (class A - | x y | ; instance variables - :: | x y z | ; class variables <--- how to initialize the class variables??? + [ x y ] ## instance variables + :: | x y z | ## class variables <--- how to initialize the class variables??? - ; everything inside defclass after the variable declarations are normal expressions. - ; however, the resolution of some variables will fall under the enclosing class. + ## everything inside class after the variable declarations are normal expressions. + ## however, the resolution of some variables will fall under the enclosing class. (set x 20) (printf "normal statement ....\n"); @@ -2511,7 +2511,7 @@ static HCL_INLINE int compile_else (hcl_t* hcl) */ -static int compile_class (hcl_t* hcl, hcl_cnode_t* src, int defclass) +static int compile_class (hcl_t* hcl, hcl_cnode_t* src) { hcl_cframe_t* cf; hcl_cnode_t* cmd, * obj, * tmp; @@ -2521,63 +2521,58 @@ static int compile_class (hcl_t* hcl, hcl_cnode_t* src, int defclass) cmd = HCL_CNODE_CONS_CAR(src); obj = HCL_CNODE_CONS_CDR(src); - if (defclass) + class_name = HCL_NULL; + + HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(cmd, HCL_SYNCODE_CLASS) || HCL_CNODE_IS_TYPED(cmd, HCL_CNODE_CLASS)); + +/* TODO: attribute lsit */ + + if (obj /*&& HCL_CNODE_IS_CONS(obj)*/) { - /* defclass must be followed by an explicit class name */ - HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(cmd, HCL_SYNCODE_DEFCLASS)); + HCL_ASSERT (hcl, HCL_CNODE_IS_CONS(obj)); - class_as_defclass: - if (!obj) + tmp = HCL_CNODE_CONS_CAR(obj); + if (HCL_CNODE_IS_FOR_DATA_SIMPLE(tmp) || HCL_CNODE_IS_FOR_LANG(tmp)) { - hcl_setsynerrbfmt (hcl, HCL_SYNERR_NAME, HCL_CNODE_GET_LOC(src), HCL_NULL, "no class name in %.*js", HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); - return -1; - } - else if (!HCL_CNODE_IS_CONS(obj)) - { - hcl_setsynerrbfmt (hcl, HCL_SYNERR_DOTBANNED, HCL_CNODE_GET_LOC(obj), HCL_CNODE_GET_TOK(obj), "redundant cdr in %.*js", HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); - return -1; - } - - class_name = HCL_CNODE_CONS_CAR(obj); - if (!HCL_CNODE_IS_SYMBOL(class_name)) - { - hcl_setsynerrbfmt ( - hcl, HCL_SYNERR_VARNAME, HCL_CNODE_GET_LOC(class_name), HCL_CNODE_GET_TOK(class_name), - "class name not symbol in %.*js", HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); - return -1; - } - - if (HCL_CNODE_SYMBOL_SYNCODE(class_name)) /*|| HCL_OBJ_GET_FLAGS_KERNEL(class_name) >= 1) */ - { - hcl_setsynerrbfmt ( - hcl, HCL_SYNERR_BANNEDVARNAME, HCL_CNODE_GET_LOC(class_name), HCL_CNODE_GET_TOK(class_name), - "special symbol not to be used as class name"); - return -1; - } - - obj = HCL_CNODE_CONS_CDR(obj); - } - else - { - 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)) - { - class_name = HCL_CNODE_CONS_CAR(obj); - if (HCL_CNODE_IS_SYMBOL_PLAIN(class_name)) + if (!HCL_CNODE_IS_SYMBOL_PLAIN_IDENT(tmp)) { - /* to handle 'class' in place of 'defclass' */ - defclass = 1; - goto class_as_defclass; + hcl_setsynerrbfmt ( + hcl, HCL_SYNERR_VARNAME, HCL_CNODE_GET_LOC(tmp), HCL_NULL, + "invalid class name '%.*js' for '%.*js'", + HCL_CNODE_GET_TOKLEN(tmp), HCL_CNODE_GET_TOKPTR(tmp), + HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); + return -1; } - } - class_name = HCL_NULL; + if (HCL_CNODE_SYMBOL_SYNCODE(tmp)) /*|| HCL_OBJ_GET_FLAGS_KERNEL(tmp) >= 1) */ + { + hcl_setsynerrbfmt ( + hcl, HCL_SYNERR_BANNEDVARNAME, HCL_CNODE_GET_LOC(tmp), HCL_NULL, + "special symbol '%.*js' used as class name", + HCL_CNODE_GET_TOKLEN(tmp), HCL_CNODE_GET_TOKPTR(tmp)); + return -1; + } + + class_name = tmp; + obj = HCL_CNODE_CONS_CDR(obj); + } } if (!obj) { - hcl_setsynerrbfmt (hcl, HCL_SYNERR_BLOCK, HCL_CNODE_GET_LOC(src), HCL_NULL, "no class body", HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); + if (class_name) + { + hcl_setsynerrbfmt ( + hcl, HCL_SYNERR_BLOCK, HCL_CNODE_GET_LOC(src), HCL_NULL, + "no class body defined for '%.*js'", + HCL_CNODE_GET_TOKLEN(class_name), HCL_CNODE_GET_TOKPTR(class_name)); + } + else + { + hcl_setsynerrbfmt ( + hcl, HCL_SYNERR_BLOCK, HCL_CNODE_GET_LOC(src), HCL_NULL, + "no class body defined for unnamed class"); + } return -1; } @@ -2590,8 +2585,10 @@ static int compile_class (hcl_t* hcl, hcl_cnode_t* src, int defclass) obj = HCL_CNODE_CONS_CDR(obj); if (!obj || !HCL_CNODE_IS_CONS(obj)) { - hcl_setsynerrbfmt (hcl, HCL_SYNERR_EOX, HCL_CNODE_GET_LOC(marker), HCL_NULL, - "no expression or declaration after %.*js", HCL_CNODE_GET_TOKLEN(marker), HCL_CNODE_GET_TOKPTR(marker)); + hcl_setsynerrbfmt ( + hcl, HCL_SYNERR_EOX, HCL_CNODE_GET_LOC(marker), HCL_NULL, + "no expression or declaration after %.*js", + HCL_CNODE_GET_TOKLEN(marker), HCL_CNODE_GET_TOKPTR(marker)); return -1; } @@ -2599,8 +2596,23 @@ static int compile_class (hcl_t* hcl, hcl_cnode_t* src, int defclass) superclass = HCL_CNODE_CONS_CAR(obj); if (!HCL_CNODE_IS_SYMBOL_PLAIN(superclass)) { - hcl_setsynerrbfmt (hcl, HCL_SYNERR_NAME, HCL_CNODE_GET_LOC(marker), HCL_NULL, - "no valid superclass name found after %.*js", HCL_CNODE_GET_TOKLEN(marker), HCL_CNODE_GET_TOKPTR(marker)); + if (HCL_CNODE_IS_FOR_DATA_SIMPLE(superclass) || HCL_CNODE_IS_FOR_LANG(superclass)) + { + hcl_setsynerrbfmt ( + hcl, HCL_SYNERR_NAME, HCL_CNODE_GET_LOC(marker), HCL_NULL, + "invalid superclass name '%.*js' after '%.*js' for '%.*js'", + HCL_CNODE_GET_TOKLEN(superclass), HCL_CNODE_GET_TOKPTR(superclass), + HCL_CNODE_GET_TOKLEN(marker), HCL_CNODE_GET_TOKPTR(marker), + HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); + } + else + { + hcl_setsynerrbfmt ( + hcl, HCL_SYNERR_NAME, HCL_CNODE_GET_LOC(marker), HCL_NULL, + "no valid superclass name after '%.*js' for '%.*js'", + HCL_CNODE_GET_TOKLEN(marker), HCL_CNODE_GET_TOKPTR(marker), + HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); + } return -1; } @@ -2613,7 +2625,6 @@ static int compile_class (hcl_t* hcl, hcl_cnode_t* src, int defclass) superclass = HCL_NULL; } - if (class_name) { #if 0 @@ -2836,7 +2847,7 @@ static int check_fun_attr_list ( { hcl_setsynerrbfmt ( hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(attr_list), HCL_NULL, - "empty attribute list for '%.*js:%.*js' for '%.*js'", + "empty attribute list on '%.*js:%.*js' for '%.*js'", HCL_CNODE_GET_TOKLEN(class_name), HCL_CNODE_GET_TOKPTR(class_name), HCL_CNODE_GET_TOKLEN(fun_name), HCL_CNODE_GET_TOKPTR(fun_name), HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); @@ -2845,7 +2856,7 @@ static int check_fun_attr_list ( { hcl_setsynerrbfmt ( hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(attr_list), HCL_NULL, - "empty attribute list for '%.*js' for '%.*js'", + "empty attribute list on '%.*js' for '%.*js'", HCL_CNODE_GET_TOKLEN(fun_name), HCL_CNODE_GET_TOKPTR(fun_name), HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); } @@ -2853,7 +2864,7 @@ static int check_fun_attr_list ( { hcl_setsynerrbfmt ( hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(attr_list), HCL_NULL, - "empty attribute list after unamed function for '%.*js'", + "empty attribute list on unamed function for '%.*js'", HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); } return -1; @@ -2954,9 +2965,9 @@ static int compile_fun (hcl_t* hcl, hcl_cnode_t* src) HCL_ASSERT (hcl, HCL_CNODE_IS_CONS(next)); /* fun (arg..) - * fun name (arg..) - * fun(#attr..) name(arg..) - * fun(#attr..) (arg..) + * fun name(arg..) + * fun(#attr..) name(arg..) ## valid as class method, not valid as plain function + * fun(#attr..) (arg..) ## not valid. not attribute list for unamed functions * fun(#attr..) class:name(arg..) */ @@ -3179,14 +3190,14 @@ static int compile_fun (hcl_t* hcl, hcl_cnode_t* src) { hcl_setsynerrbfmt ( hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(attr_list), HCL_NULL, - "unsupported attribute list for plain function '%.*js'", + "attribute list prohibited on plain function '%.*js'", HCL_CNODE_GET_TOKLEN(fun_name), HCL_CNODE_GET_TOKPTR(fun_name)); } else { hcl_setsynerrbfmt ( hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(attr_list), HCL_NULL, - "unsupported attribute list for unamed function for '%.*js'", + "attribute list prohibited on unamed function for '%.*js'", HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); } return -1; @@ -4297,7 +4308,7 @@ static int compile_cons_xlist_expression (hcl_t* hcl, hcl_cnode_t* obj, int nret switch (HCL_CNODE_GET_TYPE(car)) { case HCL_CNODE_CLASS: - if (compile_class(hcl, obj, 0) <= -1) return -1; + if (compile_class(hcl, obj) <= -1) return -1; goto done; case HCL_CNODE_FUN: @@ -4383,7 +4394,7 @@ static int compile_cons_xlist_expression (hcl_t* hcl, hcl_cnode_t* obj, int nret return -1; case HCL_SYNCODE_CLASS: - if (compile_class(hcl, obj, 0) <= -1) return -1; + if (compile_class(hcl, obj) <= -1) return -1; break; case HCL_SYNCODE_CONTINUE: @@ -4391,10 +4402,6 @@ static int compile_cons_xlist_expression (hcl_t* hcl, hcl_cnode_t* obj, int nret if (compile_continue(hcl, obj) <= -1) return -1; break; - case HCL_SYNCODE_DEFCLASS: - if (compile_class(hcl, obj, 1) <= -1) return -1; - break; - case HCL_SYNCODE_DO: if (compile_do(hcl, obj) <= -1) return -1; break; diff --git a/lib/exec.c b/lib/exec.c index a09b68b..1f165bd 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -2406,7 +2406,7 @@ static HCL_INLINE int do_throw (hcl_t* hcl, hcl_oop_t val, hcl_ooi_t ip) /* discard unfinished class definitions for the exception thrown. * * (try - * (defclass X + * (class X * (throw "exception") * catch (x) * (printf "exception %O\n" x) @@ -3016,7 +3016,7 @@ static HCL_INLINE int do_return_from_block (hcl_t* hcl) * respectively. [CASE 1] - (defclass X + (class X ; .... (return 20) ; the class defintion isn't over, but return is executed, ; .... @@ -3024,7 +3024,7 @@ static HCL_INLINE int do_return_from_block (hcl_t* hcl) [CASE 2] (try - (defclass C + (class C (return 200) (printf "============================\n")) catch (e) @@ -3032,7 +3032,7 @@ static HCL_INLINE int do_return_from_block (hcl_t* hcl) ) [CASE 3] - (defclass C + (class C (try (return 99) catch (e) @@ -3043,7 +3043,7 @@ static HCL_INLINE int do_return_from_block (hcl_t* hcl) [CASE 4] (try - (defclass C + (class C (try (return 99) catch (e) @@ -3057,8 +3057,8 @@ static HCL_INLINE int do_return_from_block (hcl_t* hcl) [CASE 5] (try - (defclass D - (defclass C + (class D + (class C (try (return 99) catch (e) diff --git a/lib/gc.c b/lib/gc.c index 5222a65..4727111 100644 --- a/lib/gc.c +++ b/lib/gc.c @@ -42,7 +42,6 @@ static struct { 5, { 'c','a','t','c','h' }, HCL_SYNCODE_CATCH, HCL_OFFSETOF(hcl_t,s_catch) }, { 5, { 'c','l','a','s','s' }, HCL_SYNCODE_CLASS, HCL_OFFSETOF(hcl_t,s_class) }, { 8, { 'c','o','n','t','i','n','u','e' }, HCL_SYNCODE_CONTINUE, HCL_OFFSETOF(hcl_t,s_continue) }, - { 8, { 'd','e','f','c','l','a','s','s' }, HCL_SYNCODE_DEFCLASS, HCL_OFFSETOF(hcl_t,s_defclass) }, { 2, { 'd','o' }, HCL_SYNCODE_DO, HCL_OFFSETOF(hcl_t,s_do) }, { 4, { 'e','l','i','f' }, HCL_SYNCODE_ELIF, HCL_OFFSETOF(hcl_t,s_elif) }, { 4, { 'e','l','s','e' }, HCL_SYNCODE_ELSE, HCL_OFFSETOF(hcl_t,s_else) }, diff --git a/lib/hcl-prv.h b/lib/hcl-prv.h index a424a29..eb4987b 100644 --- a/lib/hcl-prv.h +++ b/lib/hcl-prv.h @@ -391,13 +391,13 @@ enum hcl_cnode_type_t HCL_CNODE_RADNUMLIT, HCL_CNODE_FPDECLIT, HCL_CNODE_SMPTRLIT, - HCL_CNODE_ERRLIT, + HCL_CNODE_ERRLIT, /* last item for HCL_CNODE_IS_FOR_DATA_LITERAL */ HCL_CNODE_NIL, HCL_CNODE_TRUE, HCL_CNODE_FALSE, HCL_CNODE_SELF, - HCL_CNODE_SUPER, + HCL_CNODE_SUPER, /* last item for HCL_CNODE_IS_FOR_DATA_SIMPLE */ HCL_CNODE_CONS, HCL_CNODE_ELIST, /* empty list */ @@ -409,7 +409,7 @@ enum hcl_cnode_type_t /* the cnode types from here don't represent actual data. * these represent syntactical elements of the language only. */ - HCL_CNODE_CLASS, + HCL_CNODE_CLASS, /* first item for HCL_CNODE_IS_FOR_LANG */ HCL_CNODE_FUN, HCL_CNODE_DO, HCL_CNODE_IF, @@ -423,7 +423,7 @@ enum hcl_cnode_type_t HCL_CNODE_UNTIL, HCL_CNODE_WHILE, HCL_CNODE_RETURN, - HCL_CNODE_REVERT, + HCL_CNODE_REVERT, /* language item for HCL_CODE_IS_FOR_LANG */ HCL_CNODE_ELLIPSIS, /* ... */ HCL_CNODE_TRPCOLONS, /* ::: */ @@ -449,6 +449,12 @@ typedef enum hcl_cnode_flag_t hcl_cnode_flag_t; #define HCL_CNODE_IS_TYPED(x, _type) ((x)->cn_type == _type) #define HCL_CNODE_IS_FOR_DATA(x) ((x)->cn_type <= HCL_CNODE_SHELL) +#define HCL_CNODE_IS_FOR_DATA_SIMPLE(x) ((x)->cn_type <= HCL_CNODE_SUPER) +#define HCL_CNODE_IS_FOR_DATA_LITERAL(x) ((x)->cn_type <= HCL_CNODE_ERRLIT) + +/* words to compose the language itself. + * the words pointing to data items(e.g. super, self, nil, true, false) are excluded */ +#define HCL_CNODE_IS_FOR_LANG(x)((x)->cn_type >= HCL_CNODE_CLASS && (x)->cn_type <= HCL_CNODE_REVERT) #define HCL_CNODE_IS_ELLIPSIS(x) ((x)->cn_type == HCL_CNODE_ELLIPSIS) #define HCL_CNODE_IS_TRPCOLONS(x) ((x)->cn_type == HCL_CNODE_TRPCOLONS) diff --git a/lib/hcl.h b/lib/hcl.h index e3fd835..d556e84 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -1685,7 +1685,6 @@ struct hcl_t hcl_oop_t s_catch; /* symbol */ hcl_oop_t s_class; /* symbol */ hcl_oop_t s_continue; /* symbol */ - hcl_oop_t s_defclass; /* symbol */ hcl_oop_t s_defun; /* symbol */ hcl_oop_t s_do; /* symbol */ hcl_oop_t s_elif; /* symbol */ @@ -2055,7 +2054,6 @@ enum hcl_syncode_t HCL_SYNCODE_CATCH, HCL_SYNCODE_CLASS, HCL_SYNCODE_CONTINUE, - HCL_SYNCODE_DEFCLASS, HCL_SYNCODE_DO, HCL_SYNCODE_ELIF, HCL_SYNCODE_ELSE, diff --git a/t/Makefile.am b/t/Makefile.am index 8a2d316..d7270d2 100644 --- a/t/Makefile.am +++ b/t/Makefile.am @@ -21,7 +21,6 @@ check_ERRORS = \ mlist-5001.err \ var-5001.err \ var-5002.err \ - var-5003.err \ var-5004.err ##noinst_SCRIPTS = $(check_SCRIPTS) diff --git a/t/Makefile.in b/t/Makefile.in index fd311e5..63a84bb 100644 --- a/t/Makefile.in +++ b/t/Makefile.in @@ -493,7 +493,6 @@ check_ERRORS = \ mlist-5001.err \ var-5001.err \ var-5002.err \ - var-5003.err \ var-5004.err EXTRA_DIST = $(check_SCRIPTS) $(check_ERRORS) diff --git a/t/class-5001.err b/t/class-5001.err index 4fc314a..b403103 100644 --- a/t/class-5001.err +++ b/t/class-5001.err @@ -15,6 +15,43 @@ class B + ##ERROR: syntax error - prohibited binary selector '+' --- +class A [ a ] { + | j | ##ERROR: syntax error - variable declaration disallowed in class init scope +} + +--- + +class 10 [ a ] { ##ERROR: syntax error - invalid class name '10' for 'class' +} + +--- + +class class { ##ERROR: syntax error - invalid class name 'class' for 'class' +} + +--- + +class super.a [ a ] { ##ERROR: syntax error - invalid class name 'super.a' for 'class' +} + +--- + +class a :: 20 { ##ERROR: syntax error - invalid superclass name '20' after '::' for 'class' +} + +--- + +class a :: class { ##ERROR: syntax error - invalid superclass name 'class' after '::' for 'class' + +} + +--- + +class a :: #(1 2) { ##ERROR: syntax error - no valid superclass name after '::' for 'class' +} + +--- + J := 11 class B { if (== J 10) { diff --git a/t/fun-01.hcl b/t/fun-01.hcl index 2c13af2..c99f580 100644 --- a/t/fun-01.hcl +++ b/t/fun-01.hcl @@ -96,7 +96,7 @@ if (== y 29) { ## -------------------------------------- -defclass A [ a b c ] { +class A [ a b c ] { fun(#ci) newInstance(x y z) { set a x set b y diff --git a/t/retvar-01.hcl b/t/retvar-01.hcl index 9e9a4a1..9a644c4 100644 --- a/t/retvar-01.hcl +++ b/t/retvar-01.hcl @@ -31,7 +31,7 @@ ## test return variables in message sends - defclass B [ [X1 X2] ] { + class B [ [X1 X2] ] { set X1 999; set X2 888; diff --git a/t/var-5001.err b/t/var-5001.err index 6421519..2d64d67 100644 --- a/t/var-5001.err +++ b/t/var-5001.err @@ -1,4 +1,4 @@ -defclass A [ a ] { +class A [ a ] { fun(#ci) init1() { | b | set b (+ 1 2); diff --git a/t/var-5003.err b/t/var-5003.err deleted file mode 100644 index 0f1b1bf..0000000 --- a/t/var-5003.err +++ /dev/null @@ -1,3 +0,0 @@ -defclass A [ a ] { - | j | ##ERROR: syntax error - variable declaration disallowed in class init scope -}; diff --git a/t/var-5004.err b/t/var-5004.err index 25f6d1e..b7893c1 100644 --- a/t/var-5004.err +++ b/t/var-5004.err @@ -79,22 +79,22 @@ fun fun fun1() { ##ERROR: syntax error - invalid function name 'fun' for 'fun' --- -fun(#ci) fun1() { ##ERROR: syntax error - unsupported attribute list for plain function 'fun1' +fun(#ci) fun1() { ##ERROR: syntax error - attribute list prohibited on plain function 'fun1' } --- -fun() () { ##ERROR: syntax error - unsupported attribute list for unamed function for 'fun' +fun() () { ##ERROR: syntax error - attribute list prohibited on unamed function for 'fun' } --- -fun() X:y() { ##ERROR: syntax error - empty attribute list for 'X:y' for 'fun' +fun() X:y() { ##ERROR: syntax error - empty attribute list on 'X:y' for 'fun' } --- class X { - fun() y() { ##ERROR: syntax error - empty attribute list for 'y' for 'fun' + fun() y() { ##ERROR: syntax error - empty attribute list on 'y' for 'fun' } }