[Scummvm-git-logs] scummvm master -> 5f95faf1160421f7f6b04934ae644d71fd6bc438
djsrv
dservilla at gmail.com
Fri Jun 25 05:52:50 UTC 2021
This automated email contains information about 13 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
5b436c48aa DIRECTOR: LINGO: Clean up c_hilite
c6e6da2d2c DIRECTOR: LINGO: Remove localvars arg from varAssign
2cfa27b02d DIRECTOR: LINGO: Add CHUNKREF to varAssign
25c59ba25d DIRECTOR: LINGO: Change varFetch index check for consistency
895c36129e DIRECTOR: LINGO: Add put tests
f4d57ed911 DIRECTOR: LINGO: Fix constant compilation
f43026398f DIRECTOR: LINGO: Fix assert line numbers
effc76b14e DIRECTOR: LINGO: Implement put for non-existent chunks
fae07331ae DIRECTOR: LINGO: Add put tests for non-existent chunks
2fd96002d7 DIRECTOR: LINGO: Support nested chunks in delete and hilite
a3537bd5df DIRECTOR: LINGO: Add nested chunks tests
b4a7d4bdff DIRECTOR: LINGO: Support nested chunks in readChunkRef
5f95faf116 DIRECTOR: LINGO: Implement cb_v4assign2
Commit: 5b436c48aaf3718b5fea64b00b1cad070c9d6a0e
https://github.com/scummvm/scummvm/commit/5b436c48aaf3718b5fea64b00b1cad070c9d6a0e
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-25T01:52:40-04:00
Commit Message:
DIRECTOR: LINGO: Clean up c_hilite
For consistency with c_delete
Changed paths:
engines/director/lingo/lingo-code.cpp
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 1fafa47941..899c99f0fe 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -1627,19 +1627,19 @@ void LC::c_hilite() {
Datum d = g_lingo->pop();
int fieldId, start, end;
- if (d.isCastRef()) {
- fieldId = d.u.i;
- start = 0;
- end = -1;
- } else if (d.type == CHUNKREF) {
+ if (d.type == CHUNKREF) {
if (d.u.cref->source.isCastRef()) {
fieldId = d.u.cref->source.u.i;
start = d.u.cref->start;
end = d.u.cref->end;
} else {
- warning("BUILDBOT: c_delete: bad chunk ref field type: %s", d.u.cref->source.type2str());
+ warning("BUILDBOT: c_hilite: bad chunk ref field type: %s", d.u.cref->source.type2str());
return;
}
+ } else if (d.isCastRef()) {
+ fieldId = d.u.i;
+ start = 0;
+ end = -1;
} else {
warning("BUILDBOT: c_hilite: bad field type: %s", d.type2str());
return;
Commit: c6e6da2d2c79c1b5877eefded0012668f5c6667d
https://github.com/scummvm/scummvm/commit/c6e6da2d2c79c1b5877eefded0012668f5c6667d
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-25T01:52:40-04:00
Commit Message:
DIRECTOR: LINGO: Remove localvars arg from varAssign
I eliminated uses of this.
Changed paths:
engines/director/lingo/lingo-code.cpp
engines/director/lingo/lingo.cpp
engines/director/lingo/lingo.h
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 899c99f0fe..84caa70775 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -1394,7 +1394,7 @@ void LC::call(const Common::String &name, int nargs, bool allowRetVal) {
if (firstArg.isVarRef()) { // first arg could be method name
Datum objName(name);
objName.type = VARREF;
- Datum obj = g_lingo->varFetch(objName, nullptr, true);
+ Datum obj = g_lingo->varFetch(objName, true);
if (obj.type == OBJECT && (obj.u.obj->getObjType() & (kFactoryObj | kXObj))) {
debugC(3, kDebugLingoExec, "Method called on object: <%s>", obj.asString(true).c_str());
AbstractObject *target = obj.u.obj;
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 364e9f6caf..db2aee7c5d 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -1138,17 +1138,13 @@ int Lingo::getInt(uint pc) {
return (int)READ_UINT32(&((*_currentScript)[pc]));
}
-void Lingo::varAssign(const Datum &var, Datum &value, DatumHash *localvars) {
- if (localvars == nullptr) {
- localvars = _localvars;
- }
-
+void Lingo::varAssign(const Datum &var, Datum &value) {
switch (var.type) {
case VARREF:
{
Common::String name = *var.u.s;
- if (localvars && localvars->contains(name)) {
- (*localvars)[name] = value;
+ if (_localvars && _localvars->contains(name)) {
+ (*_localvars)[name] = value;
return;
}
if (_currentMe.type == OBJECT && _currentMe.u.obj->hasProp(name)) {
@@ -1168,8 +1164,8 @@ void Lingo::varAssign(const Datum &var, Datum &value, DatumHash *localvars) {
case LOCALREF:
{
Common::String name = *var.u.s;
- if (localvars && localvars->contains(name)) {
- (*localvars)[name] = value;
+ if (_localvars && _localvars->contains(name)) {
+ (*_localvars)[name] = value;
} else {
warning("varAssign: local variable %s not defined", name.c_str());
}
@@ -1215,11 +1211,7 @@ void Lingo::varAssign(const Datum &var, Datum &value, DatumHash *localvars) {
}
}
-Datum Lingo::varFetch(const Datum &var, DatumHash *localvars, bool silent) {
- if (localvars == nullptr) {
- localvars = _localvars;
- }
-
+Datum Lingo::varFetch(const Datum &var, bool silent) {
Datum result;
switch (var.type) {
@@ -1228,8 +1220,8 @@ Datum Lingo::varFetch(const Datum &var, DatumHash *localvars, bool silent) {
Datum d;
Common::String name = *var.u.s;
- if (localvars && localvars->contains(name)) {
- return (*localvars)[name];
+ if (_localvars && _localvars->contains(name)) {
+ return (*_localvars)[name];
}
if (_currentMe.type == OBJECT && _currentMe.u.obj->hasProp(name)) {
return _currentMe.u.obj->getProp(name);
@@ -1256,8 +1248,8 @@ Datum Lingo::varFetch(const Datum &var, DatumHash *localvars, bool silent) {
case LOCALREF:
{
Common::String name = *var.u.s;
- if (localvars && localvars->contains(name)) {
- return (*localvars)[name];
+ if (_localvars && _localvars->contains(name)) {
+ return (*_localvars)[name];
}
warning("varFetch: local variable %s not defined", name.c_str());
return result;
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 8900109282..41b03eaad0 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -277,8 +277,8 @@ public:
void pushContext(const Symbol funcSym, bool allowRetVal, Datum defaultRetVal);
void popContext();
void cleanLocalVars();
- void varAssign(const Datum &var, Datum &value, DatumHash *localvars = nullptr);
- Datum varFetch(const Datum &var, DatumHash *localvars = nullptr, bool silent = false);
+ void varAssign(const Datum &var, Datum &value);
+ Datum varFetch(const Datum &var, bool silent = false);
Datum findVarV4(int varType, const Datum &id);
int getAlignedType(const Datum &d1, const Datum &d2, bool numsOnly);
Commit: 2cfa27b02dae72a32369c258d25e182a5801318f
https://github.com/scummvm/scummvm/commit/2cfa27b02dae72a32369c258d25e182a5801318f
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-25T01:52:40-04:00
Commit Message:
DIRECTOR: LINGO: Add CHUNKREF to varAssign
Changed paths:
engines/director/lingo/lingo.cpp
engines/director/lingo/lingo.h
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index db2aee7c5d..d90e92ac47 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -1138,7 +1138,7 @@ int Lingo::getInt(uint pc) {
return (int)READ_UINT32(&((*_currentScript)[pc]));
}
-void Lingo::varAssign(const Datum &var, Datum &value) {
+void Lingo::varAssign(const Datum &var, const Datum &value) {
switch (var.type) {
case VARREF:
{
@@ -1205,6 +1205,16 @@ void Lingo::varAssign(const Datum &var, Datum &value) {
}
}
break;
+ case CHUNKREF:
+ {
+ if (var.u.cref->start < 0)
+ return;
+
+ Common::String src = var.u.cref->source.eval().asString();
+ Common::String res = src.substr(0, var.u.cref->start) + value.asString() + src.substr(var.u.cref->end);
+ varAssign(var.u.cref->source, res);
+ }
+ break;
default:
warning("varAssign: assignment to non-variable");
break;
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 41b03eaad0..c6fb17b885 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -277,7 +277,7 @@ public:
void pushContext(const Symbol funcSym, bool allowRetVal, Datum defaultRetVal);
void popContext();
void cleanLocalVars();
- void varAssign(const Datum &var, Datum &value);
+ void varAssign(const Datum &var, const Datum &value);
Datum varFetch(const Datum &var, bool silent = false);
Datum findVarV4(int varType, const Datum &id);
Commit: 25c59ba25d9d9abf92d26be572738403bad42997
https://github.com/scummvm/scummvm/commit/25c59ba25d9d9abf92d26be572738403bad42997
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-25T01:52:40-04:00
Commit Message:
DIRECTOR: LINGO: Change varFetch index check for consistency
Changed paths:
engines/director/lingo/lingo.cpp
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index d90e92ac47..4f4f7cde41 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -1304,7 +1304,7 @@ Datum Lingo::varFetch(const Datum &var, bool silent) {
{
Common::String src = var.u.cref->source.eval().asString();
result.type = STRING;
- if (var.u.cref->start == -1) {
+ if (var.u.cref->start < 0) {
result.u.s = new Common::String("");
} else {
result.u.s = new Common::String(src.substr(var.u.cref->start, var.u.cref->end - var.u.cref->start));
Commit: 895c36129e6abc38de07d2ec03907afd32daec89
https://github.com/scummvm/scummvm/commit/895c36129e6abc38de07d2ec03907afd32daec89
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-25T01:52:40-04:00
Commit Message:
DIRECTOR: LINGO: Add put tests
Changed paths:
A engines/director/lingo/tests/put.lingo
diff --git a/engines/director/lingo/tests/put.lingo b/engines/director/lingo/tests/put.lingo
new file mode 100644
index 0000000000..03bf4a5e03
--- /dev/null
+++ b/engines/director/lingo/tests/put.lingo
@@ -0,0 +1,23 @@
+put "qwertyuiop" into test
+put "a" before char 3 of test
+scummvmAssertEqual(test, "qwaertyuiop")
+
+put "qwertyuiop" into test
+put "a" into char 3 of test
+scummvmAssertEqual(test, "qwartyuiop")
+
+put "qwertyuiop" into test
+put "a" after char 3 of test
+scummvmAssertEqual(test, "qweartyuiop")
+
+put "lorem ipsum dolor sit amet" into test
+put "asdf" before word 3 of test
+scummvmAssertEqual(test, "lorem ipsum asdfdolor sit amet")
+
+put "lorem ipsum dolor sit amet" into test
+put "asdf" into word 3 of test
+scummvmAssertEqual(test, "lorem ipsum asdf sit amet")
+
+put "lorem ipsum dolor sit amet" into test
+put "asdf" after word 3 of test
+scummvmAssertEqual(test, "lorem ipsum dolorasdf sit amet")
Commit: f4d57ed911249d9e9f4bbbc69ff89b48e988ed14
https://github.com/scummvm/scummvm/commit/f4d57ed911249d9e9f4bbbc69ff89b48e988ed14
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-25T01:52:40-04:00
Commit Message:
DIRECTOR: LINGO: Fix constant compilation
Constants should never be coded as references.
Changed paths:
engines/director/lingo/lingo-codegen.cpp
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index ff259614ef..1b253f75c8 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -1079,15 +1079,15 @@ bool LingoCompiler::visitVarNode(VarNode *node) {
return true;
}
}
- if (_refMode) {
- codeVarRef(*node->name);
- return true;
- }
if (g_lingo->_builtinConsts.contains(*node->name)) {
code1(LC::c_constpush);
codeString(node->name->c_str());
return true;
}
+ if (_refMode) {
+ codeVarRef(*node->name);
+ return true;
+ }
codeVarGet(*node->name);
return true;
}
Commit: f43026398f03137af6aae4e509c459c2ae7706fa
https://github.com/scummvm/scummvm/commit/f43026398f03137af6aae4e509c459c2ae7706fa
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-25T01:52:40-04:00
Commit Message:
DIRECTOR: LINGO: Fix assert line numbers
Changed paths:
engines/director/lingo/lingo-ast.h
engines/director/lingo/lingo-codegen.cpp
engines/director/lingo/lingo-gr.cpp
engines/director/lingo/lingo-gr.y
diff --git a/engines/director/lingo/lingo-ast.h b/engines/director/lingo/lingo-ast.h
index 341d147a24..696938c22c 100644
--- a/engines/director/lingo/lingo-ast.h
+++ b/engines/director/lingo/lingo-ast.h
@@ -308,9 +308,10 @@ struct HandlerNode : Node {
struct CmdNode : StmtNode {
Common::String *name;
NodeList *args;
+ uint lineNumber;
- CmdNode(Common::String *nameIn, NodeList *argsIn)
- : StmtNode(kCmdNode), name(nameIn), args(argsIn) {}
+ CmdNode(Common::String *nameIn, NodeList *argsIn, uint lineNumberIn)
+ : StmtNode(kCmdNode), name(nameIn), args(argsIn), lineNumber(lineNumberIn) {}
virtual ~CmdNode() {
delete name;
deleteList(args);
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index 1b253f75c8..5721786d1e 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -253,14 +253,6 @@ int LingoCompiler::codeInt(int val) {
}
int LingoCompiler::codeCmd(const Common::String &s, int numpar) {
- // Insert current line number to our asserts
- if (s.equalsIgnoreCase("scummvmAssert") || s.equalsIgnoreCase("scummvmAssertEqual")) {
- code1(LC::c_intpush);
- codeInt(_linenumber);
-
- numpar++;
- }
-
int ret = code1(LC::c_callcmd);
codeString(s.c_str());
@@ -484,7 +476,9 @@ bool LingoCompiler::visitHandlerNode(HandlerNode *node) {
/* CmdNode */
bool LingoCompiler::visitCmdNode(CmdNode *node) {
- if (node->name->equalsIgnoreCase("go") && node->args->size() == 1 && (*node->args)[0]->type == kVarNode){
+ int numargs = node->args->size();
+
+ if (node->name->equalsIgnoreCase("go") && numargs == 1 && (*node->args)[0]->type == kVarNode){
VarNode *var = static_cast<VarNode *>((*node->args)[0]);
if (var->name->equalsIgnoreCase("loop") ||
var->name->equalsIgnoreCase("next") ||
@@ -497,7 +491,7 @@ bool LingoCompiler::visitCmdNode(CmdNode *node) {
}
// `play done` compiles to `play()`
- if (node->name->equalsIgnoreCase("play") && node->args->size() == 1 && (*node->args)[0]->type == kVarNode) {
+ if (node->name->equalsIgnoreCase("play") && numargs == 1 && (*node->args)[0]->type == kVarNode) {
VarNode *var = static_cast<VarNode *>((*node->args)[0]);
if (var->name->equalsIgnoreCase("done")) {
codeCmd(*node->name, 0);
@@ -506,7 +500,7 @@ bool LingoCompiler::visitCmdNode(CmdNode *node) {
}
if (node->name->equalsIgnoreCase("playAccel")) {
- for (uint i = 0; i < node->args->size(); i++) {
+ for (uint i = 0; i < numargs; i++) {
Node *arg = (*node->args)[i];
if (arg->type == kVarNode) {
code1(LC::c_symbolpush);
@@ -515,11 +509,11 @@ bool LingoCompiler::visitCmdNode(CmdNode *node) {
COMPILE(arg);
}
}
- codeCmd(*node->name, node->args->size());
+ codeCmd(*node->name, numargs);
return true;
}
- if (node->name->equalsIgnoreCase("sound") && node->args->size() >= 1 && (*node->args)[0]->type == kVarNode) {
+ if (node->name->equalsIgnoreCase("sound") && numargs >= 1 && (*node->args)[0]->type == kVarNode) {
VarNode *var = static_cast<VarNode *>((*node->args)[0]);
if (var->name->equalsIgnoreCase("close") ||
var->name->equalsIgnoreCase("fadeIn") ||
@@ -528,24 +522,30 @@ bool LingoCompiler::visitCmdNode(CmdNode *node) {
var->name->equalsIgnoreCase("stop")) {
code1(LC::c_symbolpush);
codeString(var->name->c_str());
- for (uint i = 1; i < node->args->size(); i++) {
+ for (uint i = 1; i < numargs; i++) {
COMPILE((*node->args)[i]);
}
- codeCmd(*node->name, node->args->size());
+ codeCmd(*node->name, numargs);
return true;
}
}
- if (node->args->size() >= 1 && (*node->args)[0]->type == kVarNode) {
+ if (numargs >= 1 && (*node->args)[0]->type == kVarNode) {
// This could be a method call. Code the first arg as a reference.
COMPILE_REF((*node->args)[0]);
- for (uint i = 1; i < node->args->size(); i++) {
+ for (uint i = 1; i < numargs; i++) {
COMPILE((*node->args)[i]);
}
} else {
COMPILE_LIST(node->args);
}
- codeCmd(*node->name, node->args->size());
+ // Insert current line number to our asserts
+ if (node->name->equalsIgnoreCase("scummvmAssert") || node->name->equalsIgnoreCase("scummvmAssertEqual")) {
+ code1(LC::c_intpush);
+ codeInt(node->lineNumber);
+ numargs++;
+ }
+ codeCmd(*node->name, numargs);
return true;
}
diff --git a/engines/director/lingo/lingo-gr.cpp b/engines/director/lingo/lingo-gr.cpp
index b9b0cc9e34..20deafc912 100644
--- a/engines/director/lingo/lingo-gr.cpp
+++ b/engines/director/lingo/lingo-gr.cpp
@@ -3179,43 +3179,43 @@ yyreduce:
case 113: /* proc: CMDID cmdargs '\n' */
#line 405 "engines/director/lingo/lingo-gr.y"
- { (yyval.node) = new CmdNode((yyvsp[-2].s), (yyvsp[-1].nodelist)); }
+ { (yyval.node) = new CmdNode((yyvsp[-2].s), (yyvsp[-1].nodelist), g_lingo->_compiler->_linenumber - 1); }
#line 3184 "engines/director/lingo/lingo-gr.cpp"
break;
case 114: /* proc: tPUT cmdargs '\n' */
#line 406 "engines/director/lingo/lingo-gr.y"
- { (yyval.node) = new CmdNode(new Common::String("put"), (yyvsp[-1].nodelist)); }
+ { (yyval.node) = new CmdNode(new Common::String("put"), (yyvsp[-1].nodelist), g_lingo->_compiler->_linenumber - 1); }
#line 3190 "engines/director/lingo/lingo-gr.cpp"
break;
case 115: /* proc: tGO cmdargs '\n' */
#line 407 "engines/director/lingo/lingo-gr.y"
- { (yyval.node) = new CmdNode(new Common::String("go"), (yyvsp[-1].nodelist)); }
+ { (yyval.node) = new CmdNode(new Common::String("go"), (yyvsp[-1].nodelist), g_lingo->_compiler->_linenumber - 1); }
#line 3196 "engines/director/lingo/lingo-gr.cpp"
break;
case 116: /* proc: tGO frameargs '\n' */
#line 408 "engines/director/lingo/lingo-gr.y"
- { (yyval.node) = new CmdNode(new Common::String("go"), (yyvsp[-1].nodelist)); }
+ { (yyval.node) = new CmdNode(new Common::String("go"), (yyvsp[-1].nodelist), g_lingo->_compiler->_linenumber - 1); }
#line 3202 "engines/director/lingo/lingo-gr.cpp"
break;
case 117: /* proc: tPLAY cmdargs '\n' */
#line 409 "engines/director/lingo/lingo-gr.y"
- { (yyval.node) = new CmdNode(new Common::String("play"), (yyvsp[-1].nodelist)); }
+ { (yyval.node) = new CmdNode(new Common::String("play"), (yyvsp[-1].nodelist), g_lingo->_compiler->_linenumber - 1); }
#line 3208 "engines/director/lingo/lingo-gr.cpp"
break;
case 118: /* proc: tPLAY frameargs '\n' */
#line 410 "engines/director/lingo/lingo-gr.y"
- { (yyval.node) = new CmdNode(new Common::String("play"), (yyvsp[-1].nodelist)); }
+ { (yyval.node) = new CmdNode(new Common::String("play"), (yyvsp[-1].nodelist), g_lingo->_compiler->_linenumber - 1); }
#line 3214 "engines/director/lingo/lingo-gr.cpp"
break;
case 119: /* proc: tOPEN cmdargs '\n' */
#line 411 "engines/director/lingo/lingo-gr.y"
- { (yyval.node) = new CmdNode(new Common::String("open"), (yyvsp[-1].nodelist)); }
+ { (yyval.node) = new CmdNode(new Common::String("open"), (yyvsp[-1].nodelist), g_lingo->_compiler->_linenumber - 1); }
#line 3220 "engines/director/lingo/lingo-gr.cpp"
break;
@@ -3225,7 +3225,7 @@ yyreduce:
NodeList *args = new NodeList;
args->push_back((yyvsp[-3].node));
args->push_back((yyvsp[-1].node));
- (yyval.node) = new CmdNode(new Common::String("open"), args); }
+ (yyval.node) = new CmdNode(new Common::String("open"), args, g_lingo->_compiler->_linenumber - 1); }
#line 3230 "engines/director/lingo/lingo-gr.cpp"
break;
diff --git a/engines/director/lingo/lingo-gr.y b/engines/director/lingo/lingo-gr.y
index 24315eacd4..0b367ea532 100644
--- a/engines/director/lingo/lingo-gr.y
+++ b/engines/director/lingo/lingo-gr.y
@@ -402,18 +402,18 @@ stmtoneliner: proc
| definevars
;
-proc: CMDID cmdargs '\n' { $$ = new CmdNode($CMDID, $cmdargs); }
- | tPUT cmdargs '\n' { $$ = new CmdNode(new Common::String("put"), $cmdargs); }
- | tGO cmdargs '\n' { $$ = new CmdNode(new Common::String("go"), $cmdargs); }
- | tGO frameargs '\n' { $$ = new CmdNode(new Common::String("go"), $frameargs); }
- | tPLAY cmdargs '\n' { $$ = new CmdNode(new Common::String("play"), $cmdargs); }
- | tPLAY frameargs '\n' { $$ = new CmdNode(new Common::String("play"), $frameargs); }
- | tOPEN cmdargs '\n' { $$ = new CmdNode(new Common::String("open"), $cmdargs); }
+proc: CMDID cmdargs '\n' { $$ = new CmdNode($CMDID, $cmdargs, g_lingo->_compiler->_linenumber - 1); }
+ | tPUT cmdargs '\n' { $$ = new CmdNode(new Common::String("put"), $cmdargs, g_lingo->_compiler->_linenumber - 1); }
+ | tGO cmdargs '\n' { $$ = new CmdNode(new Common::String("go"), $cmdargs, g_lingo->_compiler->_linenumber - 1); }
+ | tGO frameargs '\n' { $$ = new CmdNode(new Common::String("go"), $frameargs, g_lingo->_compiler->_linenumber - 1); }
+ | tPLAY cmdargs '\n' { $$ = new CmdNode(new Common::String("play"), $cmdargs, g_lingo->_compiler->_linenumber - 1); }
+ | tPLAY frameargs '\n' { $$ = new CmdNode(new Common::String("play"), $frameargs, g_lingo->_compiler->_linenumber - 1); }
+ | tOPEN cmdargs '\n' { $$ = new CmdNode(new Common::String("open"), $cmdargs, g_lingo->_compiler->_linenumber - 1); }
| tOPEN expr[arg1] tWITH expr[arg2] '\n' {
NodeList *args = new NodeList;
args->push_back($arg1);
args->push_back($arg2);
- $$ = new CmdNode(new Common::String("open"), args); }
+ $$ = new CmdNode(new Common::String("open"), args, g_lingo->_compiler->_linenumber - 1); }
| tNEXT tREPEAT '\n' { $$ = new NextRepeatNode(); }
| tEXIT tREPEAT '\n' { $$ = new ExitRepeatNode(); }
| tEXIT '\n' { $$ = new ExitNode(); }
Commit: effc76b14e270b5e59ad6f4d3fef56a488aa6cc3
https://github.com/scummvm/scummvm/commit/effc76b14e270b5e59ad6f4d3fef56a488aa6cc3
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-25T01:52:40-04:00
Commit Message:
DIRECTOR: LINGO: Implement put for non-existent chunks
Changed paths:
engines/director/lingo/lingo.cpp
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 4f4f7cde41..3aa804b46e 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -1207,11 +1207,38 @@ void Lingo::varAssign(const Datum &var, const Datum &value) {
break;
case CHUNKREF:
{
- if (var.u.cref->start < 0)
- return;
-
Common::String src = var.u.cref->source.eval().asString();
- Common::String res = src.substr(0, var.u.cref->start) + value.asString() + src.substr(var.u.cref->end);
+ Common::String res;
+ if (var.u.cref->start >= 0) {
+ res = src.substr(0, var.u.cref->start) + value.asString() + src.substr(var.u.cref->end);
+ } else {
+ // non-existent chunk - insert more chars, items, or lines
+ res = src;
+ int numberOfChunks = LC::lastChunk(var.u.cref->type, var.u.cref->source).u.cref->startChunk;
+ switch (var.u.cref->type) {
+ case kChunkChar:
+ while (numberOfChunks < var.u.cref->startChunk - 1) {
+ res += ' ';
+ numberOfChunks++;
+ }
+ break;
+ case kChunkWord:
+ break;
+ case kChunkItem:
+ while (numberOfChunks < var.u.cref->startChunk ) {
+ res += _itemDelimiter;
+ numberOfChunks++;
+ }
+ break;
+ case kChunkLine:
+ while (numberOfChunks < var.u.cref->startChunk ) {
+ res += '\n';
+ numberOfChunks++;
+ }
+ break;
+ }
+ res += value.asString();
+ }
varAssign(var.u.cref->source, res);
}
break;
Commit: fae07331ae67606a2a06df3b6f05b12d4343b21b
https://github.com/scummvm/scummvm/commit/fae07331ae67606a2a06df3b6f05b12d4343b21b
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-25T01:52:40-04:00
Commit Message:
DIRECTOR: LINGO: Add put tests for non-existent chunks
Changed paths:
engines/director/lingo/tests/put.lingo
diff --git a/engines/director/lingo/tests/put.lingo b/engines/director/lingo/tests/put.lingo
index 03bf4a5e03..1ebcaf4c14 100644
--- a/engines/director/lingo/tests/put.lingo
+++ b/engines/director/lingo/tests/put.lingo
@@ -21,3 +21,19 @@ scummvmAssertEqual(test, "lorem ipsum asdf sit amet")
put "lorem ipsum dolor sit amet" into test
put "asdf" after word 3 of test
scummvmAssertEqual(test, "lorem ipsum dolorasdf sit amet")
+
+put "123456789" into test
+put "foo" into char 20 of test
+scummvmAssertEqual(test, "123456789 foo")
+
+put "foo" into test
+put "bar" into word 10000 of test
+scummvmAssertEqual(test, "foobar")
+
+put "foo" into test
+put "bar" into item 10 of test
+scummvmAssertEqual(test, "foo,,,,,,,,,bar")
+
+put "foo" into test"
+put "bar" into line 10 of test
+scummvmAssertEqual(test, "foo" & RETURN & RETURN & RETURN & RETURN & RETURN & RETURN & RETURN & RETURN & RETURN & "bar")
Commit: 2fd96002d7bc7f794b489082e7fac65a76f8429b
https://github.com/scummvm/scummvm/commit/2fd96002d7bc7f794b489082e7fac65a76f8429b
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-25T01:52:40-04:00
Commit Message:
DIRECTOR: LINGO: Support nested chunks in delete and hilite
Changed paths:
engines/director/lingo/lingo-code.cpp
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 84caa70775..f56b8b3941 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -1578,11 +1578,15 @@ void LC::c_delete() {
Datum field;
int start, end;
if (d.type == CHUNKREF) {
- if (d.u.cref->source.isVarRef() || d.u.cref->source.isCastRef()) {
- field = d.u.cref->source;
- start = d.u.cref->start;
- end = d.u.cref->end;
- } else {
+ start = d.u.cref->start;
+ end = d.u.cref->end;
+ field = d.u.cref->source;
+ while (field.type == CHUNKREF) {
+ start += field.u.cref->start;
+ end += field.u.cref->start;
+ field = field.u.cref->source;
+ }
+ if (!field.isVarRef() && !field.isCastRef()) {
warning("BUILDBOT: c_delete: bad chunk ref field type: %s", d.u.cref->source.type2str());
return;
}
@@ -1628,10 +1632,16 @@ void LC::c_hilite() {
int fieldId, start, end;
if (d.type == CHUNKREF) {
- if (d.u.cref->source.isCastRef()) {
- fieldId = d.u.cref->source.u.i;
- start = d.u.cref->start;
- end = d.u.cref->end;
+ start = d.u.cref->start;
+ end = d.u.cref->end;
+ Datum src = d.u.cref->source;
+ while (src.type == CHUNKREF) {
+ start += src.u.cref->start;
+ end += src.u.cref->start;
+ src = src.u.cref->source;
+ }
+ if (src.isCastRef()) {
+ fieldId = src.u.i;
} else {
warning("BUILDBOT: c_hilite: bad chunk ref field type: %s", d.u.cref->source.type2str());
return;
Commit: a3537bd5dfc373237b9dbbaf95df12e05acd7c8b
https://github.com/scummvm/scummvm/commit/a3537bd5dfc373237b9dbbaf95df12e05acd7c8b
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-25T01:52:40-04:00
Commit Message:
DIRECTOR: LINGO: Add nested chunks tests
Changed paths:
engines/director/lingo/tests/delete.lingo
engines/director/lingo/tests/put.lingo
diff --git a/engines/director/lingo/tests/delete.lingo b/engines/director/lingo/tests/delete.lingo
index c400a0ed4d..dcab0c170b 100644
--- a/engines/director/lingo/tests/delete.lingo
+++ b/engines/director/lingo/tests/delete.lingo
@@ -57,3 +57,7 @@ scummvmAssertEqual(test, "lorem")
put "lorem" & RETURN & "ipsum" & RETURN & "dolor" & RETURN & "sit" & RETURN & "amet" into test
delete the last line of test
scummvmAssertEqual(test, "lorem" & RETURN & "ipsum" & RETURN & "dolor" & RETURN & "sit")
+
+put "foo" & RETURN & "lorem ipsum" into test
+delete char 3 of word 2 of line 2 of test
+scummvmAssertEqual(test, "foo" & RETURN & "lorem ipum")
diff --git a/engines/director/lingo/tests/put.lingo b/engines/director/lingo/tests/put.lingo
index 1ebcaf4c14..5653675f86 100644
--- a/engines/director/lingo/tests/put.lingo
+++ b/engines/director/lingo/tests/put.lingo
@@ -37,3 +37,7 @@ scummvmAssertEqual(test, "foo,,,,,,,,,bar")
put "foo" into test"
put "bar" into line 10 of test
scummvmAssertEqual(test, "foo" & RETURN & RETURN & RETURN & RETURN & RETURN & RETURN & RETURN & RETURN & RETURN & "bar")
+
+put "foo" & RETURN & "lorem ipsum" into test
+put "bar" into char 3 of word 2 of line 2 of test
+scummvmAssertEqual(test, "foo" & RETURN & "lorem ipbarum")
Commit: b4a7d4bdffdce7f07cad15ae62fa35763d785571
https://github.com/scummvm/scummvm/commit/b4a7d4bdffdce7f07cad15ae62fa35763d785571
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-25T01:52:40-04:00
Commit Message:
DIRECTOR: LINGO: Support nested chunks in readChunkRef
Changed paths:
engines/director/lingo/lingo-code.cpp
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index f56b8b3941..82233365fb 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -1012,16 +1012,17 @@ Datum LC::readChunkRef(const Datum &src) {
Datum lastChar = g_lingo->pop();
Datum firstChar = g_lingo->pop();
- if (firstChar.asInt() != 0)
- return LC::chunkRef(kChunkChar, firstChar.asInt(), lastChar.asInt(), src);
- if (firstWord.asInt() != 0)
- return LC::chunkRef(kChunkWord, firstWord.asInt(), lastWord.asInt(), src);
- if (firstItem.asInt() != 0)
- return LC::chunkRef(kChunkItem, firstItem.asInt(), lastItem.asInt(), src);
+ Datum ref = src;
if (firstLine.asInt() != 0)
- return LC::chunkRef(kChunkLine, firstLine.asInt(), lastLine.asInt(), src);
+ ref = LC::chunkRef(kChunkLine, firstLine.asInt(), lastLine.asInt(), ref);
+ if (firstItem.asInt() != 0)
+ ref = LC::chunkRef(kChunkItem, firstItem.asInt(), lastItem.asInt(), ref);
+ if (firstWord.asInt() != 0)
+ ref = LC::chunkRef(kChunkWord, firstWord.asInt(), lastWord.asInt(), ref);
+ if (firstChar.asInt() != 0)
+ ref = LC::chunkRef(kChunkChar, firstChar.asInt(), lastChar.asInt(), ref);
- return src;
+ return ref;
}
void LC::c_of() {
Commit: 5f95faf1160421f7f6b04934ae644d71fd6bc438
https://github.com/scummvm/scummvm/commit/5f95faf1160421f7f6b04934ae644d71fd6bc438
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-25T01:52:40-04:00
Commit Message:
DIRECTOR: LINGO: Implement cb_v4assign2
Changed paths:
engines/director/lingo/lingo-bytecode.cpp
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 2ed91411a3..fe1a6b6243 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -644,9 +644,33 @@ void LC::cb_varassign() {
void LC::cb_v4assign2() {
- g_lingo->readInt();
- g_lingo->printSTUBWithArglist("cb_v4assign2", 10);
- g_lingo->dropStack(10);
+int arg = g_lingo->readInt();
+ int op = (arg >> 4) & 0xF;
+ int varType = arg & 0xF;
+ Datum varId = g_lingo->pop();
+
+ Datum var = g_lingo->findVarV4(varType, varId);
+ Datum ref = readChunkRef(var);
+ g_lingo->push(ref);
+
+ switch (op) {
+ case 1:
+ // put value into chunk
+ LC::c_assign();
+ break;
+ case 2:
+ // put value after chunk
+ LC::c_putafter();
+ break;
+ case 3:
+ // put value before chunk
+ LC::c_putbefore();
+ break;
+ default:
+ warning("cb_v4assign2: unknown operator %d", op);
+ g_lingo->pop();
+ break;
+ }
}
More information about the Scummvm-git-logs
mailing list