added a new method directive #liberal to indicate a method that accept a fully variadic number of arguments.
the directive #liberal allows the caller to omit the named arguments as well. the directive #variadic requires the caller to provide at least the named arguments
This commit is contained in:
parent
aeb02213b4
commit
2ed62a5edb
@ -145,6 +145,7 @@ class MyObject(TestObject)
|
|||||||
self varg_test (10, 20, 30, 40, 50) dump.
|
self varg_test (10, 20, 30, 40, 50) dump.
|
||||||
self varg_test2 (10, 20, 30, 40, 50) dump.
|
self varg_test2 (10, 20, 30, 40, 50) dump.
|
||||||
self varg_test3 (10, 20, 30, 40, 50) dump.
|
self varg_test3 (10, 20, 30, 40, 50) dump.
|
||||||
|
self varg_test3 (10, 20, 30, 40, 50, 60, 70, 80, 90, 100) dump.
|
||||||
thisContext vargCount dump.
|
thisContext vargCount dump.
|
||||||
thisContext vargCount dump.
|
thisContext vargCount dump.
|
||||||
|
|
||||||
@ -204,21 +205,29 @@ class MyObject(TestObject)
|
|||||||
}
|
}
|
||||||
method(#class,#variadic) varg_test2(a,b,c)
|
method(#class,#variadic) varg_test2(a,b,c)
|
||||||
{
|
{
|
||||||
0 to: (thisContext vargCount - 1) do: [:k |
|
'varg_test2 start .....' dump.
|
||||||
|
a dump.
|
||||||
|
b dump.
|
||||||
|
c dump.
|
||||||
|
'varg_test2 varg .....' dump.
|
||||||
|
0 priorTo: (thisContext vargCount) do: [:k |
|
||||||
(thisContext vargAt: k) dump.
|
(thisContext vargAt: k) dump.
|
||||||
].
|
].
|
||||||
|
'varg_test2 end .....' dump.
|
||||||
^a
|
^a
|
||||||
}
|
}
|
||||||
method(#class,#variadic) varg_test3(a,b,c,d,e,f)
|
method(#class,#liberal) varg_test3(a,b,c,d,e,f)
|
||||||
{
|
{
|
||||||
0 to: (thisContext vargCount - 1) do: [:k |
|
'varg_test3 start .....' dump.
|
||||||
|
0 priorTo: (thisContext vargCount) do: [:k |
|
||||||
(thisContext vargAt: k) dump.
|
(thisContext vargAt: k) dump.
|
||||||
].
|
].
|
||||||
|
'varg_test3 end .....' dump.
|
||||||
## ^b * 100
|
## ^b * 100
|
||||||
^f
|
^f
|
||||||
}
|
}
|
||||||
|
|
||||||
method(#class,#variadic) t001(a)
|
method(#class,#liberal) t001(a)
|
||||||
{
|
{
|
||||||
a isNil ifTrue: [^error(10)].
|
a isNil ifTrue: [^error(10)].
|
||||||
(a = 20) ifTrue: [^error].
|
(a = 20) ifTrue: [^error].
|
||||||
|
@ -103,6 +103,7 @@ static struct voca_t
|
|||||||
{ 9, { '#','h','a','l','f','w','o','r','d' } },
|
{ 9, { '#','h','a','l','f','w','o','r','d' } },
|
||||||
{ 2, { 'i','f' } },
|
{ 2, { 'i','f' } },
|
||||||
{ 8, { '#','i','n','c','l','u','d','e' } },
|
{ 8, { '#','i','n','c','l','u','d','e' } },
|
||||||
|
{ 8, { '#','l','i','b','e','r','a','l' } },
|
||||||
{ 7, { '#','l','i','w','o','r','d' } },
|
{ 7, { '#','l','i','w','o','r','d' } },
|
||||||
{ 6, { 'm','e','t','h','o','d' } },
|
{ 6, { 'm','e','t','h','o','d' } },
|
||||||
{ 3, { 'n','i','l' } },
|
{ 3, { 'n','i','l' } },
|
||||||
@ -150,6 +151,7 @@ enum voca_id_t
|
|||||||
VOCA_HALFWORD_S,
|
VOCA_HALFWORD_S,
|
||||||
VOCA_IF,
|
VOCA_IF,
|
||||||
VOCA_INCLUDE_S,
|
VOCA_INCLUDE_S,
|
||||||
|
VOCA_LIBERAL_S,
|
||||||
VOCA_LIWORD_S,
|
VOCA_LIWORD_S,
|
||||||
VOCA_METHOD,
|
VOCA_METHOD,
|
||||||
VOCA_NIL,
|
VOCA_NIL,
|
||||||
@ -5752,8 +5754,8 @@ static int add_compiled_method (moo_t* moo)
|
|||||||
preamble_index = 0;
|
preamble_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (moo->c->mth.variadic /*&& moo->c->mth.tmpr_nargs > 0*/)
|
/*if (moo->c->mth.variadic) */
|
||||||
preamble_flags |= MOO_METHOD_PREAMBLE_FLAG_VARIADIC;
|
preamble_flags |= moo->c->mth.variadic;
|
||||||
|
|
||||||
MOO_ASSERT (moo, MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(preamble_index));
|
MOO_ASSERT (moo, MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(preamble_index));
|
||||||
|
|
||||||
@ -5853,9 +5855,10 @@ static int compile_method_definition (moo_t* moo)
|
|||||||
|
|
||||||
GET_TOKEN (moo);
|
GET_TOKEN (moo);
|
||||||
}
|
}
|
||||||
else if (is_token_symbol(moo, VOCA_VARIADIC_S))
|
else if (is_token_symbol(moo, VOCA_VARIADIC_S) ||
|
||||||
|
is_token_symbol(moo, VOCA_LIBERAL_S))
|
||||||
{
|
{
|
||||||
/* method(#variadic) */
|
/* method(#variadic) or method(#liberal) */
|
||||||
if (moo->c->mth.variadic)
|
if (moo->c->mth.variadic)
|
||||||
{
|
{
|
||||||
/* #variadic duplicate modifier */
|
/* #variadic duplicate modifier */
|
||||||
@ -5863,7 +5866,10 @@ static int compile_method_definition (moo_t* moo)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
moo->c->mth.variadic = 1;
|
if (is_token_symbol(moo, VOCA_LIBERAL_S))
|
||||||
|
moo->c->mth.variadic = MOO_METHOD_PREAMBLE_FLAG_LIBERAL;
|
||||||
|
else
|
||||||
|
moo->c->mth.variadic = MOO_METHOD_PREAMBLE_FLAG_VARIADIC;
|
||||||
|
|
||||||
GET_TOKEN (moo);
|
GET_TOKEN (moo);
|
||||||
}
|
}
|
||||||
@ -6024,7 +6030,7 @@ static int compile_method_definition (moo_t* moo)
|
|||||||
GET_TOKEN (moo);
|
GET_TOKEN (moo);
|
||||||
|
|
||||||
if (compile_method_temporaries(moo) <= -1 ||
|
if (compile_method_temporaries(moo) <= -1 ||
|
||||||
compile_method_progma(moo) <= -1 ||
|
compile_method_pragma(moo) <= -1 ||
|
||||||
compile_method_statements(moo) <= -1) return -1;
|
compile_method_statements(moo) <= -1) return -1;
|
||||||
|
|
||||||
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACE)
|
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACE)
|
||||||
|
@ -885,8 +885,8 @@ static MOO_INLINE int activate_new_method (moo_t* moo, moo_oop_method_t mth, moo
|
|||||||
if (actual_nargs > nargs)
|
if (actual_nargs > nargs)
|
||||||
{
|
{
|
||||||
/* more arguments than the method specification have been passed in.
|
/* more arguments than the method specification have been passed in.
|
||||||
* it must be a variadic unary method. othewise, the compiler is buggy */
|
* it must be a variadic or liberal unary method. othewise, the compiler is buggy */
|
||||||
MOO_ASSERT (moo, MOO_METHOD_GET_PREAMBLE_FLAGS(MOO_OOP_TO_SMOOI(mth->preamble)) & MOO_METHOD_PREAMBLE_FLAG_VARIADIC);
|
MOO_ASSERT (moo, MOO_METHOD_GET_PREAMBLE_FLAGS(MOO_OOP_TO_SMOOI(mth->preamble)) & (MOO_METHOD_PREAMBLE_FLAG_VARIADIC | MOO_METHOD_PREAMBLE_FLAG_LIBERAL));
|
||||||
actual_ntmprs = ntmprs + (actual_nargs - nargs);
|
actual_ntmprs = ntmprs + (actual_nargs - nargs);
|
||||||
}
|
}
|
||||||
else actual_ntmprs = ntmprs;
|
else actual_ntmprs = ntmprs;
|
||||||
@ -3018,7 +3018,7 @@ moo_pfbase_t* moo_getpfnum (moo_t* moo, const moo_ooch_t* ptr, moo_oow_t len, mo
|
|||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
|
static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
|
||||||
{
|
{
|
||||||
moo_ooi_t preamble, preamble_code;
|
moo_ooi_t preamble, preamble_code, preamble_flags;
|
||||||
moo_ooi_t /*sp,*/ stack_base;
|
moo_ooi_t /*sp,*/ stack_base;
|
||||||
|
|
||||||
#if defined(MOO_DEBUG_VM_EXEC)
|
#if defined(MOO_DEBUG_VM_EXEC)
|
||||||
@ -3026,16 +3026,22 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
preamble = MOO_OOP_TO_SMOOI(method->preamble);
|
preamble = MOO_OOP_TO_SMOOI(method->preamble);
|
||||||
|
preamble_flags = MOO_METHOD_GET_PREAMBLE_FLAGS(preamble);
|
||||||
|
|
||||||
|
if (preamble_flags & MOO_METHOD_PREAMBLE_FLAG_LIBERAL)
|
||||||
|
{
|
||||||
|
/* do nothing - no argument check */
|
||||||
|
}
|
||||||
|
else if (preamble_flags & MOO_METHOD_PREAMBLE_FLAG_VARIADIC)
|
||||||
|
{
|
||||||
|
if (nargs < MOO_OOP_TO_SMOOI(method->tmpr_nargs)) goto arg_count_mismatch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (nargs != MOO_OOP_TO_SMOOI(method->tmpr_nargs))
|
if (nargs != MOO_OOP_TO_SMOOI(method->tmpr_nargs))
|
||||||
{
|
{
|
||||||
|
|
||||||
moo_ooi_t preamble_flags;
|
|
||||||
|
|
||||||
preamble_flags = MOO_METHOD_GET_PREAMBLE_FLAGS(preamble);
|
|
||||||
if (!(preamble_flags & MOO_METHOD_PREAMBLE_FLAG_VARIADIC))
|
|
||||||
{
|
|
||||||
/* TODO: better to throw a moo exception so that the caller can catch it??? */
|
/* TODO: better to throw a moo exception so that the caller can catch it??? */
|
||||||
|
arg_count_mismatch:
|
||||||
MOO_LOG3 (moo, MOO_LOG_IC | MOO_LOG_FATAL,
|
MOO_LOG3 (moo, MOO_LOG_IC | MOO_LOG_FATAL,
|
||||||
"Fatal error - Argument count mismatch for a non-variadic method [%O] - %zd expected, %zu given\n",
|
"Fatal error - Argument count mismatch for a non-variadic method [%O] - %zd expected, %zu given\n",
|
||||||
method->name, MOO_OOP_TO_SMOOI(method->tmpr_nargs), nargs);
|
method->name, MOO_OOP_TO_SMOOI(method->tmpr_nargs), nargs);
|
||||||
|
@ -596,6 +596,7 @@ struct moo_method_t
|
|||||||
|
|
||||||
/* preamble flags */
|
/* preamble flags */
|
||||||
#define MOO_METHOD_PREAMBLE_FLAG_VARIADIC (1 << 0)
|
#define MOO_METHOD_PREAMBLE_FLAG_VARIADIC (1 << 0)
|
||||||
|
#define MOO_METHOD_PREAMBLE_FLAG_LIBERAL (1 << 1)
|
||||||
|
|
||||||
/* NOTE: if you change the number of instance variables for moo_context_t,
|
/* NOTE: if you change the number of instance variables for moo_context_t,
|
||||||
* you need to change the defintion of BlockContext and MethodContext.
|
* you need to change the defintion of BlockContext and MethodContext.
|
||||||
|
Loading…
Reference in New Issue
Block a user