[Scummvm-git-logs] scummvm master -> 449321609822e7b8c110a24cbff238b04d069917
sev-
sev at scummvm.org
Fri Mar 27 21:18:49 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:
12e4eab5de DIRECTOR: LINGO: Fix Datum::toString() for arrays
4493216098 DIRECTOR: LINGO: Implement list math
Commit: 12e4eab5de6975ddd257fe9f1792525d96ff6f85
https://github.com/scummvm/scummvm/commit/12e4eab5de6975ddd257fe9f1792525d96ff6f85
Author: djsrv (dservilla at gmail.com)
Date: 2020-03-27T22:18:44+01:00
Commit Message:
DIRECTOR: LINGO: Fix Datum::toString() for arrays
Previously it overrwrote array contents with strings, breaking arrays
whenever they were printed.
Changed paths:
engines/director/lingo/lingo.cpp
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 423716a46b..987b6bb7b2 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -518,7 +518,8 @@ Common::String *Datum::toString() {
for (uint i = 0; i < u.farr->size(); i++) {
if (i > 0)
*s += ", ";
- *s += *u.farr->operator[](i).toString();
+ Datum d = u.farr->operator[](i);
+ *s += *d.toString();
}
*s += "]";
Commit: 449321609822e7b8c110a24cbff238b04d069917
https://github.com/scummvm/scummvm/commit/449321609822e7b8c110a24cbff238b04d069917
Author: djsrv (dservilla at gmail.com)
Date: 2020-03-27T22:18:44+01:00
Commit Message:
DIRECTOR: LINGO: Implement list math
Changed paths:
engines/director/lingo/lingo-code.cpp
engines/director/lingo/lingo-code.h
engines/director/lingo/lingo.cpp
engines/director/lingo/tests/lists.lingo
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index a1dd9b3b1b..dbd6f7e2ee 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -476,83 +476,153 @@ void LC::c_swap() {
g_lingo->push(d1);
}
-void LC::c_add() {
- Datum d2 = g_lingo->pop();
- Datum d1 = g_lingo->pop();
+Datum LC::mapBinaryOp(Datum (*mapFunc)(Datum, Datum), Datum d1, Datum d2) {
+ // At least one of d1 and d2 must be an array
+ uint arraySize;
+ if (d1.type == ARRAY && d2.type == ARRAY) {
+ arraySize = MIN(d1.u.farr->size(), d2.u.farr->size());
+ } else if (d1.type == ARRAY) {
+ arraySize = d1.u.farr->size();
+ } else {
+ arraySize = d2.u.farr->size();
+ }
+ Datum res;
+ res.type = ARRAY;
+ res.u.farr = new DatumArray(arraySize);
+ Datum a = d1;
+ Datum b = d2;
+ for (uint i = 0; i < arraySize; i++) {
+ if (d1.type == ARRAY) {
+ a = d1.u.farr->operator[](i);
+ }
+ if (d2.type == ARRAY) {
+ b = d2.u.farr->operator[](i);
+ }
+ res.u.farr->operator[](i) = mapFunc(a, b);
+ }
+ return res;
+}
+Datum LC::addData(Datum d1, Datum d2) {
+ if (d1.type == ARRAY || d2.type == ARRAY) {
+ return LC::mapBinaryOp(LC::addData, d1, d2);
+ }
if (g_lingo->alignTypes(d1, d2) == FLOAT) {
d1.u.f += d2.u.f;
} else {
d1.u.i += d2.u.i;
}
- g_lingo->push(d1);
+ return d1;
}
-void LC::c_sub() {
+void LC::c_add() {
Datum d2 = g_lingo->pop();
Datum d1 = g_lingo->pop();
+ g_lingo->push(LC::addData(d1, d2));
+}
+Datum LC::subData(Datum d1, Datum d2) {
+ if (d1.type == ARRAY || d2.type == ARRAY) {
+ return LC::mapBinaryOp(LC::subData, d1, d2);
+ }
if (g_lingo->alignTypes(d1, d2) == FLOAT) {
d1.u.f -= d2.u.f;
} else {
d1.u.i -= d2.u.i;
}
- g_lingo->push(d1);
+ return d1;
}
-void LC::c_mul() {
+void LC::c_sub() {
Datum d2 = g_lingo->pop();
Datum d1 = g_lingo->pop();
+ g_lingo->push(LC::subData(d1, d2));
+}
+Datum LC::mulData(Datum d1, Datum d2) {
+ if (d1.type == ARRAY || d2.type == ARRAY) {
+ return LC::mapBinaryOp(LC::mulData, d1, d2);
+ }
if (g_lingo->alignTypes(d1, d2) == FLOAT) {
d1.u.f *= d2.u.f;
} else {
d1.u.i *= d2.u.i;
}
- g_lingo->push(d1);
+ return d1;
}
-void LC::c_div() {
+void LC::c_mul() {
Datum d2 = g_lingo->pop();
+ Datum d1 = g_lingo->pop();
+ g_lingo->push(LC::mulData(d1, d2));
+}
+
+Datum LC::divData(Datum d1, Datum d2) {
+ if (d1.type == ARRAY || d2.type == ARRAY) {
+ return LC::mapBinaryOp(LC::divData, d1, d2);
+ }
if ((d2.type == INT && d2.u.i == 0) ||
(d2.type == FLOAT && d2.u.f == 0.0))
error("division by zero");
- Datum d1 = g_lingo->pop();
-
if (g_lingo->alignTypes(d1, d2) == FLOAT) {
d1.u.f /= d2.u.f;
} else {
d1.u.i /= d2.u.i;
}
- g_lingo->push(d1);
+ return d1;
}
-void LC::c_mod() {
+void LC::c_div() {
Datum d2 = g_lingo->pop();
- d2.toInt();
+ Datum d1 = g_lingo->pop();
+ g_lingo->push(divData(d1, d2));
+}
- if (d2.u.i == 0)
- error("division by zero");
+Datum LC::modData(Datum d1, Datum d2) {
+ if (d1.type == ARRAY || d2.type == ARRAY) {
+ return LC::mapBinaryOp(LC::modData, d1, d2);
+ }
- Datum d1 = g_lingo->pop();
d1.toInt();
+ d2.toInt();
+ if (d2.u.i == 0)
+ error("division by zero");
d1.u.i %= d2.u.i;
+ return d1;
+}
- g_lingo->push(d1);
+void LC::c_mod() {
+ Datum d2 = g_lingo->pop();
+ Datum d1 = g_lingo->pop();
+ g_lingo->push(LC::modData(d1, d2));
}
-void LC::c_negate() {
- Datum d = g_lingo->pop();
+Datum LC::negateData(Datum d) {
+ if (d.type == ARRAY) {
+ uint arraySize = d.u.farr->size();
+ Datum res;
+ res.type = ARRAY;
+ res.u.farr = new DatumArray(arraySize);
+ for (uint i = 0; i < arraySize; i++) {
+ res.u.farr->operator[](i) = LC::negateData(d.u.farr->operator[](i));
+ }
+ return res;
+ }
- if (d.type == INT)
+ if (d.type == INT) {
d.u.i = -d.u.i;
- else if (d.type == FLOAT)
+ } else if (d.type == FLOAT) {
d.u.f = -d.u.f;
+ }
+ return d;
+}
- g_lingo->push(d);
+void LC::c_negate() {
+ Datum d = g_lingo->pop();
+ g_lingo->push(negateData(d));
}
void LC::c_ampersand() {
diff --git a/engines/director/lingo/lingo-code.h b/engines/director/lingo/lingo-code.h
index 6256fa82c3..9c1877632e 100644
--- a/engines/director/lingo/lingo-code.h
+++ b/engines/director/lingo/lingo-code.h
@@ -29,11 +29,18 @@ namespace LC {
void c_xpop();
void c_printtop();
+ Datum mapBinaryOp(Datum (*func)(Datum, Datum), Datum d1, Datum d2);
+ Datum addData(Datum d1, Datum d2);
void c_add();
+ Datum subData(Datum d1, Datum d2);
void c_sub();
+ Datum mulData(Datum d1, Datum d2);
void c_mul();
+ Datum divData(Datum d1, Datum d2);
void c_div();
+ Datum modData(Datum d1, Datum d2);
void c_mod();
+ Datum negateData(Datum d1);
void c_negate();
void c_and();
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 987b6bb7b2..e442fc5b70 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -316,34 +316,22 @@ int Lingo::alignTypes(Datum &d1, Datum &d2) {
if (d1.type == STRING) {
char *endPtr = 0;
- int i = strtol(d1.u.s->c_str(), &endPtr, 10);
+ double d = strtod(d1.u.s->c_str(), &endPtr);
if (*endPtr == 0) {
- d1.type = INT;
- d1.u.i = i;
+ d1.type = FLOAT;
+ d1.u.f = d;
} else {
- double d = strtod(d1.u.s->c_str(), &endPtr);
- if (*endPtr == 0) {
- d1.type = FLOAT;
- d1.u.f = d;
- } else {
- warning("Unable to parse '%s' as a number", d1.u.s->c_str());
- }
+ warning("Unable to parse '%s' as a number", d1.u.s->c_str());
}
}
if (d2.type == STRING) {
char *endPtr = 0;
- int i = strtol(d2.u.s->c_str(), &endPtr, 10);
+ double d = strtod(d2.u.s->c_str(), &endPtr);
if (*endPtr == 0) {
- d2.type = INT;
- d2.u.i = i;
+ d2.type = FLOAT;
+ d2.u.f = d;
} else {
- double d = strtod(d2.u.s->c_str(), &endPtr);
- if (*endPtr == 0) {
- d2.type = FLOAT;
- d2.u.f = d;
- } else {
- warning("Unable to parse '%s' as a number", d2.u.s->c_str());
- }
+ warning("Unable to parse '%s' as a number", d2.u.s->c_str());
}
}
diff --git a/engines/director/lingo/tests/lists.lingo b/engines/director/lingo/tests/lists.lingo
index 0634e54279..433707a477 100644
--- a/engines/director/lingo/tests/lists.lingo
+++ b/engines/director/lingo/tests/lists.lingo
@@ -8,3 +8,19 @@ set a to [1, 2, 3]
put a
set gList = [point(70, 190), point(217, 66), point(364, 185)]
+
+set b to [4, 5, 6, 7]
+set res to a + b
+set res to a - b
+set res to a * b
+set res to b / a
+set res to b mod a
+set res to -a
+
+set floats to [4.0, 5.0, 6.0, 7.0]
+set strings to ["4", "5", "6", "7"]
+
+set res to a + floats
+set res to a + strings
+set res to a + 1
+set res to 1 + b
More information about the Scummvm-git-logs
mailing list