Skip to content

Commit

Permalink
DIRECTOR: Lingo: Initial code for built-in functions
Browse files Browse the repository at this point in the history
  • Loading branch information
sev- committed Aug 3, 2016
1 parent 061f868 commit 8cc88b6
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 70 deletions.
53 changes: 53 additions & 0 deletions engines/director/lingo/lingo-builtins.cpp
@@ -0,0 +1,53 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/

#include "engines/director/lingo/lingo.h"

namespace Director {

static struct BuiltinProto {
const char *name;
void (*func)(void);
int nparams;
} builtins[] = {
{ "random", Lingo::b_random, 1},
{ 0, 0, 0 }
};

void Lingo::initBuiltIns() {
for (BuiltinProto *blt = builtins; blt->name; blt++) {
_builtins[blt->name] = new Builtin(blt->func, blt->nparams);
}
}

void Lingo::b_random() {
Datum max = g_lingo->pop();
Datum res;

res.u.i = 5;
res.type = INT;

warning("b_random");
g_lingo->push(res);
}

}
37 changes: 37 additions & 0 deletions engines/director/lingo/lingo-codegen.cpp
Expand Up @@ -126,6 +126,23 @@ void Lingo::define(Common::String &name, int start, int nargs) {
sym->nargs = nargs;
}

int Lingo::codeString(const char *str) {
int numInsts = calcStringAlignment(str);

// Where we copy the string over
int pos = _currentScript->size();

// Allocate needed space in script
for (int i = 0; i < numInsts; i++)
_currentScript->push_back(0);

byte *dst = (byte *)&_currentScript->front() + pos * sizeof(inst);

memcpy(dst, str, strlen(str) + 1);

return _currentScript->size();
}

void Lingo::codeArg(Common::String *s) {
_argstack.push_back(s);
}
Expand Down Expand Up @@ -164,4 +181,24 @@ int Lingo::codeId_(Common::String &name) {
return ret;
}

int Lingo::codeFunc(Common::String *name, int nargs) {
int ret;

if (!g_lingo->_builtins.contains(*name)) {
ret = g_lingo->code1(g_lingo->c_call);
g_lingo->codeString(name->c_str());

inst numpar = 0;
WRITE_UINT32(&numpar, nargs);
g_lingo->code1(numpar);
} else {
if (nargs != g_lingo->_builtins[*name]->nargs)
error("Built-in function %s expects %d arguments but got %d", name->c_str(), g_lingo->_builtins[*name]->nargs, nargs);

ret = g_lingo->code1(g_lingo->_builtins[*name]->func);
}

return ret;
}

}
79 changes: 38 additions & 41 deletions engines/director/lingo/lingo-gr.cpp
Expand Up @@ -532,10 +532,10 @@ static const yytype_uint16 yyrline[] =
102, 105, 111, 117, 125, 126, 127, 133, 145, 156,
172, 186, 187, 188, 190, 192, 198, 200, 202, 204,
205, 206, 209, 214, 217, 218, 219, 220, 221, 222,
223, 224, 225, 226, 227, 228, 229, 232, 238, 239,
240, 241, 242, 243, 246, 247, 258, 259, 260, 261,
266, 272, 279, 280, 281, 282, 285, 286, 287, 315,
315, 321, 322, 323, 324, 326, 329, 337, 338, 339
223, 224, 225, 226, 227, 228, 229, 232, 235, 236,
237, 238, 239, 240, 243, 244, 255, 256, 257, 258,
263, 269, 276, 277, 278, 279, 282, 283, 284, 312,
312, 318, 319, 320, 321, 323, 326, 334, 335, 336
};
#endif

Expand Down Expand Up @@ -1794,60 +1794,57 @@ yyparse ()
case 47:
#line 232 "engines/director/lingo/lingo-gr.y"
{
g_lingo->code1(g_lingo->c_call);
g_lingo->codeString((yyvsp[(1) - (4)].s)->c_str());
inst numpar = 0;
WRITE_UINT32(&numpar, (yyvsp[(3) - (4)].narg));
g_lingo->code1(numpar); ;}
g_lingo->codeFunc((yyvsp[(1) - (4)].s), (yyvsp[(3) - (4)].narg));
delete (yyvsp[(1) - (4)].s); ;}
break;

case 48:
#line 238 "engines/director/lingo/lingo-gr.y"
#line 235 "engines/director/lingo/lingo-gr.y"
{ g_lingo->code1(g_lingo->c_mci); g_lingo->codeString((yyvsp[(2) - (2)].s)->c_str()); delete (yyvsp[(2) - (2)].s); ;}
break;

case 49:
#line 239 "engines/director/lingo/lingo-gr.y"
#line 236 "engines/director/lingo/lingo-gr.y"
{ g_lingo->code1(g_lingo->c_mciwait); g_lingo->codeString((yyvsp[(2) - (2)].s)->c_str()); delete (yyvsp[(2) - (2)].s); ;}
break;

