diff --git a/lib/comp.c b/lib/comp.c index ebcfd3e..3329bf4 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -2725,6 +2725,8 @@ static int compile_lambda (hcl_t* hcl, hcl_cnode_t* src, int defun) cmd = HCL_CNODE_CONS_CAR(src); obj = HCL_CNODE_CONS_CDR(src); + class_name = HCL_NULL; + if (defun) { /* defun must be followed by an explicit function name */ @@ -2761,9 +2763,46 @@ static int compile_lambda (hcl_t* hcl, hcl_cnode_t* src, int defun) } else { + if (HCL_CNODE_IS_SYMBOL_PLAIN(defun_name)) + { + /* probably this form - defun XXX:yyy () ... + * the class name must not be specified in the class initialization scope */ + hcl_cnode_t* tmp; + tmp = HCL_CNODE_CONS_CDR(obj); + if (tmp && HCL_CNODE_IS_CONS(tmp)) + { + tmp = HCL_CNODE_CONS_CAR(tmp); + if (HCL_CNODE_IS_SYMBOL_PLAIN(tmp)) + { + hcl_setsynerrbfmt ( + hcl, HCL_SYNERR_VARNAME, + HCL_CNODE_GET_LOC(defun_name), HCL_CNODE_GET_TOK(defun_name), + "function name not valid in %.*js", + HCL_CNODE_GET_TOKLEN(tmp), HCL_CNODE_GET_TOKPTR(tmp)); + return -1; + } + } + } + fun_type = FUN_IM; } } + else if (HCL_CNODE_IS_SYMBOL_PLAIN(defun_name)) + { + hcl_cnode_t* tmp; + tmp = HCL_CNODE_CONS_CDR(obj); + if (tmp && HCL_CNODE_IS_CONS(tmp) && HCL_CNODE_IS_SYMBOL_PLAIN(HCL_CNODE_CONS_CAR(tmp))) + { + /* for defun String:length() { ... } , class_name is String, defun_name is length. */ +/* TODO: this must be treated as an error - defun String length() { ... } + for this, the reader must be able to tell between String:length and String:length... + or it must inject a special symbol between String and length or must use a different list type... */ +/* TODO: this must not be allowed at the in-class definition level.... */ + class_name = defun_name; + defun_name = HCL_CNODE_CONS_CAR(tmp); + obj = HCL_CNODE_CONS_CDR(tmp); + } + } if (!HCL_CNODE_IS_SYMBOL(defun_name)) { @@ -2805,32 +2844,6 @@ static int compile_lambda (hcl_t* hcl, hcl_cnode_t* src, int defun) args = HCL_CNODE_CONS_CAR(obj); HCL_ASSERT (hcl, args != HCL_NULL); - class_name = HCL_NULL; - if (defun_name && HCL_CNODE_IS_SYMBOL_PLAIN(args)) - { - /* for defun String:length() { ... } , class_name is String, defun_name is length. */ -/* TODO: this must be treated as an error - defun String length() { ... } - for this, the reader must be able to tell between String:length and String:length... - or it must inject a special symbol between String and length or must use a different list type... */ -/* TODO: this must not be allowed at the in-class definition level.... */ - - class_name = defun_name; - defun_name = args; - obj = HCL_CNODE_CONS_CDR(obj); - if (!obj) goto no_arg_list; - else if (!HCL_CNODE_IS_CONS(obj)) goto redundant_cdr; - args = HCL_CNODE_CONS_CAR(obj); - - if (is_in_class_init_scope(hcl)) - { - /* you must not speicfy the class name when defining a method in the class initialization scope. - * however, it's allowed to do so in another method (class method scope) for the class or in a - * normal function outside class defintion. */ - hcl_setsynerrbfmt (hcl, HCL_SYNERR_BANNED, HCL_CNODE_GET_LOC(class_name), HCL_CNODE_GET_TOK(class_name), "class name prohibited in this scope"); - return -1; - } - } - if (HCL_CNODE_IS_ELIST_CONCODED(args, HCL_CONCODE_XLIST)) { /* empty list - no argument - (lambda () (+ 10 20)) */ diff --git a/t/class-5001.err b/t/class-5001.err index 99f4f9f..3cc1131 100644 --- a/t/class-5001.err +++ b/t/class-5001.err @@ -32,7 +32,7 @@ defclass X { return "hello" } - defun String:length() { ##ERROR: syntax error - class name prohibited + defun String:length() { ##ERROR: syntax error - function name not valid return (str.length self) } }