aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/director/lingo/lingo-builtins.cpp54
-rw-r--r--engines/director/lingo/lingo-code.cpp28
-rw-r--r--engines/director/lingo/lingo-lex.l5
-rw-r--r--engines/director/lingo/lingo.cpp2
-rw-r--r--engines/director/lingo/lingo.h5
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();