diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/glk/archetype/archetype.cpp | 279 | ||||
-rw-r--r-- | engines/glk/archetype/expression.h | 10 | ||||
-rw-r--r-- | engines/glk/archetype/interpreter.cpp | 94 | ||||
-rw-r--r-- | engines/glk/archetype/interpreter.h | 2 | ||||
-rw-r--r-- | engines/glk/archetype/keywords.cpp | 1 | ||||
-rw-r--r-- | engines/glk/archetype/saveload.cpp | 86 | ||||
-rw-r--r-- | engines/glk/archetype/semantic.cpp | 32 | ||||
-rw-r--r-- | engines/glk/archetype/statement.h | 10 | ||||
-rw-r--r-- | engines/glk/archetype/sys_object.cpp | 24 |
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; } |