aboutsummaryrefslogtreecommitdiff
path: root/engines/glk
diff options
context:
space:
mode:
authorPaul Gilbert2019-11-01 22:12:41 -0700
committerPaul Gilbert2019-11-11 18:20:29 -0800
commite1911f9aff91a2264b6d05c3fda8505bed07739a (patch)
treeafa7503d9d5b5897c65f517dc761859b75958766 /engines/glk
parentfdb5ead5ca91a92c11192e61d23beee90e4caacb (diff)
downloadscummvm-rg350-e1911f9aff91a2264b6d05c3fda8505bed07739a.tar.gz
scummvm-rg350-e1911f9aff91a2264b6d05c3fda8505bed07739a.tar.bz2
scummvm-rg350-e1911f9aff91a2264b6d05c3fda8505bed07739a.zip
GLK: Fix structures using unions
Diffstat (limited to 'engines/glk')
-rw-r--r--engines/glk/archetype/archetype.cpp279
-rw-r--r--engines/glk/archetype/expression.h10
-rw-r--r--engines/glk/archetype/interpreter.cpp94
-rw-r--r--engines/glk/archetype/interpreter.h2
-rw-r--r--engines/glk/archetype/keywords.cpp1
-rw-r--r--engines/glk/archetype/saveload.cpp86
-rw-r--r--engines/glk/archetype/semantic.cpp32
-rw-r--r--engines/glk/archetype/statement.h10
-rw-r--r--engines/glk/archetype/sys_object.cpp24
9 files changed, 275 insertions, 263 deletions
diff --git a/engines/glk/archetype/archetype.cpp b/engines/glk/archetype/archetype.cpp
index 37b40ab335..5ab3744d4a 100644
--- a/engines/glk/archetype/archetype.cpp
+++ b/engines/glk/archetype/archetype.cpp
@@ -101,6 +101,7 @@ void Archetype::interpret() {
ContextType context;
ResultType result;
+
undefine(result);
if (!send_message(OP_SEND, find_message("START"), MainObject, result, context))
@@ -140,8 +141,8 @@ void Archetype::lookup(int the_obj, int the_attr, ResultType &result, ContextTyp
if (desired == NAME) {
result._kind = IDENT;
- result._ident.ident_kind = ATTRIBUTE_ID;
- result._ident.ident_int = the_attr;
+ result._data._ident.ident_kind = ATTRIBUTE_ID;
+ result._data._ident.ident_int = the_attr;
return;
}
@@ -202,19 +203,19 @@ void Archetype::lookup(int the_obj, int the_attr, ResultType &result, ContextTyp
case LVALUE:
if (first_pass) {
result._kind = ATTR_PTR;
- result._attr.acl_attr = np;
+ result._data._attr.acl_attr = np;
} else {
// inherited - must create new node }
result._kind = ATTR_PTR;
- result._attr.acl_attr = (NodePtr)malloc(sizeof(NodeType));
+ result._data._attr.acl_attr = (NodePtr)malloc(sizeof(NodeType));
e = (ExprTree)malloc(sizeof(ExprNode));
undefine(*e);
eval_expr((ExprPtr)np->data, *e, c, RVALUE);
- result._attr.acl_attr->data = e;
- result._attr.acl_attr->key = the_attr;
- insert_item(((ObjectPtr)original)->attributes, result._attr.acl_attr);
+ result._data._attr.acl_attr->data = e;
+ result._data._attr.acl_attr->key = the_attr;
+ insert_item(((ObjectPtr)original)->attributes, result._data._attr.acl_attr);
}
break;
@@ -228,7 +229,7 @@ bool Archetype::send_message(int transport, int message_sent, int recipient,
bool done, find_other;
ObjectPtr op, original;
ResultType r;
- NodePtr np;
+ NodePtr np;
StatementPtr st;
void *p;
ContextType c;
@@ -240,8 +241,8 @@ bool Archetype::send_message(int transport, int message_sent, int recipient,
if ((Debug & DEBUG_MSGS) > 0) {
r._kind = IDENT;
- r._ident.ident_kind = OBJECT_ID;
- r._ident.ident_int = context.self;
+ r._data._ident.ident_kind = OBJECT_ID;
+ r._data._ident.ident_int = context.self;
wrapout(" : ", false);
display_result(r);
@@ -256,10 +257,10 @@ bool Archetype::send_message(int transport, int message_sent, int recipient,
}
if (transport == OP_SEND_TO_TYPE)
- r._ident.ident_kind = TYPE_ID;
+ r._data._ident.ident_kind = TYPE_ID;
wrapout(" to ", false);
- r._ident.ident_int = recipient;
+ r._data._ident.ident_int = recipient;
display_result(r);
wrapout("", true);
}
@@ -319,7 +320,7 @@ bool Archetype::send_message(int transport, int message_sent, int recipient,
// If we get here, it means that there was not even a "default" handler for
// the message in the given object or its lineage. Return ABSENT
result._kind = RESERVED;
- result._reserved.keyword = RW_ABSENT;
+ result._data._reserved.keyword = RW_ABSENT;
return false;
}
@@ -342,19 +343,19 @@ void Archetype::eval_expr(ExprTree the_expr, ResultType &result, ContextType &co
return;
// Check: if this is a lone attribute, look it up in this object"s table
- if (the_expr->_kind == IDENT && the_expr->_ident.ident_kind == ATTRIBUTE_ID)
- lookup(context.self, the_expr->_ident.ident_int, result, context, desired);
+ if (the_expr->_kind == IDENT && the_expr->_data._ident.ident_kind == ATTRIBUTE_ID)
+ lookup(context.self, the_expr->_data._ident.ident_int, result, context, desired);
else if (the_expr->_kind == RESERVED) {
// it is a special reserved word that requires an action
- switch (the_expr->_reserved.keyword) {
+ switch (the_expr->_data._reserved.keyword) {
case RW_READ:
case RW_KEY:
result._kind = STR_PTR;
- if (the_expr->_reserved.keyword == RW_READ)
- result._str.acl_str = ReadLine(true); // read full line
+ if (the_expr->_data._reserved.keyword == RW_READ)
+ result._data._str.acl_str = ReadLine(true); // read full line
else
- result._str.acl_str = ReadLine(false); // read single key
+ result._data._str.acl_str = ReadLine(false); // read single key
Rows = 0;
cursor_reset(); // user will have had to hit <RETURN>
@@ -362,24 +363,24 @@ void Archetype::eval_expr(ExprTree the_expr, ResultType &result, ContextType &co
case RW_MESSAGE:
result._kind = MESSAGE;
- result._msgTextQuote.index = context.message;
+ result._data._msgTextQuote.index = context.message;
break;
case RW_EACH:
case RW_SELF:
case RW_SENDER:
result._kind = IDENT;
- result._ident.ident_kind = OBJECT_ID;
+ result._data._ident.ident_kind = OBJECT_ID;
- switch (the_expr->_reserved.keyword) {
+ switch (the_expr->_data._reserved.keyword) {
case RW_EACH:
- result._ident.ident_int = context.each;
+ result._data._ident.ident_int = context.each;
break;
case RW_SELF:
- result._ident.ident_int = context.self;
+ result._data._ident.ident_int = context.self;
break;
case RW_SENDER:
- result._ident.ident_int = context.sender;
+ result._data._ident.ident_int = context.sender;
break;
default:
break;
@@ -391,37 +392,37 @@ void Archetype::eval_expr(ExprTree the_expr, ResultType &result, ContextType &co
}
} else if (the_expr->_kind == OPER) {
// It's an operator, need to evaulate it
- switch (the_expr->_oper.op_name) {
+ switch (the_expr->_data._oper.op_name) {
case OP_SEND:
case OP_PASS:
- eval_expr(the_expr->_oper.left, r1, context, RVALUE);
- eval_expr(the_expr->_oper.right, r2, context, RVALUE);
+ eval_expr(the_expr->_data._oper.left, r1, context, RVALUE);
+ eval_expr(the_expr->_data._oper.right, r2, context, RVALUE);
- if (r2._kind == IDENT && (r2._ident.ident_kind == OBJECT_ID || r2._ident.ident_kind == TYPE_ID)) {
+ if (r2._kind == IDENT && (r2._data._ident.ident_kind == OBJECT_ID || r2._data._ident.ident_kind == TYPE_ID)) {
// Object 0 is the system object and always receives string messages
- if (r2._ident.ident_kind == OBJECT_ID && r2._ident.ident_int == 0) {
+ if (r2._data._ident.ident_kind == OBJECT_ID && r2._data._ident.ident_int == 0) {
if (convert_to(STR_PTR, r1))
- send_to_system(the_expr->_oper.op_name, *r1._str.acl_str, result, context);
+ send_to_system(the_expr->_data._oper.op_name, *r1._data._str.acl_str, result, context);
} else if (convert_to(MESSAGE, r1)) {
- if (r2._ident.ident_kind == TYPE_ID)
- b = send_message(OP_SEND_TO_TYPE, r1._msgTextQuote.index, r2._ident.ident_int,
+ if (r2._data._ident.ident_kind == TYPE_ID)
+ b = send_message(OP_SEND_TO_TYPE, r1._data._msgTextQuote.index, r2._data._ident.ident_int,
result, context);
else
- b = send_message(the_expr->_oper.op_name, r1._msgTextQuote.index,
- r2._ident.ident_int, result, context);
+ b = send_message(the_expr->_data._oper.op_name, r1._data._msgTextQuote.index,
+ r2._data._ident.ident_int, result, context);
}
}
break;
case OP_DOT:
- eval_expr(the_expr->_oper.left, r1, context, RVALUE);
+ eval_expr(the_expr->_data._oper.left, r1, context, RVALUE);
- if (r1._kind == IDENT && r1._ident.ident_kind == OBJECT_ID) {
- eval_expr(the_expr->_oper.right, r2, context, NAME);
- if (r2._kind == IDENT && r2._ident.ident_kind == ATTRIBUTE_ID)
- lookup(r1._ident.ident_int, r2._ident.ident_int, result, context, desired);
+ if (r1._kind == IDENT && r1._data._ident.ident_kind == OBJECT_ID) {
+ eval_expr(the_expr->_data._oper.right, r2, context, NAME);
+ if (r2._kind == IDENT && r2._data._ident.ident_kind == ATTRIBUTE_ID)
+ lookup(r1._data._ident.ident_int, r2._data._ident.ident_int, result, context, desired);
}
break;
@@ -429,15 +430,15 @@ void Archetype::eval_expr(ExprTree the_expr, ResultType &result, ContextType &co
if (desired == NAME)
return;
- eval_expr(the_expr->_oper.right, result, context, RVALUE);
- eval_expr(the_expr->_oper.left, r1, context, LVALUE);
+ eval_expr(the_expr->_data._oper.right, result, context, RVALUE);
+ eval_expr(the_expr->_data._oper.left, r1, context, LVALUE);
if (!assignment(r1, result))
cleanup(result);
else if (desired == LVALUE) {
cleanup(result);
result._kind = ATTR_PTR;
- result._attr.acl_attr = r1._attr.acl_attr;
+ result._data._attr.acl_attr = r1._data._attr.acl_attr;
}
break;
@@ -453,29 +454,29 @@ void Archetype::eval_expr(ExprTree the_expr, ResultType &result, ContextType &co
e = (ExprTree)malloc(sizeof(ExprNode));
*e = *the_expr;
- switch (the_expr->_oper.op_name) {
+ switch (the_expr->_data._oper.op_name) {
case OP_C_MULTIPLY:
- e->_oper.op_name = OP_MULTIPLY;
+ e->_data._oper.op_name = OP_MULTIPLY;
break;
case OP_C_DIVIDE:
- e->_oper.op_name = OP_DIVIDE;
+ e->_data._oper.op_name = OP_DIVIDE;
break;
case OP_C_PLUS:
- e->_oper.op_name = OP_PLUS;
+ e->_data._oper.op_name = OP_PLUS;
break;
case OP_C_MINUS:
- e->_oper.op_name = OP_MINUS;
+ e->_data._oper.op_name = OP_MINUS;
break;
case OP_C_CONCAT:
- e->_oper.op_name = OP_CONCAT;
+ e->_data._oper.op_name = OP_CONCAT;
break;
default:
break;
}
eval_expr(e, r1, context, RVALUE);
- e->_oper.op_name = OP_ASSIGN;
- e->_oper.right = &r1;
+ e->_data._oper.op_name = OP_ASSIGN;
+ e->_data._oper.right = &r1;
eval_expr(e, result, context, desired);
free(e);
@@ -483,24 +484,24 @@ void Archetype::eval_expr(ExprTree the_expr, ResultType &result, ContextType &co
case OP_CHS:
case OP_NUMERIC:
- eval_expr(the_expr->_oper.right, result, context, RVALUE);
+ eval_expr(the_expr->_data._oper.right, result, context, RVALUE);
if (!convert_to(NUMERIC, result))
cleanup(result);
- else if (the_expr->_oper.op_name == OP_CHS)
- result._numeric.acl_int = -result._numeric.acl_int;
+ else if (the_expr->_data._oper.op_name == OP_CHS)
+ result._data._numeric.acl_int = -result._data._numeric.acl_int;
break;
case OP_STRING:
- eval_expr(the_expr->_oper.right, result, context, RVALUE);
+ eval_expr(the_expr->_data._oper.right, result, context, RVALUE);
if (!convert_to(STR_PTR, result))
cleanup(result);
break;
case OP_LENGTH:
- eval_expr(the_expr->_oper.right, r1, context, RVALUE);
+ eval_expr(the_expr->_data._oper.right, r1, context, RVALUE);
if (convert_to(STR_PTR, r1)) {
result._kind = NUMERIC;
- result._numeric.acl_int = r1._str.acl_str->size();
+ result._data._numeric.acl_int = r1._data._str.acl_str->size();
}
break;
@@ -509,45 +510,45 @@ void Archetype::eval_expr(ExprTree the_expr, ResultType &result, ContextType &co
// range 1 - 1234. However, we can neither immediately convert it to string, because
// ? 6 should produce a value in the range 1 - 6, not the character "6". }
case OP_RANDOM:
- eval_expr(the_expr->_oper.right, result, context, RVALUE);
+ eval_expr(the_expr->_data._oper.right, result, context, RVALUE);
if (result._kind == NUMERIC)
// convert x < range to 1 <= x <= range
- result._numeric.acl_int = g_vm->getRandomNumber(result._numeric.acl_int - 1) + 1;
+ result._data._numeric.acl_int = g_vm->getRandomNumber(result._data._numeric.acl_int - 1) + 1;
else if (convert_to(STR_PTR, result)) {
// Replace the string with a single random character for it
- String &s = *result._str.acl_str;
+ String &s = *result._data._str.acl_str;
s = s[g_vm->getRandomNumber(s.size() - 1)];
}
break;
case OP_NOT:
result._kind = RESERVED;
- if (eval_condition(the_expr->_oper.right, context))
- result._reserved.keyword = RW_FALSE;
+ if (eval_condition(the_expr->_data._oper.right, context))
+ result._data._reserved.keyword = RW_FALSE;
else
- result._reserved.keyword = RW_TRUE;
+ result._data._reserved.keyword = RW_TRUE;
break;
case OP_PLUS:
case OP_MINUS:
case OP_MULTIPLY:
case OP_DIVIDE:
- eval_expr(the_expr->_oper.left, r1, context, RVALUE);
- eval_expr(the_expr->_oper.right, r2, context, RVALUE);
+ eval_expr(the_expr->_data._oper.left, r1, context, RVALUE);
+ eval_expr(the_expr->_data._oper.right, r2, context, RVALUE);
if (convert_to(NUMERIC, r1) && convert_to(NUMERIC, r2)) {
result._kind = NUMERIC;
- switch (the_expr->_oper.op_name) {
+ switch (the_expr->_data._oper.op_name) {
case OP_PLUS:
- result._numeric.acl_int = r1._numeric.acl_int + r2._numeric.acl_int;
+ result._data._numeric.acl_int = r1._data._numeric.acl_int + r2._data._numeric.acl_int;
break;
case OP_MINUS:
- result._numeric.acl_int = r1._numeric.acl_int - r2._numeric.acl_int;
+ result._data._numeric.acl_int = r1._data._numeric.acl_int - r2._data._numeric.acl_int;
break;
case OP_MULTIPLY:
- result._numeric.acl_int = r1._numeric.acl_int * r2._numeric.acl_int;
+ result._data._numeric.acl_int = r1._data._numeric.acl_int * r2._data._numeric.acl_int;
break;
case OP_DIVIDE:
- result._numeric.acl_int = r1._numeric.acl_int / r2._numeric.acl_int;
+ result._data._numeric.acl_int = r1._data._numeric.acl_int / r2._data._numeric.acl_int;
break;
default:
break;
@@ -557,59 +558,59 @@ void Archetype::eval_expr(ExprTree the_expr, ResultType &result, ContextType &co
case OP_AND:
result._kind = RESERVED;
- if (eval_condition(the_expr->_oper.left, context) && eval_condition(the_expr->_oper.right, context))
- result._reserved.keyword = RW_TRUE;
+ if (eval_condition(the_expr->_data._oper.left, context) && eval_condition(the_expr->_data._oper.right, context))
+ result._data._reserved.keyword = RW_TRUE;
else
- result._reserved.keyword = RW_FALSE;
+ result._data._reserved.keyword = RW_FALSE;
break;
case OP_OR:
- if (eval_condition(the_expr->_oper.left, context) || eval_condition(the_expr->_oper.right, context))
- result._reserved.keyword = RW_TRUE;
+ if (eval_condition(the_expr->_data._oper.left, context) || eval_condition(the_expr->_data._oper.right, context))
+ result._data._reserved.keyword = RW_TRUE;
else
- result._reserved.keyword = RW_FALSE;
+ result._data._reserved.keyword = RW_FALSE;
break;
case OP_POWER:
- eval_expr(the_expr->_oper.right, r2, context, RVALUE);
- eval_expr(the_expr->_oper.left, r1, context, RVALUE);
+ eval_expr(the_expr->_data._oper.right, r2, context, RVALUE);
+ eval_expr(the_expr->_data._oper.left, r1, context, RVALUE);
if (convert_to(NUMERIC, r2) && convert_to(NUMERIC, r1)) {
result._kind = NUMERIC;
- result._numeric.acl_int = 1;
- for (i = 1; i <= r2._numeric.acl_int; ++i)
- result._numeric.acl_int *= r1._numeric.acl_int;
+ result._data._numeric.acl_int = 1;
+ for (i = 1; i <= r2._data._numeric.acl_int; ++i)
+ result._data._numeric.acl_int *= r1._data._numeric.acl_int;
}
break;
case OP_CONCAT:
- eval_expr(the_expr->_oper.left, r1, context, RVALUE);
- eval_expr(the_expr->_oper.right, r2, context, RVALUE);
+ eval_expr(the_expr->_data._oper.left, r1, context, RVALUE);
+ eval_expr(the_expr->_data._oper.right, r2, context, RVALUE);
if (convert_to(STR_PTR, r1) && convert_to(STR_PTR, r2)) {
result._kind = STR_PTR;
- result._str.acl_str = MakeNewDynStr(*r1._str.acl_str + *r2._str.acl_str);
+ result._data._str.acl_str = MakeNewDynStr(*r1._data._str.acl_str + *r2._data._str.acl_str);
}
break;
case OP_LEFTFROM:
case OP_RIGHTFROM:
- eval_expr(the_expr->_oper.left, r1, context, RVALUE);
- eval_expr(the_expr->_oper.right, r2, context, RVALUE);
+ eval_expr(the_expr->_data._oper.left, r1, context, RVALUE);
+ eval_expr(the_expr->_data._oper.right, r2, context, RVALUE);
if (convert_to(STR_PTR, r1) && convert_to(NUMERIC, r2)) {
result._kind = STR_PTR;
- if (the_expr->_oper.op_name == OP_LEFTFROM)
- result._str.acl_str = MakeNewDynStr(r1._str.acl_str->left(r2._numeric.acl_int));
+ if (the_expr->_data._oper.op_name == OP_LEFTFROM)
+ result._data._str.acl_str = MakeNewDynStr(r1._data._str.acl_str->left(r2._data._numeric.acl_int));
else
- result._str.acl_str = MakeNewDynStr(r1._str.acl_str->right(r2._numeric.acl_int));
+ result._data._str.acl_str = MakeNewDynStr(r1._data._str.acl_str->right(r2._data._numeric.acl_int));
}
break;
case OP_WITHIN:
- eval_expr(the_expr->_oper.left, r1, context, RVALUE);
- eval_expr(the_expr->_oper.right, r2, context, RVALUE);
+ eval_expr(the_expr->_data._oper.left, r1, context, RVALUE);
+ eval_expr(the_expr->_data._oper.right, r2, context, RVALUE);
if (convert_to(STR_PTR, r1) && convert_to(STR_PTR, r2)) {
result._kind = NUMERIC;
- result._numeric.acl_int = r2._str.acl_str->indexOf(*r1._str.acl_str);
- if (result._numeric.acl_int == -1)
+ result._data._numeric.acl_int = r2._data._str.acl_str->indexOf(*r1._data._str.acl_str);
+ if (result._data._numeric.acl_int == -1)
cleanup(result);
}
break;
@@ -620,18 +621,18 @@ void Archetype::eval_expr(ExprTree the_expr, ResultType &result, ContextType &co
case OP_GT:
case OP_LE:
case OP_GE:
- eval_expr(the_expr->_oper.left, r1, context, RVALUE);
- eval_expr(the_expr->_oper.right, r2, context, RVALUE);
+ eval_expr(the_expr->_data._oper.left, r1, context, RVALUE);
+ eval_expr(the_expr->_data._oper.right, r2, context, RVALUE);
result._kind = RESERVED;
- if (result_compare(the_expr->_oper.op_name, r1, r2))
- result._reserved.keyword = RW_TRUE;
+ if (result_compare(the_expr->_data._oper.op_name, r1, r2))
+ result._data._reserved.keyword = RW_TRUE;
else
- result._reserved.keyword = RW_FALSE;
+ result._data._reserved.keyword = RW_FALSE;
break;
default:
- g_vm->writeln("Internal error: \"%s\" not yet supported", Operators[the_expr->_oper.op_name]);
+ g_vm->writeln("Internal error: \"%s\" not yet supported", Operators[the_expr->_data._oper.op_name]);
break;
}
@@ -666,8 +667,8 @@ bool Archetype::eval_condition(ExprTree the_expr, ContextType &context) {
undefine(result);
eval_expr(the_expr, result, context, RVALUE);
- failure = (result._kind == RESERVED) && (result._reserved.keyword = RW_UNDEFINED
- || result._reserved.keyword == RW_FALSE || result._reserved.keyword == RW_ABSENT);
+ failure = (result._kind == RESERVED) && (result._data._reserved.keyword = RW_UNDEFINED
+ || result._data._reserved.keyword == RW_FALSE || result._data._reserved.keyword == RW_ABSENT);
cleanup(result);
return !failure;
@@ -697,32 +698,32 @@ void Archetype::exec_stmt(StatementPtr the_stmt, ResultType &result, ContextType
case COMPOUND:
np = nullptr;
b = false;
- while (!b && iterate_list(the_stmt->_compound.statements, np)) {
+ while (!b && iterate_list(the_stmt->_data._compound.statements, np)) {
cleanup(result);
exec_stmt((StatementPtr)np->data, result, context);
- b = (result._kind == RESERVED) && (result._reserved.keyword == RW_BREAK);
+ b = (result._kind == RESERVED) && (result._data._reserved.keyword == RW_BREAK);
}
break;
case ST_EXPR:
if (verbose)
- display_expr(the_stmt->_expr.expression);
+ display_expr(the_stmt->_data._expr.expression);
- switch (the_stmt->_expr.expression->_kind) {
+ switch (the_stmt->_data._expr.expression->_kind) {
case QUOTE_LIT:
- if (index_xarray(Literals, the_stmt->_expr.expression->_msgTextQuote.index, p)) {
+ if (index_xarray(Literals, the_stmt->_data._expr.expression->_data._msgTextQuote.index, p)) {
result._kind = TEXT_LIT;
- result._msgTextQuote.index = the_stmt->_expr.expression->_msgTextQuote.index;
+ result._data._msgTextQuote.index = the_stmt->_data._expr.expression->_data._msgTextQuote.index;
wrapout(*((StringPtr)p), true);
}
break;
case MESSAGE:
- b = send_message(OP_PASS, the_stmt->_expr.expression->_msgTextQuote.index,
+ b = send_message(OP_PASS, the_stmt->_data._expr.expression->_data._msgTextQuote.index,
context.self, result, context);
default:
- eval_expr(the_stmt->_expr.expression, result, context, RVALUE);
+ eval_expr(the_stmt->_data._expr.expression, result, context, RVALUE);
break;
}
break;
@@ -747,9 +748,9 @@ void Archetype::exec_stmt(StatementPtr the_stmt, ResultType &result, ContextType
wrapout(" ", false);
np = nullptr;
- while (iterate_list(the_stmt->_write.print_list, np)) {
+ while (iterate_list(the_stmt->_data._write.print_list, np)) {
display_expr((ExprTree)np->data);
- if (np->next != the_stmt->_write.print_list)
+ if (np->next != the_stmt->_data._write.print_list)
wrapout(", ", false);
}
@@ -757,7 +758,7 @@ void Archetype::exec_stmt(StatementPtr the_stmt, ResultType &result, ContextType
}
np = nullptr;
- while (iterate_list(the_stmt->_write.print_list, np)) {
+ while (iterate_list(the_stmt->_data._write.print_list, np)) {
cleanup(result);
eval_expr((ExprTree)np->data, result, context, RVALUE);
write_result(result);
@@ -776,38 +777,38 @@ void Archetype::exec_stmt(StatementPtr the_stmt, ResultType &result, ContextType
case ST_IF:
if (verbose) {
wrapout("if: Testing ", false);
- display_expr(the_stmt->_if.condition);
+ display_expr(the_stmt->_data._if.condition);
}
- if (eval_condition(the_stmt->_if.condition, context)) {
+ if (eval_condition(the_stmt->_data._if.condition, context)) {
if (verbose)
wrapout(" Evaluated true; executing then branch", true);
- exec_stmt(the_stmt->_if.then_branch, result, context);
+ exec_stmt(the_stmt->_data._if.then_branch, result, context);
}
- else if (the_stmt->_if.else_branch != nullptr) {
+ else if (the_stmt->_data._if.else_branch != nullptr) {
if (verbose)
wrapout(" Evaluated false; executing else branch", true);
- exec_stmt(the_stmt->_if.else_branch, result, context);
+ exec_stmt(the_stmt->_data._if.else_branch, result, context);
}
break;
case ST_CASE:
if (verbose) {
wrapout("case ", false);
- display_expr(the_stmt->_case.test_expr);
+ display_expr(the_stmt->_data._case.test_expr);
wrapout(" of", false);
wrapout("", true);
}
- eval_expr(the_stmt->_case.test_expr, r1, context, RVALUE);
+ eval_expr(the_stmt->_data._case.test_expr, r1, context, RVALUE);
np = nullptr;
- while (iterate_list(the_stmt->_case.cases, np)) {
+ while (iterate_list(the_stmt->_data._case.cases, np)) {
this_case = (CasePairPtr)np->data;
//with this_case^ do begin
eval_expr(this_case->value, r2, context, RVALUE);
- if ((r2._kind == RESERVED && r2._reserved.keyword == RW_DEFAULT)
+ if ((r2._kind == RESERVED && r2._data._reserved.keyword == RW_DEFAULT)
|| result_compare(OP_EQ, r1, r2)) {
exec_stmt(this_case->action, result, context);
cleanup(r1);
@@ -824,7 +825,7 @@ void Archetype::exec_stmt(StatementPtr the_stmt, ResultType &result, ContextType
case ST_BREAK:
result._kind = RESERVED;
- result._reserved.keyword = RW_BREAK;
+ result._data._reserved.keyword = RW_BREAK;
break;
case ST_FOR:
@@ -833,9 +834,9 @@ void Archetype::exec_stmt(StatementPtr the_stmt, ResultType &result, ContextType
c.each = 1;
while (!b && c.each < (int)Object_List.size()) {
- if (eval_condition(the_stmt->_loop.selection, c)) {
- exec_stmt(the_stmt->_loop.action, result, c);
- b = (result._kind == RESERVED) && (result._reserved.keyword == RW_BREAK);
+ if (eval_condition(the_stmt->_data._loop.selection, c)) {
+ exec_stmt(the_stmt->_data._loop.action, result, c);
+ b = (result._kind == RESERVED) && (result._data._reserved.keyword == RW_BREAK);
cleanup(result);
}
@@ -845,20 +846,20 @@ void Archetype::exec_stmt(StatementPtr the_stmt, ResultType &result, ContextType
case ST_WHILE:
b = false;
- while (!b && eval_condition(the_stmt->_loop.selection, context)) {
- exec_stmt(the_stmt->_loop.action, result, context);
- b = (result._kind == RESERVED) && (result._reserved.keyword == RW_BREAK);
+ while (!b && eval_condition(the_stmt->_data._loop.selection, context)) {
+ exec_stmt(the_stmt->_data._loop.action, result, context);
+ b = (result._kind == RESERVED) && (result._data._reserved.keyword == RW_BREAK);
cleanup(result);
}
break;
case ST_CREATE:
- eval_expr(the_stmt->_create.new_name, r1, context, LVALUE);
+ eval_expr(the_stmt->_data._create.new_name, r1, context, LVALUE);
// Attempt a dummy assignment just to see if it works
result._kind = IDENT;
- result._ident.ident_kind = OBJECT_ID;
- result._ident.ident_int = 0;
+ result._data._ident.ident_kind = OBJECT_ID;
+ result._data._ident.ident_int = 0;
if (!assignment(r1, result)) {
cleanup(result);
@@ -866,7 +867,7 @@ void Archetype::exec_stmt(StatementPtr the_stmt, ResultType &result, ContextType
else {
// do it for real
the_object = (ObjectPtr)malloc(sizeof(ObjectType));
- the_object->inherited_from = the_stmt->_create.archetype;
+ the_object->inherited_from = the_stmt->_data._create.archetype;
new_list(the_object->attributes);
new_list(the_object->methods);
the_object->other = nullptr;
@@ -885,8 +886,8 @@ void Archetype::exec_stmt(StatementPtr the_stmt, ResultType &result, ContextType
// Now we know its number; go back and update the result"s object reference.
// "Return" this same value
- ((ExprPtr)r1._attr.acl_attr->data)->_ident.ident_int = i;
- copy_result(result, *(ExprPtr)r1._attr.acl_attr->data);
+ ((ExprPtr)r1._data._attr.acl_attr->data)->_data._ident.ident_int = i;
+ copy_result(result, *(ExprPtr)r1._data._attr.acl_attr->data);
cleanup(r1);
}
@@ -895,14 +896,14 @@ void Archetype::exec_stmt(StatementPtr the_stmt, ResultType &result, ContextType
// Just dispose of the indicated object in the Object_List. Shrink the list only if
// the very last object was destroyed
case ST_DESTROY:
- eval_expr(the_stmt->_destroy.victim, result, context, RVALUE);
- if (result._kind == IDENT && result._ident.ident_kind == OBJECT_ID
- && index_xarray(Object_List, result._ident.ident_int, p)) {
+ eval_expr(the_stmt->_data._destroy.victim, result, context, RVALUE);
+ if (result._kind == IDENT && result._data._ident.ident_kind == OBJECT_ID
+ && index_xarray(Object_List, result._data._ident.ident_int, p)) {
the_object = (ObjectPtr)p;
dispose_object(the_object);
p = nullptr;
- b = access_xarray(Object_List, result._ident.ident_int, p, POKE_ACCESS);
- if (result._ident.ident_int == ((int)Object_List.size() - 1))
+ b = access_xarray(Object_List, result._data._ident.ident_int, p, POKE_ACCESS);
+ if (result._data._ident.ident_int == ((int)Object_List.size() - 1))
shrink_xarray(Object_List);
} else {
wraperr("Can only destroy previously created objects");
diff --git a/engines/glk/archetype/expression.h b/engines/glk/archetype/expression.h
index 4e927ec400..6ccc0b019a 100644
--- a/engines/glk/archetype/expression.h
+++ b/engines/glk/archetype/expression.h
@@ -35,7 +35,7 @@ const int OP_SEND_TO_TYPE = NUM_OPERS + 2; // for use with interpreter
struct OperNode {
int8 op_name;
- union ExprNode *left, *right;
+ struct ExprNode *left, *right;
};
struct MessageTextQuoteNode {
@@ -63,8 +63,7 @@ struct IdentNode {
int ident_int;
};
-union ExprNode {
- AclType _kind;
+union ExprNodeData {
OperNode _oper;
NumericNode _numeric;
MessageTextQuoteNode _msgTextQuote;
@@ -74,6 +73,11 @@ union ExprNode {
IdentNode _ident;
};
+struct ExprNode {
+ AclType _kind;
+ ExprNodeData _data;
+};
+
typedef ExprNode *ExprPtr;
typedef ExprPtr ExprTree;
diff --git a/engines/glk/archetype/interpreter.cpp b/engines/glk/archetype/interpreter.cpp
index de4273fa82..21f732b827 100644
--- a/engines/glk/archetype/interpreter.cpp
+++ b/engines/glk/archetype/interpreter.cpp
@@ -77,42 +77,42 @@ bool convert_to(AclType target_type, ResultType &the_scalar) {
switch (the_scalar._kind) {
case NUMERIC:
dir_from = 'N';
- the_number = the_scalar._numeric.acl_int;
+ the_number = the_scalar._data._numeric.acl_int;
break;
case MESSAGE:
dir_from = 'S';
- if (index_xarray(g_vm->Vocabulary, the_scalar._msgTextQuote.index, p))
+ if (index_xarray(g_vm->Vocabulary, the_scalar._data._msgTextQuote.index, p))
s1 = *(StringPtr)p;
break;
case TEXT_LIT:
case QUOTE_LIT:
dir_from = 'S';
- if (index_xarray(g_vm->Literals, the_scalar._msgTextQuote.index, p))
+ if (index_xarray(g_vm->Literals, the_scalar._data._msgTextQuote.index, p))
s1 = *(StringPtr)p;
break;
case STR_PTR:
// string memory will be disposed ONLY if successful convert
dir_from = 'S';
- s1 = *the_scalar._str.acl_str;
+ s1 = *the_scalar._data._str.acl_str;
break;
case IDENT:
//with the_scalar do begin
dir_from = 'S';
- switch (the_scalar._ident.ident_kind) {
+ switch (the_scalar._data._ident.ident_kind) {
case ENUMERATE_ID:
dir_from = 'N';
- the_number = the_scalar._ident.ident_int;
+ the_number = the_scalar._data._ident.ident_int;
break;
case OBJECT_ID:
- if (the_scalar._ident.ident_int == 0)
+ if (the_scalar._data._ident.ident_int == 0)
s1 = "system";
- else if (index_xarray(g_vm->Object_ID_List, the_scalar._ident.ident_int, p)) {
+ else if (index_xarray(g_vm->Object_ID_List, the_scalar._data._ident.ident_int, p)) {
if (p == nullptr)
s1 = "null";
else
@@ -123,16 +123,16 @@ bool convert_to(AclType target_type, ResultType &the_scalar) {
break;
case TYPE_ID:
- if (the_scalar._ident.ident_int == 0)
+ if (the_scalar._data._ident.ident_int == 0)
s1 = "null";
- else if (index_xarray(g_vm->Type_ID_List, the_scalar._ident.ident_int, p))
+ else if (index_xarray(g_vm->Type_ID_List, the_scalar._data._ident.ident_int, p))
s1 = *(StringPtr)p;
else
return false;
break;
case ATTRIBUTE_ID:
- if (index_xarray(g_vm->Attribute_ID_List, the_scalar._ident.ident_int, p))
+ if (index_xarray(g_vm->Attribute_ID_List, the_scalar._data._ident.ident_int, p))
s1 = *((StringPtr)p);
else
return false;
@@ -144,9 +144,9 @@ bool convert_to(AclType target_type, ResultType &the_scalar) {
break;
case RESERVED:
- if (the_scalar._reserved.keyword == RW_TRUE || the_scalar._reserved.keyword == RW_FALSE) {
+ if (the_scalar._data._reserved.keyword == RW_TRUE || the_scalar._data._reserved.keyword == RW_FALSE) {
dir_from = 'B';
- boolval = (the_scalar._reserved.keyword == RW_TRUE);
+ boolval = (the_scalar._data._reserved.keyword == RW_TRUE);
} else {
return false;
}
@@ -158,7 +158,7 @@ bool convert_to(AclType target_type, ResultType &the_scalar) {
if (target_type == STR_PTR || target_type == MESSAGE) {
if (the_scalar._kind == STR_PTR)
- FreeDynStr(the_scalar._str.acl_str); // we know this will succeed
+ FreeDynStr(the_scalar._data._str.acl_str); // we know this will succeed
the_scalar._kind = target_type;
@@ -174,9 +174,9 @@ bool convert_to(AclType target_type, ResultType &the_scalar) {
}
if (target_type == MESSAGE)
- the_scalar._msgTextQuote.index = find_message(s1);
+ the_scalar._data._msgTextQuote.index = find_message(s1);
else
- the_scalar._str.acl_str = NewDynStr(s1);
+ the_scalar._data._str.acl_str = NewDynStr(s1);
return true;
} else {
@@ -184,12 +184,12 @@ bool convert_to(AclType target_type, ResultType &the_scalar) {
switch (dir_from) {
case 'N':
the_scalar._kind = NUMERIC;
- the_scalar._numeric.acl_int = the_number;
+ the_scalar._data._numeric.acl_int = the_number;
return true;
case 'B':
the_scalar._kind = NUMERIC;
- the_scalar._numeric.acl_int = boolval ? 1 : 0;
+ the_scalar._data._numeric.acl_int = boolval ? 1 : 0;
break;
case 'S':
@@ -201,10 +201,10 @@ bool convert_to(AclType target_type, ResultType &the_scalar) {
} else {
// successful
if (the_scalar._kind == STR_PTR)
- FreeDynStr(the_scalar._str.acl_str); // memory no longer needed
+ FreeDynStr(the_scalar._data._str.acl_str); // memory no longer needed
the_scalar._kind = NUMERIC;
- the_scalar._numeric.acl_int = the_number;
+ the_scalar._data._numeric.acl_int = the_number;
}
return true;
@@ -219,21 +219,21 @@ bool convert_to(AclType target_type, ResultType &the_scalar) {
void undefine(ResultType &result) {
result._kind = RESERVED;
- result._reserved.keyword = RW_UNDEFINED;
+ result._data._reserved.keyword = RW_UNDEFINED;
}
void cleanup(ResultType &result) {
if (result._kind == STR_PTR)
- FreeDynStr(result._str.acl_str);
+ FreeDynStr(result._data._str.acl_str);
result._kind = RESERVED;
- result._reserved.keyword = RW_UNDEFINED;
+ result._data._reserved.keyword = RW_UNDEFINED;
}
void copy_result(ResultType &r1, const ResultType &r2) {
cleanup(r1);
r1 = r2;
if (r1._kind == STR_PTR)
- r1._str.acl_str = NewDynStr(*r2._str.acl_str);
+ r1._data._str.acl_str = NewDynStr(*r2._data._str.acl_str);
}
bool result_compare(short comparison, ResultType &r1, ResultType &r2) {
@@ -244,19 +244,19 @@ bool result_compare(short comparison, ResultType &r1, ResultType &r2) {
switch (comparison) {
case OP_EQ:
case OP_NE:
- verdict = r1._numeric.acl_int == r2._numeric.acl_int;
+ verdict = r1._data._numeric.acl_int == r2._data._numeric.acl_int;
break;
case OP_LT:
- verdict = r1._numeric.acl_int < r2._numeric.acl_int;
+ verdict = r1._data._numeric.acl_int < r2._data._numeric.acl_int;
break;
case OP_LE:
- verdict = r1._numeric.acl_int <= r2._numeric.acl_int;
+ verdict = r1._data._numeric.acl_int <= r2._data._numeric.acl_int;
break;
case OP_GT:
- verdict = r1._numeric.acl_int > r2._numeric.acl_int;
+ verdict = r1._data._numeric.acl_int > r2._data._numeric.acl_int;
break;
case OP_GE:
- verdict = r1._numeric.acl_int >= r2._numeric.acl_int;
+ verdict = r1._data._numeric.acl_int >= r2._data._numeric.acl_int;
break;
default:
break;
@@ -266,19 +266,19 @@ bool result_compare(short comparison, ResultType &r1, ResultType &r2) {
switch (comparison) {
case OP_EQ:
case OP_NE:
- verdict = *r1._str.acl_str == *r2._str.acl_str;
+ verdict = *r1._data._str.acl_str == *r2._data._str.acl_str;
break;
case OP_LT:
- verdict = *r1._str.acl_str < *r2._str.acl_str;
+ verdict = *r1._data._str.acl_str < *r2._data._str.acl_str;
break;
case OP_LE:
- verdict = *r1._str.acl_str <= *r2._str.acl_str;
+ verdict = *r1._data._str.acl_str <= *r2._data._str.acl_str;
break;
case OP_GT:
- verdict = *r1._str.acl_str > *r2._str.acl_str;
+ verdict = *r1._data._str.acl_str > *r2._data._str.acl_str;
break;
case OP_GE:
- verdict = *r1._str.acl_str >= *r2._str.acl_str;
+ verdict = *r1._data._str.acl_str >= *r2._data._str.acl_str;
break;
default:
break;
@@ -290,18 +290,18 @@ bool result_compare(short comparison, ResultType &r1, ResultType &r2) {
switch (comparison) {
case OP_EQ:
case OP_NE:
- verdict = r1._reserved.keyword == r2._reserved.keyword;
+ verdict = r1._data._reserved.keyword == r2._data._reserved.keyword;
break;
default:
break;
}
case IDENT:
- if (r1._ident.ident_kind == r2._ident.ident_kind) {
+ if (r1._data._ident.ident_kind == r2._data._ident.ident_kind) {
switch (comparison) {
case OP_EQ:
case OP_NE:
- verdict = r1._ident.ident_int == r2._ident.ident_int;
+ verdict = r1._data._ident.ident_int == r2._data._ident.ident_int;
break;
default:
break;
@@ -327,7 +327,7 @@ bool assignment(ResultType &target, ResultType &value) {
wraperr("Warning: attempted assignment to a non-attribute");
return false;
} else {
- e = (ExprPtr)target._attr.acl_attr->data;
+ e = (ExprPtr)target._data._attr.acl_attr->data;
// If the current expression starts with an operator, we know it isn't a flat result
// and must therefore be disposed of before proceeding. Otherwise simply clean up
@@ -342,7 +342,7 @@ bool assignment(ResultType &target, ResultType &value) {
}
copy_result(*e, value);
- target._attr.acl_attr->data = e;
+ target._data._attr.acl_attr->data = e;
return true;
}
@@ -352,16 +352,16 @@ void write_result(ResultType &result) {
undefine(r1);
if (result._kind == STR_PTR)
- wrapout(*result._str.acl_str, false);
+ wrapout(*result._data._str.acl_str, false);
else if (result._kind == RESERVED)
- wrapout(Reserved_Wds[result._reserved.keyword], false);
+ wrapout(Reserved_Wds[result._data._reserved.keyword], false);
else {
if (result._kind == ATTR_PTR)
- copy_result(r1, *(ResultType *)result._attr.acl_attr->data);
+ copy_result(r1, *(ResultType *)result._data._attr.acl_attr->data);
else
copy_result(r1, result);
if (convert_to(STR_PTR, r1))
- wrapout(*r1._str.acl_str, false);
+ wrapout(*r1._data._str.acl_str, false);
cleanup(r1);
}
}
@@ -395,15 +395,15 @@ void display_expr(ExprTree the_tree) {
if (the_tree->_kind != OPER) {
display_result(*the_tree);
} else {
- if (Binary[the_tree->_oper.op_name]) {
+ if (Binary[the_tree->_data._oper.op_name]) {
wrapout(" (", false);
- display_expr(the_tree->_oper.left);
+ display_expr(the_tree->_data._oper.left);
wrapout(") ", false);
}
- wrapout(Operators[the_tree->_oper.op_name], false);
+ wrapout(Operators[the_tree->_data._oper.op_name], false);
wrapout(" (", false);
- display_expr(the_tree->_oper.right);
+ display_expr(the_tree->_data._oper.right);
wrapout(") ", false);
}
}
diff --git a/engines/glk/archetype/interpreter.h b/engines/glk/archetype/interpreter.h
index 2ee357aad5..331cd7a6f7 100644
--- a/engines/glk/archetype/interpreter.h
+++ b/engines/glk/archetype/interpreter.h
@@ -35,6 +35,8 @@ typedef ExprNode ResultType;
struct ContextType {
int sender, self, each, message;
+
+ ContextType() : sender(0), self(0), each(0), message(0) {}
};
extern int MainObject;
diff --git a/engines/glk/archetype/keywords.cpp b/engines/glk/archetype/keywords.cpp
index c794750699..e3514c6720 100644
--- a/engines/glk/archetype/keywords.cpp
+++ b/engines/glk/archetype/keywords.cpp
@@ -109,6 +109,7 @@ void load_text_list(Common::ReadStream *fIn, XArrayType &the_list) {
new_xarray(the_list);
n = fIn->readUint16LE();
+
for (i = 0; i < n; ++i) {
load_string(fIn, s);
append_to_xarray(the_list, NewConstStr(s));
diff --git a/engines/glk/archetype/saveload.cpp b/engines/glk/archetype/saveload.cpp
index bd236a8c54..2816a1f480 100644
--- a/engines/glk/archetype/saveload.cpp
+++ b/engines/glk/archetype/saveload.cpp
@@ -268,8 +268,8 @@ static void walk_expr(MissionType mission, Common::Stream *bfile, ExprTree &the_
return;
assert(writeStream);
- while (the_expr->_kind == OPER && the_expr->_oper.op_name == OP_LPAREN)
- the_expr = the_expr->_oper.right;
+ while (the_expr->_kind == OPER && the_expr->_data._oper.op_name == OP_LPAREN)
+ the_expr = the_expr->_data._oper.right;
writeStream->writeByte(the_expr->_kind);
break;
@@ -288,28 +288,28 @@ static void walk_expr(MissionType mission, Common::Stream *bfile, ExprTree &the_
case OPER:
switch (mission) {
case LOAD:
- the_expr->_oper.op_name = readStream->readSByte();
- the_expr->_oper.left = nullptr;
+ the_expr->_data._oper.op_name = readStream->readSByte();
+ the_expr->_data._oper.left = nullptr;
break;
case DUMP:
- writeStream->writeSByte(the_expr->_oper.op_name);
+ writeStream->writeSByte(the_expr->_data._oper.op_name);
break;
default:
break;
}
- if (Binary[the_expr->_oper.op_name])
- walk_expr(mission, bfile, the_expr->_oper.left);
- walk_expr(mission, bfile, the_expr->_oper.right);
+ if (Binary[the_expr->_data._oper.op_name])
+ walk_expr(mission, bfile, the_expr->_data._oper.left);
+ walk_expr(mission, bfile, the_expr->_data._oper.right);
break;
case NUMERIC:
switch (mission) {
case LOAD:
- the_expr->_numeric.acl_int = readStream->readUint32LE();
+ the_expr->_data._numeric.acl_int = readStream->readUint32LE();
break;
case DUMP:
- writeStream->writeSint32LE(the_expr->_numeric.acl_int);
+ writeStream->writeSint32LE(the_expr->_data._numeric.acl_int);
break;
default:
break;
@@ -321,10 +321,10 @@ static void walk_expr(MissionType mission, Common::Stream *bfile, ExprTree &the_
case QUOTE_LIT:
switch (mission) {
case LOAD:
- the_expr->_msgTextQuote.index = readStream->readSint16LE();
+ the_expr->_data._msgTextQuote.index = readStream->readSint16LE();
break;
case DUMP:
- writeStream->writeSint16LE(the_expr->_msgTextQuote.index);
+ writeStream->writeSint16LE(the_expr->_data._msgTextQuote.index);
break;
default:
break;
@@ -334,22 +334,22 @@ static void walk_expr(MissionType mission, Common::Stream *bfile, ExprTree &the_
case IDENT:
switch (mission) {
case LOAD:
- the_expr->_ident.ident_kind = (ClassifyType)readStream->readByte();
- the_expr->_ident.ident_int = readStream->readSint16LE();
+ the_expr->_data._ident.ident_kind = (ClassifyType)readStream->readByte();
+ the_expr->_data._ident.ident_int = readStream->readSint16LE();
break;
case DUMP:
- if (Translating && the_expr->_ident.ident_kind == DefaultClassification) {
+ if (Translating && the_expr->_data._ident.ident_kind == DefaultClassification) {
// may have changed meaning
- get_meaning(the_expr->_ident.ident_int, ID_kind, temp);
+ get_meaning(the_expr->_data._ident.ident_int, ID_kind, temp);
if (ID_kind == UNDEFINED_ID)
- add_undefined(the_expr->_ident.ident_int);
+ add_undefined(the_expr->_data._ident.ident_int);
} else {
- the_expr->_ident.ident_kind = ID_kind;
- the_expr->_ident.ident_int = temp;
+ the_expr->_data._ident.ident_kind = ID_kind;
+ the_expr->_data._ident.ident_int = temp;
}
- writeStream->writeByte(the_expr->_ident.ident_kind);
- writeStream->writeSint16LE(the_expr->_ident.ident_int);
+ writeStream->writeByte(the_expr->_data._ident.ident_kind);
+ writeStream->writeSint16LE(the_expr->_data._ident.ident_int);
break;
default:
break;
@@ -359,10 +359,10 @@ static void walk_expr(MissionType mission, Common::Stream *bfile, ExprTree &the_
case RESERVED:
switch (mission) {
case LOAD:
- the_expr->_reserved.keyword = readStream->readSByte();
+ the_expr->_data._reserved.keyword = readStream->readSByte();
break;
case DUMP:
- writeStream->writeSByte(the_expr->_reserved.keyword);
+ writeStream->writeSByte(the_expr->_data._reserved.keyword);
break;
default:
break;
@@ -372,13 +372,13 @@ static void walk_expr(MissionType mission, Common::Stream *bfile, ExprTree &the_
case STR_PTR:
switch (mission) {
case LOAD:
- the_expr->_str.acl_str = LoadDynStr(readStream);
+ the_expr->_data._str.acl_str = LoadDynStr(readStream);
break;
case DUMP:
- dump_string(writeStream, *the_expr->_str.acl_str);
+ dump_string(writeStream, *the_expr->_data._str.acl_str);
break;
case FREE:
- FreeDynStr(the_expr->_str.acl_str);
+ FreeDynStr(the_expr->_data._str.acl_str);
break;
default:
break;
@@ -468,47 +468,47 @@ static void walk_stmt(MissionType mission, Common::Stream *bfile, StatementPtr &
// Main walk
switch (the_stmt->_kind) {
case COMPOUND:
- walk_item_list(mission, bfile, the_stmt->_compound.statements, STMT_LIST);
+ walk_item_list(mission, bfile, the_stmt->_data._compound.statements, STMT_LIST);
break;
case ST_EXPR:
- walk_expr(mission, bfile, the_stmt->_expr.expression);
+ walk_expr(mission, bfile, the_stmt->_data._expr.expression);
break;
case ST_IF:
- walk_expr(mission, bfile, the_stmt->_if.condition);
- walk_stmt(mission, bfile, the_stmt->_if.then_branch);
- walk_stmt(mission, bfile, the_stmt->_if.else_branch);
+ walk_expr(mission, bfile, the_stmt->_data._if.condition);
+ walk_stmt(mission, bfile, the_stmt->_data._if.then_branch);
+ walk_stmt(mission, bfile, the_stmt->_data._if.else_branch);
break;
case ST_CASE:
- walk_expr(mission, bfile, the_stmt->_case.test_expr);
- walk_item_list(mission, bfile, the_stmt->_case.cases, CASE_LIST);
+ walk_expr(mission, bfile, the_stmt->_data._case.test_expr);
+ walk_item_list(mission, bfile, the_stmt->_data._case.cases, CASE_LIST);
break;
case ST_CREATE:
switch (mission) {
case LOAD:
- the_stmt->_create.archetype = readStream->readSint16LE();
+ the_stmt->_data._create.archetype = readStream->readSint16LE();
break;
case DUMP:
- writeStream->writeSint16LE(the_stmt->_create.archetype);
+ writeStream->writeSint16LE(the_stmt->_data._create.archetype);
break;
default:
break;
}
- walk_expr(mission, bfile, the_stmt->_create.new_name);
+ walk_expr(mission, bfile, the_stmt->_data._create.new_name);
break;
case ST_DESTROY:
- walk_expr(mission, bfile, the_stmt->_destroy.victim);
+ walk_expr(mission, bfile, the_stmt->_data._destroy.victim);
break;
case ST_FOR:
case ST_WHILE:
- walk_expr(mission, bfile, the_stmt->_loop.selection);
- walk_stmt(mission, bfile, the_stmt->_loop.action);
+ walk_expr(mission, bfile, the_stmt->_data._loop.selection);
+ walk_stmt(mission, bfile, the_stmt->_data._loop.action);
break;
case ST_WRITE:
@@ -516,7 +516,7 @@ static void walk_stmt(MissionType mission, Common::Stream *bfile, StatementPtr &
case ST_STOP:
switch (mission) {
case LOAD:
- new_list(the_stmt->_write.print_list);
+ new_list(the_stmt->_data._write.print_list);
sentinel = (StatementKind)readStream->readByte();
while (sentinel != END_SEQ) {
@@ -525,7 +525,7 @@ static void walk_stmt(MissionType mission, Common::Stream *bfile, StatementPtr &
add_bytes(sizeof(NodeType));
np->data = this_expr;
- append_to_list(the_stmt->_write.print_list, np);
+ append_to_list(the_stmt->_data._write.print_list, np);
sentinel = (StatementKind)readStream->readByte();
}
@@ -534,7 +534,7 @@ static void walk_stmt(MissionType mission, Common::Stream *bfile, StatementPtr &
case DUMP:
case FREE:
np = nullptr;
- while (iterate_list(the_stmt->_write.print_list, np)) {
+ while (iterate_list(the_stmt->_data._write.print_list, np)) {
if (mission == DUMP)
writeStream->writeByte(vContSeq);
this_expr = (ExprTree)np->data;
@@ -547,7 +547,7 @@ static void walk_stmt(MissionType mission, Common::Stream *bfile, StatementPtr &
if (mission == DUMP)
writeStream->writeByte(vEndSeq);
else
- dispose_list(the_stmt->_write.print_list);
+ dispose_list(the_stmt->_data._write.print_list);
break;
default:
diff --git a/engines/glk/archetype/semantic.cpp b/engines/glk/archetype/semantic.cpp
index 4e2cd37205..132f530dfb 100644
--- a/engines/glk/archetype/semantic.cpp
+++ b/engines/glk/archetype/semantic.cpp
@@ -174,19 +174,19 @@ bool verify_expr(progfile &f, ExprTree the_expr) {
switch (the_expr->_kind) {
case OPER:
- switch (the_expr->_oper.op_name) {
+ switch (the_expr->_data._oper.op_name) {
case OP_DOT:
- if (the_expr->_oper.right->_kind != IDENT) {
+ if (the_expr->_data._oper.right->_kind != IDENT) {
error_message(f, "Right side of dot must be an identifier");
success = false;
}
- else if (the_expr->_oper.right->_ident.ident_kind != ATTRIBUTE_ID) {
- the_expr->_oper.right->_ident.ident_int = classify_as(f,
- the_expr->_oper.right->_ident.ident_int, ATTRIBUTE_ID, nullptr);
+ else if (the_expr->_data._oper.right->_data._ident.ident_kind != ATTRIBUTE_ID) {
+ the_expr->_data._oper.right->_data._ident.ident_int = classify_as(f,
+ the_expr->_data._oper.right->_data._ident.ident_int, ATTRIBUTE_ID, nullptr);
}
- the_expr->_oper.right->_ident.ident_kind = ATTRIBUTE_ID;
- if (the_expr->_oper.right->_ident.ident_int == 0)
+ the_expr->_data._oper.right->_data._ident.ident_kind = ATTRIBUTE_ID;
+ if (the_expr->_data._oper.right->_data._ident.ident_int == 0)
success = false;
case OP_ASSIGN:
@@ -195,17 +195,17 @@ bool verify_expr(progfile &f, ExprTree the_expr) {
case OP_C_DIVIDE:
case OP_C_PLUS:
case OP_C_MINUS:
- if (the_expr->_oper.left->_kind == IDENT) {
- get_meaning(the_expr->_oper.left->_ident.ident_int,
- the_expr->_oper.left->_ident.ident_kind, the_expr->_oper.left->_ident.ident_int);
+ if (the_expr->_data._oper.left->_kind == IDENT) {
+ get_meaning(the_expr->_data._oper.left->_data._ident.ident_int,
+ the_expr->_data._oper.left->_data._ident.ident_kind, the_expr->_data._oper.left->_data._ident.ident_int);
- if (the_expr->_oper.left->_ident.ident_kind != ATTRIBUTE_ID) {
+ if (the_expr->_data._oper.left->_data._ident.ident_kind != ATTRIBUTE_ID) {
error_message(f, "Left side of assignment is not an attribute");
success = false;
}
}
- else if (!(the_expr->_oper.left->_kind == OPER &&
- the_expr->_oper.left->_oper.op_name == OP_DOT)) {
+ else if (!(the_expr->_data._oper.left->_kind == OPER &&
+ the_expr->_data._oper.left->_data._oper.op_name == OP_DOT)) {
error_message(f, "Left side of assignment must reference an attribute");
success = false;
}
@@ -216,11 +216,11 @@ bool verify_expr(progfile &f, ExprTree the_expr) {
}
if (success) {
- if (Binary[the_expr->_oper.op_name])
- success = verify_expr(f, the_expr->_oper.left);
+ if (Binary[the_expr->_data._oper.op_name])
+ success = verify_expr(f, the_expr->_data._oper.left);
}
if (success)
- success = verify_expr(f, the_expr->_oper.right);
+ success = verify_expr(f, the_expr->_data._oper.right);
break;
default:
diff --git a/engines/glk/archetype/statement.h b/engines/glk/archetype/statement.h
index 0be8c1b9a0..62c2095797 100644
--- a/engines/glk/archetype/statement.h
+++ b/engines/glk/archetype/statement.h
@@ -34,7 +34,7 @@ enum StatementKind {
ST_DESTROY, ST_WRITE, ST_WRITES, ST_STOP, CONT_SEQ, END_SEQ
};
-union StatementType;
+struct StatementType;
typedef StatementType *StatementPtr;
struct StmtCompound {
@@ -74,8 +74,7 @@ struct StmtWrite {
ListType print_list;
};
-union StatementType {
- StatementKind _kind;
+union StatementTypeData {
StmtCompound _compound;
StmtExpr _expr;
StmtIf _if;
@@ -86,6 +85,11 @@ union StatementType {
StmtWrite _write;
};
+struct StatementType {
+ StatementKind _kind;
+ StatementTypeData _data;
+};
+
struct CasePairType {
ExprTree value;
StatementPtr action;
diff --git a/engines/glk/archetype/sys_object.cpp b/engines/glk/archetype/sys_object.cpp
index c30a1b87f6..d4191a3ca0 100644
--- a/engines/glk/archetype/sys_object.cpp
+++ b/engines/glk/archetype/sys_object.cpp
@@ -117,15 +117,15 @@ void send_to_system(int transport, String &strmsg, ResultType &result, ContextTy
case NORMALIZE:
// last normalized command
result._kind = STR_PTR;
- result._str.acl_str = NewDynStr(g_vm->Command);
+ result._data._str.acl_str = NewDynStr(g_vm->Command);
sys_state = IDLING;
case ABBR:
result._kind = STR_PTR;
- result._str.acl_str = NewDynStr(strmsg);
+ result._data._str.acl_str = NewDynStr(strmsg);
if (convert_to(NUMERIC, result)) {
- g_vm->Abbreviate = result._numeric.acl_int;
+ g_vm->Abbreviate = result._data._numeric.acl_int;
}
else {
wraperr("Warning: non-numeric abbreviation message sent to system");
@@ -180,7 +180,7 @@ void send_to_system(int transport, String &strmsg, ResultType &result, ContextTy
cleanup(result);
} else {
result._kind = STR_PTR;
- result._str.acl_str = (StringPtr)p;
+ result._data._str.acl_str = (StringPtr)p;
sys_state = IDLING;
}
break;
@@ -189,8 +189,8 @@ void send_to_system(int transport, String &strmsg, ResultType &result, ContextTy
obj_index = find_object(strmsg);
if (obj_index != 0) {
result._kind = IDENT;
- result._ident.ident_kind = OBJECT_ID;
- result._ident.ident_int = obj_index;
+ result._data._ident.ident_kind = OBJECT_ID;
+ result._data._ident.ident_int = obj_index;
}
sys_state = IDLING;
break;
@@ -220,11 +220,11 @@ void send_to_system(int transport, String &strmsg, ResultType &result, ContextTy
cleanup(result);
} else if (obj_index < 0) {
result._kind = STR_PTR;
- result._str.acl_str = NewDynStr(nomatch);
+ result._data._str.acl_str = NewDynStr(nomatch);
} else {
result._kind = IDENT;
- result._ident.ident_kind = OBJECT_ID;
- result._ident.ident_int = obj_index;
+ result._data._ident.ident_kind = OBJECT_ID;
+ result._data._ident.ident_int = obj_index;
}
sys_state = IDLING;
@@ -254,7 +254,7 @@ void send_to_system(int transport, String &strmsg, ResultType &result, ContextTy
case FREE_MEMORY:
result._kind = NUMERIC;
- result._numeric.acl_int = 0xffff; // MemAvail;
+ result._data._numeric.acl_int = 0xffff; // MemAvail;
sys_state = IDLING;
break;
@@ -267,7 +267,7 @@ void send_to_system(int transport, String &strmsg, ResultType &result, ContextTy
else {
save_game_state(stfile, g_vm->Object_List);
result._kind = RESERVED;
- result._reserved.keyword = RW_TRUE;
+ result._data._reserved.keyword = RW_TRUE;
stfile->finalize();
delete stfile;
@@ -284,7 +284,7 @@ void send_to_system(int transport, String &strmsg, ResultType &result, ContextTy
cleanup(result);
} else {
result._kind = RESERVED;
- result._reserved.keyword = load_game_state(stfile, g_vm->Object_List) ? RW_TRUE : RW_FALSE;
+ result._data._reserved.keyword = load_game_state(stfile, g_vm->Object_List) ? RW_TRUE : RW_FALSE;
delete stfile;
}