mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-17 15:18:11 +00:00
DIRECTOR: LINGO: Implement chunk refs
This commit is contained in:
parent
3bf6f79a3e
commit
c147a5c979
@ -875,266 +875,226 @@ 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 || (0 > endChunk && endChunk < startChunk))
|
||||
return src;
|
||||
|
||||
if (endChunk < 1)
|
||||
endChunk = startChunk;
|
||||
|
||||
Common::String skipChars;
|
||||
Common::String breakChars;
|
||||
|
||||
switch (type) {
|
||||
case kChunkChar:
|
||||
skipChars = "";
|
||||
breakChars = "";
|
||||
break;
|
||||
case kChunkWord:
|
||||
skipChars = "\t\n\r ";
|
||||
breakChars = "\t\n\r ";
|
||||
break;
|
||||
case kChunkItem:
|
||||
skipChars = "";
|
||||
breakChars = Common::String::format("%c", g_lingo->_itemDelimiter);
|
||||
break;
|
||||
case kChunkLine:
|
||||
skipChars = "";
|
||||
breakChars = "\n\r";
|
||||
break;
|
||||
}
|
||||
|
||||
Common::String str = src.asString();
|
||||
int idx = 0;
|
||||
int chunkNum = 0;
|
||||
|
||||
int startIdx = -1;
|
||||
int endIdx = -1;
|
||||
|
||||
while (true) {
|
||||
// each iteration processes one chunk
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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 (chunkNum == endChunk || idx == (int)str.size()) {
|
||||
endIdx = idx; // found end of chunk expression
|
||||
break;
|
||||
}
|
||||
|
||||
if (!breakChars.empty())
|
||||
idx++; // skip break char
|
||||
}
|
||||
|
||||
if (startIdx < 0)
|
||||
startIdx = endIdx;
|
||||
|
||||
Datum res;
|
||||
res.u.cref = new ChunkReference(src, startIdx, endIdx);
|
||||
res.type = CHUNKREF;
|
||||
return res;
|
||||
}
|
||||
|
||||
void LC::c_of() {
|
||||
// put char 5 of word 1 of line 2 into field "thing"
|
||||
Datum target = g_lingo->pop();
|
||||
Datum last_line = g_lingo->pop();
|
||||
Datum first_line = g_lingo->pop();
|
||||
Datum last_item = g_lingo->pop();
|
||||
Datum first_item = g_lingo->pop();
|
||||
Datum last_word = g_lingo->pop();
|
||||
Datum first_word = g_lingo->pop();
|
||||
Datum last_char = g_lingo->pop();
|
||||
Datum first_char = g_lingo->pop();
|
||||
Datum src = g_lingo->pop();
|
||||
Datum lastLine = g_lingo->pop();
|
||||
Datum firstLine = g_lingo->pop();
|
||||
Datum lastItem = g_lingo->pop();
|
||||
Datum firstItem = g_lingo->pop();
|
||||
Datum lastWord = g_lingo->pop();
|
||||
Datum firstWord = g_lingo->pop();
|
||||
Datum lastChar = g_lingo->pop();
|
||||
Datum firstChar = g_lingo->pop();
|
||||
|
||||
Common::String result = target.asString();
|
||||
Datum res = src;
|
||||
|
||||
if (first_line.u.i > 0) {
|
||||
Common::String newline("\r");
|
||||
int first = first_line.u.i;
|
||||
int last = first;
|
||||
if (last_line.u.i > 0) {
|
||||
if ((first_item.u.i > 0) || (first_word.u.i > 0) || (first_char.u.i > 0)) {
|
||||
warning("LC::c_of(): last_line defined but unused");
|
||||
} else if (last_line.u.i < first_line.u.i) {
|
||||
warning("LC::c_of(): last_line before first_line, ignoring");
|
||||
} else {
|
||||
last = last_line.u.i;
|
||||
}
|
||||
}
|
||||
uint32 pointer = 0;
|
||||
int curLine = 0;
|
||||
int firstIndex = -1;
|
||||
int lastIndex = -1;
|
||||
while (pointer < result.size()) {
|
||||
curLine += 1;
|
||||
if (curLine == first) {
|
||||
firstIndex = pointer;
|
||||
}
|
||||
pointer = result.find(newline, pointer);
|
||||
if (curLine == last) {
|
||||
lastIndex = pointer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (firstIndex < 0 || lastIndex < 0) {
|
||||
warning("LC::c_of(): first_line or last_line out of range");
|
||||
result = "";
|
||||
} else {
|
||||
result = result.substr(firstIndex, lastIndex);
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
if (first_item.u.i > 0 || last_item.u.i > 0) {
|
||||
warning("STUB: LC::c_of() item indexing");
|
||||
}
|
||||
|
||||
if (first_word.u.i > 0) {
|
||||
int first = first_word.u.i;
|
||||
int last = first;
|
||||
if (last_word.u.i > 0) {
|
||||
if (first_char.u.i > 0) {
|
||||
warning("LC::c_of(): last_word defined but unused");
|
||||
} else if (last_word.u.i < first_word.u.i) {
|
||||
warning("LC::c_of(): last_word before first_word, ignoring");
|
||||
} else {
|
||||
last = last_word.u.i;
|
||||
}
|
||||
}
|
||||
uint32 pointer = 0;
|
||||
int curWord = 0;
|
||||
int firstIndex = -1;
|
||||
int lastIndex = -1;
|
||||
bool inWord = false;
|
||||
while (pointer < result.size()) {
|
||||
if ((result[pointer] == '\r') || (result[pointer] == '\t') ||
|
||||
(result[pointer] == '\n') || (result[pointer] == ' ')) {
|
||||
if (inWord) {
|
||||
inWord = false;
|
||||
if (last == curWord) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!inWord) {
|
||||
inWord = true;
|
||||
curWord += 1;
|
||||
if (first == curWord) {
|
||||
firstIndex = pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
pointer += 1;
|
||||
}
|
||||
lastIndex = pointer;
|
||||
if (firstIndex < 0) {
|
||||
warning("LC::c_of(): first_word out of range");
|
||||
result = "";
|
||||
} else {
|
||||
result = result.substr(firstIndex, lastIndex - firstIndex);
|
||||
}
|
||||
}
|
||||
|
||||
if (first_char.u.i > 0) {
|
||||
int first = first_char.u.i;
|
||||
int last = first;
|
||||
if (last_char.u.i > 0) {
|
||||
if (last_char.u.i < first_char.u.i) {
|
||||
warning("LC::c_of(): last_char before first_char, ignoring");
|
||||
} else {
|
||||
last = last_char.u.i;
|
||||
}
|
||||
}
|
||||
result = result.substr(first - 1, last - first);
|
||||
}
|
||||
|
||||
target = Datum(result);
|
||||
|
||||
g_lingo->push(target);
|
||||
g_lingo->push(res);
|
||||
}
|
||||
|
||||
void LC::c_charOf() {
|
||||
Datum d2 = g_lingo->pop(); // string
|
||||
Datum d1 = g_lingo->pop(); // index
|
||||
Datum src = g_lingo->pop(false);
|
||||
Datum index = g_lingo->pop();
|
||||
|
||||
if ((d1.type != INT && d1.type != FLOAT) || d2.type != STRING) {
|
||||
warning("LC::c_charOf(): Called with wrong data types: %s and %s", d1.type2str(), d2.type2str());
|
||||
if ((index.type != INT && index.type != FLOAT)
|
||||
|| (src.type != STRING && src.type != VAR && src.type != FIELDREF && src.type != CHUNKREF && src.type != CASTREF)) {
|
||||
g_lingo->lingoError("LC::c_charOf(): Called with wrong data types: %s and %s", index.type2str(), src.type2str());
|
||||
g_lingo->push(Datum(""));
|
||||
return;
|
||||
}
|
||||
|
||||
Datum res;
|
||||
int index = d1.asInt();
|
||||
Common::String chunkExpr = *d2.u.s;
|
||||
|
||||
if (index < 1)
|
||||
res = Datum(chunkExpr);
|
||||
else if (uint(index) > chunkExpr.size())
|
||||
res = Datum("");
|
||||
else
|
||||
res = Datum(Common::String(chunkExpr[index - 1]));
|
||||
g_lingo->push(res);
|
||||
g_lingo->push(LC::chunkRef(kChunkChar, index.asInt(), 0, src));
|
||||
}
|
||||
|
||||
void LC::c_charToOf() {
|
||||
Datum d3 = g_lingo->pop(); // string
|
||||
Datum d2 = g_lingo->pop(); // indexFrom
|
||||
Datum d1 = g_lingo->pop(); // indexTo
|
||||
Datum src = g_lingo->pop(false);
|
||||
Datum indexTo = g_lingo->pop();
|
||||
Datum indexFrom = g_lingo->pop();
|
||||
|
||||
if ((d1.type != INT && d1.type != FLOAT) || (d2.type != INT && d2.type != FLOAT) || d3.type != STRING) {
|
||||
warning("LC::c_charToOf(): Called with wrong data types: %s, %s and %s", d1.type2str(), d2.type2str(), d3.type2str());
|
||||
if ((indexTo.type != INT && indexTo.type != FLOAT) || (indexFrom.type != INT && indexFrom.type != FLOAT)
|
||||
|| (src.type != STRING && src.type != VAR && src.type != FIELDREF && src.type != CHUNKREF && src.type != CASTREF)) {
|
||||
warning("LC::c_charToOf(): Called with wrong data types: %s, %s and %s", indexTo.type2str(), indexFrom.type2str(), src.type2str());
|
||||
g_lingo->push(Datum(""));
|
||||
return;
|
||||
}
|
||||
|
||||
int indexFrom = d1.asInt();
|
||||
int indexTo = d2.asInt();
|
||||
Common::String chunkExpr = *d3.u.s;
|
||||
|
||||
Datum res;
|
||||
// The if order is important. It mimicks the checks, i.e. bugs, of Director 4.
|
||||
if (indexFrom < 1)
|
||||
res = Datum(chunkExpr);
|
||||
else if (indexTo < 1)
|
||||
res = Datum(Common::String(chunkExpr[indexFrom - 1])); // treat as charOf
|
||||
else if (indexFrom > indexTo)
|
||||
res = Datum("");
|
||||
else if (uint(indexFrom) > chunkExpr.size())
|
||||
res = Datum("");
|
||||
else
|
||||
res = Datum(chunkExpr.substr(indexFrom - 1, indexTo - indexFrom + 1));
|
||||
g_lingo->push(res);
|
||||
g_lingo->push(LC::chunkRef(kChunkChar, indexFrom.asInt(), indexTo.asInt(), src));
|
||||
}
|
||||
|
||||
void LC::c_itemOf() {
|
||||
Datum src = g_lingo->pop(false);
|
||||
Datum index = g_lingo->pop();
|
||||
|
||||
Datum d2 = g_lingo->pop(); // chunkExpression
|
||||
Datum d1 = g_lingo->pop(); // index
|
||||
|
||||
char delimiter = g_lingo->_itemDelimiter;
|
||||
|
||||
if ((d1.type != INT && d1.type != FLOAT) || d2.type != STRING) {
|
||||
warning("LC::c_itemOf(): Called with wrong data types: %s and %s", d1.type2str(), d2.type2str());
|
||||
if ((index.type != INT && index.type != FLOAT)
|
||||
|| (src.type != STRING && src.type != VAR && src.type != FIELDREF && src.type != CHUNKREF && src.type != CASTREF)) {
|
||||
warning("LC::c_itemOf(): Called with wrong data types: %s and %s", index.type2str(), src.type2str());
|
||||
g_lingo->push(Datum(""));
|
||||
return;
|
||||
}
|
||||
|
||||
int index = d1.asInt();
|
||||
|
||||
if (index < 1) {
|
||||
// returns the input string
|
||||
g_lingo->push(d2);
|
||||
return;
|
||||
}
|
||||
Common::String chunkExpr = *d2.u.s;
|
||||
uint startPos = 0;
|
||||
|
||||
while (index-- > 1) {
|
||||
startPos = chunkExpr.find(delimiter, startPos);
|
||||
if (startPos == Common::String::npos)
|
||||
break;
|
||||
startPos++; // skipping comma
|
||||
}
|
||||
|
||||
Datum res;
|
||||
if (startPos == Common::String::npos) {
|
||||
res = Datum("");
|
||||
} else {
|
||||
uint endPos = chunkExpr.find(delimiter, startPos);
|
||||
if (endPos == Common::String::npos)
|
||||
endPos = chunkExpr.size();
|
||||
res = Datum(chunkExpr.substr(startPos, endPos - startPos));
|
||||
}
|
||||
|
||||
g_lingo->push(res);
|
||||
g_lingo->push(LC::chunkRef(kChunkItem, index.asInt(), 0, src));
|
||||
}
|
||||
|
||||
void LC::c_itemToOf() {
|
||||
Datum d3 = g_lingo->pop();
|
||||
Datum d2 = g_lingo->pop();
|
||||
Datum d1 = g_lingo->pop();
|
||||
Datum src = g_lingo->pop(false);
|
||||
Datum indexTo = g_lingo->pop();
|
||||
Datum indexFrom = g_lingo->pop();
|
||||
|
||||
warning("STUB: LC::c_itemToOf(): %d %d %d", d1.u.i, d2.u.i, d3.u.i);
|
||||
if ((indexTo.type != INT && indexTo.type != FLOAT) || (indexFrom.type != INT && indexFrom.type != FLOAT)
|
||||
|| (src.type != STRING && src.type != VAR && src.type != FIELDREF && src.type != CHUNKREF && src.type != CASTREF)) {
|
||||
warning("LC::c_itemToOf(): Called with wrong data types: %s, %s and %s", indexTo.type2str(), indexFrom.type2str(), src.type2str());
|
||||
g_lingo->push(Datum(""));
|
||||
return;
|
||||
}
|
||||
|
||||
g_lingo->push(d1);
|
||||
g_lingo->push(LC::chunkRef(kChunkItem, indexFrom.asInt(), indexTo.asInt(), src));
|
||||
}
|
||||
|
||||
void LC::c_lineOf() {
|
||||
Datum d2 = g_lingo->pop();
|
||||
Datum d1 = g_lingo->pop();
|
||||
Datum src = g_lingo->pop(false);
|
||||
Datum index = g_lingo->pop();
|
||||
|
||||
warning("STUB: LC::c_lineOf(): %d %d", d1.u.i, d2.u.i);
|
||||
if ((index.type != INT && index.type != FLOAT)
|
||||
|| (src.type != STRING && src.type != VAR && src.type != FIELDREF && src.type != CHUNKREF && src.type != CASTREF)) {
|
||||
warning("LC::c_lineOf(): Called with wrong data types: %s and %s", index.type2str(), src.type2str());
|
||||
g_lingo->push(Datum(""));
|
||||
return;
|
||||
}
|
||||
|
||||
g_lingo->push(d1);
|
||||
g_lingo->push(LC::chunkRef(kChunkLine, index.asInt(), 0, src));
|
||||
}
|
||||
|
||||
void LC::c_lineToOf() {
|
||||
Datum d3 = g_lingo->pop();
|
||||
Datum d2 = g_lingo->pop();
|
||||
Datum d1 = g_lingo->pop();
|
||||
Datum src = g_lingo->pop(false);
|
||||
Datum indexTo = g_lingo->pop();
|
||||
Datum indexFrom = g_lingo->pop();
|
||||
|
||||
warning("STUB: LC::c_lineToOf(): %d %d %d", d1.u.i, d2.u.i, d3.u.i);
|
||||
if ((indexTo.type != INT && indexTo.type != FLOAT) || (indexFrom.type != INT && indexFrom.type != FLOAT)
|
||||
|| (src.type != STRING && src.type != VAR && src.type != FIELDREF && src.type != CHUNKREF && src.type != CASTREF)) {
|
||||
warning("LC::c_lineToOf(): Called with wrong data types: %s, %s and %s", indexTo.type2str(), indexFrom.type2str(), src.type2str());
|
||||
g_lingo->push(Datum(""));
|
||||
return;
|
||||
}
|
||||
|
||||
g_lingo->push(d1);
|
||||
g_lingo->push(LC::chunkRef(kChunkLine, indexFrom.asInt(), indexTo.asInt(), src));
|
||||
}
|
||||
|
||||
void LC::c_wordOf() {
|
||||
Datum d2 = g_lingo->pop();
|
||||
Datum d1 = g_lingo->pop();
|
||||
Datum src = g_lingo->pop(false);
|
||||
Datum index = g_lingo->pop();
|
||||
|
||||
warning("STUB: LC::c_wordOf(): %d %d", d1.u.i, d2.u.i);
|
||||
if ((index.type != INT && index.type != FLOAT)
|
||||
|| (src.type != STRING && src.type != VAR && src.type != FIELDREF && src.type != CHUNKREF && src.type != CASTREF)) {
|
||||
warning("LC::c_wordOf(): Called with wrong data types: %s and %s", index.type2str(), src.type2str());
|
||||
g_lingo->push(Datum(""));
|
||||
return;
|
||||
}
|
||||
|
||||
g_lingo->push(d1);
|
||||
g_lingo->push(LC::chunkRef(kChunkWord, index.asInt(), 0, src));
|
||||
}
|
||||
|
||||
void LC::c_wordToOf() {
|
||||
Datum d3 = g_lingo->pop();
|
||||
Datum d2 = g_lingo->pop();
|
||||
Datum d1 = g_lingo->pop();
|
||||
Datum src = g_lingo->pop(false);
|
||||
Datum indexTo = g_lingo->pop();
|
||||
Datum indexFrom = g_lingo->pop();
|
||||
|
||||
warning("STUB: LC::c_wordToOf(): %d %d %d", d1.u.i, d2.u.i, d3.u.i);
|
||||
if ((indexTo.type != INT && indexTo.type != FLOAT) || (indexFrom.type != INT && indexFrom.type != FLOAT)
|
||||
|| (src.type != STRING && src.type != VAR && src.type != FIELDREF && src.type != CHUNKREF && src.type != CASTREF)) {
|
||||
warning("LC::c_wordToOf(): Called with wrong data types: %s, %s and %s", indexTo.type2str(), indexFrom.type2str(), src.type2str());
|
||||
g_lingo->push(Datum(""));
|
||||
return;
|
||||
}
|
||||
|
||||
g_lingo->push(d1);
|
||||
g_lingo->push(LC::chunkRef(kChunkWord, indexFrom.asInt(), indexTo.asInt(), src));
|
||||
}
|
||||
|
||||
void LC::c_and() {
|
||||
|
@ -56,6 +56,7 @@ void c_starts();
|
||||
|
||||
void c_intersects();
|
||||
void c_within();
|
||||
Datum chunkRef(ChunkType type, int startChunk, int endChunk, const Datum &src);
|
||||
void c_of();
|
||||
void c_charOf();
|
||||
void c_charToOf();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -65,81 +65,82 @@ extern int yydebug;
|
||||
PARRAY = 266, /* PARRAY */
|
||||
CASTREF = 267, /* CASTREF */
|
||||
FIELDREF = 268, /* FIELDREF */
|
||||
INT = 269, /* INT */
|
||||
ARGC = 270, /* ARGC */
|
||||
ARGCNORET = 271, /* ARGCNORET */
|
||||
THEENTITY = 272, /* THEENTITY */
|
||||
THEENTITYWITHID = 273, /* THEENTITYWITHID */
|
||||
THEMENUITEMENTITY = 274, /* THEMENUITEMENTITY */
|
||||
THEMENUITEMSENTITY = 275, /* THEMENUITEMSENTITY */
|
||||
FLOAT = 276, /* FLOAT */
|
||||
THEFUNC = 277, /* THEFUNC */
|
||||
THEFUNCINOF = 278, /* THEFUNCINOF */
|
||||
VARID = 279, /* VARID */
|
||||
STRING = 280, /* STRING */
|
||||
SYMBOL = 281, /* SYMBOL */
|
||||
ENDCLAUSE = 282, /* ENDCLAUSE */
|
||||
tPLAYACCEL = 283, /* tPLAYACCEL */
|
||||
tMETHOD = 284, /* tMETHOD */
|
||||
THEOBJECTPROP = 285, /* THEOBJECTPROP */
|
||||
tCAST = 286, /* tCAST */
|
||||
tFIELD = 287, /* tFIELD */
|
||||
tSCRIPT = 288, /* tSCRIPT */
|
||||
tWINDOW = 289, /* tWINDOW */
|
||||
tDOWN = 290, /* tDOWN */
|
||||
tELSE = 291, /* tELSE */
|
||||
tELSIF = 292, /* tELSIF */
|
||||
tEXIT = 293, /* tEXIT */
|
||||
tGLOBAL = 294, /* tGLOBAL */
|
||||
tGO = 295, /* tGO */
|
||||
tGOLOOP = 296, /* tGOLOOP */
|
||||
tIF = 297, /* tIF */
|
||||
tIN = 298, /* tIN */
|
||||
tINTO = 299, /* tINTO */
|
||||
tMACRO = 300, /* tMACRO */
|
||||
tMOVIE = 301, /* tMOVIE */
|
||||
tNEXT = 302, /* tNEXT */
|
||||
tOF = 303, /* tOF */
|
||||
tPREVIOUS = 304, /* tPREVIOUS */
|
||||
tPUT = 305, /* tPUT */
|
||||
tREPEAT = 306, /* tREPEAT */
|
||||
tSET = 307, /* tSET */
|
||||
tTHEN = 308, /* tTHEN */
|
||||
tTO = 309, /* tTO */
|
||||
tWHEN = 310, /* tWHEN */
|
||||
tWITH = 311, /* tWITH */
|
||||
tWHILE = 312, /* tWHILE */
|
||||
tFACTORY = 313, /* tFACTORY */
|
||||
tOPEN = 314, /* tOPEN */
|
||||
tPLAY = 315, /* tPLAY */
|
||||
tINSTANCE = 316, /* tINSTANCE */
|
||||
tGE = 317, /* tGE */
|
||||
tLE = 318, /* tLE */
|
||||
tEQ = 319, /* tEQ */
|
||||
tNEQ = 320, /* tNEQ */
|
||||
tAND = 321, /* tAND */
|
||||
tOR = 322, /* tOR */
|
||||
tNOT = 323, /* tNOT */
|
||||
tMOD = 324, /* tMOD */
|
||||
tAFTER = 325, /* tAFTER */
|
||||
tBEFORE = 326, /* tBEFORE */
|
||||
tCONCAT = 327, /* tCONCAT */
|
||||
tCONTAINS = 328, /* tCONTAINS */
|
||||
tSTARTS = 329, /* tSTARTS */
|
||||
tCHAR = 330, /* tCHAR */
|
||||
tITEM = 331, /* tITEM */
|
||||
tLINE = 332, /* tLINE */
|
||||
tWORD = 333, /* tWORD */
|
||||
tSPRITE = 334, /* tSPRITE */
|
||||
tINTERSECTS = 335, /* tINTERSECTS */
|
||||
tWITHIN = 336, /* tWITHIN */
|
||||
tTELL = 337, /* tTELL */
|
||||
tPROPERTY = 338, /* tPROPERTY */
|
||||
tON = 339, /* tON */
|
||||
tENDIF = 340, /* tENDIF */
|
||||
tENDREPEAT = 341, /* tENDREPEAT */
|
||||
tENDTELL = 342, /* tENDTELL */
|
||||
tASSERTERROR = 343 /* tASSERTERROR */
|
||||
CHUNKREF = 269, /* CHUNKREF */
|
||||
INT = 270, /* INT */
|
||||
ARGC = 271, /* ARGC */
|
||||
ARGCNORET = 272, /* ARGCNORET */
|
||||
THEENTITY = 273, /* THEENTITY */
|
||||
THEENTITYWITHID = 274, /* THEENTITYWITHID */
|
||||
THEMENUITEMENTITY = 275, /* THEMENUITEMENTITY */
|
||||
THEMENUITEMSENTITY = 276, /* THEMENUITEMSENTITY */
|
||||
FLOAT = 277, /* FLOAT */
|
||||
THEFUNC = 278, /* THEFUNC */
|
||||
THEFUNCINOF = 279, /* THEFUNCINOF */
|
||||
VARID = 280, /* VARID */
|
||||
STRING = 281, /* STRING */
|
||||
SYMBOL = 282, /* SYMBOL */
|
||||
ENDCLAUSE = 283, /* ENDCLAUSE */
|
||||
tPLAYACCEL = 284, /* tPLAYACCEL */
|
||||
tMETHOD = 285, /* tMETHOD */
|
||||
THEOBJECTPROP = 286, /* THEOBJECTPROP */
|
||||
tCAST = 287, /* tCAST */
|
||||
tFIELD = 288, /* tFIELD */
|
||||
tSCRIPT = 289, /* tSCRIPT */
|
||||
tWINDOW = 290, /* tWINDOW */
|
||||
tDOWN = 291, /* tDOWN */
|
||||
tELSE = 292, /* tELSE */
|
||||
tELSIF = 293, /* tELSIF */
|
||||
tEXIT = 294, /* tEXIT */
|
||||
tGLOBAL = 295, /* tGLOBAL */
|
||||
tGO = 296, /* tGO */
|
||||
tGOLOOP = 297, /* tGOLOOP */
|
||||
tIF = 298, /* tIF */
|
||||
tIN = 299, /* tIN */
|
||||
tINTO = 300, /* tINTO */
|
||||
tMACRO = 301, /* tMACRO */
|
||||
tMOVIE = 302, /* tMOVIE */
|
||||
tNEXT = 303, /* tNEXT */
|
||||
tOF = 304, /* tOF */
|
||||
tPREVIOUS = 305, /* tPREVIOUS */
|
||||
tPUT = 306, /* tPUT */
|
||||
tREPEAT = 307, /* tREPEAT */
|
||||
tSET = 308, /* tSET */
|
||||
tTHEN = 309, /* tTHEN */
|
||||
tTO = 310, /* tTO */
|
||||
tWHEN = 311, /* tWHEN */
|
||||
tWITH = 312, /* tWITH */
|
||||
tWHILE = 313, /* tWHILE */
|
||||
tFACTORY = 314, /* tFACTORY */
|
||||
tOPEN = 315, /* tOPEN */
|
||||
tPLAY = 316, /* tPLAY */
|
||||
tINSTANCE = 317, /* tINSTANCE */
|
||||
tGE = 318, /* tGE */
|
||||
tLE = 319, /* tLE */
|
||||
tEQ = 320, /* tEQ */
|
||||
tNEQ = 321, /* tNEQ */
|
||||
tAND = 322, /* tAND */
|
||||
tOR = 323, /* tOR */
|
||||
tNOT = 324, /* tNOT */
|
||||
tMOD = 325, /* tMOD */
|
||||
tAFTER = 326, /* tAFTER */
|
||||
tBEFORE = 327, /* tBEFORE */
|
||||
tCONCAT = 328, /* tCONCAT */
|
||||
tCONTAINS = 329, /* tCONTAINS */
|
||||
tSTARTS = 330, /* tSTARTS */
|
||||
tCHAR = 331, /* tCHAR */
|
||||
tITEM = 332, /* tITEM */
|
||||
tLINE = 333, /* tLINE */
|
||||
tWORD = 334, /* tWORD */
|
||||
tSPRITE = 335, /* tSPRITE */
|
||||
tINTERSECTS = 336, /* tINTERSECTS */
|
||||
tWITHIN = 337, /* tWITHIN */
|
||||
tTELL = 338, /* tTELL */
|
||||
tPROPERTY = 339, /* tPROPERTY */
|
||||
tON = 340, /* tON */
|
||||
tENDIF = 341, /* tENDIF */
|
||||
tENDREPEAT = 342, /* tENDREPEAT */
|
||||
tENDTELL = 343, /* tENDTELL */
|
||||
tASSERTERROR = 344 /* tASSERTERROR */
|
||||
};
|
||||
typedef enum yytokentype yytoken_kind_t;
|
||||
#endif
|
||||
@ -163,7 +164,7 @@ union YYSTYPE
|
||||
Common::String *prop;
|
||||
} objectprop;
|
||||
|
||||
#line 167 "engines/director/lingo/lingo-gr.h"
|
||||
#line 168 "engines/director/lingo/lingo-gr.h"
|
||||
|
||||
};
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
|
@ -196,7 +196,7 @@ static void mVar(Common::String *s, VarType type) {
|
||||
|
||||
// Datum types
|
||||
%token VOID VAR POINT RECT ARRAY OBJECT LEXERROR PARRAY
|
||||
%token CASTREF FIELDREF
|
||||
%token CASTREF FIELDREF CHUNKREF
|
||||
%token<i> INT ARGC ARGCNORET
|
||||
|
||||
%token<e> THEENTITY THEENTITYWITHID THEMENUITEMENTITY THEMENUITEMSENTITY
|
||||
|
@ -838,6 +838,9 @@ void Datum::reset() {
|
||||
delete u.obj;
|
||||
}
|
||||
break;
|
||||
case CHUNKREF:
|
||||
delete u.cref;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -848,7 +851,7 @@ void Datum::reset() {
|
||||
}
|
||||
|
||||
Datum Datum::eval() {
|
||||
if (type == VAR || type == FIELDREF) {
|
||||
if (type == VAR || type == FIELDREF || type == CHUNKREF) {
|
||||
return g_lingo->varFetch(*this);
|
||||
}
|
||||
|
||||
@ -982,6 +985,12 @@ Common::String Datum::asString(bool printonly) const {
|
||||
s = Common::String::format("field: \"%s\"", ((TextCastMember *)member)->getText().c_str());
|
||||
}
|
||||
break;
|
||||
case CHUNKREF:
|
||||
{
|
||||
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());
|
||||
}
|
||||
break;
|
||||
case POINT:
|
||||
s = "point:";
|
||||
// fallthrough
|
||||
@ -1076,6 +1085,8 @@ const char *Datum::type2str(bool isk) const {
|
||||
return isk ? "#object" : "OBJECT";
|
||||
case FIELDREF:
|
||||
return "FIELDREF";
|
||||
case CHUNKREF:
|
||||
return "CHUNKREF";
|
||||
case VAR:
|
||||
return isk ? "#var" : "VAR";
|
||||
default:
|
||||
@ -1360,6 +1371,10 @@ Datum Lingo::varFetch(Datum &var, bool global, DatumHash *localvars, bool silent
|
||||
warning("varFetch: Unhandled cast type %d", member->_type);
|
||||
break;
|
||||
}
|
||||
} 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));
|
||||
} else {
|
||||
warning("varFetch: fetch from non-variable");
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ class SeekableReadStreamEndian;
|
||||
|
||||
namespace Director {
|
||||
|
||||
struct ChunkReference;
|
||||
struct TheEntity;
|
||||
struct TheEntityField;
|
||||
struct LingoArchive;
|
||||
@ -116,7 +117,8 @@ struct Datum { /* interpreter stack type */
|
||||
Common::String *s; /* STRING, VAR, OBJECT */
|
||||
DatumArray *farr; /* ARRAY, POINT, RECT */
|
||||
PropertyArray *parr; /* PARRAY */
|
||||
AbstractObject *obj;
|
||||
AbstractObject *obj; /* OBJECT */
|
||||
ChunkReference *cref; /* CHUNKREF */
|
||||
} u;
|
||||
|
||||
int *refCount;
|
||||
@ -146,6 +148,14 @@ struct Datum { /* interpreter stack type */
|
||||
int compareTo(Datum &d, bool ignoreCase = false) const;
|
||||
};
|
||||
|
||||
struct ChunkReference {
|
||||
Datum source;
|
||||
int start;
|
||||
int end;
|
||||
|
||||
ChunkReference(const Datum &src, uint s, uint e) : source(src), start(s), end(e) {}
|
||||
};
|
||||
|
||||
struct PCell {
|
||||
Datum p;
|
||||
Datum v;
|
||||
|
@ -307,6 +307,13 @@ enum SymbolType {
|
||||
HANDLER // user-defined handler
|
||||
};
|
||||
|
||||
enum ChunkType {
|
||||
kChunkChar,
|
||||
kChunkWord,
|
||||
kChunkItem,
|
||||
kChunkLine
|
||||
};
|
||||
|
||||
struct Datum;
|
||||
struct PCell;
|
||||
typedef Common::Array<Datum> DatumArray;
|
||||
|
Loading…
Reference in New Issue
Block a user