case 50:
#line 240 "engines/director/lingo/lingo-gr.y"
#line 237 "engines/director/lingo/lingo-gr.y"
{ g_lingo->code1(g_lingo->c_printtop); ;}
break;

case 52:
#line 242 "engines/director/lingo/lingo-gr.y"
#line 239 "engines/director/lingo/lingo-gr.y"
{ g_lingo->code1(g_lingo->c_exit); ;}
break;

case 54:
#line 246 "engines/director/lingo/lingo-gr.y"
#line 243 "engines/director/lingo/lingo-gr.y"
{ g_lingo->code1(g_lingo->c_global); g_lingo->codeString((yyvsp[(1) - (1)].s)->c_str()); delete (yyvsp[(1) - (1)].s); ;}
break;

case 55:
#line 247 "engines/director/lingo/lingo-gr.y"
#line 244 "engines/director/lingo/lingo-gr.y"
{ g_lingo->code1(g_lingo->c_global); g_lingo->codeString((yyvsp[(3) - (3)].s)->c_str()); delete (yyvsp[(3) - (3)].s); ;}
break;

case 56:
#line 258 "engines/director/lingo/lingo-gr.y"
#line 255 "engines/director/lingo/lingo-gr.y"
{ g_lingo->code1(g_lingo->c_gotoloop); ;}
break;

case 57:
#line 259 "engines/director/lingo/lingo-gr.y"
#line 256 "engines/director/lingo/lingo-gr.y"
{ g_lingo->code1(g_lingo->c_gotonext); ;}
break;

case 58:
#line 260 "engines/director/lingo/lingo-gr.y"
#line 257 "engines/director/lingo/lingo-gr.y"
{ g_lingo->code1(g_lingo->c_gotoprevious); ;}
break;

