mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-02 11:58:05 +03:00
aindump/ainedit: various macros
.LOCALINC2/.LOCALDEC2 are semantically identical to .LOCALINC/.LOCALDEC except that they represent an uglier instruction sequence which is frequently used in Rance 10. .LOCALPLUSA/.LOCALMINUSA and .STRING_LOCALASSIGN do what you would expect.
This commit is contained in:
@@ -219,7 +219,7 @@ char *escape_string(const char *str)
|
||||
return _escape_string(str, escape_chars, replace_chars);
|
||||
}
|
||||
|
||||
static void print_string(struct dasm_state *dasm, const char *str)
|
||||
void dasm_print_string(struct dasm_state *dasm, const char *str)
|
||||
{
|
||||
char *u = escape_string(str);
|
||||
fprintf(dasm->out, "\"%s\"", u);
|
||||
@@ -230,7 +230,7 @@ void dasm_print_identifier(struct dasm_state *dasm, const char *str)
|
||||
{
|
||||
char *u = encode_text_utf8(str);
|
||||
if (strchr(u, ' '))
|
||||
print_string(dasm, str);
|
||||
dasm_print_string(dasm, str);
|
||||
else
|
||||
print_sjis(dasm, str);
|
||||
free(u);
|
||||
@@ -335,7 +335,7 @@ static void print_argument(struct dasm_state *dasm, int32_t arg, enum instructio
|
||||
fprintf(dasm->out, "0x%x ", arg);
|
||||
*comment = ain->strings[arg]->text;
|
||||
} else {
|
||||
print_string(dasm, ain->strings[arg]->text);
|
||||
dasm_print_string(dasm, ain->strings[arg]->text);
|
||||
}
|
||||
break;
|
||||
case T_MSG:
|
||||
@@ -345,14 +345,14 @@ static void print_argument(struct dasm_state *dasm, int32_t arg, enum instructio
|
||||
fprintf(dasm->out, "0x%x ", arg);
|
||||
*comment = ain->messages[arg]->text;
|
||||
} else {
|
||||
print_string(dasm, ain->messages[arg]->text);
|
||||
dasm_print_string(dasm, ain->messages[arg]->text);
|
||||
}
|
||||
break;
|
||||
case T_LOCAL:
|
||||
if (dasm->func < 0) {
|
||||
DASM_ERROR(dasm, "Attempt to access local variable outside of function");
|
||||
//WARNING("Attempt to access local variable outside of function");
|
||||
//print_string(dasm, "???");
|
||||
//dasm_print_string(dasm, "???");
|
||||
break;
|
||||
}
|
||||
if (arg < 0 || arg >= ain->functions[dasm->func].nr_vars)
|
||||
@@ -423,7 +423,7 @@ static void print_arguments(struct dasm_state *dasm, const struct instruction *i
|
||||
}
|
||||
if (comment) {
|
||||
fprintf(dasm->out, "; ");
|
||||
print_string(dasm, comment);
|
||||
dasm_print_string(dasm, comment);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,9 +489,9 @@ static void print_switch_case(struct dasm_state *dasm, struct ain_switch_case *c
|
||||
case AIN_SWITCH_STRING:
|
||||
if (dasm->flags & DASM_NO_STRINGS) {
|
||||
fprintf(dasm->out, "%d ; ", c->value);
|
||||
print_string(dasm, dasm->ain->strings[c->value]->text);
|
||||
dasm_print_string(dasm, dasm->ain->strings[c->value]->text);
|
||||
} else {
|
||||
print_string(dasm, dasm->ain->strings[c->value]->text);
|
||||
dasm_print_string(dasm, dasm->ain->strings[c->value]->text);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -28,5 +28,6 @@ bool dasm_is_jump_target(struct dasm_state *dasm);
|
||||
bool dasm_print_macro(struct dasm_state *dasm);
|
||||
void dasm_print_identifier(struct dasm_state *dasm, const char *str);
|
||||
void dasm_print_local_variable(struct dasm_state *dasm, struct ain_function *func, int varno);
|
||||
void dasm_print_string(struct dasm_state *dasm, const char *str);
|
||||
|
||||
#endif /* AINDUMP_DASM_H */
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <string.h>
|
||||
#include "system4/ain.h"
|
||||
#include "system4/instructions.h"
|
||||
#include "system4/string.h"
|
||||
#include "system4/utfsjis.h"
|
||||
#include "aindump.h"
|
||||
#include "dasm.h"
|
||||
|
||||
@@ -67,10 +69,15 @@ static bool local_check(struct dasm_state *dasm, int32_t *args)
|
||||
#define LOCALREF_check local_check
|
||||
#define LOCALREFREF_check local_check
|
||||
#define LOCALINC_check local_check
|
||||
#define LOCALINC2_check local_check
|
||||
#define LOCALDEC_check local_check
|
||||
#define LOCALDEC2_check local_check
|
||||
#define LOCALPLUSA_check local_check
|
||||
#define LOCALMINUSA_check local_check
|
||||
#define LOCALASSIGN_check local_check
|
||||
#define LOCALASSIGN2_check local_check
|
||||
#define F_LOCALASSIGN_check local_check
|
||||
#define STRING_LOCALASSIGN_check local_check
|
||||
|
||||
static bool S_LOCALASSIGN_check(struct dasm_state *dasm, int32_t *args)
|
||||
{
|
||||
@@ -94,16 +101,21 @@ static void local_emit(struct dasm_state *dasm, int32_t *args)
|
||||
#define LOCALREF_emit local_emit
|
||||
#define LOCALREFREF_emit local_emit
|
||||
#define LOCALINC_emit local_emit
|
||||
#define LOCALINC2_emit local_emit
|
||||
#define LOCALDEC_emit local_emit
|
||||
#define LOCALDEC2_emit local_emit
|
||||
#define LOCALDELETE_emit local_emit
|
||||
#define LOCALASSIGN2_emit local_emit
|
||||
#define S_LOCALASSIGN_emit local_emit
|
||||
|
||||
static void LOCALASSIGN_emit(struct dasm_state *dasm, int32_t *args)
|
||||
static void localassign_emit(struct dasm_state *dasm, int32_t *args)
|
||||
{
|
||||
print_local(dasm, args[0]);
|
||||
fprintf(dasm->out, " %d", args[1]);
|
||||
}
|
||||
#define LOCALASSIGN_emit localassign_emit
|
||||
#define LOCALPLUSA_emit localassign_emit
|
||||
#define LOCALMINUSA_emit localassign_emit
|
||||
|
||||
static void F_LOCALASSIGN_emit(struct dasm_state *dasm, int32_t *args)
|
||||
{
|
||||
@@ -112,6 +124,19 @@ static void F_LOCALASSIGN_emit(struct dasm_state *dasm, int32_t *args)
|
||||
fprintf(dasm->out, " %f", v.f);
|
||||
}
|
||||
|
||||
static void STRING_LOCALASSIGN_emit(struct dasm_state *dasm, int32_t *args)
|
||||
{
|
||||
print_local(dasm, args[0]);
|
||||
fprintf(dasm->out, " 0x%x ; ", args[1]);
|
||||
dasm_print_string(dasm, dasm->ain->strings[args[1]]->text);
|
||||
/*
|
||||
char *u = sjis2utf(dasm->ain->strings[args[1]]->text, 0);
|
||||
print_local(dasm, args[0]);
|
||||
fprintf(dasm->out, " 0x%x ; \"%s\"", args[1], u);
|
||||
free(u);
|
||||
*/
|
||||
}
|
||||
|
||||
static void LOCALCREATE_emit(struct dasm_state *dasm, int32_t *args)
|
||||
{
|
||||
print_local(dasm, args[0]);
|
||||
@@ -224,11 +249,16 @@ struct macrodef macrodefs[] = {
|
||||
DEFMACRO(LOCALREF, PUSHLOCALPAGE, PUSH, REF),
|
||||
DEFMACRO(LOCALREFREF, PUSHLOCALPAGE, PUSH, REFREF),
|
||||
DEFMACRO(LOCALINC, PUSHLOCALPAGE, PUSH, INC),
|
||||
DEFMACRO(LOCALINC2, PUSHLOCALPAGE, PUSH, DUP2, REF, DUP_X2, POP, INC, POP),
|
||||
DEFMACRO(LOCALDEC, PUSHLOCALPAGE, PUSH, DEC),
|
||||
DEFMACRO(LOCALDEC2, PUSHLOCALPAGE, PUSH, DUP2, REF, DUP_X2, POP, DEC, POP),
|
||||
DEFMACRO(LOCALPLUSA, PUSHLOCALPAGE, PUSH, PUSH, PLUSA, POP),
|
||||
DEFMACRO(LOCALMINUSA, PUSHLOCALPAGE, PUSH, PUSH, MINUSA, POP),
|
||||
DEFMACRO(LOCALASSIGN, PUSHLOCALPAGE, PUSH, PUSH, ASSIGN, POP),
|
||||
DEFMACRO(LOCALASSIGN2, PUSHLOCALPAGE, SWAP, PUSH, SWAP, ASSIGN),
|
||||
DEFMACRO(F_LOCALASSIGN, PUSHLOCALPAGE, PUSH, F_PUSH, F_ASSIGN, POP),
|
||||
DEFMACRO(S_LOCALASSIGN, PUSHLOCALPAGE, PUSH, REF, DELETE, PUSHLOCALPAGE, SWAP, PUSH, SWAP, ASSIGN),
|
||||
DEFMACRO(STRING_LOCALASSIGN, PUSHLOCALPAGE, PUSH, REF, S_PUSH, S_ASSIGN, DELETE),
|
||||
DEFMACRO(LOCALCREATE, PUSHLOCALPAGE, PUSH, DUP2, REF, DELETE, DUP2, NEW, ASSIGN, POP, POP, POP),
|
||||
DEFMACRO(LOCALDELETE, PUSHLOCALPAGE, PUSH, DUP2, REF, DELETE, PUSH, ASSIGN, POP),
|
||||
DEFMACRO(GLOBALREF, PUSHGLOBALPAGE, PUSH, REF),
|
||||
|
||||
@@ -39,11 +39,16 @@ enum asm_pseudo_opcode {
|
||||
PO_LOCALREFREF,
|
||||
PO_GLOBALREFREF,
|
||||
PO_LOCALINC,
|
||||
PO_LOCALINC2,
|
||||
PO_LOCALDEC,
|
||||
PO_LOCALDEC2,
|
||||
PO_LOCALPLUSA,
|
||||
PO_LOCALMINUSA,
|
||||
PO_LOCALASSIGN,
|
||||
PO_LOCALASSIGN2,
|
||||
PO_F_LOCALASSIGN,
|
||||
PO_S_LOCALASSIGN,
|
||||
PO_STRING_LOCALASSIGN,
|
||||
PO_LOCALDELETE,
|
||||
PO_LOCALCREATE,
|
||||
PO_GLOBALINC,
|
||||
|
||||
+65
-5
@@ -27,7 +27,7 @@
|
||||
#include "system4/string.h"
|
||||
#include "asm_parser.tab.h"
|
||||
|
||||
extern FILE *yyin;
|
||||
extern FILE *asm_in;
|
||||
|
||||
KHASH_MAP_INIT_STR(string_ht, size_t);
|
||||
|
||||
@@ -64,11 +64,16 @@ const struct instruction asm_pseudo_ops[NR_PSEUDO_OPS - PSEUDO_OP_OFFSET] = {
|
||||
MACRO(PO_LOCALREF, ".LOCALREF", 1, 10),
|
||||
MACRO(PO_LOCALREFREF, ".LOCALREFREF", 1, 10),
|
||||
MACRO(PO_LOCALINC, ".LOCALINC", 1, 10),
|
||||
MACRO(PO_LOCALINC2, ".LOCALINC2", 1, 20),
|
||||
MACRO(PO_LOCALDEC, ".LOCALDEC", 1, 10),
|
||||
MACRO(PO_LOCALDEC2, ".LOCALDEC2", 1, 20),
|
||||
MACRO(PO_LOCALPLUSA, ".LOCALPLUSA", 2, 18),
|
||||
MACRO(PO_LOCALMINUSA, ".LOCALMINUSA", 2, 18),
|
||||
MACRO(PO_LOCALASSIGN, ".LOCALASSIGN", 2, 18),
|
||||
MACRO(PO_LOCALASSIGN2, ".LOCALASSIGN2", 1, 14),
|
||||
MACRO(PO_F_LOCALASSIGN, ".F_LOCALASSIGN", 2, 18),
|
||||
MACRO(PO_S_LOCALASSIGN, ".S_LOCALASSIGN", 1, 26),
|
||||
MACRO(PO_STRING_LOCALASSIGN, ".STRING_LOCALASSIGN", 2, 20),
|
||||
MACRO(PO_LOCALDELETE, ".LOCALDELETE", 1, 24),
|
||||
MACRO(PO_LOCALCREATE, ".LOCALCREATE", 2, 34),
|
||||
MACRO(PO_GLOBALREF, ".GLOBALREF", 1, 10),
|
||||
@@ -607,6 +612,18 @@ void handle_pseudo_op(struct asm_state *state, struct parse_instruction *instr)
|
||||
asm_write_opcode(state, INC);
|
||||
break;
|
||||
}
|
||||
case PO_LOCALINC2: {
|
||||
asm_write_opcode(state, PUSHLOCALPAGE);
|
||||
asm_write_opcode(state, PUSH);
|
||||
asm_write_argument(state, asm_resolve_arg(state, PUSH, T_LOCAL, kv_A(*instr->args, 0)->text));
|
||||
asm_write_opcode(state, DUP2);
|
||||
asm_write_opcode(state, REF);
|
||||
asm_write_opcode(state, DUP_X2);
|
||||
asm_write_opcode(state, POP);
|
||||
asm_write_opcode(state, INC);
|
||||
asm_write_opcode(state, POP);
|
||||
break;
|
||||
}
|
||||
case PO_LOCALDEC: {
|
||||
asm_write_opcode(state, PUSHLOCALPAGE);
|
||||
asm_write_opcode(state, PUSH);
|
||||
@@ -614,6 +631,38 @@ void handle_pseudo_op(struct asm_state *state, struct parse_instruction *instr)
|
||||
asm_write_opcode(state, DEC);
|
||||
break;
|
||||
}
|
||||
case PO_LOCALDEC2: {
|
||||
asm_write_opcode(state, PUSHLOCALPAGE);
|
||||
asm_write_opcode(state, PUSH);
|
||||
asm_write_argument(state, asm_resolve_arg(state, PUSH, T_LOCAL, kv_A(*instr->args, 0)->text));
|
||||
asm_write_opcode(state, DUP2);
|
||||
asm_write_opcode(state, REF);
|
||||
asm_write_opcode(state, DUP_X2);
|
||||
asm_write_opcode(state, POP);
|
||||
asm_write_opcode(state, DEC);
|
||||
asm_write_opcode(state, POP);
|
||||
break;
|
||||
}
|
||||
case PO_LOCALPLUSA: {
|
||||
asm_write_opcode(state, PUSHLOCALPAGE);
|
||||
asm_write_opcode(state, PUSH);
|
||||
asm_write_argument(state, asm_resolve_arg(state, PUSH, T_LOCAL, kv_A(*instr->args, 0)->text));
|
||||
asm_write_opcode(state, PUSH);
|
||||
asm_write_argument(state, asm_resolve_arg(state, PUSH, T_INT, kv_A(*instr->args, 1)->text));
|
||||
asm_write_opcode(state, PLUSA);
|
||||
asm_write_opcode(state, POP);
|
||||
break;
|
||||
}
|
||||
case PO_LOCALMINUSA: {
|
||||
asm_write_opcode(state, PUSHLOCALPAGE);
|
||||
asm_write_opcode(state, PUSH);
|
||||
asm_write_argument(state, asm_resolve_arg(state, PUSH, T_LOCAL, kv_A(*instr->args, 0)->text));
|
||||
asm_write_opcode(state, PUSH);
|
||||
asm_write_argument(state, asm_resolve_arg(state, PUSH, T_INT, kv_A(*instr->args, 1)->text));
|
||||
asm_write_opcode(state, MINUSA);
|
||||
asm_write_opcode(state, POP);
|
||||
break;
|
||||
}
|
||||
case PO_LOCALASSIGN: {
|
||||
asm_write_opcode(state, PUSHLOCALPAGE);
|
||||
asm_write_opcode(state, PUSH);
|
||||
@@ -657,6 +706,17 @@ void handle_pseudo_op(struct asm_state *state, struct parse_instruction *instr)
|
||||
asm_write_opcode(state, ASSIGN);
|
||||
break;
|
||||
}
|
||||
case PO_STRING_LOCALASSIGN: {
|
||||
asm_write_opcode(state, PUSHLOCALPAGE);
|
||||
asm_write_opcode(state, PUSH);
|
||||
asm_write_argument(state, asm_resolve_arg(state, PUSH, T_LOCAL, kv_A(*instr->args, 0)->text));
|
||||
asm_write_opcode(state, REF);
|
||||
asm_write_opcode(state, S_PUSH);
|
||||
asm_write_argument(state, asm_resolve_arg(state, PUSH, T_INT, kv_A(*instr->args, 1)->text));
|
||||
asm_write_opcode(state, S_ASSIGN);
|
||||
asm_write_opcode(state, DELETE);
|
||||
break;
|
||||
}
|
||||
case PO_LOCALDELETE: {
|
||||
asm_write_opcode(state, PUSHLOCALPAGE);
|
||||
asm_write_opcode(state, PUSH);
|
||||
@@ -852,15 +912,15 @@ void asm_assemble_jam(const char *filename, struct ain *ain, uint32_t flags)
|
||||
|
||||
if (filename) {
|
||||
if (!strcmp(filename, "-"))
|
||||
yyin = stdin;
|
||||
asm_in = stdin;
|
||||
else
|
||||
yyin = fopen(filename, "r");
|
||||
if (!yyin)
|
||||
asm_in = fopen(filename, "r");
|
||||
if (!asm_in)
|
||||
ERROR("Opening input file '%s': %s", filename, strerror(errno));
|
||||
}
|
||||
label_table = kh_init(label_table);
|
||||
NOTICE("Parsing...");
|
||||
yyparse();
|
||||
asm_parse();
|
||||
|
||||
NOTICE("Encoding...");
|
||||
for (size_t i = 0; i < kv_size(*parsed_code); i++) {
|
||||
|
||||
@@ -23,17 +23,18 @@
|
||||
#include "system4.h"
|
||||
#include "system4/string.h"
|
||||
|
||||
#define SAVE_TOKEN yylval.string = makes_string(yytext, yyleng)
|
||||
#define SAVE_TOKEN asm_lval.string = makes_string(asm_text, asm_leng)
|
||||
|
||||
char string_buf[65536];
|
||||
char *string_buf_ptr;
|
||||
|
||||
unsigned long asm_line = 1;
|
||||
extern void yyerror(const char *s);
|
||||
extern void asm_error(const char *s);
|
||||
|
||||
%}
|
||||
|
||||
%option noyywrap
|
||||
%option prefix="asm_"
|
||||
|
||||
%x str
|
||||
|
||||
@@ -44,8 +45,8 @@ id_char [^ \t\r\n:;\"]
|
||||
[ \t] ;
|
||||
;[^\n]*\n asm_line++; return NEWLINE;
|
||||
\n asm_line++; return NEWLINE;
|
||||
[a-zA-Z0-9_-]+: yylval.string = make_string(yytext, yyleng-1); return LABEL;
|
||||
({id_char}|:)*{id_char}+ yylval.string = make_string(yytext, yyleng); return IDENTIFIER;
|
||||
[a-zA-Z0-9_-]+: asm_lval.string = make_string(asm_text, asm_leng-1); return LABEL;
|
||||
({id_char}|:)*{id_char}+ asm_lval.string = make_string(asm_text, asm_leng); return IDENTIFIER;
|
||||
|
||||
|
||||
\" string_buf_ptr = string_buf; BEGIN(str);
|
||||
@@ -54,11 +55,11 @@ id_char [^ \t\r\n:;\"]
|
||||
\" {
|
||||
BEGIN(INITIAL);
|
||||
*string_buf_ptr = '\0';
|
||||
yylval.string = make_string(string_buf, strlen(string_buf));
|
||||
asm_lval.string = make_string(string_buf, strlen(string_buf));
|
||||
return IDENTIFIER;
|
||||
}
|
||||
|
||||
\n yyerror("Unterminated string literal");
|
||||
\n asm_error("Unterminated string literal");
|
||||
|
||||
\\n *string_buf_ptr++ = '\n';
|
||||
\\t *string_buf_ptr++ = '\t';
|
||||
@@ -66,10 +67,10 @@ id_char [^ \t\r\n:;\"]
|
||||
\\b *string_buf_ptr++ = '\b';
|
||||
\\f *string_buf_ptr++ = '\f';
|
||||
|
||||
\\(.|\n) *string_buf_ptr++ = yytext[1];
|
||||
\\(.|\n) *string_buf_ptr++ = asm_text[1];
|
||||
|
||||
[^\\\n\"]+ {
|
||||
char *yptr = yytext;
|
||||
char *yptr = asm_text;
|
||||
while (*yptr)
|
||||
*string_buf_ptr++ = *yptr++;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
%define api.prefix {asm_}
|
||||
|
||||
%union {
|
||||
int token;
|
||||
struct string *string;
|
||||
@@ -36,13 +38,13 @@
|
||||
#include "system4/instructions.h"
|
||||
#include "system4/string.h"
|
||||
|
||||
extern int yylex();
|
||||
extern int asm_lex();
|
||||
extern unsigned long asm_line;
|
||||
|
||||
#define PARSE_ERROR(fmt, ...) \
|
||||
sys_error("ERROR: At line %d: " fmt "\n", asm_line-1, ##__VA_ARGS__)
|
||||
|
||||
void yyerror(const char *s)
|
||||
void asm_error(const char *s)
|
||||
{
|
||||
sys_error("ERROR: At line %d: %s\n", asm_line, s);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user