[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