diff options
-rw-r--r-- | engines/director/lingo/lingo-builtins.cpp | 54 | ||||
-rw-r--r-- | engines/director/lingo/lingo-code.cpp | 28 | ||||
-rw-r--r-- | engines/director/lingo/lingo-lex.l | 5 | ||||
-rw-r--r-- | engines/director/lingo/lingo.cpp | 2 | ||||
-rw-r--r-- | engines/director/lingo/lingo.h | 5 |
5 files changed, 57 insertions, 37 deletions
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp index acec59345c..0361fa7bc8 100644 --- a/engines/director/lingo/lingo-builtins.cpp +++ b/engines/director/lingo/lingo-builtins.cpp @@ -27,35 +27,37 @@ namespace Director { static struct BuiltinProto { const char *name; void (*func)(void); - int nparams; + int minArgs; + int maxArgs; + bool parens; } builtins[] = { // Math - { "abs", Lingo::b_abs, 1 }, - { "atan", Lingo::b_atan, 1 }, - { "cos", Lingo::b_cos, 1 }, - { "exp", Lingo::b_exp, 1 }, - { "float", Lingo::b_float, 1 }, - { "integer",Lingo::b_integer, 1 }, - { "log", Lingo::b_log, 1 }, - { "pi", Lingo::b_pi, 0 }, - { "power", Lingo::b_power, 2 }, - { "random", Lingo::b_random, 1 }, - { "sin", Lingo::b_sin, 1 }, - { "sqrt", Lingo::b_sqrt, 1 }, - { "tan", Lingo::b_tan, 1 }, + { "abs", Lingo::b_abs, 1, 1, true }, + { "atan", Lingo::b_atan, 1, 1, true }, + { "cos", Lingo::b_cos, 1, 1, true }, + { "exp", Lingo::b_exp, 1, 1, true }, + { "float", Lingo::b_float, 1, 1, true }, + { "integer",Lingo::b_integer, 1, 1, true }, + { "log", Lingo::b_log, 1, 1, true }, + { "pi", Lingo::b_pi, 0, 0, true }, + { "power", Lingo::b_power, 2, 2, true }, + { "random", Lingo::b_random, 1, 1, true }, + { "sin", Lingo::b_sin, 1, 1, true }, + { "sqrt", Lingo::b_sqrt, 1, 1, true }, + { "tan", Lingo::b_tan, 1, 1, true }, // String - { "chars", Lingo::b_chars, 3 }, - { "length", Lingo::b_length, 1 }, - { "string", Lingo::b_string, 1 }, + { "chars", Lingo::b_chars, 3, 3, true }, + { "length", Lingo::b_length, 1, 1, true }, + { "string", Lingo::b_string, 1, 1, true }, // Misc - { "closeDA", Lingo::b_closeDA, -1 }, - { "continue", Lingo::b_continue, -1 }, - { "dontpassevent", Lingo::b_dontpassevent, -1 }, - { "updatestage", Lingo::b_updatestage, -1 }, - { "ilk", Lingo::b_ilk, 1 }, + { "closeDA", Lingo::b_closeDA, 0, 0, false }, + { "continue", Lingo::b_continue, 0, 0, false }, + { "dontpassevent", Lingo::b_dontpassevent, 0, 0, false }, + { "updatestage", Lingo::b_updatestage, 0, 0, false }, + { "ilk", Lingo::b_ilk, 1, 2, true }, // point - { "point", Lingo::b_point, 2 }, - { 0, 0, 0 } + { "point", Lingo::b_point, 2, 2, true }, + { 0, 0, 0, 0, false } }; void Lingo::initBuiltIns() { @@ -65,7 +67,9 @@ void Lingo::initBuiltIns() { sym->name = (char *)calloc(strlen(blt->name) + 1, 1); Common::strlcpy(sym->name, blt->name, strlen(blt->name)); sym->type = BLTIN; - sym->nargs = blt->nparams; + sym->nargs = blt->minArgs; + sym->maxArgs = blt->maxArgs; + sym->parens = blt->parens; sym->u.func = blt->func; _handlers[blt->name] = sym; diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp index bcd479f1a6..0d5b07c554 100644 --- a/engines/director/lingo/lingo-code.cpp +++ b/engines/director/lingo/lingo-code.cpp @@ -740,10 +740,27 @@ void Lingo::c_call() { g_lingo->_pc += g_lingo->calcStringAlignment(name.c_str()); int nargs = READ_UINT32(&(*g_lingo->_currentScript)[g_lingo->_pc++]); + bool drop = false; + + Symbol *sym; if (!g_lingo->_handlers.contains(name)) { warning("Call to undefined handler '%s'. Dropping %d stack items", name.c_str(), nargs); + drop = true; + } else { + sym = g_lingo->_handlers[name]; + + if (sym->type == BLTIN && sym->nargs != nargs && sym->maxArgs != nargs) { + if (sym->nargs == sym->maxArgs) + warning("Incorrect number of arguments to handler '%s', expecting %d. Dropping %d stack items", name.c_str(), sym->nargs, nargs); + else + warning("Incorrect number of arguments to handler '%s', expecting %d or %d. Dropping %d stack items", name.c_str(), sym->nargs, sym->maxArgs, nargs); + + drop = true; + } + } + if (drop) { for (int i = 0; i < nargs; i++) g_lingo->pop(); @@ -753,8 +770,6 @@ void Lingo::c_call() { return; } - Symbol *sym = g_lingo->_handlers[name]; - if (sym->nargs < nargs) { warning("Incorrect number of arguments for function %s. Dropping extra %d", name.c_str(), nargs - sym->nargs); for (int i = 0; i < nargs - sym->nargs; i++) @@ -762,15 +777,8 @@ void Lingo::c_call() { } if (sym->type == BLTIN) { - if (sym->nargs > 0 && nargs < sym->nargs) { - warning("Too few arguments for function %s. Expecting %d but got %d", name.c_str(), sym->nargs, nargs); - for (int i = 0; i < nargs; i++) - g_lingo->pop(); + // FIXME. TODO. Pass nargs - g_lingo->pushVoid(); - - return; - } (*sym->u.func)(); return; diff --git a/engines/director/lingo/lingo-lex.l b/engines/director/lingo/lingo-lex.l index 5e64922894..2d871ce875 100644 --- a/engines/director/lingo/lingo-lex.l +++ b/engines/director/lingo/lingo-lex.l @@ -185,7 +185,10 @@ whitespace [\t ] yylval.s = new Common::String(yytext); if (g_lingo->_handlers.contains(yytext)) { - if (g_lingo->_handlers[yytext]->type == BLTIN && g_lingo->_handlers[yytext]->nargs == -1) + if (g_lingo->_handlers[yytext]->type == BLTIN && + g_lingo->_handlers[yytext]->nargs == 0 && + g_lingo->_handlers[yytext]->maxArgs == 0 && + !g_lingo->_handlers[yytext]->parens) return BLTINNOARGS; } diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp index 0bb43092f3..05478bb453 100644 --- a/engines/director/lingo/lingo.cpp +++ b/engines/director/lingo/lingo.cpp @@ -72,6 +72,8 @@ Symbol::Symbol() { type = VOID; u.s = NULL; nargs = 0; + maxArgs = 0; + parens = true; global = false; } diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h index 8e73e23ba1..94fe92f9c7 100644 --- a/engines/director/lingo/lingo.h +++ b/engines/director/lingo/lingo.h @@ -89,7 +89,10 @@ struct Symbol { /* symbol table entry */ Common::String *s; /* STRING */ FloatArray *arr; /* ARRAY, POINT, RECT */ } u; - int nargs; + int nargs; /* number of arguments */ + int maxArgs; /* maximal number of arguments, for builtins */ + bool parens; /* whether parens required or not, for builitins */ + bool global; Symbol(); |