This patch makes @push x and @pull x work as aliases for @copy x sp and @copy sp x,
respectively, when in Glulx mode.
Many of the ifdef blocks in the library are there only because Z-code and Glulx
currently use different syntax for saving values on the stack. Apply the following patch.
About Patches
Issue C63104 [previous patch]
Support @push and @pull macros in Glulx
Submitted by: Jesse McGrew
Appeared in: Compiler 6.31 or before
Fixed in: -
Problem
Solution
diff -c inform631-old/asm.c inform631_source/asm.c
*** inform631-old/asm.c Sat Jan 28 06:13:46 2006
--- inform631_source/asm.c Sat Jul 15 05:41:42 2006
***************
*** 554,559 ****
--- 554,566 ----
{ (uchar *) "callfiii", 0x0163, St, 0, 5 },
};
+ /* The opmacros table is used for fake opcodes. The opcode numbers are
+ ignored; this table is only used for argument parsing. */
+ static opcodeg opmacros_table_g[] = {
+ { (uchar *) "pull", 0, St, 0, 1 },
+ { (uchar *) "push", 0, 0, 0, 1 },
+ };
+
static opcodeg custom_opcode_g;
static opcodez internal_number_to_opcode_z(int32 i)
***************
*** 611,616 ****
--- 618,628 ----
return x;
}
+ static opcodeg internal_number_to_opmacro_g(int32 i)
+ {
+ return opmacros_table_g[i];
+ }
+
static void make_opcode_syntax_g(opcodeg opco)
{
int ix;
***************
*** 944,949 ****
--- 956,1015 ----
error_named("Assembly mistake: syntax is", opcode_syntax_string);
}
+ static void assembleg_macro(assembly_instruction *AI)
+ {
+ /* validate macro syntax first */
+ int ix, no_operands_given;
+ opcodeg opco;
+
+ opco = internal_number_to_opmacro_g(AI->internal_number);
+ no_operands_given = AI->operand_count;
+
+ if (no_operands_given != opco.no)
+ goto OpcodeSyntaxError;
+
+ for (ix = 0; ix < no_operands_given; ix++) {
+ int type = AI->operand[ix].type;
+ if ((opco.flags & St)
+ && ((!(opco.flags & Br) && (ix == no_operands_given-1))
+ || ((opco.flags & Br) && (ix == no_operands_given-2)))) {
+ if (is_constant_ot(type)) {
+ error("*** assembly macro tried to store to a constant ***");
+ goto OpcodeSyntaxError;
+ }
+ }
+ if ((opco.flags & St2)
+ && (ix == no_operands_given-2)) {
+ if (is_constant_ot(type)) {
+ error("*** assembly macro tried to store to a constant ***");
+ goto OpcodeSyntaxError;
+ }
+ }
+ }
+
+ /* expand the macro */
+ switch (AI->internal_number) {
+ case pull_gm:
+ assembleg_store(AI->operand[0], stack_pointer);
+ break;
+
+ case push_gm:
+ assembleg_store(stack_pointer, AI->operand[0]);
+ break;
+
+ default:
+ compiler_error("Invalid Glulx assembly macro");
+ break;
+ }
+
+ return;
+
+ OpcodeSyntaxError:
+
+ make_opcode_syntax_g(opco);
+ error_named("Assembly mistake: syntax is", opcode_syntax_string);
+ }
+
extern void assembleg_instruction(assembly_instruction *AI)
{
uchar *start_pc, *opmodes_pc;
***************
*** 2729,2741 ****
{
opcodeg O;
assembly_operand AO;
! int error_flag = FALSE;
AI.operand_count = 0;
opcode_names.enabled = TRUE;
get_next_token();
opcode_names.enabled = FALSE;
if (token_type == DQ_TT) {
error("Runtime assembly definitions are not yet supported in Glulx.");
--- 2795,2809 ----
{
opcodeg O;
assembly_operand AO;
! int error_flag = FALSE, is_macro = FALSE;
AI.operand_count = 0;
opcode_names.enabled = TRUE;
+ opcode_macros.enabled = TRUE;
get_next_token();
opcode_names.enabled = FALSE;
+ opcode_macros.enabled = FALSE;
if (token_type == DQ_TT) {
error("Runtime assembly definitions are not yet supported in Glulx.");
***************
*** 2743,2755 ****
return;
}
else {
! if (token_type != OPCODE_NAME_TT) {
ebf_error("an opcode name", token_text);
panic_mode_error_recovery();
return;
}
AI.internal_number = token_value;
! O = internal_number_to_opcode_g(AI.internal_number);
}
return_sp_as_variable = TRUE;
--- 2811,2828 ----
return;
}
else {
! if (token_type != OPCODE_NAME_TT && token_type != OPCODE_MACRO_TT) {
ebf_error("an opcode name", token_text);
panic_mode_error_recovery();
return;
}
AI.internal_number = token_value;
! if (token_type == OPCODE_MACRO_TT) {
! O = internal_number_to_opmacro_g(AI.internal_number);
! is_macro = TRUE;
! }
! else
! O = internal_number_to_opcode_g(AI.internal_number);
}
return_sp_as_variable = TRUE;
***************
*** 2791,2798 ****
error_flag = TRUE;
}
! if (!error_flag)
! assembleg_instruction(&AI);
if (error_flag) {
make_opcode_syntax_g(O);
--- 2864,2875 ----
error_flag = TRUE;
}
! if (!error_flag) {
! if (is_macro)
! assembleg_macro(&AI);
! else
! assembleg_instruction(&AI);
! }
if (error_flag) {
make_opcode_syntax_g(O);
diff -c inform631-old/header.h inform631_source/header.h
*** inform631-old/header.h Fri Feb 10 02:21:06 2006
--- inform631_source/header.h Sat Jul 15 05:11:41 2006
***************
*** 1118,1123 ****
--- 1118,1131 ----
#define callfii_gc 78
#define callfiii_gc 79
+ /* ------------------------------------------------------------------------- */
+ /* Index numbers into the keyword group "opcode_macros_g" (see "lexer.c") */
+ /* ------------------------------------------------------------------------- */
+
+ #define pull_gm 0
+ #define push_gm 1
+
+
#define SYMBOL_TT 0 /* value = index in symbol table */
#define NUMBER_TT 1 /* value = the number */
#define DQ_TT 2 /* no value */
***************
*** 1138,1143 ****
--- 1146,1152 ----
syntax for a directive */
#define TRACE_KEYWORD_TT 110 /* keyword used in debugging */
#define SYSTEM_CONSTANT_TT 111 /* such as "code_offset" */
+ #define OPCODE_MACRO_TT 112 /* fake opcode for compatibility */
#define OP_TT 200 /* value = operator no */
#define ENDEXP_TT 201 /* no value */
***************
*** 2345,2351 ****
extern keyword_group directives, statements, segment_markers,
conditions, system_functions, local_variables, opcode_names,
! misc_keywords, directive_keywords, trace_keywords, system_constants;
/* ------------------------------------------------------------------------- */
/* Extern definitions for "linker" */
--- 2354,2361 ----
extern keyword_group directives, statements, segment_markers,
conditions, system_functions, local_variables, opcode_names,
! misc_keywords, directive_keywords, trace_keywords, system_constants,
! opcode_macros;
/* ------------------------------------------------------------------------- */
/* Extern definitions for "linker" */
diff -c inform631-old/lexer.c inform631_source/lexer.c
*** inform631-old/lexer.c Sat Jan 28 06:14:30 2006
--- inform631_source/lexer.c Sat Jul 15 05:22:36 2006
***************
*** 267,272 ****
--- 267,284 ----
""
};
+ keyword_group opcode_macros =
+ { { "" },
+ OPCODE_MACRO_TT, FALSE, TRUE
+ };
+
+ static char *opmacro_list_z[] = { "" };
+
+ static char *opmacro_list_g[] = {
+ "pull", "push",
+ ""
+ };
+
keyword_group directives =
{ { "abbreviate", "array", "attribute", "class", "constant",
"default", "dictionary", "end", "endif", "extend", "fake_action",
***************
*** 364,373 ****
SYSTEM_CONSTANT_TT, FALSE, TRUE
};
! keyword_group *keyword_groups[11]
= { NULL, &opcode_names, &directives, &trace_keywords, &segment_markers,
&directive_keywords, &misc_keywords, &statements, &conditions,
! &system_functions, &system_constants};
keyword_group local_variables =
{ { "" }, /* Filled in when routine declared */
--- 376,385 ----
SYSTEM_CONSTANT_TT, FALSE, TRUE
};
! keyword_group *keyword_groups[12]
= { NULL, &opcode_names, &directives, &trace_keywords, &segment_markers,
&directive_keywords, &misc_keywords, &statements, &conditions,
! &system_functions, &system_constants, &opcode_macros};
keyword_group local_variables =
{ { "" }, /* Filled in when routine declared */
***************
*** 433,456 ****
static void make_keywords_tables(void)
{ int i, j, h, tp=0;
! char **oplist;
! if (!glulx_mode)
oplist = opcode_list_z;
! else
oplist = opcode_list_g;
for (j=0; *(oplist[j]); j++) {
opcode_names.keywords[j] = oplist[j];
}
opcode_names.keywords[j] = "";
for (i=0; i<HASH_TAB_SIZE; i++)
{ keywords_hash_table[i] = -1;
keywords_hash_ends_table[i] = -1;
}
! for (i=1; i<=10; i++)
{ keyword_group *kg = keyword_groups[i];
for (j=0; *(kg->keywords[j]) != 0; j++)
{ h = hash_code_from_string(kg->keywords[j]);
--- 445,477 ----
static void make_keywords_tables(void)
{ int i, j, h, tp=0;
! char **oplist, **maclist;
! if (!glulx_mode) {
oplist = opcode_list_z;
! maclist = opmacro_list_z;
! }
! else {
oplist = opcode_list_g;
+ maclist = opmacro_list_g;
+ }
for (j=0; *(oplist[j]); j++) {
opcode_names.keywords[j] = oplist[j];
}
opcode_names.keywords[j] = "";
+
+ for (j=0; *(maclist[j]); j++) {
+ opcode_macros.keywords[j] = maclist[j];
+ }
+ opcode_macros.keywords[j] = "";
for (i=0; i<HASH_TAB_SIZE; i++)
{ keywords_hash_table[i] = -1;
keywords_hash_ends_table[i] = -1;
}
! for (i=1; i<=11; i++)
{ keyword_group *kg = keyword_groups[i];
for (j=0; *(kg->keywords[j]) != 0; j++)
{ h = hash_code_from_string(kg->keywords[j]);
Last updated 17 April 2013.
This site is no longer supported; information may be out of date.
Maintained as a historical archive by the Interactive Fiction Technology Foundation.
Copyright 1993-2018 IFTF, CC-BY-SA unless otherwise noted.
This page was originally managed by Roger Firth.