[Scummvm-git-logs] scummvm master -> b0d8880919ef68688fc3fd033ceb4aec647d091f
sev-
sev at scummvm.org
Tue Apr 28 21:33:03 UTC 2020
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
94b80a2e10 DIRECTOR: LINGO: Collapse compareTo functions
1f77ea3a31 DIRECTOR: LINGO: Finish property array datum type
c74ef4136b DIRECTOR: LINGO: Implement property array comparisons
b0d8880919 DIRECTOR: LINGO: Implement property array functions
Commit: 94b80a2e1080d40f9f68ef611939f36f9c2f2832
https://github.com/scummvm/scummvm/commit/94b80a2e1080d40f9f68ef611939f36f9c2f2832
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-04-28T23:32:57+02:00
Commit Message:
DIRECTOR: LINGO: Collapse compareTo functions
Changed paths:
engines/director/lingo/lingo-code.cpp
engines/director/lingo/lingo.cpp
engines/director/lingo/lingo.h
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index e4ab35f9cf..b1465a3548 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -1022,7 +1022,7 @@ 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.u.i = (d1.compareTo(d2, true) == 0) ? 1 : 0;
d1.type = INT;
return d1;
}
@@ -1037,7 +1037,7 @@ Datum LC::neqData(Datum d1, Datum d2) {
if (d1.type == ARRAY || d2.type == ARRAY) {
return LC::compareArrays(LC::neqData, d1, d2);
}
- d1.u.i = (d1.compareToIgnoreCase(d2) != 0) ? 1 : 0;
+ d1.u.i = (d1.compareTo(d2, true) != 0) ? 1 : 0;
d1.type = INT;
return d1;
}
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 3816c4edd6..c515a0eda3 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -578,9 +578,9 @@ const char *Datum::type2str(bool isk) {
}
}
-int Datum::compareTo(Datum d) {
+int Datum::compareTo(Datum d, bool ignoreCase) {
if (type == STRING && d.type == STRING) {
- return u.s->compareTo(*d.u.s);
+ return ignoreCase ? u.s->compareToIgnoreCase(*d.u.s) : u.s->compareTo(*d.u.s);
} else if (g_lingo->alignTypes(*this, d) == FLOAT) {
if (u.f < d.u.f) {
return -1;
@@ -600,15 +600,6 @@ int Datum::compareTo(Datum d) {
}
}
-int Datum::compareToIgnoreCase(Datum d) {
- if (type == STRING && d.type == STRING) {
- Common::String *s1 = toLowercaseMac(u.s);
- Common::String *s2 = toLowercaseMac(d.u.s);
- return s1->compareTo(*s2);
- }
- 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 b5413fe0dd..cc7655348b 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -115,8 +115,7 @@ struct Datum { /* interpreter stack type */
const char *type2str(bool isk = false);
- int compareTo(Datum d);
- int compareToIgnoreCase(Datum d);
+ int compareTo(Datum d, bool ignoreCase = false);
};
struct Builtin {
Commit: 1f77ea3a31ad2912daf3f56550a1cc70dce7c22c
https://github.com/scummvm/scummvm/commit/1f77ea3a31ad2912daf3f56550a1cc70dce7c22c
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-04-28T23:32:57+02:00
Commit Message:
DIRECTOR: LINGO: Finish property array datum type
Changed paths:
engines/director/lingo/lingo-code.cpp
engines/director/lingo/lingo-codegen.cpp
engines/director/lingo/lingo.cpp
engines/director/lingo/lingo.h
engines/director/types.h
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index b1465a3548..52cd7a6303 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -230,6 +230,9 @@ void LC::c_printtop(void) {
case ARRAY:
warning("%s", d.getPrintable().c_str());
break;
+ case PARRAY:
+ warning("%s", d.getPrintable().c_str());
+ break;
default:
warning("--unknown--");
}
@@ -315,13 +318,17 @@ void LC::c_proparraypush() {
Datum d;
int arraySize = g_lingo->readInt();
- warning("STUB: c_proparraypush()");
+ d.type = PARRAY;
+ d.u.parr = new PropertyArray;
- for (int i = 0; i < arraySize * 2; i++)
- g_lingo->pop();
+ for (int i = 0; i < arraySize; i++) {
+ Datum p = g_lingo->pop();
+ Datum v = g_lingo->pop();
+
+ PCell cell = PCell(p, v);
+ d.u.parr->insert_at(0, cell);
+ }
- d.u.i = arraySize;
- d.type = INT;
g_lingo->push(d);
}
@@ -380,7 +387,7 @@ void LC::c_assign() {
}
bool LC::verify(Symbol *s) {
- if (s->type != INT && s->type != VOID && s->type != FLOAT && s->type != STRING && s->type != POINT && s->type != SYMBOL && s->type != ARRAY) {
+ if (s->type != INT && s->type != VOID && s->type != FLOAT && s->type != STRING && s->type != POINT && s->type != SYMBOL && s->type != ARRAY && s->type != PARRAY) {
warning("attempt to evaluate non-variable '%s'", s->name.c_str());
return false;
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index 292b296e8f..10e23bac72 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -532,7 +532,8 @@ void Lingo::varAssign(Datum &var, Datum &value) {
}
if (sym->type != INT && sym->type != VOID &&
- sym->type != FLOAT && sym->type != STRING && sym->type != ARRAY) {
+ sym->type != FLOAT && sym->type != STRING &&
+ sym->type != ARRAY && sym->type != PARRAY) {
warning("varAssign: assignment to non-variable '%s'", sym->name.c_str());
return;
}
@@ -542,6 +543,8 @@ void Lingo::varAssign(Datum &var, Datum &value) {
if (sym->type == POINT || sym->type == RECT || sym->type == ARRAY)
delete var.u.sym->u.farr;
+ else if (sym->type == PARRAY)
+ delete var.u.sym->u.parr;
sym->type = value.type;
if (value.type == INT) {
@@ -554,6 +557,8 @@ void Lingo::varAssign(Datum &var, Datum &value) {
} else if (value.type == POINT || value.type == ARRAY) {
sym->u.farr = new DatumArray(*value.u.farr);
delete value.u.farr;
+ } else if (value.type == PARRAY) {
+ sym->u.parr = new PropertyArray(*value.u.parr);
} else if (value.type == SYMBOL) {
sym->u.s = value.u.s;
} else if (value.type == OBJECT) {
@@ -623,9 +628,11 @@ Datum Lingo::varFetch(Datum &var) {
result.u.s = var.u.sym->u.s;
else if (sym->type == VOID)
result.u.i = 0;
- else if (sym->type == ARRAY) {
+ else if (sym->type == ARRAY)
result.u.farr = sym->u.farr;
- } else {
+ else if (sym->type == PARRAY)
+ result.u.parr = sym->u.parr;
+ else {
warning("varFetch: unhandled type: %s", var.type2str());
result.type = VOID;
}
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index c515a0eda3..80bd0d03e6 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -50,6 +50,21 @@ Symbol::Symbol() {
archiveIndex = 0;
}
+PCell::PCell() {
+ p = nullptr;
+ v = nullptr;
+}
+
+PCell::PCell(Datum &prop, Datum &val) {
+ p = new Datum;
+ p->type = prop.type;
+ p->u = prop.u;
+
+ v = new Datum;
+ v->type = val.type;
+ v->u = val.u;
+}
+
Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
g_lingo = this;
@@ -533,6 +548,20 @@ Common::String *Datum::makeString(bool printonly) {
*s += *d.makeString(printonly);
}
+ *s += "]";
+ break;
+ case PARRAY:
+ *s = "[";
+ if (u.parr->size() == 0)
+ *s += ":";
+ for (uint i = 0; i < u.parr->size(); i++) {
+ if (i > 0)
+ *s += ", ";
+ Datum p = *u.parr->operator[](i).p;
+ Datum v = *u.parr->operator[](i).v;
+ *s += Common::String::format("%s:%s", p.makeString(printonly)->c_str(), v.makeString(printonly)->c_str());
+ }
+
*s += "]";
break;
default:
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index cc7655348b..44cccd75d7 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -78,6 +78,7 @@ struct Symbol { /* symbol table entry */
void (*bltin)(int); /* BUILTIN */
Common::String *s; /* STRING */
DatumArray *farr; /* ARRAY, POINT, RECT */
+ PropertyArray *parr;
} u;
int nargs; /* number of arguments */
int maxArgs; /* maximal number of arguments, for builtins */
@@ -92,6 +93,14 @@ struct Symbol { /* symbol table entry */
Symbol();
};
+struct PCell {
+ Datum *p;
+ Datum *v;
+
+ PCell();
+ PCell(Datum &prop, Datum &val);
+};
+
struct Datum { /* interpreter stack type */
int type;
@@ -101,6 +110,7 @@ struct Datum { /* interpreter stack type */
Common::String *s; /* STRING */
Symbol *sym;
DatumArray *farr; /* ARRAY, POINT, RECT */
+ PropertyArray *parr; /* PARRAY */
} u;
Datum() { u.sym = NULL; type = VOID; }
diff --git a/engines/director/types.h b/engines/director/types.h
index 647d976144..ac74569a19 100644
--- a/engines/director/types.h
+++ b/engines/director/types.h
@@ -238,7 +238,9 @@ enum {
};
struct Datum;
+struct PCell;
typedef Common::Array<Datum> DatumArray;
+typedef Common::Array<PCell> PropertyArray;
const char *scriptType2str(ScriptType scr);
Commit: c74ef4136be3a29badd114ca1b93e4d71e3b9465
https://github.com/scummvm/scummvm/commit/c74ef4136be3a29badd114ca1b93e4d71e3b9465
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-04-28T23:32:57+02:00
Commit Message:
DIRECTOR: LINGO: Implement property array comparisons
Changed paths:
engines/director/lingo/lingo-code.cpp
engines/director/lingo/lingo-code.h
engines/director/lingo/lingo.cpp
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 52cd7a6303..da14421752 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -995,38 +995,62 @@ void LC::c_not() {
g_lingo->push(d);
}
-Datum LC::compareArrays(Datum (*compareFunc)(Datum, Datum), Datum d1, Datum d2) {
+Datum LC::compareArrays(Datum (*compareFunc)(Datum, Datum), Datum d1, Datum d2, bool location, bool value) {
// 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 == PARRAY && d2.type == PARRAY) {
+ arraySize = MIN(d1.u.parr->size(), d2.u.parr->size());
} else if (d1.type == ARRAY) {
arraySize = d1.u.farr->size();
- } else {
+ } else if (d1.type == PARRAY) {
+ arraySize = d1.u.parr->size();
+ } else if (d2.type == ARRAY) {
arraySize = d2.u.farr->size();
+ } else if (d2.type == PARRAY) {
+ arraySize = d2.u.parr->size();
}
+
Datum res;
res.type = INT;
- res.u.i = 1;
+ res.u.i = location ? -1 : 1;
Datum a = d1;
Datum b = d2;
for (uint i = 0; i < arraySize; i++) {
if (d1.type == ARRAY) {
a = d1.u.farr->operator[](i);
+ } else if (d1.type == PARRAY) {
+ PCell t = d1.u.parr->operator[](i);
+ a = value ? *t.v : *t.p;
}
+
if (d2.type == ARRAY) {
b = d2.u.farr->operator[](i);
+ } else if (d2.type == PARRAY) {
+ PCell t = d2.u.parr->operator[](i);
+ b = value ? *t.v : *t.p;
}
+
res = compareFunc(a, b);
- if (res.u.i == 0) {
- break;
+ if (!location) {
+ if (res.u.i == 0) {
+ break;
+ }
+ } else {
+ if (res.u.i == 1) {
+ // Lingo indexing starts at 1
+ res.u.i = (int)i + 1;
+ break;
+ }
}
}
return res;
}
Datum LC::eqData(Datum d1, Datum d2) {
- if (d1.type == ARRAY || d2.type == ARRAY) {
+ if (d1.type == ARRAY || d2.type == ARRAY ||
+ d1.type == PARRAY || d2.type == PARRAY) {
return LC::compareArrays(LC::eqData, d1, d2);
}
d1.u.i = (d1.compareTo(d2, true) == 0) ? 1 : 0;
diff --git a/engines/director/lingo/lingo-code.h b/engines/director/lingo/lingo-code.h
index 02abd91164..ac3d61fbb4 100644
--- a/engines/director/lingo/lingo-code.h
+++ b/engines/director/lingo/lingo-code.h
@@ -101,7 +101,7 @@ namespace LC {
void c_tell();
void c_telldone();
void c_exitRepeat();
- Datum compareArrays(Datum (*compareFunc)(Datum, Datum), Datum d1, Datum d2);
+ Datum compareArrays(Datum (*compareFunc)(Datum, Datum), Datum d1, Datum d2, bool location = false, bool value = false);
Datum eqData(Datum d1, Datum d2);
void c_eq();
Datum neqData(Datum d1, Datum d2);
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 80bd0d03e6..d57c093c94 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -349,10 +349,10 @@ void Lingo::restartLingo() {
int Lingo::alignTypes(Datum &d1, Datum &d2) {
int opType = VOID;
- if (d1.type == REFERENCE)
+ if (d1.type == REFERENCE || d1.type == SYMBOL)
d1.makeString();
- if (d2.type == REFERENCE)
+ if (d2.type == REFERENCE || d2.type == SYMBOL)
d2.makeString();
if (d1.type == STRING) {
@@ -609,7 +609,14 @@ const char *Datum::type2str(bool isk) {
int Datum::compareTo(Datum d, bool ignoreCase) {
if (type == STRING && d.type == STRING) {
- return ignoreCase ? u.s->compareToIgnoreCase(*d.u.s) : u.s->compareTo(*d.u.s);
+ if (ignoreCase) {
+ return toLowercaseMac(u.s)->compareTo(*toLowercaseMac(d.u.s));
+ } else {
+ return u.s->compareTo(*d.u.s);
+ }
+ } else if (type == SYMBOL && d.type == SYMBOL) {
+ // TODO: Implement union comparisons
+ return ignoreCase ? u.sym->name.compareToIgnoreCase(d.u.sym->name) : u.sym->name.compareTo(d.u.sym->name);
} else if (g_lingo->alignTypes(*this, d) == FLOAT) {
if (u.f < d.u.f) {
return -1;
Commit: b0d8880919ef68688fc3fd033ceb4aec647d091f
https://github.com/scummvm/scummvm/commit/b0d8880919ef68688fc3fd033ceb4aec647d091f
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-04-28T23:32:57+02:00
Commit Message:
DIRECTOR: LINGO: Implement property array functions
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 55a7b934fc..d2c90ca2ea 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -52,6 +52,12 @@ namespace Director {
return; \
}
+#define TYPECHECK2(datum, t1, t2) \
+ if ((datum).type != (t1) && (datum).type != (t2)) { \
+ warning("%s: %s arg should be of type %s or %s, not %s", __FUNCTION__, #datum, #t1, #t2, (datum).type2str()); \
+ return; \
+ }
+
#define ARRBOUNDSCHECK(idx,array) \
if ((idx)-1 < 0 || (idx) > (array).u.farr->size()) { \
warning("%s: index out of bounds (%d of %d)", __FUNCTION__, (idx), (array).u.farr->size()); \
@@ -582,14 +588,30 @@ void LB::b_addAt(int nargs) {
Datum list = g_lingo->pop();
TYPECHECK(index, INT);
+ if (index.type == FLOAT)
+ index.makeInt();
TYPECHECK(list, ARRAY);
+ if (!((uint)index.u.i < list.u.farr->size())) {
+ for (uint i = 0; i < index.u.i-list.u.farr->size()-1; i++)
+ list.u.farr->push_back(Datum(0));
+ }
list.u.farr->insert_at(index.u.i-1, value);
}
void LB::b_addProp(int nargs) {
- g_lingo->printSTUBWithArglist("b_addProp", nargs);
- g_lingo->dropStack(nargs);
+ ARGNUMCHECK(3);
+
+ Datum value = g_lingo->pop();
+ Datum prop = g_lingo->pop();
+ Datum list = g_lingo->pop();
+
+ TYPECHECK(list, PARRAY);
+ if (prop.type == REFERENCE)
+ prop = g_lingo->varFetch(prop);
+
+ PCell cell = PCell(prop, value);
+ list.u.parr->push_back(cell);
}
void LB::b_append(int nargs) {
@@ -607,12 +629,20 @@ void LB::b_count(int nargs) {
ARGNUMCHECK(1);
Datum list = g_lingo->pop();
-
- TYPECHECK(list, ARRAY);
-
Datum result;
result.type = INT;
- result.u.i = list.u.farr->size();
+
+ switch (list.type) {
+ case ARRAY:
+ result.u.i = list.u.farr->size();
+ break;
+ case PARRAY:
+ result.u.i = list.u.parr->size();
+ break;
+ default:
+ TYPECHECK2(list, ARRAY, PARRAY);
+ }
+
g_lingo->push(result);
}
@@ -621,31 +651,111 @@ void LB::b_deleteAt(int nargs) {
Datum index = g_lingo->pop();
Datum list = g_lingo->pop();
-
+ if (index.type == FLOAT)
+ index.makeInt();
TYPECHECK(index, INT);
- TYPECHECK(list, ARRAY);
- list.u.farr->remove_at(index.u.i-1);
+ switch (list.type) {
+ case ARRAY:
+ list.u.farr->remove_at(index.u.i-1);
+ break;
+ case PARRAY:
+ list.u.parr->remove_at(index.u.i-1);
+ break;
+ default:
+ TYPECHECK2(list, ARRAY, PARRAY);
+ }
}
void LB::b_deleteProp(int nargs) {
- g_lingo->printSTUBWithArglist("b_deleteProp", nargs);
- g_lingo->dropStack(nargs);
+ ARGNUMCHECK(2);
+
+ Datum prop = g_lingo->pop();
+ Datum list = g_lingo->pop();
+
+ switch (list.type) {
+ case ARRAY:
+ g_lingo->push(list);
+ g_lingo->push(prop);
+ b_deleteAt(nargs);
+ break;
+ case PARRAY: {
+ int index = LC::compareArrays(LC::eqData, list, prop, true).u.i;
+ if (index > 0) {
+ list.u.parr->remove_at(index-1);
+ }
+ break;
+ }
+ default:
+ TYPECHECK2(list, ARRAY, PARRAY);
+ }
}
void LB::b_findPos(int nargs) {
- g_lingo->printSTUBWithArglist("b_findPos", nargs);
- g_lingo->dropStack(nargs);
+ ARGNUMCHECK(2);
+
+ Datum prop = g_lingo->pop();
+ Datum list = g_lingo->pop();
+ Datum d(0);
+ TYPECHECK(list, PARRAY);
+
+ int index = LC::compareArrays(LC::eqData, list, prop, true).u.i;
+ if (index > 0) {
+ d.type = INT;
+ d.u.i = index;
+ }
+
+ g_lingo->push(d);
}
void LB::b_findPosNear(int nargs) {
- g_lingo->printSTUBWithArglist("b_findPosNear", nargs);
- g_lingo->dropStack(nargs);
+ ARGNUMCHECK(2);
+
+ Datum prop = g_lingo->pop();
+ Datum list = g_lingo->pop();
+ Datum d(0);
+ TYPECHECK(list, PARRAY);
+
+ // FIXME: Integrate with compareTo framework
+ prop = prop.makeString();
+ prop.u.s->toLowercase();
+
+ for (uint i = 0; i < list.u.parr->size(); i++) {
+ Datum p = *list.u.parr->operator[](i).p;
+ p.makeString();
+ p.u.s->toLowercase();
+ if (p.u.s->find(prop.u.s->c_str()) == 0) {
+ d.u.i = i+1;
+ break;
+ }
+ }
+
+ g_lingo->push(d);
}
void LB::b_getaProp(int nargs) {
- g_lingo->printSTUBWithArglist("b_getaProp", nargs);
- g_lingo->dropStack(nargs);
+ ARGNUMCHECK(2);
+ Datum prop = g_lingo->pop();
+ Datum list = g_lingo->pop();
+
+ switch (list.type) {
+ case ARRAY:
+ g_lingo->push(list);
+ g_lingo->push(prop);
+ b_getAt(nargs);
+ break;
+ case PARRAY: {
+ Datum d;
+ int index = LC::compareArrays(LC::eqData, list, prop, true).u.i;
+ if (index > 0) {
+ d = *list.u.parr->operator[](index-1).v;
+ }
+ g_lingo->push(d);
+ break;
+ }
+ default:
+ TYPECHECK2(list, ARRAY, PARRAY);
+ }
}
void LB::b_getAt(int nargs) {
@@ -655,38 +765,131 @@ void LB::b_getAt(int nargs) {
Datum list = g_lingo->pop();
if (index.type == FLOAT)
index.makeInt();
-
TYPECHECK(index, INT);
- TYPECHECK(list, ARRAY);
- ARRBOUNDSCHECK(index.u.i, list);
- Datum result = list.u.farr->operator[](index.u.i-1);
- g_lingo->push(result);
+ switch (list.type) {
+ case ARRAY:
+ ARRBOUNDSCHECK(index.u.i, list);
+ g_lingo->push(list.u.farr->operator[](index.u.i-1));
+ break;
+ case PARRAY:
+ ARRBOUNDSCHECK(index.u.i, list);
+ g_lingo->push(*list.u.parr->operator[](index.u.i-1).v);
+ break;
+ default:
+ TYPECHECK2(list, ARRAY, PARRAY);
+ }
}
void LB::b_getLast(int nargs) {
- g_lingo->printSTUBWithArglist("b_getLast", nargs);
- g_lingo->dropStack(nargs);
+ ARGNUMCHECK(1);
+
+ Datum list = g_lingo->pop();
+ switch (list.type) {
+ case ARRAY:
+ g_lingo->push(list.u.farr->back());
+ break;
+ case PARRAY:
+ g_lingo->push(*list.u.parr->back().v);
+ break;
+ default:
+ TYPECHECK(list, ARRAY);
+ }
}
void LB::b_getOne(int nargs) {
- g_lingo->printSTUBWithArglist("b_getOne", nargs);
- g_lingo->dropStack(nargs);
+ ARGNUMCHECK(2);
+ Datum val = g_lingo->pop();
+ Datum list = g_lingo->pop();
+
+ switch (list.type) {
+ case ARRAY:
+ g_lingo->push(list);
+ g_lingo->push(val);
+ b_getPos(nargs);
+ break;
+ case PARRAY: {
+ Datum d;
+ int index = LC::compareArrays(LC::eqData, list, val, true, true).u.i;
+ if (index > 0) {
+ d = *list.u.parr->operator[](index-1).p;
+ }
+ g_lingo->push(d);
+ break;
+ }
+ default:
+ TYPECHECK2(list, ARRAY, PARRAY);
+ }
}
void LB::b_getPos(int nargs) {
- g_lingo->printSTUBWithArglist("b_getPos", nargs);
- g_lingo->dropStack(nargs);
+ ARGNUMCHECK(2);
+ Datum val = g_lingo->pop();
+ Datum list = g_lingo->pop();
+
+ switch (list.type) {
+ case ARRAY: {
+ if (val.type == FLOAT)
+ val.makeInt();
+ TYPECHECK(val, INT);
+ Datum d(0);
+ int index = LC::compareArrays(LC::eqData, list, val, true).u.i;
+ if (index > 0) {
+ d.u.i = index;
+ }
+ g_lingo->push(d);
+ break;
+ }
+ case PARRAY: {
+ Datum d(0);
+ int index = LC::compareArrays(LC::eqData, list, val, true, true).u.i;
+ if (index > 0) {
+ d.u.i = index;
+ }
+ g_lingo->push(d);
+ break;
+ }
+ default:
+ TYPECHECK2(list, ARRAY, PARRAY);
+ }
}
void LB::b_getProp(int nargs) {
- g_lingo->printSTUBWithArglist("b_getProp", nargs);
- g_lingo->dropStack(nargs);
+ ARGNUMCHECK(2);
+ Datum prop = g_lingo->pop();
+ Datum list = g_lingo->pop();
+
+ switch (list.type) {
+ case ARRAY:
+ g_lingo->push(list);
+ g_lingo->push(prop);
+ b_getPos(nargs);
+ break;
+ case PARRAY: {
+ int index = LC::compareArrays(LC::eqData, list, prop, true).u.i;
+ if (index > 0) {
+ g_lingo->push(*list.u.parr->operator[](index-1).v);
+ } else {
+ error("b_getProp: Property %s not found", prop.makeString()->c_str());
+ }
+ break;
+ }
+ default:
+ TYPECHECK2(list, ARRAY, PARRAY);
+ }
}
void LB::b_getPropAt(int nargs) {
- g_lingo->printSTUBWithArglist("b_getPropAt", nargs);
- g_lingo->dropStack(nargs);
+ ARGNUMCHECK(2);
+ Datum index = g_lingo->pop();
+ Datum list = g_lingo->pop();
+ TYPECHECK(list, PARRAY);
+
+ if (index.type == FLOAT)
+ index.makeInt();
+ TYPECHECK(index, INT);
+
+ g_lingo->push(*list.u.parr->operator[](index.u.i-1).p);
}
void LB::b_list(int nargs) {
@@ -701,8 +904,13 @@ void LB::b_list(int nargs) {
}
void LB::b_listP(int nargs) {
- g_lingo->printSTUBWithArglist("b_listP", nargs);
- g_lingo->dropStack(nargs);
+ ARGNUMCHECK(1);
+ Datum list = g_lingo->pop();
+ Datum d(0);
+ if (list.type == ARRAY || list.type == PARRAY) {
+ d.u.i = 1;
+ }
+ g_lingo->push(d);
}
void LB::b_max(int nargs) {
@@ -772,18 +980,75 @@ void LB::b_min(int nargs) {
}
void LB::b_setaProp(int nargs) {
- g_lingo->printSTUBWithArglist("b_setaProp", nargs);
- g_lingo->dropStack(nargs);
+ ARGNUMCHECK(3);
+ Datum value = g_lingo->pop();
+ Datum prop = g_lingo->pop();
+ Datum list = g_lingo->pop();
+
+ switch (list.type) {
+ case ARRAY:
+ g_lingo->push(list);
+ g_lingo->push(prop);
+ g_lingo->push(value);
+ b_setAt(nargs);
+ break;
+ case PARRAY: {
+ int index = LC::compareArrays(LC::eqData, list, prop, true).u.i;
+ if (index > 0) {
+ *list.u.parr->operator[](index-1).v = value;
+ } else {
+ PCell cell = PCell(prop, value);
+ list.u.parr->push_back(cell);
+ }
+ break;
+ }
+ default:
+ TYPECHECK2(list, ARRAY, PARRAY);
+ }
}
void LB::b_setAt(int nargs) {
- g_lingo->printSTUBWithArglist("b_setAt", nargs);
- g_lingo->dropStack(nargs);
+ ARGNUMCHECK(3);
+ Datum value = g_lingo->pop();
+ Datum index = g_lingo->pop();
+ Datum list = g_lingo->pop();
+ if (index.type == FLOAT)
+ index.makeInt();
+ TYPECHECK(index, INT);
+
+ switch (list.type) {
+ case ARRAY:
+ if ((uint)index.u.i < list.u.farr->size()) {
+ list.u.farr->operator[](index.u.i-1) = value;
+ } else {
+ // TODO: Extend the list if we request an index beyond it
+ ARRBOUNDSCHECK(index.u.i, list);
+ }
+ break;
+ case PARRAY:
+ ARRBOUNDSCHECK(index.u.i, list);
+ *list.u.parr->operator[](index.u.i-1).v = value;
+ break;
+ default:
+ TYPECHECK2(list, ARRAY, PARRAY);
+ }
}
void LB::b_setProp(int nargs) {
- g_lingo->printSTUBWithArglist("b_setProp", nargs);
- g_lingo->dropStack(nargs);
+ ARGNUMCHECK(3);
+ Datum value = g_lingo->pop();
+ Datum prop = g_lingo->pop();
+ Datum list = g_lingo->pop();
+ TYPECHECK(list, PARRAY);
+ if (prop.type == REFERENCE)
+ prop = g_lingo->varFetch(prop);
+
+ int index = LC::compareArrays(LC::eqData, list, prop, true).u.i;
+ if (index > 0) {
+ *list.u.parr->operator[](index-1).v = value;
+ } else {
+ warning("b_setProp: Property not found");
+ }
}
void LB::b_sort(int nargs) {
More information about the Scummvm-git-logs
mailing list