[Scummvm-git-logs] scummvm master -> 11925974256d07ac05b2a9b4ba3322132719049f
moralrecordings
code at moral.net.au
Sun May 31 10:04:32 UTC 2020
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
69f4acacc8 DIRECTOR: LINGO: Split out varCreate from varAssign
1192597425 DIRECTOR: LINGO: Extend _methodVars to store a type
Commit: 69f4acacc8cb3928de3b2f6236b6fec9fb1bfed4
https://github.com/scummvm/scummvm/commit/69f4acacc8cb3928de3b2f6236b6fec9fb1bfed4
Author: Scott Percival (code at moral.net.au)
Date: 2020-05-31T17:32:58+08:00
Commit Message:
DIRECTOR: LINGO: Split out varCreate from varAssign
Changed paths:
engines/director/lingo/lingo-builtins.cpp
engines/director/lingo/lingo-bytecode.cpp
engines/director/lingo/lingo-code.cpp
engines/director/lingo/lingo-codegen.cpp
engines/director/lingo/lingo.h
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 24d4023f1b..99079a8bbf 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -301,7 +301,8 @@ void Lingo::initBuiltIns() {
target.type = VAR;
Datum source(name);
source.type = SYMBOL;
- g_lingo->varAssign(target, source, true, true);
+ g_lingo->varCreate(name, true);
+ g_lingo->varAssign(target, source, true);
}
}
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 45e7042bf7..ab2057f99b 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -452,7 +452,8 @@ void LC::cb_globalassign() {
// Lingo lets you declare globals inside a method.
// This doesn't define them in the script list, but you can still
// read and write to them???
- g_lingo->varAssign(target, source, true, true);
+ g_lingo->varCreate(name, true);
+ g_lingo->varAssign(target, source, true);
}
void LC::cb_objectfieldassign() {
@@ -532,8 +533,8 @@ void LC::cb_varassign() {
target.type = VAR;
debugC(3, kDebugLingoExec, "cb_varassign: assigning to %s", name.c_str());
Datum source = g_lingo->pop();
- // Local variables should be initialised by the script
- g_lingo->varAssign(target, source, false, false);
+ // Local variables should be initialised by the script, no varCreate here
+ g_lingo->varAssign(target, source, false);
}
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 0e28967594..6106a69a03 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -1366,10 +1366,11 @@ void LC::call(const Symbol &sym, int nargs) {
for (int i = symNArgs - 1; i >= 0; i--) {
Common::String name = (*sym.argNames)[i];
if (!g_lingo->_localvars->contains(name)) {
+ g_lingo->varCreate(name, false);
Datum arg(name);
arg.type = VAR;
Datum value = g_lingo->pop();
- g_lingo->varAssign(arg, value, true);
+ g_lingo->varAssign(arg, value);
} else {
warning("Argument %s already defined", name.c_str());
}
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index f49fccc6ed..4b6fcff0f7 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -227,7 +227,6 @@ Symbol Lingo::define(Common::String &name, int nargs, ScriptData *code, Common::
sym.u.defn = code;
sym.nargs = nargs;
sym.maxArgs = nargs;
- // TODO: Assign these properties from here
sym.argNames = argNames;
sym.varNames = varNames;
sym.ctx = _currentScriptContext;
@@ -454,7 +453,27 @@ int Lingo::castIdFetch(Datum &var) {
return id;
}
-void Lingo::varAssign(Datum &var, Datum &value, bool create, bool global) {
+void Lingo::varCreate(const Common::String &name, bool global) {
+ if (_localvars && _localvars->contains(name)) {
+ if (global)
+ warning("varCreate: variable %s is local, not global", name.c_str());
+ return;
+ } else if (_globalvars.contains(name)) {
+ if (!global)
+ warning("varCreate: variable %s is global, not local", name.c_str());
+ return;
+ }
+
+ if (global) {
+ _globalvars[name] = Symbol();
+ _globalvars[name].name = new Common::String(name);
+ } else {
+ (*_localvars)[name] = Symbol();
+ (*_localvars)[name].name = new Common::String(name);
+ }
+}
+
+void Lingo::varAssign(Datum &var, Datum &value, bool global) {
if (var.type != VAR && var.type != REFERENCE) {
warning("varAssign: assignment to non-variable");
return;
@@ -475,18 +494,8 @@ void Lingo::varAssign(Datum &var, Datum &value, bool create, bool global) {
}
if (!sym) {
- if (create) {;
- if (global) {
- _globalvars[name] = Symbol();
- sym = &_globalvars[name];
- } else {
- (*_localvars)[name] = Symbol();
- sym = &(*_localvars)[name];
- }
- } else {
- warning("varAssign: variable %s not defined", name.c_str());
- return;
- }
+ warning("varAssign: variable %s not defined", name.c_str());
+ return;
}
if (sym->type != INT && sym->type != VOID &&
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index beb2296b92..a4e1fa2a7d 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -325,7 +325,8 @@ public:
Symbol define(Common::String &s, int start, int nargs, Common::String *prefix = NULL, int end = -1, bool removeCode = true);
void processIf(int toplabel, int endlabel);
int castIdFetch(Datum &var);
- void varAssign(Datum &var, Datum &value, bool create = false, bool global = false);
+ void varCreate(const Common::String &name, bool global);
+ void varAssign(Datum &var, Datum &value, bool global = false);
Datum varFetch(Datum &var, bool global = false);
int getAlignedType(Datum &d1, Datum &d2);
Commit: 11925974256d07ac05b2a9b4ba3322132719049f
https://github.com/scummvm/scummvm/commit/11925974256d07ac05b2a9b4ba3322132719049f
Author: Scott Percival (code at moral.net.au)
Date: 2020-05-31T18:03:57+08:00
Commit Message:
DIRECTOR: LINGO: Extend _methodVars to store a type
Changed paths:
engines/director/lingo/lingo-code.cpp
engines/director/lingo/lingo-codegen.cpp
engines/director/lingo/lingo-gr.cpp
engines/director/lingo/lingo-gr.y
engines/director/lingo/lingo-lex.cpp
engines/director/lingo/lingo-lex.l
engines/director/lingo/lingo.h
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 6106a69a03..ffbfb15d2d 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -1169,7 +1169,7 @@ void LC::c_whencode() {
int entity = g_lingo->_currentEntityId;
g_lingo->_currentEntityId = 0;
- Symbol sym = g_lingo->define(eventname, start, 0, NULL, end, false); // Redefine, but not remove code
+ Symbol sym = g_lingo->codeDefine(eventname, start, 0, NULL, end, false); // Redefine, but not remove code
g_lingo->_currentEntityId = entity;
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index 4b6fcff0f7..823c3ef86d 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -255,11 +255,11 @@ Symbol Lingo::define(Common::String &name, int nargs, ScriptData *code, Common::
return sym;
}
-Symbol Lingo::define(Common::String &name, int start, int nargs, Common::String *prefix, int end, bool removeCode) {
+Symbol Lingo::codeDefine(Common::String &name, int start, int nargs, Common::String *prefix, int end, bool removeCode) {
if (prefix)
name = *prefix + "-" + name;
- debugC(1, kDebugLingoCompile, "define(\"%s\"(len: %d), %d, %d, \"%s\", %d) entity: %d",
+ debugC(1, kDebugLingoCompile, "codeDefine(\"%s\"(len: %d), %d, %d, \"%s\", %d) entity: %d",
name.c_str(), _currentScript->size() - 1, start, nargs, (prefix ? prefix->c_str() : ""),
end, _currentEntityId);
@@ -267,7 +267,13 @@ Symbol Lingo::define(Common::String &name, int start, int nargs, Common::String
end = _currentScript->size();
ScriptData *code = new ScriptData(&(*_currentScript)[start], end - start);
- Symbol sym = define(name, nargs, code);
+ Common::Array<Common::String> *argNames = new Common::Array<Common::String>;
+ for (uint i = 0; i < _argstack.size(); i++) {
+ argNames->push_back(Common::String(_argstack[i]->c_str()));
+ }
+ Common::Array<Common::String> *varNames = new Common::Array<Common::String>;
+ // FIXME: introspect variable names
+ Symbol sym = define(name, nargs, code, argNames, varNames);
// Now remove all defined code from the _currentScript
if (removeCode)
@@ -275,7 +281,6 @@ Symbol Lingo::define(Common::String &name, int start, int nargs, Common::String
_currentScript->remove_at(i);
}
-
return sym;
}
diff --git a/engines/director/lingo/lingo-gr.cpp b/engines/director/lingo/lingo-gr.cpp
index ff8d471966..db8a18a6e0 100644
--- a/engines/director/lingo/lingo-gr.cpp
+++ b/engines/director/lingo/lingo-gr.cpp
@@ -118,8 +118,8 @@ static void endDef() {
g_lingo->_methodVars.clear();
}
-static void mArg(Common::String *s) {
- g_lingo->_methodVars[*s] = true;
+static void mArg(Common::String *s, VarType type) {
+ g_lingo->_methodVars[*s] = type;
}
@@ -3178,7 +3178,7 @@ yyreduce:
{
g_lingo->code1(LC::c_global);
g_lingo->codeString((yyvsp[0].s)->c_str());
- mArg((yyvsp[0].s));
+ mArg((yyvsp[0].s), kVarGlobal);
delete (yyvsp[0].s); }
#line 3184 "engines/director/lingo/lingo-gr.cpp"
break;
@@ -3188,7 +3188,7 @@ yyreduce:
{
g_lingo->code1(LC::c_global);
g_lingo->codeString((yyvsp[0].s)->c_str());
- mArg((yyvsp[0].s));
+ mArg((yyvsp[0].s), kVarGlobal);
delete (yyvsp[0].s); }
#line 3194 "engines/director/lingo/lingo-gr.cpp"
break;
@@ -3198,7 +3198,7 @@ yyreduce:
{
g_lingo->code1(LC::c_property);
g_lingo->codeString((yyvsp[0].s)->c_str());
- mArg((yyvsp[0].s));
+ mArg((yyvsp[0].s), kVarProperty);
delete (yyvsp[0].s); }
#line 3204 "engines/director/lingo/lingo-gr.cpp"
break;
@@ -3208,7 +3208,7 @@ yyreduce:
{
g_lingo->code1(LC::c_property);
g_lingo->codeString((yyvsp[0].s)->c_str());
- mArg((yyvsp[0].s));
+ mArg((yyvsp[0].s), kVarProperty);
delete (yyvsp[0].s); }
#line 3214 "engines/director/lingo/lingo-gr.cpp"
break;
@@ -3218,7 +3218,7 @@ yyreduce:
{
g_lingo->code1(LC::c_instance);
g_lingo->codeString((yyvsp[0].s)->c_str());
- mArg((yyvsp[0].s));
+ mArg((yyvsp[0].s), kVarInstance);
delete (yyvsp[0].s); }
#line 3224 "engines/director/lingo/lingo-gr.cpp"
break;
@@ -3228,7 +3228,7 @@ yyreduce:
{
g_lingo->code1(LC::c_instance);
g_lingo->codeString((yyvsp[0].s)->c_str());
- mArg((yyvsp[0].s));
+ mArg((yyvsp[0].s), kVarInstance);
delete (yyvsp[0].s); }
#line 3234 "engines/director/lingo/lingo-gr.cpp"
break;
@@ -3336,7 +3336,7 @@ yyreduce:
#line 692 "engines/director/lingo/lingo-gr.y"
{
g_lingo->code1(LC::c_procret);
- g_lingo->define(*(yyvsp[-6].s), (yyvsp[-4].code), (yyvsp[-3].narg));
+ g_lingo->codeDefine(*(yyvsp[-6].s), (yyvsp[-4].code), (yyvsp[-3].narg));
endDef();
delete (yyvsp[-6].s); }
#line 3343 "engines/director/lingo/lingo-gr.cpp"
@@ -3358,7 +3358,7 @@ yyreduce:
#line 699 "engines/director/lingo/lingo-gr.y"
{
g_lingo->code1(LC::c_procret);
- g_lingo->define(*(yyvsp[-6].s), (yyvsp[-4].code), (yyvsp[-3].narg) + 1, &g_lingo->_currentFactory);
+ g_lingo->codeDefine(*(yyvsp[-6].s), (yyvsp[-4].code), (yyvsp[-3].narg) + 1, &g_lingo->_currentFactory);
endDef();
delete (yyvsp[-6].s); }
#line 3365 "engines/director/lingo/lingo-gr.cpp"
@@ -3368,7 +3368,7 @@ yyreduce:
#line 704 "engines/director/lingo/lingo-gr.y"
{ // D3
g_lingo->code1(LC::c_procret);
- g_lingo->define(*(yyvsp[-7].s), (yyvsp[-6].code), (yyvsp[-5].narg));
+ g_lingo->codeDefine(*(yyvsp[-7].s), (yyvsp[-6].code), (yyvsp[-5].narg));
endDef();
checkEnd((yyvsp[-1].s), (yyvsp[-7].s)->c_str(), false);
@@ -3381,7 +3381,7 @@ yyreduce:
#line 712 "engines/director/lingo/lingo-gr.y"
{ // D4. No 'end' clause
g_lingo->code1(LC::c_procret);
- g_lingo->define(*(yyvsp[-5].s), (yyvsp[-4].code), (yyvsp[-3].narg));
+ g_lingo->codeDefine(*(yyvsp[-5].s), (yyvsp[-4].code), (yyvsp[-3].narg));
endDef();
delete (yyvsp[-5].s); }
#line 3388 "engines/director/lingo/lingo-gr.cpp"
@@ -3408,13 +3408,13 @@ yyreduce:
case 160:
#line 722 "engines/director/lingo/lingo-gr.y"
- { g_lingo->codeArg((yyvsp[0].s)); mArg((yyvsp[0].s)); (yyval.narg) = 1; delete (yyvsp[0].s); }
+ { g_lingo->codeArg((yyvsp[0].s)); mArg((yyvsp[0].s), kVarArgument); (yyval.narg) = 1; delete (yyvsp[0].s); }
#line 3413 "engines/director/lingo/lingo-gr.cpp"
break;
case 161:
#line 723 "engines/director/lingo/lingo-gr.y"
- { g_lingo->codeArg((yyvsp[0].s)); mArg((yyvsp[0].s)); (yyval.narg) = (yyvsp[-2].narg) + 1; delete (yyvsp[0].s); }
+ { g_lingo->codeArg((yyvsp[0].s)); mArg((yyvsp[0].s), kVarArgument); (yyval.narg) = (yyvsp[-2].narg) + 1; delete (yyvsp[0].s); }
#line 3419 "engines/director/lingo/lingo-gr.cpp"
break;
diff --git a/engines/director/lingo/lingo-gr.y b/engines/director/lingo/lingo-gr.y
index 89a21ae93b..914142f28b 100644
--- a/engines/director/lingo/lingo-gr.y
+++ b/engines/director/lingo/lingo-gr.y
@@ -101,8 +101,8 @@ static void endDef() {
g_lingo->_methodVars.clear();
}
-static void mArg(Common::String *s) {
- g_lingo->_methodVars[*s] = true;
+static void mArg(Common::String *s, VarType type) {
+ g_lingo->_methodVars[*s] = type;
}
%}
@@ -590,34 +590,34 @@ proc: tPUT expr { g_lingo->code1(LC::c_printtop); }
globallist: ID {
g_lingo->code1(LC::c_global);
g_lingo->codeString($ID->c_str());
- mArg($ID);
+ mArg($ID, kVarGlobal);
delete $ID; }
| globallist ',' ID {
g_lingo->code1(LC::c_global);
g_lingo->codeString($ID->c_str());
- mArg($ID);
+ mArg($ID, kVarGlobal);
delete $ID; }
propertylist: ID {
g_lingo->code1(LC::c_property);
g_lingo->codeString($ID->c_str());
- mArg($ID);
+ mArg($ID, kVarProperty);
delete $ID; }
| propertylist ',' ID {
g_lingo->code1(LC::c_property);
g_lingo->codeString($ID->c_str());
- mArg($ID);
+ mArg($ID, kVarProperty);
delete $ID; }
instancelist: ID {
g_lingo->code1(LC::c_instance);
g_lingo->codeString($ID->c_str());
- mArg($ID);
+ mArg($ID, kVarInstance);
delete $ID; }
| instancelist ',' ID {
g_lingo->code1(LC::c_instance);
g_lingo->codeString($ID->c_str());
- mArg($ID);
+ mArg($ID, kVarInstance);
delete $ID; }
// go {to} {frame} whichFrame {of movie whichMovie}
@@ -691,19 +691,19 @@ playfunc: tPLAY expr { // "play #done" is also caught by this
defn: tMACRO { startDef(); } ID { g_lingo->_currentFactory.clear(); }
begin argdef '\n' argstore stmtlist {
g_lingo->code1(LC::c_procret);
- g_lingo->define(*$ID, $begin, $argdef);
+ g_lingo->codeDefine(*$ID, $begin, $argdef);
endDef();
delete $ID; }
| tFACTORY ID { g_lingo->codeFactory(*$ID); delete $ID; }
| tMETHOD { startDef(); }
begin argdef '\n' argstore stmtlist {
g_lingo->code1(LC::c_procret);
- g_lingo->define(*$tMETHOD, $begin, $argdef + 1, &g_lingo->_currentFactory);
+ g_lingo->codeDefine(*$tMETHOD, $begin, $argdef + 1, &g_lingo->_currentFactory);
endDef();
delete $tMETHOD; }
| on begin argdef '\n' argstore stmtlist ENDCLAUSE endargdef { // D3
g_lingo->code1(LC::c_procret);
- g_lingo->define(*$on, $begin, $argdef);
+ g_lingo->codeDefine(*$on, $begin, $argdef);
endDef();
checkEnd($ENDCLAUSE, $on->c_str(), false);
@@ -711,7 +711,7 @@ defn: tMACRO { startDef(); } ID { g_lingo->_currentFactory.clear(); }
delete $ENDCLAUSE; }
| on begin argdef '\n' argstore stmtlist { // D4. No 'end' clause
g_lingo->code1(LC::c_procret);
- g_lingo->define(*$on, $begin, $argdef);
+ g_lingo->codeDefine(*$on, $begin, $argdef);
endDef();
delete $on; }
@@ -719,8 +719,8 @@ on: tON { startDef(); } ID {
$$ = $ID; g_lingo->_currentFactory.clear(); g_lingo->_ignoreMe = true; }
argdef: /* nothing */ { $$ = 0; }
- | ID { g_lingo->codeArg($ID); mArg($ID); $$ = 1; delete $ID; }
- | argdef ',' ID { g_lingo->codeArg($ID); mArg($ID); $$ = $1 + 1; delete $ID; }
+ | ID { g_lingo->codeArg($ID); mArg($ID, kVarArgument); $$ = 1; delete $ID; }
+ | argdef ',' ID { g_lingo->codeArg($ID); mArg($ID, kVarArgument); $$ = $1 + 1; delete $ID; }
endargdef: /* nothing */
| ID { delete $ID; }
diff --git a/engines/director/lingo/lingo-lex.cpp b/engines/director/lingo/lingo-lex.cpp
index ce3cd88d5f..4c05b05bab 100644
--- a/engines/director/lingo/lingo-lex.cpp
+++ b/engines/director/lingo/lingo-lex.cpp
@@ -1612,7 +1612,7 @@ YY_RULE_SETUP
return ID;
// Check that this is one of locally used names:
- // argument, propery, instance or global
+ // argument, property, instance or global
if (g_lingo->_methodVars.contains(yytext))
return ID;
diff --git a/engines/director/lingo/lingo-lex.l b/engines/director/lingo/lingo-lex.l
index b6f410469e..948f481c3e 100644
--- a/engines/director/lingo/lingo-lex.l
+++ b/engines/director/lingo/lingo-lex.l
@@ -400,7 +400,7 @@ word { count(); return varCheck(tWORD, "word"); }
return ID;
// Check that this is one of locally used names:
- // argument, propery, instance or global
+ // argument, property, instance or global
if (g_lingo->_methodVars.contains(yytext))
return ID;
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index a4e1fa2a7d..d404db9ef8 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -52,6 +52,13 @@ enum LexerDefineState {
kStateInArgs
};
+enum VarType {
+ kVarArgument,
+ kVarProperty,
+ kVarInstance,
+ kVarGlobal
+};
+
typedef void (*inst)(void);
#define STOP (inst)0
#define ENTITY_INDEX(t,id) ((t) * 100000 + (id))
@@ -322,7 +329,7 @@ public:
void popContext();
void cleanLocalVars();
Symbol define(Common::String &s, int nargs, ScriptData *code, Common::Array<Common::String> *argNames = nullptr, Common::Array<Common::String> *varNames = nullptr);
- Symbol define(Common::String &s, int start, int nargs, Common::String *prefix = NULL, int end = -1, bool removeCode = true);
+ Symbol codeDefine(Common::String &s, int start, int nargs, Common::String *prefix = NULL, int end = -1, bool removeCode = true);
void processIf(int toplabel, int endlabel);
int castIdFetch(Datum &var);
void varCreate(const Common::String &name, bool global);
@@ -425,7 +432,7 @@ public:
LexerDefineState _indef;
bool _ignoreMe;
bool _immediateMode;
- Common::HashMap<Common::String, bool, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _methodVars;
+ Common::HashMap<Common::String, VarType, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _methodVars;
Common::Array<CFrame *> _callstack;
Common::Array<Common::String *> _argstack;
More information about the Scummvm-git-logs
mailing list