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_test2 (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.
|
||||
|
||||
@ -204,21 +205,29 @@ class MyObject(TestObject)
|
||||
}
|
||||
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.
|
||||
].
|
||||
'varg_test2 end .....' dump.
|
||||
^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.
|
||||
].
|
||||
'varg_test3 end .....' dump.
|
||||
## ^b * 100
|
||||
^f
|
||||
}
|
||||
|
||||
method(#class,#variadic) t001(a)
|
||||
method(#class,#liberal) t001(a)
|
||||
{
|
||||
a isNil ifTrue: [^error(10)].
|
||||
(a = 20) ifTrue: [^error].
|
||||
|
@ -103,6 +103,7 @@ static struct voca_t
|
||||
{ 9, { '#','h','a','l','f','w','o','r','d' } },
|
||||
{ 2, { 'i','f' } },
|
||||
{ 8, { '#','i','n','c','l','u','d','e' } },
|
||||
{ 8, { '#','l','i','b','e','r','a','l' } },
|
||||
{ 7, { '#','l','i','w','o','r','d' } },
|
||||
{ 6, { 'm','e','t','h','o','d' } },
|
||||
{ 3, { 'n','i','l' } },
|
||||
@ -150,6 +151,7 @@ enum voca_id_t
|
||||
VOCA_HALFWORD_S,
|
||||
VOCA_IF,
|
||||
VOCA_INCLUDE_S,
|
||||
VOCA_LIBERAL_S,
|
||||
VOCA_LIWORD_S,
|
||||
VOCA_METHOD,
|
||||
VOCA_NIL,
|
||||
@ -5752,8 +5754,8 @@ static int add_compiled_method (moo_t* moo)
|
||||
preamble_index = 0;
|
||||
}
|
||||
|
||||
if (moo->c->mth.variadic /*&& moo->c->mth.tmpr_nargs > 0*/)
|
||||
preamble_flags |= MOO_METHOD_PREAMBLE_FLAG_VARIADIC;
|
||||
/*if (moo->c->mth.variadic) */
|
||||
preamble_flags |= moo->c->mth.variadic;
|
||||
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
/* #variadic duplicate modifier */
|
||||
@ -5863,7 +5866,10 @@ static int compile_method_definition (moo_t* moo)
|
||||
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);
|
||||
}
|
||||
@ -6024,7 +6030,7 @@ static int compile_method_definition (moo_t* moo)
|
||||
GET_TOKEN (moo);
|
||||
|
||||
if (compile_method_temporaries(moo) <= -1 ||
|
||||
compile_method_progma(moo) <= -1 ||
|
||||
compile_method_pragma(moo) <= -1 ||
|
||||
compile_method_statements(moo) <= -1) return -1;
|
||||
|
||||
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)
|
||||
{
|
||||
/* more arguments than the method specification have been passed in.
|
||||
* it must be a variadic 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);
|
||||
* 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_METHOD_PREAMBLE_FLAG_LIBERAL));
|
||||
actual_ntmprs = ntmprs + (actual_nargs - nargs);
|
||||
}
|
||||
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)
|
||||
{
|
||||
moo_ooi_t preamble, preamble_code;
|
||||
moo_ooi_t preamble, preamble_code, preamble_flags;
|
||||
moo_ooi_t /*sp,*/ stack_base;
|
||||
|
||||
#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
|
||||
|
||||
preamble = MOO_OOP_TO_SMOOI(method->preamble);
|
||||
preamble_flags = MOO_METHOD_GET_PREAMBLE_FLAGS(preamble);
|
||||
|
||||
if (nargs != MOO_OOP_TO_SMOOI(method->tmpr_nargs))
|
||||
if (preamble_flags & MOO_METHOD_PREAMBLE_FLAG_LIBERAL)
|
||||
{
|
||||
|
||||
moo_ooi_t preamble_flags;
|
||||
|
||||
preamble_flags = MOO_METHOD_GET_PREAMBLE_FLAGS(preamble);
|
||||
if (!(preamble_flags & MOO_METHOD_PREAMBLE_FLAG_VARIADIC))
|
||||
/* 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))
|
||||
{
|
||||
/* 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,
|
||||
"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);
|
||||
|
@ -596,6 +596,7 @@ struct moo_method_t
|
||||
|
||||
/* preamble flags */
|
||||
#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,
|
||||
* you need to change the defintion of BlockContext and MethodContext.
|
||||
|
Loading…
Reference in New Issue
Block a user