mirror of
https://github.com/libretro/scummvm.git
synced 2025-05-13 09:36:21 +00:00
DIRECTOR: Lingo: Made built-in functions generic
This commit is contained in:
parent
cdf3c9f89e
commit
464f360e97
@ -27,35 +27,37 @@ namespace Director {
|
|||||||
static struct BuiltinProto {
|
static struct BuiltinProto {
|
||||||
const char *name;
|
const char *name;
|
||||||
void (*func)(void);
|
void (*func)(void);
|
||||||
int nparams;
|
int minArgs;
|
||||||
|
int maxArgs;
|
||||||
|
bool parens;
|
||||||
} builtins[] = {
|
} builtins[] = {
|
||||||
// Math
|
// Math
|
||||||
{ "abs", Lingo::b_abs, 1 },
|
{ "abs", Lingo::b_abs, 1, 1, true },
|
||||||
{ "atan", Lingo::b_atan, 1 },
|
{ "atan", Lingo::b_atan, 1, 1, true },
|
||||||
{ "cos", Lingo::b_cos, 1 },
|
{ "cos", Lingo::b_cos, 1, 1, true },
|
||||||
{ "exp", Lingo::b_exp, 1 },
|
{ "exp", Lingo::b_exp, 1, 1, true },
|
||||||
{ "float", Lingo::b_float, 1 },
|
{ "float", Lingo::b_float, 1, 1, true },
|
||||||
{ "integer",Lingo::b_integer, 1 },
|
{ "integer",Lingo::b_integer, 1, 1, true },
|
||||||
{ "log", Lingo::b_log, 1 },
|
{ "log", Lingo::b_log, 1, 1, true },
|
||||||
{ "pi", Lingo::b_pi, 0 },
|
{ "pi", Lingo::b_pi, 0, 0, true },
|
||||||
{ "power", Lingo::b_power, 2 },
|
{ "power", Lingo::b_power, 2, 2, true },
|
||||||
{ "random", Lingo::b_random, 1 },
|
{ "random", Lingo::b_random, 1, 1, true },
|
||||||
{ "sin", Lingo::b_sin, 1 },
|
{ "sin", Lingo::b_sin, 1, 1, true },
|
||||||
{ "sqrt", Lingo::b_sqrt, 1 },
|
{ "sqrt", Lingo::b_sqrt, 1, 1, true },
|
||||||
{ "tan", Lingo::b_tan, 1 },
|
{ "tan", Lingo::b_tan, 1, 1, true },
|
||||||
// String
|
// String
|
||||||
{ "chars", Lingo::b_chars, 3 },
|
{ "chars", Lingo::b_chars, 3, 3, true },
|
||||||
{ "length", Lingo::b_length, 1 },
|
{ "length", Lingo::b_length, 1, 1, true },
|
||||||
{ "string", Lingo::b_string, 1 },
|
{ "string", Lingo::b_string, 1, 1, true },
|
||||||
// Misc
|
// Misc
|
||||||
{ "closeDA", Lingo::b_closeDA, -1 },
|
{ "closeDA", Lingo::b_closeDA, 0, 0, false },
|
||||||
{ "continue", Lingo::b_continue, -1 },
|
{ "continue", Lingo::b_continue, 0, 0, false },
|
||||||
{ "dontpassevent", Lingo::b_dontpassevent, -1 },
|
{ "dontpassevent", Lingo::b_dontpassevent, 0, 0, false },
|
||||||
{ "updatestage", Lingo::b_updatestage, -1 },
|
{ "updatestage", Lingo::b_updatestage, 0, 0, false },
|
||||||
{ "ilk", Lingo::b_ilk, 1 },
|
{ "ilk", Lingo::b_ilk, 1, 2, true },
|
||||||
// point
|
// point
|
||||||
{ "point", Lingo::b_point, 2 },
|
{ "point", Lingo::b_point, 2, 2, true },
|
||||||
{ 0, 0, 0 }
|
{ 0, 0, 0, 0, false }
|
||||||
};
|
};
|
||||||
|
|
||||||
void Lingo::initBuiltIns() {
|
void Lingo::initBuiltIns() {
|
||||||
@ -65,7 +67,9 @@ void Lingo::initBuiltIns() {
|
|||||||
sym->name = (char *)calloc(strlen(blt->name) + 1, 1);
|
sym->name = (char *)calloc(strlen(blt->name) + 1, 1);
|
||||||
Common::strlcpy(sym->name, blt->name, strlen(blt->name));
|
Common::strlcpy(sym->name, blt->name, strlen(blt->name));
|
||||||
sym->type = BLTIN;
|
sym->type = BLTIN;
|
||||||
sym->nargs = blt->nparams;
|
sym->nargs = blt->minArgs;
|
||||||
|
sym->maxArgs = blt->maxArgs;
|
||||||
|
sym->parens = blt->parens;
|
||||||
sym->u.func = blt->func;
|
sym->u.func = blt->func;
|
||||||
|
|
||||||
_handlers[blt->name] = sym;
|
_handlers[blt->name] = sym;
|
||||||
|
@ -740,10 +740,27 @@ void Lingo::c_call() {
|
|||||||
g_lingo->_pc += g_lingo->calcStringAlignment(name.c_str());
|
g_lingo->_pc += g_lingo->calcStringAlignment(name.c_str());
|
||||||
|
|
||||||
int nargs = READ_UINT32(&(*g_lingo->_currentScript)[g_lingo->_pc++]);
|
int nargs = READ_UINT32(&(*g_lingo->_currentScript)[g_lingo->_pc++]);
|
||||||
|
bool drop = false;
|
||||||
|
|
||||||
|
Symbol *sym;
|
||||||
|
|
||||||
if (!g_lingo->_handlers.contains(name)) {
|
if (!g_lingo->_handlers.contains(name)) {
|
||||||
warning("Call to undefined handler '%s'. Dropping %d stack items", name.c_str(), nargs);
|
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++)
|
for (int i = 0; i < nargs; i++)
|
||||||
g_lingo->pop();
|
g_lingo->pop();
|
||||||
|
|
||||||
@ -753,8 +770,6 @@ void Lingo::c_call() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol *sym = g_lingo->_handlers[name];
|
|
||||||
|
|
||||||
if (sym->nargs < nargs) {
|
if (sym->nargs < nargs) {
|
||||||
warning("Incorrect number of arguments for function %s. Dropping extra %d", name.c_str(), nargs - sym->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++)
|
for (int i = 0; i < nargs - sym->nargs; i++)
|
||||||
@ -762,15 +777,8 @@ void Lingo::c_call() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sym->type == BLTIN) {
|
if (sym->type == BLTIN) {
|
||||||
if (sym->nargs > 0 && nargs < sym->nargs) {
|
// FIXME. TODO. Pass 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();
|
|
||||||
|
|
||||||
g_lingo->pushVoid();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
(*sym->u.func)();
|
(*sym->u.func)();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -185,7 +185,10 @@ whitespace [\t ]
|
|||||||
yylval.s = new Common::String(yytext);
|
yylval.s = new Common::String(yytext);
|
||||||
|
|
||||||
if (g_lingo->_handlers.contains(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;
|
return BLTINNOARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,8 @@ Symbol::Symbol() {
|
|||||||
type = VOID;
|
type = VOID;
|
||||||
u.s = NULL;
|
u.s = NULL;
|
||||||
nargs = 0;
|
nargs = 0;
|
||||||
|
maxArgs = 0;
|
||||||
|
parens = true;
|
||||||
global = false;
|
global = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,10 @@ struct Symbol { /* symbol table entry */
|
|||||||
Common::String *s; /* STRING */
|
Common::String *s; /* STRING */
|
||||||
FloatArray *arr; /* ARRAY, POINT, RECT */
|
FloatArray *arr; /* ARRAY, POINT, RECT */
|
||||||
} u;
|
} 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;
|
bool global;
|
||||||
|
|
||||||
Symbol();
|
Symbol();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user