changed the syntax for clarity - attribute list to use a tuple, class variable list to use a normal parenthesized list

This commit is contained in:
2025-09-15 01:41:43 +09:00
parent ef293d35d4
commit 37b652ead6
10 changed files with 140 additions and 148 deletions

View File

@ -1514,7 +1514,7 @@ static int collect_vardcl_for_class (hak_t* hak, hak_cnode_t* obj, hak_cnode_t**
tv_slen_saved = hak->c->tv.s.len; tv_slen_saved = hak->c->tv.s.len;
dcl = HAK_CNODE_CONS_CAR(obj); dcl = HAK_CNODE_CONS_CAR(obj);
HAK_ASSERT(hak, HAK_CNODE_IS_CONS_CONCODED(dcl, HAK_CONCODE_TUPLE)); HAK_ASSERT(hak, HAK_CNODE_IS_CONS_CONCODED(dcl, HAK_CONCODE_XLIST));
do do
{ {
@ -1524,7 +1524,7 @@ static int collect_vardcl_for_class (hak_t* hak, hak_cnode_t* obj, hak_cnode_t**
var = HAK_CNODE_CONS_CAR(dcl); var = HAK_CNODE_CONS_CAR(dcl);
if (HAK_CNODE_IS_CONS_CONCODED(var, HAK_CONCODE_TUPLE)) /* [ ... ] */ if (HAK_CNODE_IS_CONS_CONCODED(var, HAK_CONCODE_XLIST)) /* ( ... ) */
{ {
if (enclosed) if (enclosed)
{ {
@ -1539,10 +1539,10 @@ static int collect_vardcl_for_class (hak_t* hak, hak_cnode_t* obj, hak_cnode_t**
dcl = var; dcl = var;
continue; /* start over */ continue; /* start over */
} }
else if (HAK_CNODE_IS_ELIST_CONCODED(var, HAK_CONCODE_TUPLE)) else if (HAK_CNODE_IS_ELIST_CONCODED(var, HAK_CONCODE_XLIST))
{ {
/* no variables inside [] */ /* no variables inside () */
if (enclosed) goto synerr_varname; /* [] inside [] */ if (enclosed) goto synerr_varname; /* () inside () */
goto next; goto next;
} }
@ -2652,10 +2652,10 @@ static int check_class_attr_list (hak_t* hak, hak_cnode_t* attr_list, unsigned i
ct = HAK_OBJ_TYPE_OOP; ct = HAK_OBJ_TYPE_OOP;
HAK_ASSERT(hak, attr_list != HAK_NULL); HAK_ASSERT(hak, attr_list != HAK_NULL);
HAK_ASSERT(hak, HAK_CNODE_IS_CONS_CONCODED(attr_list, HAK_CONCODE_XLIST) || HAK_ASSERT(hak, HAK_CNODE_IS_CONS_CONCODED(attr_list, HAK_CONCODE_TUPLE) ||
HAK_CNODE_IS_ELIST_CONCODED(attr_list, HAK_CONCODE_XLIST)); HAK_CNODE_IS_ELIST_CONCODED(attr_list, HAK_CONCODE_TUPLE));
if (HAK_CNODE_IS_ELIST_CONCODED(attr_list, HAK_CONCODE_XLIST)) if (HAK_CNODE_IS_ELIST_CONCODED(attr_list, HAK_CONCODE_TUPLE))
{ {
/* don't allow empty attribute list */ /* don't allow empty attribute list */
if (class_name) if (class_name)
@ -2676,7 +2676,7 @@ static int check_class_attr_list (hak_t* hak, hak_cnode_t* attr_list, unsigned i
return -1; return -1;
} }
if (HAK_CNODE_IS_CONS_CONCODED(attr_list, HAK_CONCODE_XLIST)) if (HAK_CNODE_IS_CONS_CONCODED(attr_list, HAK_CONCODE_TUPLE))
{ {
hak_cnode_t* c; hak_cnode_t* c;
const hak_ooch_t* tokptr; const hak_ooch_t* tokptr;
@ -2759,30 +2759,23 @@ static int check_class_attr_list (hak_t* hak, hak_cnode_t* attr_list, unsigned i
} }
/* /*
(class A class[#attr1 #attr2] Name: SuperclassName (ivar1 ivar2 (cvar1) ivar3) {
[ x y ] ## instance variables cvar1 := 20
:: | x y z | ## class variables <--- how to initialize the class variables??? fun[#ci] new(a b c) {
self.ivar1 := a
## everything inside class after the variable declarations are normal expressions. ivar2 := b
## however, the resolution of some variables will fall under the enclosing class. ivar3 := (self.cvar1 * 2)
(set x 20) }
(printf "normal statement ....\n"); }
(fun new (a b c)
(printf "%O\n" self) ; self is A
(set obj super.new)
(obj.init a b c)
;(obj.x 10)
;(obj.y 20)
(return obj)
)
)
(class B :: A ; A is a parent class
| p q |
....
)
class Name(ivar1 ivar2 (cvar1) ivar3) {
cvar1 := 20
fun[#ci] new(a b c) {
self.ivar1 := a
ivar2 := b
ivar3 := (self.cvar1 * 2)
}
}
*/ */
static int compile_class (hak_t* hak, hak_cnode_t* src) static int compile_class (hak_t* hak, hak_cnode_t* src)
@ -2807,9 +2800,10 @@ static int compile_class (hak_t* hak, hak_cnode_t* src)
{ {
HAK_ASSERT(hak, HAK_CNODE_IS_CONS(obj)); HAK_ASSERT(hak, HAK_CNODE_IS_CONS(obj));
/* class[#b] .... */
tmp = HAK_CNODE_CONS_CAR(obj); tmp = HAK_CNODE_CONS_CAR(obj);
if (HAK_CNODE_IS_ELIST_CONCODED(tmp, HAK_CONCODE_XLIST) || if (HAK_CNODE_IS_ELIST_CONCODED(tmp, HAK_CONCODE_TUPLE) ||
HAK_CNODE_IS_CONS_CONCODED(tmp, HAK_CONCODE_XLIST)) HAK_CNODE_IS_CONS_CONCODED(tmp, HAK_CONCODE_TUPLE))
{ {
attr_list = tmp; attr_list = tmp;
obj = HAK_CNODE_CONS_CDR(obj); obj = HAK_CNODE_CONS_CDR(obj);
@ -2984,13 +2978,13 @@ static HAK_INLINE int compile_class_p1 (hak_t* hak)
if (obj && HAK_CNODE_IS_CONS(obj)) if (obj && HAK_CNODE_IS_CONS(obj))
{ {
/* class-level variables - instance variables and class variable /* class-level variables - instance variables and class variable
* - class X [ a b c [d e] x ] { ... } * - class X ( a b c (d e) x ) { ... }
* - a b c are instance variables. * - a b c are instance variables.
* - d e, enclsoed in another [], are class variables. * - d e, enclsoed in another [], are class variables.
* */ * */
hak_cnode_t* tmp; hak_cnode_t* tmp;
tmp = HAK_CNODE_CONS_CAR(obj); tmp = HAK_CNODE_CONS_CAR(obj);
if (HAK_CNODE_IS_CONS_CONCODED(tmp, HAK_CONCODE_TUPLE)) if (HAK_CNODE_IS_CONS_CONCODED(tmp, HAK_CONCODE_XLIST))
{ {
if (collect_vardcl_for_class(hak, obj, &obj, &vardcl) <= -1) return -1; if (collect_vardcl_for_class(hak, obj, &obj, &vardcl) <= -1) return -1;
} }
@ -3150,10 +3144,10 @@ static int check_fun_attr_list (hak_t* hak, hak_cnode_t* attr_list, unsigned int
ft = FUN_IM; ft = FUN_IM;
HAK_ASSERT(hak, attr_list != HAK_NULL); HAK_ASSERT(hak, attr_list != HAK_NULL);
HAK_ASSERT(hak, HAK_CNODE_IS_CONS_CONCODED(attr_list, HAK_CONCODE_XLIST) || HAK_ASSERT(hak, HAK_CNODE_IS_CONS_CONCODED(attr_list, HAK_CONCODE_TUPLE) ||
HAK_CNODE_IS_ELIST_CONCODED(attr_list, HAK_CONCODE_XLIST)); HAK_CNODE_IS_ELIST_CONCODED(attr_list, HAK_CONCODE_TUPLE));
if (HAK_CNODE_IS_ELIST_CONCODED(attr_list, HAK_CONCODE_XLIST)) if (HAK_CNODE_IS_ELIST_CONCODED(attr_list, HAK_CONCODE_TUPLE))
{ {
/* don't allow empty attribute list */ /* don't allow empty attribute list */
if (class_name && fun_name) if (class_name && fun_name)
@ -3183,7 +3177,7 @@ static int check_fun_attr_list (hak_t* hak, hak_cnode_t* attr_list, unsigned int
return -1; return -1;
} }
if (HAK_CNODE_IS_CONS_CONCODED(attr_list, HAK_CONCODE_XLIST)) if (HAK_CNODE_IS_CONS_CONCODED(attr_list, HAK_CONCODE_TUPLE))
{ {
hak_cnode_t* c, * a; hak_cnode_t* c, * a;
const hak_ooch_t* tokptr; const hak_ooch_t* tokptr;
@ -3279,12 +3273,28 @@ static int compile_fun (hak_t* hak, hak_cnode_t* src)
/* fun (arg..) /* fun (arg..)
* fun name(arg..) * fun name(arg..)
* fun(#attr..) name(arg..) ## valid as class method, not valid as plain function * fun[#attr..] name(arg..) ## valid as class method, not valid as plain function
* fun(#attr..) (arg..) ## not valid. not attribute list for unnamed functions * fun[#attr..] (arg..) ## not valid. no attribute list for unnamed functions
* fun(#attr..) class:name(arg..) * fun[#attr..] class:name(arg..)
*/ */
tmp = HAK_CNODE_CONS_CAR(next); tmp = HAK_CNODE_CONS_CAR(next);
if (HAK_CNODE_IS_CONS_CONCODED(tmp, HAK_CONCODE_TUPLE) ||
HAK_CNODE_IS_ELIST_CONCODED(tmp, HAK_CONCODE_TUPLE))
{
attr_list = tmp;
next = HAK_CNODE_CONS_CDR(next);
if (!next)
{
hak_setsynerrbfmt(
hak, HAK_SYNERR_FUN, HAK_CNODE_GET_LOC(fun_name), HAK_NULL,
"no function name or arguments after attribute list for '%.*js'",
HAK_CNODE_GET_TOKLEN(cmd), HAK_CNODE_GET_TOKPTR(cmd));
return -1;
}
tmp = HAK_CNODE_CONS_CAR(next);
}
if (HAK_CNODE_IS_SYMBOL(tmp)) if (HAK_CNODE_IS_SYMBOL(tmp))
{ {
/* 'fun' followed by name */ /* 'fun' followed by name */
@ -3365,72 +3375,32 @@ static int compile_fun (hak_t* hak, hak_cnode_t* src)
{ {
/* 'fun' followed by attribute or argument list */ /* 'fun' followed by attribute or argument list */
arg_list = tmp; arg_list = tmp;
if (fun_name) /* argument list
{
/* argument list for sure
* fun class:name() * fun class:name()
* fun name () * fun name ()
* fun ()
* ^ */ * ^ */
next = HAK_CNODE_CONS_CDR(next); /* point past argument list */ next = HAK_CNODE_CONS_CDR(next); /* point past argument list */
if (!next) if (!next)
{
if (fun_name)
{ {
hak_setsynerrbfmt( hak_setsynerrbfmt(
hak, HAK_SYNERR_FUN, HAK_CNODE_GET_LOC(cmd), HAK_NULL, hak, HAK_SYNERR_FUN, HAK_CNODE_GET_LOC(cmd), HAK_NULL,
"no function body after argument list of function '%.*js' for '%.*js'", "no function body after argument list of function '%.*js' for '%.*js'",
HAK_CNODE_GET_TOKLEN(fun_name), HAK_CNODE_GET_TOKPTR(fun_name), HAK_CNODE_GET_TOKLEN(fun_name), HAK_CNODE_GET_TOKPTR(fun_name),
HAK_CNODE_GET_TOKLEN(cmd), HAK_CNODE_GET_TOKPTR(cmd)); HAK_CNODE_GET_TOKLEN(cmd), HAK_CNODE_GET_TOKPTR(cmd));
return -1;
}
fun_body = next;
} }
else else
{ {
/* not clear if it is attribute list or argument list */
next = HAK_CNODE_CONS_CDR(next); /* point past attribute/argument list */
if (!next)
{
/* TODO: guess if the current list looks like attribute list or
* not by inspecting elements and produce better error mesage.
* another hack is to disallow ELIST as attribute list? */
hak_setsynerrbfmt( hak_setsynerrbfmt(
hak, HAK_SYNERR_FUN, HAK_CNODE_GET_LOC(cmd), HAK_NULL, hak, HAK_SYNERR_FUN, HAK_CNODE_GET_LOC(cmd), HAK_NULL,
"unnamed function not followed by function body for '%.*js'", "unnamed function not followed by function body for '%.*js'",
HAK_CNODE_GET_TOKLEN(cmd), HAK_CNODE_GET_TOKPTR(cmd)); HAK_CNODE_GET_TOKLEN(cmd), HAK_CNODE_GET_TOKPTR(cmd));
return -1;
} }
tmp = HAK_CNODE_CONS_CAR(next);
if (HAK_CNODE_IS_SYMBOL(tmp))
{
/* it is attribute list for sure. fun(#attr..) name */
attr_list = arg_list;
arg_list = HAK_NULL;
goto fun_got_name;
}
else if (HAK_CNODE_IS_CONS_CONCODED(tmp, HAK_CONCODE_XLIST) ||
HAK_CNODE_IS_ELIST_CONCODED(tmp, HAK_CONCODE_XLIST))
{
/* fun(#attr..) (arg..) .. */
attr_list = arg_list;
arg_list = tmp;
next = HAK_CNODE_CONS_CDR(next); /* point past argument list */
if (!next)
{
hak_setsynerrbfmt(
hak, HAK_SYNERR_FUN, HAK_CNODE_GET_LOC(cmd), HAK_NULL,
"no function body after attribute list and argument list of unnamed function for '%.*js'",
HAK_CNODE_GET_TOKLEN(cmd), HAK_CNODE_GET_TOKPTR(cmd));
return -1; return -1;
} }
fun_body = next; fun_body = next;
}
else
{
/* fun(arg..) .. */
fun_body = next;
}
}
if (src->cn_llvl >= 2 && is_in_class_init_scope_but_not_at_llvl(hak, src->cn_llvl - 2)) if (src->cn_llvl >= 2 && is_in_class_init_scope_but_not_at_llvl(hak, src->cn_llvl - 2))
{ {

View File

@ -1553,7 +1553,6 @@ static int feed_process_token (hak_t* hak)
int oldflagv; int oldflagv;
frd->expect_vlist_item = 0; frd->expect_vlist_item = 0;
frd->obj = leave_list(hak, &frd->list_loc, &frd->flagv, &oldflagv); frd->obj = leave_list(hak, &frd->list_loc, &frd->flagv, &oldflagv);
if (HAK_LIKELY(frd->obj)) frd->obj->cn_llvl = frd->level;
frd->level--; frd->level--;
frd->flagv |= AT_BEGINNING; frd->flagv |= AT_BEGINNING;
list_loc = &frd->list_loc; list_loc = &frd->list_loc;
@ -1787,7 +1786,6 @@ static int feed_process_token (hak_t* hak)
#endif #endif
frd->obj = leave_list(hak, &frd->list_loc, &frd->flagv, &oldflagv); frd->obj = leave_list(hak, &frd->list_loc, &frd->flagv, &oldflagv);
if (HAK_LIKELY(frd->obj)) frd->obj->cn_llvl = frd->level; /* list level */
frd->level--; frd->level--;
frd->flagv |= AT_BEGINNING; /* the current one is over. move on the beginning for the next expression */ frd->flagv |= AT_BEGINNING; /* the current one is over. move on the beginning for the next expression */
list_loc = &frd->list_loc; list_loc = &frd->list_loc;

View File

@ -58,16 +58,36 @@ class a: #(1 2) { ##ERROR: syntax error - no valid superclass name after ':' for
J := 11 J := 11
class B { class B {
if (== J 10) { if (== J 10) {
fun(#ci) newA() { fun[#ci] newA() { ##ERROR: syntax error - function 'newA' defined with 'fun' prohibited in class initialziation context
return self return self
} }
} else { } else {
fun(#ci) newB() { fun[#ci] newB() {
return self return self
} }
} }
} }
##t2 := (B:newB)
##t1 := (B:newA) ##error: exception not handled - "unable to send newA to B - 'newA' not found in B"
---
class B {
}
J := 11
if (== J 10) {
fun[#ci] B:newA() {
return self
}
} else {
fun[#ci] B:newB() {
return self
}
}
t2 := (B:newB) t2 := (B:newB)
t1 := (B:newA) ##ERROR: exception not handled - "unable to send newA to B - 'newA' not found in B" t1 := (B:newA) ##ERROR: exception not handled - "unable to send newA to B - 'newA' not found in B"
@ -87,7 +107,7 @@ class B {
class X: B { class X: B {
var a b var a b
fun(#ci) new(t) { fun[#ci] new(t) {
| a | | a |
set self.a t; set self.a t;
set a 100; set a 100;
@ -109,11 +129,11 @@ class X: B {
--- ---
class X { class X {
fun(#ci) xxx() { fun[#ci] xxx() {
return X; return X;
} }
fun(#ci) qqq() { fun[#ci] qqq() {
return "hello" return "hello"
} }
@ -124,10 +144,10 @@ class X {
--- ---
class X { class X {
fun(#ci) xxx() { fun[#ci] xxx() {
return X; return X;
} }
fun(#ci) qqq() { fun[#ci] qqq() {
return "hello" return "hello"
} }
} }
@ -152,7 +172,7 @@ fun X:xxx() { ##ERROR: exception not handled - "not class"
## and the clase instantiation method can't specify the size ## and the clase instantiation method can't specify the size
## you can't place an item in the arrya at all. ## you can't place an item in the arrya at all.
fun(#ci) Array:boom() { fun[#ci] Array:boom() {
core.basicAtPut self 0 10 ##ERROR: exception not handled - "position(0) out of range - negative or greater than or equal to 0" core.basicAtPut self 0 10 ##ERROR: exception not handled - "position(0) out of range - negative or greater than or equal to 0"
printf "%O" self printf "%O" self
return self return self
@ -163,7 +183,7 @@ Array:boom
class X { class X {
var a b c var a b c
fun(#ci) new () { fun[#ci] new () {
self.a := 20 self.a := 20
return self return self
} }
@ -243,7 +263,7 @@ class a {
class X10 { class X10 {
var x var x
fun(#ci) make() { x := 1234; return self; }; fun[#ci] make() { x := 1234; return self; };
fun get-x() { return x }; fun get-x() { return x };
} }
@ -260,44 +280,44 @@ class String { ##ERROR: exception not handled - "incompatible redefintion of Str
--- ---
class() { ##ERROR: syntax error - empty attribute list on unnamed class for 'class' class[] { ##ERROR: syntax error - empty attribute list on unnamed class for 'class'
} }
--- ---
class() Kuduro { ##ERROR: syntax error - empty attribute list on 'Kuduro' for 'class' class[] Kuduro { ##ERROR: syntax error - empty attribute list on 'Kuduro' for 'class'
} }
--- ---
class(#byte #limited #char) Kuduro { ##ERROR: syntax error - conflicting or duplicate class attribute name '#char' class[#byte #limited #char] Kuduro { ##ERROR: syntax error - conflicting or duplicate class attribute name '#char'
} }
--- ---
class(#byte #limited #final #limited) Kuduro { ##ERROR: syntax error - conflicting or duplicate class attribute name '#limited' class[#byte #limited #final #limited] Kuduro { ##ERROR: syntax error - conflicting or duplicate class attribute name '#limited'
} }
--- ---
class(#byte #bytes) Kuduro { ##ERROR: syntax error - unrecognized class attribute name '#bytes' class[#byte #bytes] Kuduro { ##ERROR: syntax error - unrecognized class attribute name '#bytes'
} }
--- ---
class Kuduro [a b c] { class Kuduro (a b c) {
var d e var d e
var a ##ERROR: syntax error - duplicate instance variable name 'a' var a ##ERROR: syntax error - duplicate instance variable name 'a'
} }
--- ---
class Kuduro [a [b] c] { class Kuduro (a (b) c) {
var d e var d e
var b ##ERROR: syntax error - duplicate instance variable name 'b' var b ##ERROR: syntax error - duplicate instance variable name 'b'
} }
--- ---
class Kuduro [a [b] c] { class Kuduro (a (b) c) {
var d e var d e
var(#class) b ##ERROR: syntax error - duplicate class variable name 'b' var(#class) b ##ERROR: syntax error - duplicate class variable name 'b'
} }

View File

@ -98,7 +98,7 @@ if (== y 29) {
class A { class A {
var a b c var a b c
fun(#ci) newInstance(x y z) { fun[#ci] newInstance(x y z) {
set a x set a x
set b y set b y
set c z set c z

View File

@ -15,7 +15,7 @@ fun Number: ~= (oprnd) { return (~= self oprnd) }
class A { class A {
var a b c var a b c
fun(#ci) newInstance(x y z) { fun[#ci] newInstance(x y z) {
set a x; set a x;
set b y; set b y;
set c z; set c z;
@ -30,7 +30,7 @@ class A {
class B: A { class B: A {
var d e f var d e f
fun(#ci) newInstance(x y z) { fun[#ci] newInstance(x y z) {
super:newInstance (* x 2) (* y 2) (* z 2); super:newInstance (* x 2) (* y 2) (* z 2);
set d x; set d x;
set e y; set e y;
@ -38,9 +38,9 @@ class B: A {
return self; return self;
}; };
fun(#c) getSuper() { return super; }; fun[#c] getSuper() { return super; };
###fun(#c) getSuperclass() { return (self:superclass); }; ###fun[#c] getSuperclass() { return (self:superclass); };
fun(#c) getSelf() { return self; }; fun[#c] getSelf() { return self; };
fun sum() { fun sum() {
return (+ (super:get-a) (super:get-b) (super:get-c) self.d self.e self.f); return (+ (super:get-a) (super:get-b) (super:get-c) self.d self.e self.f);

View File

@ -13,7 +13,7 @@ fun Number: ~= (oprnd) { return (~= self oprnd) }
set t ( set t (
class { class {
var x var x
fun(#ci) make() { x := 1234; return self; }; fun[#ci] make() { x := 1234; return self; };
fun get-x() { return x }; fun get-x() { return x };
} }
); );
@ -43,7 +43,7 @@ else { printf "OK: value is %d\n" v };
class X0 { class X0 {
var a b c d var a b c d
fun(#ci) new() { fun[#ci] new() {
return self; return self;
} }
@ -72,7 +72,7 @@ else { printf "OK: value is %d\n" v }
class X1 { class X1 {
var a b c var a b c
fun(#classinst) new () { fun[#classinst] new () {
self.a := 20 self.a := 20
return self return self
} }
@ -115,11 +115,11 @@ class F {
class X2 { class X2 {
var a b c var a b c
fun(#classinst) new () { fun[#classinst] new () {
| j | | j |
self.a := 20 self.a := 20
j := (self.a * 2) j := (self.a * 2)
fun(#class) F:get_x() { return (j * j) } fun[#class] F:get_x() { return (j * j) }
return self return self
} }
} }
@ -131,7 +131,7 @@ else { printf "OK: value is %d\n" v }
## -------------------------------------------------------------- ## --------------------------------------------------------------
class X3 { class X3 {
fun(#ci) new (a b) { fun[#ci] new (a b) {
fun X3:sum() { return (fun(j) { return (j + (a + b)) }) } fun X3:sum() { return (fun(j) { return (j + (a + b)) }) }
return self; return self;
} }
@ -143,15 +143,15 @@ else { printf "OK: value is %d\n" v }
## -------------------------------------------------------------- ## --------------------------------------------------------------
class X4 { class X4 {
fun(#class) t() { fun[#class] t() {
| X5 | | X5 |
class X5 { ## this X5 isn't the local variable X4 class X5 { ## this X5 isn't the local variable X4
fun(#class) t() { fun[#class] t() {
X6 := (class { X6 := (class {
fun(#class) t() { fun[#class] t() {
| X7 | | X7 |
X7 := (class { ## this X4 is the local variable X4 X7 := (class { ## this X4 is the local variable X4
fun(#class) t() { return 60 } fun[#class] t() { return 60 }
}) })
return 40 return 40
} }
@ -186,7 +186,7 @@ else { printf "OK: value is %d\n" v }
## -------------------------------------------------------------- ## --------------------------------------------------------------
class X10 { class X10 {
var x var x
fun(#ci) make() { x := 1234; return self; }; fun[#ci] make() { x := 1234; return self; };
fun get-x() { return x }; fun get-x() { return x };
} }

View File

@ -37,12 +37,12 @@
set X1 999; set X1 999;
set X2 888; set X2 888;
fun(#class) get ( :: x y) { fun[#class] get ( :: x y) {
set x X1; set x X1;
set y X2; set y X2;
}; };
fun(#class) get2 (inc :: x y) { fun[#class] get2 (inc :: x y) {
set x (+ X1 inc); set x (+ X1 inc);
set y (+ X2 inc); set y (+ X2 inc);
}; };
@ -63,9 +63,9 @@
class X { class X {
var x y var x y
fun(#class) f(a :: b c) { b := (+ a 10); c := (+ a 20) } fun[#class] f(a :: b c) { b := (+ a 10); c := (+ a 20) }
fun(#classinst) new(z) { fun[#classinst] new(z) {
## multi-variable assignment with return variables to member variables ## multi-variable assignment with return variables to member variables
[self.x, self.y] := (X:f z) [self.x, self.y] := (X:f z)
return self; return self;

View File

@ -59,7 +59,7 @@ x
class T { class T {
var j var j
fun(#classinst) new() { fun[#classinst] new() {
set j 99 set j 99
return self return self
} }

View File

@ -1,5 +1,5 @@
class A [ a ] { class A ( a ) {
fun(#ci) init1() { fun[#ci] init1() {
| b | | b |
set b (+ 1 2); set b (+ 1 2);
set a b; set a b;
@ -15,7 +15,7 @@ class A [ a ] {
printf ">>> %d\n" j; printf ">>> %d\n" j;
} }
fun(#ci) init2() { fun[#ci] init2() {
| b | | b |
set b (+ 10 20); set b (+ 10 20);
set a b; set a b;
@ -31,24 +31,28 @@ fun String length() { ##ERROR: syntax error - 'String' not followed by ( but fol
--- ---
class A [ 10 ] { ##ERROR: syntax error - not variable name '10' class A ( 10 ) { ##ERROR: syntax error - not variable name '10'
} }
--- ---
class A [ a := 20 ] { ##ERROR: syntax error - := disallowed class A ( a := 20 ) { ##ERROR: syntax error - block expression expected as 'class' body
} }
--- ---
class A [ [ [a] ] ] { ##ERROR: syntax error - not variable name
class A ( ( (a) ) ) { ##ERROR: syntax error - not variable name
} }
--- ---
class A [ a + ] { ##ERROR: syntax error - not variable name '+'
## TODO: improve the reader to be aware that it's in the class definition context
## while reading '(a + )' and to flag + as an invalid variable name...
class A ( a + ) { ##ERROR: syntax error - no operand after binary selector '+'
} }
--- ---
class A [ + ] { ##ERROR: syntax error - not variable name '+' class A ( + ) { ##ERROR: syntax error - not variable name '+'
} }
--- ---

View File

@ -79,22 +79,22 @@ fun fun fun1() { ##ERROR: syntax error - invalid function name 'fun' for 'fun'
--- ---
fun(#ci) fun1() { ##ERROR: syntax error - attribute list prohibited on plain function 'fun1' fun[#ci] fun1() { ##ERROR: syntax error - attribute list prohibited on plain function 'fun1'
} }
--- ---
fun() () { ##ERROR: syntax error - attribute list prohibited on unnamed function for 'fun' fun[] () { ##ERROR: syntax error - attribute list prohibited on unnamed function for 'fun'
} }
--- ---
fun() X:y() { ##ERROR: syntax error - empty attribute list on 'X:y' for 'fun' fun[] X:y() { ##ERROR: syntax error - empty attribute list on 'X:y' for 'fun'
} }
--- ---
class X { class X {
fun() y() { ##ERROR: syntax error - empty attribute list on 'y' for 'fun' fun[] y() { ##ERROR: syntax error - empty attribute list on 'y' for 'fun'
} }
} }