[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