case 59:
#line 261 "engines/director/lingo/lingo-gr.y"
#line 258 "engines/director/lingo/lingo-gr.y"
{
g_lingo->code1(g_lingo->c_goto);
g_lingo->codeString((yyvsp[(2) - (2)].s)->c_str());
Expand All @@ -1856,7 +1853,7 @@ yyparse ()
break;

case 60:
#line 266 "engines/director/lingo/lingo-gr.y"
#line 263 "engines/director/lingo/lingo-gr.y"
{
g_lingo->code1(g_lingo->c_goto);
g_lingo->codeString((yyvsp[(2) - (3)].s)->c_str());
Expand All @@ -1866,7 +1863,7 @@ yyparse ()
break;

case 61:
#line 272 "engines/director/lingo/lingo-gr.y"
#line 269 "engines/director/lingo/lingo-gr.y"
{
g_lingo->code1(g_lingo->c_goto);
g_lingo->codeString("");
Expand All @@ -1875,80 +1872,80 @@ yyparse ()
break;

case 62:
#line 279 "engines/director/lingo/lingo-gr.y"
#line 276 "engines/director/lingo/lingo-gr.y"
{ (yyval.s) = (yyvsp[(3) - (3)].s); ;}
break;

case 63:
#line 280 "engines/director/lingo/lingo-gr.y"
#line 277 "engines/director/lingo/lingo-gr.y"
{ (yyval.s) = (yyvsp[(2) - (2)].s); ;}
break;

case 64:
#line 281 "engines/director/lingo/lingo-gr.y"
#line 278 "engines/director/lingo/lingo-gr.y"
{ (yyval.s) = (yyvsp[(2) - (2)].s); ;}
break;

case 65:
#line 282 "engines/director/lingo/lingo-gr.y"
#line 279 "engines/director/lingo/lingo-gr.y"
{ (yyval.s) = (yyvsp[(1) - (1)].s); ;}
break;

case 66:
#line 285 "engines/director/lingo/lingo-gr.y"
#line 282 "engines/director/lingo/lingo-gr.y"
{ (yyval.s) = (yyvsp[(3) - (3)].s); ;}
break;

case 67:
#line 286 "engines/director/lingo/lingo-gr.y"
#line 283 "engines/director/lingo/lingo-gr.y"
{ (yyval.s) = (yyvsp[(2) - (2)].s); ;}
break;

case 68:
#line 287 "engines/director/lingo/lingo-gr.y"
#line 284 "engines/director/lingo/lingo-gr.y"
{ (yyval.s) = (yyvsp[(3) - (3)].s); ;}
break;

case 69:
#line 315 "engines/director/lingo/lingo-gr.y"
#line 312 "engines/director/lingo/lingo-gr.y"
{ g_lingo->_indef = true; ;}
break;

case 70:
#line 316 "engines/director/lingo/lingo-gr.y"
#line 313 "engines/director/lingo/lingo-gr.y"
{
g_lingo->code1(g_lingo->c_procret);
g_lingo->define(*(yyvsp[(2) - (8)].s), (yyvsp[(4) - (8)].code), (yyvsp[(5) - (8)].narg));
g_lingo->_indef = false; ;}
break;

case 71:
#line 321 "engines/director/lingo/lingo-gr.y"
#line 318 "engines/director/lingo/lingo-gr.y"
{ (yyval.narg) = 0; ;}
break;

case 72:
#line 322 "engines/director/lingo/lingo-gr.y"
#line 319 "engines/director/lingo/lingo-gr.y"
{ g_lingo->codeArg((yyvsp[(1) - (1)].s)); (yyval.narg) = 1; ;}
break;

case 73:
#line 323 "engines/director/lingo/lingo-gr.y"
#line 320 "engines/director/lingo/lingo-gr.y"
{ g_lingo->codeArg((yyvsp[(3) - (3)].s)); (yyval.narg) = (yyvsp[(1) - (3)].narg) + 1; ;}
break;

case 74:
#line 324 "engines/director/lingo/lingo-gr.y"
#line 321 "engines/director/lingo/lingo-gr.y"
{ g_lingo->codeArg((yyvsp[(4) - (4)].s)); (yyval.narg) = (yyvsp[(1) - (4)].narg) + 1; ;}
break;

case 75:
#line 326 "engines/director/lingo/lingo-gr.y"
#line 323 "engines/director/lingo/lingo-gr.y"
{ g_lingo->codeArgStore(); ;}
break;

case 76:
#line 329 "engines/director/lingo/lingo-gr.y"
#line 326 "engines/director/lingo/lingo-gr.y"
{
g_lingo->code1(g_lingo->c_call);
g_lingo->codeString((yyvsp[(1) - (3)].s)->c_str());
Expand All @@ -1958,23 +1955,23 @@ yyparse ()
break;

case 77:
#line 337 "engines/director/lingo/lingo-gr.y"
#line 334 "engines/director/lingo/lingo-gr.y"
{ (yyval.narg) = 0; ;}
break;

case 78:
#line 338 "engines/director/lingo/lingo-gr.y"
#line 335 "engines/director/lingo/lingo-gr.y"
{ (yyval.narg) = 1; ;}
break;

case 79:
#line 339 "engines/director/lingo/lingo-gr.y"
#line 336 "engines/director/lingo/lingo-gr.y"
{ (yyval.narg) = (yyvsp[(1) - (3)].narg) + 1; ;}
break;


/* Line 1267 of yacc.c. */
#line 1978 "engines/director/lingo/lingo-gr.cpp"
#line 1975 "engines/director/lingo/lingo-gr.cpp"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
Expand Down Expand Up @@ -2188,6 +2185,6 @@ yyparse ()
}


#line 342 "engines/director/lingo/lingo-gr.y"
#line 339 "engines/director/lingo/lingo-gr.y"


7 changes: 2 additions & 5 deletions engines/director/lingo/lingo-gr.y
Expand Up @@ -230,11 +230,8 @@ expr: INT {
;

func: ID '(' arglist ')' {
g_lingo->code1(g_lingo->c_call);
g_lingo->codeString($1->c_str());
inst numpar = 0;
WRITE_UINT32(&numpar, $3);
g_lingo->code1(numpar); };
g_lingo->codeFunc($1, $3);
delete $1; }
| tMCI STRING { g_lingo->code1(g_lingo->c_mci); g_lingo->codeString($2->c_str()); delete $2; }
| tMCIWAIT ID { g_lingo->code1(g_lingo->c_mciwait); g_lingo->codeString($2->c_str()); delete $2; }
| tPUT expr { g_lingo->code1(g_lingo->c_printtop); }
Expand Down
19 changes: 2 additions & 17 deletions engines/director/lingo/lingo.cpp
Expand Up @@ -81,6 +81,8 @@ Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
for (const EventHandlerType *t = &eventHanlerDescs[0]; t->handler != kEventNone; ++t)
_eventHandlerTypes[t->handler] = t->name;

initBuiltIns();

_currentScript = 0;
_currentScriptType = kMovieScript;
_pc = 0;
Expand All @@ -93,23 +95,6 @@ Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
Lingo::~Lingo() {
}

int Lingo::codeString(const char *str) {
int numInsts = calcStringAlignment(str);

// Where we copy the string over
int pos = _currentScript->size();

// Allocate needed space in script
for (int i = 0; i < numInsts; i++)
_currentScript->push_back(0);

byte *dst = (byte *)&_currentScript->front() + pos * sizeof(inst);

memcpy(dst, str, strlen(str) + 1);

return _currentScript->size();
}

void Lingo::addCode(Common::String code, ScriptType type, uint16 id) {
code += '\n';

Expand Down

0 comments on commit 8cc88b6

Please sign in to comment.