[Scummvm-git-logs] scummvm master -> 8347638ea66b8379c8ed35eddf1674c78ed80005
sev-
sev at scummvm.org
Wed Apr 8 22:51:30 UTC 2020
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
a4803d77aa DIRECTOR: LINGO: Create Datum::compareTo()
a4c643052c DIRECTOR: LINGO: Implement list comparison
8347638ea6 DIRECTOR: LINGO: Implement b_max and b_min
Commit: a4803d77aab6a379b090329dc9155f2a203fb037
https://github.com/scummvm/scummvm/commit/a4803d77aab6a379b090329dc9155f2a203fb037
Author: djsrv (dservilla at gmail.com)
Date: 2020-04-09T00:51:25+02:00
Commit Message:
DIRECTOR: LINGO: Create Datum::compareTo()
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 c1618e983a..6f1caaa27c 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -576,6 +576,35 @@ const char *Datum::type2str(bool isk) {
}
}
+int Datum::compareTo(Datum d) {
+ if (type == STRING && d.type == STRING) {
+ return u.s->compareTo(*d.u.s);
+ } else if (g_lingo->alignTypes(*this, d) == FLOAT) {
+ if (u.f < d.u.f) {
+ return -1;
+ } else if (u.f == d.u.f) {
+ return 0;
+ } else {
+ return 1;
+ }
+ } else {
+ if (u.i < d.u.i) {
+ return -1;
+ } else if (u.i == d.u.i) {
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+}
+
+int Datum::compareToIgnoreCase(Datum d) {
+ if (type == STRING && d.type == STRING) {
+ return u.s->compareToIgnoreCase(*d.u.s);
+ }
+ return compareTo(d);
+}
+
void Lingo::parseMenu(const char *code) {
warning("STUB: parseMenu");
}
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index b3ffa43bc1..f61cfe55ff 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -114,6 +114,9 @@ struct Datum { /* interpreter stack type */
Common::String getPrintable() { return *makeString(true); }
const char *type2str(bool isk = false);
+
+ int compareTo(Datum d);
+ int compareToIgnoreCase(Datum d);
};
struct Builtin {
Commit: a4c643052cedac4ac51ba738e146f141de614e35
https://github.com/scummvm/scummvm/commit/a4c643052cedac4ac51ba738e146f141de614e35
Author: djsrv (dservilla at gmail.com)
Date: 2020-04-09T00:51:25+02:00
Commit Message:
DIRECTOR: LINGO: Implement list comparison
Changed paths:
engines/director/lingo/lingo-code.cpp
engines/director/lingo/lingo-code.h
engines/director/lingo/tests/lists.lingo
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 7a7fb437c2..c948a400ce 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -967,88 +967,124 @@ void LC::c_not() {
g_lingo->push(d);
}
+Datum LC::compareArrays(Datum (*compareFunc)(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 = INT;
+ res.u.i = 1;
+ 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 = compareFunc(a, b);
+ if (res.u.i == 0) {
+ break;
+ }
+ }
+ return res;
+}
+
+Datum LC::eqData(Datum d1, Datum d2) {
+ if (d1.type == ARRAY || d2.type == ARRAY) {
+ return LC::compareArrays(LC::eqData, d1, d2);
+ }
+ d1.u.i = (d1.compareToIgnoreCase(d2) == 0) ? 1 : 0;
+ d1.type = INT;
+ return d1;
+}
+
void LC::c_eq() {
Datum d2 = g_lingo->pop();
Datum d1 = g_lingo->pop();
+ g_lingo->push(LC::eqData(d1, d2));
+}
- if (d1.type == STRING && d2.type == STRING) {
- d1.u.i = (d1.u.s->equalsIgnoreCase(*d2.u.s)) ? 1 : 0;
- d1.type = INT;
- } else if (g_lingo->alignTypes(d1, d2) == FLOAT) {
- d1.u.i = (d1.u.f == d2.u.f) ? 1 : 0;
- d1.type = INT;
- } else {
- d1.u.i = (d1.u.i == d2.u.i) ? 1 : 0;
+Datum LC::neqData(Datum d1, Datum d2) {
+ if (d1.type == ARRAY || d2.type == ARRAY) {
+ return LC::compareArrays(LC::neqData, d1, d2);
}
- g_lingo->push(d1);
+ d1.u.i = (d1.compareToIgnoreCase(d2) != 0) ? 1 : 0;
+ d1.type = INT;
+ return d1;
}
void LC::c_neq() {
Datum d2 = g_lingo->pop();
Datum d1 = g_lingo->pop();
+ g_lingo->push(LC::neqData(d1, d2));
+}
- if (d1.type == STRING && d2.type == STRING) {
- d1.u.i = !(d1.u.s->equalsIgnoreCase(*d2.u.s)) ? 1 : 0;
- d1.type = INT;
- } else if (g_lingo->alignTypes(d1, d2) == FLOAT) {
- d1.u.i = (d1.u.f != d2.u.f) ? 1 : 0;
- d1.type = INT;
- } else {
- d1.u.i = (d1.u.i != d2.u.i) ? 1 : 0;
+Datum LC::gtData(Datum d1, Datum d2) {
+ if (d1.type == ARRAY || d2.type == ARRAY) {
+ return LC::compareArrays(LC::gtData, d1, d2);
}
- g_lingo->push(d1);
+ d1.u.i = (d1.compareTo(d2) > 0) ? 1 : 0;
+ d1.type = INT;
+ return d1;
}
void LC::c_gt() {
Datum d2 = g_lingo->pop();
Datum d1 = g_lingo->pop();
+ g_lingo->push(LC::gtData(d1, d2));
+}
- if (g_lingo->alignTypes(d1, d2) == FLOAT) {
- d1.u.i = (d1.u.f > d2.u.f) ? 1 : 0;
- d1.type = INT;
- } else {
- d1.u.i = (d1.u.i > d2.u.i) ? 1 : 0;
+Datum LC::ltData(Datum d1, Datum d2) {
+ if (d1.type == ARRAY || d2.type == ARRAY) {
+ return LC::compareArrays(LC::ltData, d1, d2);
}
- g_lingo->push(d1);
+ d1.u.i = (d1.compareTo(d2) < 0) ? 1 : 0;
+ d1.type = INT;
+ return d1;
}
void LC::c_lt() {
Datum d2 = g_lingo->pop();
Datum d1 = g_lingo->pop();
+ g_lingo->push(LC::ltData(d1, d2));
+}
- if (g_lingo->alignTypes(d1, d2) == FLOAT) {
- d1.u.i = (d1.u.f < d2.u.f) ? 1 : 0;
- d1.type = INT;
- } else {
- d1.u.i = (d1.u.i < d2.u.i) ? 1 : 0;
+Datum LC::geData(Datum d1, Datum d2) {
+ if (d1.type == ARRAY || d2.type == ARRAY) {
+ return LC::compareArrays(LC::geData, d1, d2);
}
- g_lingo->push(d1);
+ d1.u.i = (d1.compareTo(d2) >= 0) ? 1 : 0;
+ d1.type = INT;
+ return d1;
}
void LC::c_ge() {
Datum d2 = g_lingo->pop();
Datum d1 = g_lingo->pop();
+ g_lingo->push(LC::geData(d1, d2));
+}
- if (g_lingo->alignTypes(d1, d2) == FLOAT) {
- d1.u.i = (d1.u.f >= d2.u.f) ? 1 : 0;
- d1.type = INT;
- } else {
- d1.u.i = (d1.u.i >= d2.u.i) ? 1 : 0;
+Datum LC::leData(Datum d1, Datum d2) {
+ if (d1.type == ARRAY || d2.type == ARRAY) {
+ return LC::compareArrays(LC::leData, d1, d2);
}
- g_lingo->push(d1);
+ d1.u.i = (d1.compareTo(d2) <= 0) ? 1 : 0;
+ d1.type = INT;
+ return d1;
}
void LC::c_le() {
Datum d2 = g_lingo->pop();
Datum d1 = g_lingo->pop();
-
- if (g_lingo->alignTypes(d1, d2) == FLOAT) {
- d1.u.i = (d1.u.f <= d2.u.f) ? 1 : 0;
- d1.type = INT;
- } else {
- d1.u.i = (d1.u.i <= d2.u.i) ? 1 : 0;
- }
- g_lingo->push(d1);
+ g_lingo->push(LC::leData(d1, d2));
}
void LC::c_jump() {
diff --git a/engines/director/lingo/lingo-code.h b/engines/director/lingo/lingo-code.h
index 29e896071b..1120986563 100644
--- a/engines/director/lingo/lingo-code.h
+++ b/engines/director/lingo/lingo-code.h
@@ -100,11 +100,18 @@ namespace LC {
void c_tell();
void c_telldone();
void c_exitRepeat();
+ Datum compareArrays(Datum (*compareFunc)(Datum, Datum), Datum d1, Datum d2);
+ Datum eqData(Datum d1, Datum d2);
void c_eq();
+ Datum neqData(Datum d1, Datum d2);
void c_neq();
+ Datum gtData(Datum d1, Datum d2);
void c_gt();
+ Datum ltData(Datum d1, Datum d2);
void c_lt();
+ Datum geData(Datum d1, Datum d2);
void c_ge();
+ Datum leData(Datum d1, Datum d2);
void c_le();
void c_jump();
void c_jumpifz();
diff --git a/engines/director/lingo/tests/lists.lingo b/engines/director/lingo/tests/lists.lingo
index 433707a477..4a29c88011 100644
--- a/engines/director/lingo/tests/lists.lingo
+++ b/engines/director/lingo/tests/lists.lingo
@@ -24,3 +24,7 @@ set res to a + floats
set res to a + strings
set res to a + 1
set res to 1 + b
+
+set res to a = a
+set res to a = b
+set res to a < b
Commit: 8347638ea66b8379c8ed35eddf1674c78ed80005
https://github.com/scummvm/scummvm/commit/8347638ea66b8379c8ed35eddf1674c78ed80005
Author: djsrv (dservilla at gmail.com)
Date: 2020-04-09T00:51:25+02:00
Commit Message:
DIRECTOR: LINGO: Implement b_max and b_min
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 cfc96698fe..9b8d34e17a 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -91,8 +91,8 @@ static struct BuiltinProto {
{ "getPropAt", LB::b_getPropAt, 2, 2, true, 4, FBLTIN }, // D4 f
{ "list", LB::b_list, -1, 0, true, 4, FBLTIN }, // D4 f
{ "listP", LB::b_listP, 1, 1, true, 4, FBLTIN }, // D4 f
- { "max", LB::b_max, 1, 1, true, 4, FBLTIN }, // D4 f
- { "min", LB::b_min, 1, 1, true, 4, FBLTIN }, // D4 f
+ { "max", LB::b_max, -1,0, true, 4, FBLTIN }, // D4 f
+ { "min", LB::b_min, -1,0, true, 4, FBLTIN }, // D4 f
{ "setaProp", LB::b_setaProp, 3, 3, false, 4, BLTIN }, // D4 c
{ "setAt", LB::b_setAt, 3, 3, false, 4, BLTIN }, // D4 c
{ "setProp", LB::b_setProp, 3, 3, false, 4, BLTIN }, // D4 c
@@ -717,13 +717,69 @@ void LB::b_listP(int nargs) {
}
void LB::b_max(int nargs) {
- g_lingo->printSTUBWithArglist("b_max", nargs);
- g_lingo->dropStack(nargs);
+ Datum max;
+ max.type = INT;
+ max.u.i = 0;
+
+ if (nargs == 1) {
+ Datum d = g_lingo->pop();
+ if (d.type == ARRAY) {
+ uint arrsize = d.u.farr->size();
+ for (uint i = 0; i < arrsize; i++) {
+ Datum item = d.u.farr->operator[](i);
+ if (i == 0 || item.compareTo(max) > 0) {
+ max = item;
+ }
+ }
+ } else {
+ max = d;
+ }
+ } else if (nargs > 0) {
+ for (int i = 0; i < nargs; i++) {
+ Datum d = g_lingo->_stack[g_lingo->_stack.size() - nargs + i];
+ if (d.type == ARRAY) {
+ warning("b_max: undefined behavior: array mixed with other args");
+ }
+ if (i == 0 || d.compareTo(max) > 0) {
+ max = d;
+ }
+ }
+ g_lingo->dropStack(nargs);
+ }
+ g_lingo->push(max);
}
void LB::b_min(int nargs) {
- g_lingo->printSTUBWithArglist("b_min", nargs);
- g_lingo->dropStack(nargs);
+ Datum min;
+ min.type = INT;
+ min.u.i = 0;
+
+ if (nargs == 1) {
+ Datum d = g_lingo->pop();
+ if (d.type == ARRAY) {
+ uint arrsize = d.u.farr->size();
+ for (uint i = 0; i < arrsize; i++) {
+ Datum item = d.u.farr->operator[](i);
+ if (i == 0 || item.compareTo(min) < 0) {
+ min = item;
+ }
+ }
+ } else {
+ min = d;
+ }
+ } else if (nargs > 0) {
+ for (int i = 0; i < nargs; i++) {
+ Datum d = g_lingo->_stack[g_lingo->_stack.size() - nargs + i];
+ if (d.type == ARRAY) {
+ warning("b_min: undefined behavior: array mixed with other args");
+ }
+ if (i == 0 || d.compareTo(min) < 0) {
+ min = d;
+ }
+ }
+ g_lingo->dropStack(nargs);
+ }
+ g_lingo->push(min);
}
void LB::b_setaProp(int nargs) {
More information about the Scummvm-git-logs
mailing list