[Scummvm-git-logs] scummvm master -> f747445e15cbf81876d54b28f6c2d53b0500a2f5
djsrv
dservilla at gmail.com
Wed Jun 9 00:10:58 UTC 2021
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
9c6165554f DIRECTOR: LINGO: Add LC::readChunkRef
5378369652 DIRECTOR: Add consts
e50ea9b06e DIRECTOR: LINGO: Rework chunk references
ce30bcb0d7 DIRECTOR: LINGO: Use chunk refs in b_numberof/lastof
f747445e15 DIRECTOR: LINGO: Implement kTEAString properties
Commit: 9c6165554fe8b573a275ec184340263fe30ed6c6
https://github.com/scummvm/scummvm/commit/9c6165554fe8b573a275ec184340263fe30ed6c6
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-08T20:06:28-04:00
Commit Message:
DIRECTOR: LINGO: Add LC::readChunkRef
Changed paths:
engines/director/lingo/lingo-code.cpp
engines/director/lingo/lingo-code.h
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index dcb519b7dc..6afdb74143 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -954,9 +954,7 @@ Datum LC::chunkRef(ChunkType type, int startChunk, int endChunk, const Datum &sr
return res;
}
-void LC::c_of() {
- // put char 5 of word 1 of line 2 into field "thing"
- Datum src = g_lingo->pop();
+Datum LC::readChunkRef(const Datum &src) {
Datum lastLine = g_lingo->pop();
Datum firstLine = g_lingo->pop();
Datum lastItem = g_lingo->pop();
@@ -966,18 +964,22 @@ void LC::c_of() {
Datum lastChar = g_lingo->pop();
Datum firstChar = g_lingo->pop();
- Datum res = src;
-
if (firstChar.asInt() > 0)
- res = LC::chunkRef(kChunkChar, firstChar.asInt(), lastChar.asInt(), src);
- else if (firstWord.asInt() > 0)
- res = LC::chunkRef(kChunkWord, firstWord.asInt(), lastWord.asInt(), src);
- else if (firstItem.asInt() > 0)
- res = LC::chunkRef(kChunkItem, firstItem.asInt(), lastItem.asInt(), src);
- else if (lastLine.asInt() > 0)
- res = LC::chunkRef(kChunkLine, firstLine.asInt(), lastLine.asInt(), src);
+ 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);
+ if (lastLine.asInt() > 0)
+ return LC::chunkRef(kChunkLine, firstLine.asInt(), lastLine.asInt(), src);
- g_lingo->push(res);
+ return src;
+}
+
+void LC::c_of() {
+ Datum src = g_lingo->pop();
+ Datum ref = readChunkRef(src);
+ g_lingo->push(ref.eval());
}
void LC::c_charOf() {
diff --git a/engines/director/lingo/lingo-code.h b/engines/director/lingo/lingo-code.h
index c07a9a75d4..8da24fea9b 100644
--- a/engines/director/lingo/lingo-code.h
+++ b/engines/director/lingo/lingo-code.h
@@ -57,6 +57,7 @@ void c_starts();
void c_intersects();
void c_within();
Datum chunkRef(ChunkType type, int startChunk, int endChunk, const Datum &src);
+Datum readChunkRef(const Datum &src);
void c_of();
void c_charOf();
void c_charToOf();
Commit: 53783696525f8d1a934767034b893344860be10d
https://github.com/scummvm/scummvm/commit/53783696525f8d1a934767034b893344860be10d
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-08T20:06:28-04:00
Commit Message:
DIRECTOR: Add consts
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 055e6f5c10..2405755564 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -855,7 +855,7 @@ void Datum::reset() {
#endif
}
-Datum Datum::eval() {
+Datum Datum::eval() const {
if (type == VAR || type == FIELDREF || type == CHUNKREF) {
return g_lingo->varFetch(*this);
}
@@ -1272,7 +1272,7 @@ int Lingo::getInt(uint pc) {
return (int)READ_UINT32(&((*_currentScript)[pc]));
}
-void Lingo::varAssign(Datum &var, Datum &value, bool global, DatumHash *localvars) {
+void Lingo::varAssign(const Datum &var, Datum &value, bool global, DatumHash *localvars) {
if (localvars == nullptr) {
localvars = _localvars;
}
@@ -1325,7 +1325,7 @@ void Lingo::varAssign(Datum &var, Datum &value, bool global, DatumHash *localvar
}
}
-Datum Lingo::varFetch(Datum &var, bool global, DatumHash *localvars, bool silent) {
+Datum Lingo::varFetch(const Datum &var, bool global, DatumHash *localvars, bool silent) {
if (localvars == nullptr) {
localvars = _localvars;
}
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 1f9a5c6406..7781f460b8 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -136,7 +136,7 @@ struct Datum { /* interpreter stack type */
reset();
}
- Datum eval();
+ Datum eval() const;
double asFloat() const;
int asInt() const;
Common::String asString(bool printonly = false) const;
@@ -295,8 +295,8 @@ public:
void pushContext(const Symbol funcSym, bool allowRetVal, Datum defaultRetVal);
void popContext();
void cleanLocalVars();
- void varAssign(Datum &var, Datum &value, bool global = false, DatumHash *localvars = nullptr);
- Datum varFetch(Datum &var, bool global = false, DatumHash *localvars = nullptr, bool silent = false);
+ void varAssign(const Datum &var, Datum &value, bool global = false, DatumHash *localvars = nullptr);
+ Datum varFetch(const Datum &var, bool global = false, DatumHash *localvars = nullptr, bool silent = false);
Datum findVarV4(int varType, const Datum &id);
int getAlignedType(const Datum &d1, const Datum &d2, bool numsOnly);
Commit: e50ea9b06e4ca638e276fc3d48b2a8779418602d
https://github.com/scummvm/scummvm/commit/e50ea9b06e4ca638e276fc3d48b2a8779418602d
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-08T20:06:28-04:00
Commit Message:
DIRECTOR: LINGO: Rework chunk references
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 6afdb74143..a61470a93a 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -876,80 +876,128 @@ void LC::c_within() {
Datum LC::chunkRef(ChunkType type, int startChunk, int endChunk, const Datum &src) {
// A chunk expression is made up of 0 or more chunks within a source text.
- // These chunks are called chars, words, items, or lines, but it's easier to think of them
- // as a substring between 0 or more skip characters and a break character (or the end of the string).
// This function returns a reference to the source text, the start index of the first chunk,
// and the end index of the last chunk in the chunk expression.
+ // If startChunk < 1, return the last chunk.
- if (startChunk < 1 || (0 > endChunk && endChunk < startChunk))
+ if (0 > endChunk && endChunk < startChunk)
return src;
if (endChunk < 1)
endChunk = startChunk;
- Common::String skipChars;
- Common::String breakChars;
+ Common::String str = src.eval().asString();
+
+ // these hold the bounds of the last chunk in the expression
+ int chunkNum = 0;
+ int chunkStartIdx = -1;
+ int chunkEndIdx = -1;
+
+ // these hold the bounds of the entire chunk expression
+ int exprStartIdx = -1;
+ int exprEndIdx = -1;
switch (type) {
case kChunkChar:
- skipChars = "";
- breakChars = "";
+ if (startChunk < 1) {
+ // last char was requested. set its bounds.
+ chunkNum = str.size();
+ chunkStartIdx = str.size() - 1;
+ chunkEndIdx = str.size();
+ } else if (str.size() > 0) {
+ exprStartIdx = MIN(startChunk, (int)str.size()) - 1;
+ exprEndIdx = MIN(endChunk, (int)str.size());
+ }
break;
case kChunkWord:
- skipChars = "\t\n\r ";
- breakChars = "\t\n\r ";
+ {
+ Common::String whitespace = "\t\n\r ";
+
+ int idx = 0;
+ while (idx < (int)str.size() && whitespace.contains(str[idx])) {
+ idx++;
+ }
+ while (idx < (int)str.size()) {
+ // each loop processes one chunk
+ chunkNum++;
+
+ // start of chunk
+ chunkStartIdx = idx;
+ if (chunkNum == startChunk) {
+ exprStartIdx = chunkStartIdx;
+ }
+
+ while (idx < (int)str.size() && !whitespace.contains(str[idx])) {
+ idx++;
+ }
+
+ // end of chunk
+ chunkEndIdx = idx;
+
+ if (chunkNum == endChunk) {
+ exprEndIdx = chunkEndIdx;
+ break;
+ }
+
+ while (idx < (int)str.size() && whitespace.contains(str[idx])) {
+ idx++;
+ }
+ }
+ }
break;
case kChunkItem:
- skipChars = "";
- breakChars = g_lingo->_itemDelimiter;
- break;
case kChunkLine:
- skipChars = "";
- breakChars = "\n\r";
- break;
- }
-
- Common::String str = src.asString();
- int idx = 0;
- int chunkNum = 0;
+ {
+ char delimiter = (type == kChunkItem) ? g_lingo->_itemDelimiter : '\n';
+
+ int idx = 0;
+ while (true) {
+ // each loop processes one chunk
+ chunkNum++;
+
+ // start of chunk
+ chunkStartIdx = idx;
+ if (chunkNum == startChunk) {
+ exprStartIdx = chunkStartIdx;
+ }
- int startIdx = -1;
- int endIdx = -1;
+ while (idx < (int)str.size() && str[idx] != delimiter) {
+ idx++;
+ }
- while (true) {
- // each iteration processes one chunk
+ // end of chunk
+ chunkEndIdx = idx;
+ if (chunkNum == endChunk) {
+ exprEndIdx = chunkEndIdx;
+ break;
+ }
- // find the start of the chunk
- while (idx < (int)str.size() && skipChars.contains(str[idx])) {
- idx++;
- }
- chunkNum++;
- if (chunkNum == startChunk) {
- startIdx = idx; // found start of chunk expression
+ if (idx == (int)str.size())
+ break;
+
+ idx++; // skip delimiter
+ }
}
+ break;
+ }
- // find the end of the chunk
- if (!breakChars.empty()) {
- while (idx < (int)str.size() && !breakChars.contains(str[idx])) {
- idx++;
- }
- } else if (idx < (int)str.size()) {
- idx++;
+ if (startChunk < 1) {
+ // return the last chunk we found
+ exprStartIdx = chunkStartIdx;
+ exprEndIdx = chunkEndIdx;
+ } else {
+ if (exprStartIdx < 0) {
+ // we never found the requested start chunk
+ exprStartIdx = -1;
}
- if (chunkNum == endChunk || idx == (int)str.size()) {
- endIdx = idx; // found end of chunk expression
- break;
+ if (exprEndIdx < 0) {
+ // we never found the requested end chunk
+ exprEndIdx = str.size();
}
-
- if (!breakChars.empty())
- idx++; // skip break char
}
- if (startIdx < 0)
- startIdx = endIdx;
-
Datum res;
- res.u.cref = new ChunkReference(src, startIdx, endIdx);
+ res.u.cref = new ChunkReference(src, type, startChunk, endChunk, exprStartIdx, exprEndIdx);
res.type = CHUNKREF;
return res;
}
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 2405755564..e23d638788 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -992,8 +992,24 @@ Common::String Datum::asString(bool printonly) const {
break;
case CHUNKREF:
{
+ Common::String chunkType;
+ switch (u.cref->type) {
+ case kChunkChar:
+ chunkType = "char";
+ break;
+ case kChunkWord:
+ chunkType = "word";
+ break;
+ case kChunkItem:
+ chunkType = "item";
+ break;
+ case kChunkLine:
+ chunkType = "line";
+ break;
+ }
Common::String src = u.cref->source.asString(true);
- s = Common::String::format("chunk: char %d to %d of %s", u.cref->start, u.cref->end, src.c_str());
+ Common::String chunk = eval().asString(true);
+ s += Common::String::format("chunk: %s %d to %d of %s (%s)", chunkType.c_str(), u.cref->startChunk, u.cref->endChunk, src.c_str(), chunk.c_str());
}
break;
case POINT:
@@ -1379,7 +1395,11 @@ Datum Lingo::varFetch(const Datum &var, bool global, DatumHash *localvars, bool
} else if (var.type == CHUNKREF) {
Common::String src = var.u.cref->source.eval().asString();
result.type = STRING;
- result.u.s = new Common::String(src.substr(var.u.cref->start, var.u.cref->end - var.u.cref->start));
+ if (var.u.cref->start == -1) {
+ 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));
+ }
} else {
warning("varFetch: fetch from non-variable");
}
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 7781f460b8..a8f8edd6ed 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -150,10 +150,14 @@ struct Datum { /* interpreter stack type */
struct ChunkReference {
Datum source;
+ ChunkType type;
+ int startChunk;
+ int endChunk;
int start;
int end;
- ChunkReference(const Datum &src, uint s, uint e) : source(src), start(s), end(e) {}
+ ChunkReference(const Datum &src, ChunkType t, int sc, int ec, int s, int e)
+ : source(src), type(t), startChunk(sc), endChunk(ec), start(s), end(e) {}
};
struct PCell {
Commit: ce30bcb0d7c1bbbc06117f980541badb4d3bc3de
https://github.com/scummvm/scummvm/commit/ce30bcb0d7c1bbbc06117f980541badb4d3bc3de
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-08T20:06:29-04:00
Commit Message:
DIRECTOR: LINGO: Use chunk refs in b_numberof/lastof
For consistency.
Changed paths:
engines/director/lingo/lingo-builtins.cpp
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index ec2e5cf13b..fea287eb07 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -2439,112 +2439,50 @@ void LB::b_window(int nargs) {
void LB::b_numberofchars(int nargs) {
Datum d = g_lingo->pop();
-
- int len = strlen(d.asString().c_str());
-
- Datum res(len);
- g_lingo->push(res);
+ Datum chunkRef = LC::chunkRef(kChunkChar, 0, 0, d); // get reference to last char
+ g_lingo->push(chunkRef.u.cref->startChunk);
}
void LB::b_numberofitems(int nargs) {
Datum d = g_lingo->pop();
-
- int numberofitems = 1;
- Common::String contents = d.asString();
- for (uint32 i = 0; i < contents.size(); i++) {
- if (contents[i] == g_lingo->_itemDelimiter)
- numberofitems++;
- }
-
- Datum res(numberofitems);
- g_lingo->push(res);
+ Datum chunkRef = LC::chunkRef(kChunkItem, 0, 0, d); // get reference to last item
+ g_lingo->push(chunkRef.u.cref->startChunk);
}
void LB::b_numberoflines(int nargs) {
Datum d = g_lingo->pop();
-
- int numberoflines = 1;
- Common::String contents = d.asString();
- for (uint32 i = 0; i < contents.size(); i++) {
- if (contents[i] == '\n')
- numberoflines++;
- }
-
- Datum res(numberoflines);
- g_lingo->push(res);
+ Datum chunkRef = LC::chunkRef(kChunkLine, 0, 0, d); // get reference to last line
+ g_lingo->push(chunkRef.u.cref->startChunk);
}
void LB::b_numberofwords(int nargs) {
Datum d = g_lingo->pop();
-
- int numberofwords = 0;
- Common::String contents = d.asString();
- if (contents.empty()) {
- g_lingo->push(Datum(0));
- return;
- }
- for (uint32 i = 1; i < contents.size(); i++) {
- if (Common::isSpace(contents[i]) && !Common::isSpace(contents[i - 1]))
- numberofwords++;
- }
- // Count the last word
- if (!Common::isSpace(contents[contents.size() - 1]))
- numberofwords++;
-
- Datum res(numberofwords);
- g_lingo->push(res);
+ Datum chunkRef = LC::chunkRef(kChunkWord, 0, 0, d); // get reference to last word
+ g_lingo->push(chunkRef.u.cref->startChunk);
}
void LB::b_lastcharof(int nargs) {
Datum d = g_lingo->pop();
- if (d.type != STRING) {
- warning("LB::b_lastcharof(): Called with wrong data type: %s", d.type2str());
- g_lingo->push(Datum(""));
- return;
- }
-
- Common::String contents = d.asString();
- Common::String res;
- if (contents.size() != 0)
- res = contents.lastChar();
- g_lingo->push(Datum(res));
+ Datum chunkRef = LC::chunkRef(kChunkChar, 0, 0, d); // get reference to last char
+ g_lingo->push(chunkRef.eval());
}
void LB::b_lastitemof(int nargs) {
Datum d = g_lingo->pop();
- if (d.type != STRING) {
- warning("LB::b_lastitemof(): Called with wrong data type: %s", d.type2str());
- g_lingo->push(Datum(""));
- return;
- }
-
- Common::String res;
- Common::String chunkExpr = d.asString();
- uint pos = chunkExpr.findLastOf(g_lingo->_itemDelimiter);
- if (pos == Common::String::npos) {
- res = chunkExpr;
- } else {
- pos++; // skip the item delimiter
- res = chunkExpr.substr(pos , chunkExpr.size() - pos);
- }
-
- g_lingo->push(Datum(res));
+ Datum chunkRef = LC::chunkRef(kChunkItem, 0, 0, d); // get reference to last item
+ g_lingo->push(chunkRef.eval());
}
void LB::b_lastlineof(int nargs) {
Datum d = g_lingo->pop();
-
- warning("STUB: b_lastlineof");
-
- g_lingo->push(Datum(0));
+ Datum chunkRef = LC::chunkRef(kChunkLine, 0, 0, d); // get reference to last line
+ g_lingo->push(chunkRef.eval());
}
void LB::b_lastwordof(int nargs) {
Datum d = g_lingo->pop();
-
- warning("STUB: b_lastwordof");
-
- g_lingo->push(Datum(0));
+ Datum chunkRef = LC::chunkRef(kChunkWord, 0, 0, d); // get reference to last word
+ g_lingo->push(chunkRef.eval());
}
void LB::b_scummvmassert(int nargs) {
Commit: f747445e15cbf81876d54b28f6c2d53b0500a2f5
https://github.com/scummvm/scummvm/commit/f747445e15cbf81876d54b28f6c2d53b0500a2f5
Author: djsrv (dservilla at gmail.com)
Date: 2021-06-08T20:06:29-04:00
Commit Message:
DIRECTOR: LINGO: Implement kTEAString properties
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 17a1dd7590..d54f25aa03 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -679,8 +679,31 @@ void LC::cb_v4theentitypush() {
break;
case kTEAString:
{
- /*Datum stringArg = */g_lingo->pop();
- warning("cb_v4theentitypush: STUB: kTEAString");
+ Datum stringArg = g_lingo->pop();
+ ChunkType chunkType;
+ switch (entity) {
+ case kTheChars:
+ chunkType = kChunkChar;
+ break;
+ case kTheWords:
+ chunkType = kChunkWord;
+ break;
+ case kTheLines:
+ chunkType = kChunkLine;
+ break;
+ case kTheItems:
+ chunkType = kChunkItem;
+ break;
+ }
+ Datum chunkRef = LC::chunkRef(chunkType, 0, 0, stringArg); // get reference to last of chunk type
+ switch (field) {
+ case kTheLast:
+ result = chunkRef.eval();
+ break;
+ case kTheNumber:
+ result = chunkRef.u.cref->startChunk;
+ break;
+ }
}
break;
case kTEAMenuIdItemId:
More information about the Scummvm-git-logs
mailing list