mirror of
https://github.com/dschmenk/PLASMA.git
synced 2025-02-03 22:35:52 +00:00
813 lines
21 KiB
C
Executable File
813 lines
21 KiB
C
Executable File
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#include "tokens.h"
|
|
#include "lex.h"
|
|
#include "symbols.h"
|
|
#include "codegen.h"
|
|
/*
|
|
* Symbol table and fixup information.
|
|
*/
|
|
static int consts = 0;
|
|
static int externs = 0;
|
|
static int globals = 0;
|
|
static int locals = 0;
|
|
static int predefs = 0;
|
|
static int defs = 0;
|
|
static int asmdefs = 0;
|
|
static int codetags = 0;
|
|
static int fixups = 0;
|
|
static char idconst_name[1024][17];
|
|
static int idconst_value[1024];
|
|
static char idglobal_name[1024][17];
|
|
static int idglobal_type[1024];
|
|
static int idglobal_tag[1024];
|
|
static int localsize = 0;
|
|
static char idlocal_name[128][17];
|
|
static int idlocal_type[128];
|
|
static int idlocal_offset[128];
|
|
static char fixup_size[2048];
|
|
static int fixup_type[2048];
|
|
static int fixup_tag[2048];
|
|
#define FIXUP_BYTE 0x00
|
|
#define FIXUP_WORD 0x80
|
|
int id_match(char *name, int len, char *id)
|
|
{
|
|
if (len == id[0])
|
|
{
|
|
if (len > 16) len = 16;
|
|
while (len--)
|
|
{
|
|
if (name[len] != id[1 + len])
|
|
return (0);
|
|
}
|
|
return (1);
|
|
}
|
|
return (0);
|
|
}
|
|
int idconst_lookup(char *name, int len)
|
|
{
|
|
int i;
|
|
for (i = 0; i < consts; i++)
|
|
if (id_match(name, len, &(idconst_name[i][0])))
|
|
return (i);
|
|
return (-1);
|
|
}
|
|
int idlocal_lookup(char *name, int len)
|
|
{
|
|
int i;
|
|
for (i = 0; i < locals; i++)
|
|
if (id_match(name, len, &(idlocal_name[i][0])))
|
|
return (i);
|
|
return (-1);
|
|
}
|
|
int idglobal_lookup(char *name, int len)
|
|
{
|
|
int i;
|
|
for (i = 0; i < globals; i++)
|
|
if (id_match(name, len, &(idglobal_name[i][0])))
|
|
return (i);
|
|
return (-1);
|
|
}
|
|
int idconst_add(char *name, int len, int value)
|
|
{
|
|
char c = name[len];
|
|
if (consts > 1024)
|
|
{
|
|
printf("Constant count overflow\n");
|
|
return (0);
|
|
}
|
|
name[len] = '\0';
|
|
emit_idconst(name, value);
|
|
name[len] = c;
|
|
idconst_name[consts][0] = len;
|
|
if (len > 16) len = 16;
|
|
while (len--)
|
|
idconst_name[consts][1 + len] = name[len];
|
|
idconst_value[consts] = value;
|
|
consts++;
|
|
return (1);
|
|
}
|
|
int idlocal_add(char *name, int len, int type, int size)
|
|
{
|
|
char c = name[len];
|
|
if (localsize > 255)
|
|
{
|
|
printf("Local variable size overflow\n");
|
|
return (0);
|
|
}
|
|
name[len] = '\0';
|
|
emit_idlocal(name, localsize);
|
|
name[len] = c;
|
|
idlocal_name[locals][0] = len;
|
|
if (len > 16) len = 16;
|
|
while (len--)
|
|
idlocal_name[locals][1 + len] = name[len];
|
|
idlocal_type[locals] = type | LOCAL_TYPE;
|
|
idlocal_offset[locals] = localsize;
|
|
localsize += size;
|
|
locals++;
|
|
return (1);
|
|
}
|
|
int idglobal_add(char *name, int len, int type, int size)
|
|
{
|
|
char c = name[len];
|
|
if (globals > 1024)
|
|
{
|
|
printf("Global variable count overflow\n");
|
|
return (0);
|
|
}
|
|
name[len] = '\0';
|
|
name[len] = c;
|
|
idglobal_name[globals][0] = len;
|
|
if (len > 16) len = 16;
|
|
while (len--)
|
|
idglobal_name[globals][1 + len] = name[len];
|
|
idglobal_type[globals] = type;
|
|
if (!(type & EXTERN_TYPE))
|
|
{
|
|
emit_idglobal(globals, size, name);
|
|
idglobal_tag[globals] = globals;
|
|
globals++;
|
|
}
|
|
else
|
|
{
|
|
printf("\t\t\t\t\t; %s -> X%03d\n", &idglobal_name[globals][1], externs);
|
|
idglobal_tag[globals++] = externs++;
|
|
}
|
|
return (1);
|
|
}
|
|
int id_add(char *name, int len, int type, int size)
|
|
{
|
|
return ((type & LOCAL_TYPE) ? idlocal_add(name, len, type, size) : idglobal_add(name, len, type, size));
|
|
}
|
|
int idfunc_add(char *name, int len, int type, int tag)
|
|
{
|
|
if (globals > 1024)
|
|
{
|
|
printf("Global variable count overflow\n");
|
|
return (0);
|
|
}
|
|
idglobal_name[globals][0] = len;
|
|
if (len > 16) len = 16;
|
|
while (len--)
|
|
idglobal_name[globals][1 + len] = name[len];
|
|
idglobal_type[globals] = type;
|
|
idglobal_tag[globals++] = tag;
|
|
if (type & EXTERN_TYPE)
|
|
printf("\t\t\t\t\t; %s -> X%03d\n", &idglobal_name[globals - 1][1], tag);
|
|
return (1);
|
|
}
|
|
int idfunc_set(char *name, int len, int type, int tag)
|
|
{
|
|
int i;
|
|
if (((i = idglobal_lookup(name, len)) >= 0) && (idglobal_type[i] & FUNC_TYPE))
|
|
{
|
|
idglobal_tag[i] = tag;
|
|
idglobal_type[i] = type;
|
|
return (type);
|
|
}
|
|
parse_error("Undeclared identifier");
|
|
return (0);
|
|
}
|
|
void idglobal_size(int type, int size, int constsize)
|
|
{
|
|
if (size > constsize)
|
|
emit_data(0, 0, 0, size - constsize);
|
|
else if (size)
|
|
emit_data(0, 0, 0, size);
|
|
}
|
|
int idlocal_size(void)
|
|
{
|
|
return (localsize);
|
|
}
|
|
void idlocal_reset(void)
|
|
{
|
|
locals = 0;
|
|
localsize = 2;
|
|
}
|
|
int id_tag(char *name, int len)
|
|
{
|
|
int i;
|
|
if ((i = idlocal_lookup(name, len)) >= 0)
|
|
return (idlocal_offset[i]);
|
|
if ((i = idglobal_lookup(name, len)) >= 0)
|
|
return (idglobal_tag[i]);
|
|
return (-1);
|
|
}
|
|
int id_const(char *name, int len)
|
|
{
|
|
int i;
|
|
if ((i = idconst_lookup(name, len)) >= 0)
|
|
return (idconst_value[i]);
|
|
parse_error("Undeclared constant");
|
|
return (0);
|
|
}
|
|
int id_type(char *name, int len)
|
|
{
|
|
int i;
|
|
if ((i = idconst_lookup(name, len)) >= 0)
|
|
return (CONST_TYPE);
|
|
if ((i = idlocal_lookup(name, len)) >= 0)
|
|
return (idlocal_type[i] | LOCAL_TYPE);
|
|
if ((i = idglobal_lookup(name, len)) >= 0)
|
|
return (idglobal_type[i]);
|
|
parse_error("Undeclared identifier");
|
|
return (0);
|
|
}
|
|
int tag_new(int type)
|
|
{
|
|
if (type & EXTERN_TYPE)
|
|
{
|
|
if (externs > 254)
|
|
parse_error("External variable count overflow\n");
|
|
return (externs++);
|
|
}
|
|
if (type & PREDEF_TYPE)
|
|
return (predefs++);
|
|
if (type & ASM_TYPE)
|
|
return (asmdefs++);
|
|
if (type & DEF_TYPE)
|
|
return (defs++);
|
|
if (type & BRANCH_TYPE)
|
|
return (codetags++);
|
|
return globals++;
|
|
}
|
|
int fixup_new(int tag, int type, int size)
|
|
{
|
|
fixup_tag[fixups] = tag;
|
|
fixup_type[fixups] = type;
|
|
fixup_size[fixups] = size;
|
|
return (fixups++);
|
|
}
|
|
/*
|
|
* Emit assembly code.
|
|
*/
|
|
#define BYTECODE_SEG 8
|
|
#define INIT 16
|
|
#define SYSFLAGS 32
|
|
static int outflags = 0;
|
|
static char *DB = ".BYTE";
|
|
static char *DW = ".WORD";
|
|
static char *DS = ".RES";
|
|
static char LBL = ':';
|
|
char *supper(char *s)
|
|
{
|
|
static char su[80];
|
|
int i;
|
|
for (i = 0; s[i]; i++)
|
|
su[i] = toupper(s[i]);
|
|
su[i] = '\0';
|
|
return su;
|
|
}
|
|
char *tag_string(int tag, int type)
|
|
{
|
|
static char str[16];
|
|
char t;
|
|
|
|
if (type & EXTERN_TYPE)
|
|
t = 'X';
|
|
else if (type & DEF_TYPE)
|
|
t = 'C';
|
|
else if (type & ASM_TYPE)
|
|
t = 'A';
|
|
else if (type & BRANCH_TYPE)
|
|
t = 'B';
|
|
else if (type & PREDEF_TYPE)
|
|
t = 'P';
|
|
else
|
|
t = 'D';
|
|
sprintf(str, "_%c%03d", t, tag);
|
|
return str;
|
|
}
|
|
void emit_dci(char *str, int len)
|
|
{
|
|
if (len--)
|
|
{
|
|
printf("\t; DCI STRING: %s\n", supper(str));
|
|
printf("\t%s\t$%02X", DB, toupper(*str++) | (len ? 0x80 : 0x00));
|
|
while (len--)
|
|
printf(",$%02X", toupper(*str++) | (len ? 0x80 : 0x00));
|
|
printf("\n");
|
|
}
|
|
}
|
|
void emit_flags(int flags)
|
|
{
|
|
outflags = flags;
|
|
if (outflags & ACME)
|
|
{
|
|
DB = "!BYTE";
|
|
DW = "!WORD";
|
|
DS = "!FILL";
|
|
LBL = ' ';
|
|
}
|
|
}
|
|
void emit_header(void)
|
|
{
|
|
if (outflags & ACME)
|
|
printf("; ACME COMPATIBLE OUTPUT\n");
|
|
else
|
|
printf("; CA65 COMPATIBLE OUTPUT\n");
|
|
if (outflags & MODULE)
|
|
{
|
|
printf("\t%s\t_SEGEND-_SEGBEGIN\t; LENGTH OF HEADER + CODE/DATA + BYTECODE SEGMENT\n", DW);
|
|
printf("_SEGBEGIN%c\n", LBL);
|
|
printf("\t%s\t$DA7E\t\t\t; MAGIC #\n", DW);
|
|
printf("\t%s\t_SYSFLAGS\t\t\t; SYSTEM FLAGS\n", DW);
|
|
printf("\t%s\t_SUBSEG\t\t\t; BYTECODE SUB-SEGMENT\n", DW);
|
|
printf("\t%s\t_DEFCNT\t\t\t; BYTECODE DEF COUNT\n", DW);
|
|
printf("\t%s\t_INIT\t\t\t; MODULE INITIALIZATION ROUTINE\n", DW);
|
|
}
|
|
else
|
|
{
|
|
printf("\tJMP\t_INIT\t\t\t; MODULE INITIALIZATION ROUTINE\n");
|
|
}
|
|
}
|
|
void emit_rld(void)
|
|
{
|
|
int i;
|
|
|
|
printf(";\n; RE-LOCATEABLE DICTIONARY\n;\n");
|
|
/*
|
|
* First emit the bytecode definition entrypoint information.
|
|
*/
|
|
for (i = 0; i < globals; i++)
|
|
if (!(idglobal_type[i] & EXTERN_TYPE) && (idglobal_type[i] & DEF_TYPE))
|
|
{
|
|
printf("\t%s\t$02\t\t\t; CODE TABLE FIXUP\n", DB);
|
|
printf("\t%s\t_C%03d\t\t\n", DW, idglobal_tag[i]);
|
|
printf("\t%s\t$00\n", DB);
|
|
}
|
|
/*
|
|
* Now emit the fixup table.
|
|
*/
|
|
for (i = 0; i < fixups; i++)
|
|
{
|
|
if (fixup_type[i] & EXTERN_TYPE)
|
|
{
|
|
printf("\t%s\t$%02X\t\t\t; EXTERNAL FIXUP\n", DB, 0x11 + fixup_size[i] & 0xFF);
|
|
printf("\t%s\t_F%03d-_SEGBEGIN\t\t\n", DW, i);
|
|
printf("\t%s\t%d\t\t\t; ESD INDEX\n", DB, fixup_tag[i]);
|
|
}
|
|
else
|
|
{
|
|
printf("\t%s\t$%02X\t\t\t; INTERNAL FIXUP\n", DB, 0x01 + fixup_size[i] & 0xFF);
|
|
printf("\t%s\t_F%03d-_SEGBEGIN\t\t\n", DW, i);
|
|
printf("\t%s\t$00\n", DB);
|
|
}
|
|
}
|
|
printf("\t%s\t$00\t\t\t; END OF RLD\n", DB);
|
|
}
|
|
void emit_esd(void)
|
|
{
|
|
int i;
|
|
|
|
printf(";\n; EXTERNAL/ENTRY SYMBOL DICTIONARY\n;\n");
|
|
for (i = 0; i < globals; i++)
|
|
{
|
|
if (idglobal_type[i] & EXTERN_TYPE)
|
|
{
|
|
emit_dci(&idglobal_name[i][1], idglobal_name[i][0]);
|
|
printf("\t%s\t$10\t\t\t; EXTERNAL SYMBOL FLAG\n", DB);
|
|
printf("\t%s\t%d\t\t\t; ESD INDEX\n", DW, idglobal_tag[i]);
|
|
}
|
|
else if (idglobal_type[i] & EXPORT_TYPE)
|
|
{
|
|
emit_dci(&idglobal_name[i][1], idglobal_name[i][0]);
|
|
printf("\t%s\t$08\t\t\t; ENTRY SYMBOL FLAG\n", DB);
|
|
printf("\t%s\t%s\t\t\n", DW, tag_string(idglobal_tag[i], idglobal_type[i]));
|
|
}
|
|
}
|
|
printf("\t%s\t$00\t\t\t; END OF ESD\n", DB);
|
|
}
|
|
void emit_trailer(void)
|
|
{
|
|
if (!(outflags & BYTECODE_SEG))
|
|
emit_bytecode_seg();
|
|
if (!(outflags & INIT))
|
|
printf("_INIT\t=\t0\n");
|
|
if (!(outflags & SYSFLAGS))
|
|
printf("_SYSFLAGS\t=\t0\n");
|
|
if (outflags & MODULE)
|
|
{
|
|
printf("_DEFCNT\t=\t%d\n", defs);
|
|
printf("_SEGEND%c\n", LBL);
|
|
emit_rld();
|
|
emit_esd();
|
|
}
|
|
}
|
|
void emit_moddep(char *name, int len)
|
|
{
|
|
if (name)
|
|
emit_dci(name, len);
|
|
else
|
|
printf("\t%s\t$00\t\t\t; END OF MODULE DEPENDENCIES\n", DB);
|
|
}
|
|
void emit_sysflags(int val)
|
|
{
|
|
printf("_SYSFLAGS\t=\t$%04X\t\t; SYSTEM FLAGS\n", val);
|
|
outflags |= SYSFLAGS;
|
|
}
|
|
void emit_bytecode_seg(void)
|
|
{
|
|
if ((outflags & MODULE) && !(outflags & BYTECODE_SEG))
|
|
printf("_SUBSEG%c\t\t\t\t; BYTECODE STARTS\n", LBL);
|
|
outflags |= BYTECODE_SEG;
|
|
}
|
|
void emit_comment(char *s)
|
|
{
|
|
printf("\t\t\t\t\t; %s\n", s);
|
|
}
|
|
void emit_asm(char *s)
|
|
{
|
|
printf("%s\n", s);
|
|
}
|
|
void emit_idlocal(char *name, int value)
|
|
{
|
|
printf("\t\t\t\t\t; %s -> [%d]\n", name, value);
|
|
}
|
|
void emit_idglobal(int tag, int size, char *name)
|
|
{
|
|
if (size == 0)
|
|
printf("_D%03d%c\t\t\t\t\t; %s\n", tag, LBL, name);
|
|
else
|
|
printf("_D%03d%c\t%s\t%d\t\t\t; %s\n", tag, LBL, DS, size, name);
|
|
}
|
|
void emit_idfunc(int tag, int type, char *name)
|
|
{
|
|
printf("%s%c\t\t\t\t\t; %s()\n", tag_string(tag, type), LBL, name);
|
|
}
|
|
void emit_idconst(char *name, int value)
|
|
{
|
|
printf("\t\t\t\t\t; %s = %d\n", name, value);
|
|
}
|
|
int emit_data(int vartype, int consttype, long constval, int constsize)
|
|
{
|
|
int datasize, i;
|
|
char *str;
|
|
if (consttype == 0)
|
|
{
|
|
datasize = constsize;
|
|
printf("\t%s\t$%02X\n", DS, constsize);
|
|
}
|
|
else if (consttype & STRING_TYPE)
|
|
{
|
|
datasize = constsize;
|
|
str = (char *)constval;
|
|
printf("\t%s\t$%02X\n", DB, --constsize);
|
|
while (constsize-- > 0)
|
|
{
|
|
printf("\t%s\t$%02X", DB, *str++);
|
|
for (i = 0; i < 7; i++)
|
|
{
|
|
if (constsize-- > 0)
|
|
printf(",$%02X", *str++);
|
|
else
|
|
break;
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
else if (consttype & ADDR_TYPE)
|
|
{
|
|
if (vartype & WORD_TYPE)
|
|
{
|
|
int fixup = fixup_new(constval, consttype, FIXUP_WORD);
|
|
datasize = 2;
|
|
if (consttype & EXTERN_TYPE)
|
|
printf("_F%03d%c\t%s\t0\t\t\t; %s\n", fixup, LBL, DW, tag_string(constval, consttype));
|
|
else
|
|
printf("_F%03d%c\t%s\t%s\n", fixup, LBL, DW, tag_string(constval, consttype));
|
|
}
|
|
else
|
|
{
|
|
int fixup = fixup_new(constval, consttype, FIXUP_BYTE);
|
|
datasize = 1;
|
|
if (consttype & EXTERN_TYPE)
|
|
printf("_F%03d%c\t%s\t0\t\t\t; %s\n", fixup, LBL, DB, tag_string(constval, consttype));
|
|
else
|
|
printf("_F%03d%c\t%s\t%s\n", fixup, LBL, DB, tag_string(constval, consttype));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (vartype & WORD_TYPE)
|
|
{
|
|
datasize = 2;
|
|
printf("\t%s\t$%04lX\n", DW, constval & 0xFFFF);
|
|
}
|
|
else
|
|
{
|
|
datasize = 1;
|
|
printf("\t%s\t$%02lX\n", DB, constval & 0xFF);
|
|
}
|
|
}
|
|
return (datasize);
|
|
}
|
|
void emit_def(char *name, int is_bytecode)
|
|
{
|
|
if (!(outflags & MODULE))
|
|
{
|
|
//printf("%s%c\n", name, LBL);
|
|
if (is_bytecode)
|
|
printf("\tJSR\tINTERP\n");
|
|
}
|
|
}
|
|
void emit_codetag(int tag)
|
|
{
|
|
printf("_B%03d%c\n", tag, LBL);
|
|
}
|
|
void emit_const(int cval)
|
|
{
|
|
if (cval == 0)
|
|
printf("\t%s\t$00\t\t\t; ZERO\n", DB);
|
|
else if (cval > 0 && cval < 256)
|
|
printf("\t%s\t$2A,$%02X\t\t\t; CB\t%d\n", DB, cval, cval);
|
|
else
|
|
printf("\t%s\t$2C,$%02X,$%02X\t\t; CW\t%d\n", DB, cval&0xFF,(cval>>8)&0xFF, cval);
|
|
}
|
|
void emit_lb(void)
|
|
{
|
|
printf("\t%s\t$60\t\t\t; LB\n", DB);
|
|
}
|
|
void emit_lw(void)
|
|
{
|
|
printf("\t%s\t$62\t\t\t; LW\n", DB);
|
|
}
|
|
void emit_llb(int index)
|
|
{
|
|
printf("\t%s\t$64,$%02X\t\t\t; LLB\t[%d]\n", DB, index, index);
|
|
}
|
|
void emit_llw(int index)
|
|
{
|
|
printf("\t%s\t$66,$%02X\t\t\t; LLW\t[%d]\n", DB, index, index);
|
|
}
|
|
void emit_lab(int tag, int offset, int type)
|
|
{
|
|
int fixup = fixup_new(tag, type, FIXUP_WORD);
|
|
char *taglbl = tag_string(tag, type);
|
|
printf("\t%s\t$68\t\t\t; LAB\t%s+%d\n", DB, taglbl, offset);
|
|
printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl, offset);
|
|
}
|
|
void emit_law(int tag, int offset, int type)
|
|
{
|
|
int fixup = fixup_new(tag, type, FIXUP_WORD);
|
|
char *taglbl = tag_string(tag, type);
|
|
printf("\t%s\t$6A\t\t\t; LAW\t%s+%d\n", DB, taglbl, offset);
|
|
printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl, offset);
|
|
}
|
|
void emit_sb(void)
|
|
{
|
|
printf("\t%s\t$70\t\t\t; SB\n", DB);
|
|
}
|
|
void emit_sw(void)
|
|
{
|
|
printf("\t%s\t$72\t\t\t; SW\n", DB);
|
|
}
|
|
void emit_slb(int index)
|
|
{
|
|
printf("\t%s\t$74,$%02X\t\t\t; SLB\t[%d]\n", DB, index, index);
|
|
}
|
|
void emit_slw(int index)
|
|
{
|
|
printf("\t%s\t$76,$%02X\t\t\t; SLW\t[%d]\n", DB, index, index);
|
|
}
|
|
void emit_dlb(int index)
|
|
{
|
|
printf("\t%s\t$6C,$%02X\t\t\t; DLB\t[%d]\n", DB, index, index);
|
|
}
|
|
void emit_dlw(int index)
|
|
{
|
|
printf("\t%s\t$6E,$%02X\t\t\t; DLW\t[%d]\n", DB, index, index);
|
|
}
|
|
void emit_sab(int tag, int offset, int type)
|
|
{
|
|
int fixup = fixup_new(tag, type, FIXUP_WORD);
|
|
char *taglbl = tag_string(tag, type);
|
|
printf("\t%s\t$78\t\t\t; SAB\t%s+%d\n", DB, taglbl, offset);
|
|
printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl, offset);
|
|
}
|
|
void emit_saw(int tag, int offset, int type)
|
|
{
|
|
int fixup = fixup_new(tag, type, FIXUP_WORD);
|
|
char *taglbl = tag_string(tag, type);
|
|
printf("\t%s\t$7A\t\t\t; SAW\t%s+%d\n", DB, taglbl, offset);
|
|
printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl, offset);
|
|
}
|
|
void emit_dab(int tag, int type)
|
|
{
|
|
int fixup = fixup_new(tag, type, FIXUP_WORD);
|
|
char *taglbl = tag_string(tag, type);
|
|
printf("\t%s\t$7C\t\t\t; DAB\t%s\n", DB, taglbl);
|
|
printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl);
|
|
}
|
|
void emit_daw(int tag, int type)
|
|
{
|
|
int fixup = fixup_new(tag, type, FIXUP_WORD);
|
|
char *taglbl = tag_string(tag, type);
|
|
printf("\t%s\t$7E\t\t\t; DAW\t%s\n", DB, taglbl);
|
|
printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl);
|
|
}
|
|
void emit_localaddr(int index)
|
|
{
|
|
printf("\t%s\t$28,$%02X\t\t\t; LLA\t[%d]\n", DB, index, index);
|
|
}
|
|
void emit_globaladdr(int tag, int offset, int type)
|
|
{
|
|
int fixup = fixup_new(tag, type, FIXUP_WORD);
|
|
char *taglbl = tag_string(tag, type);
|
|
printf("\t%s\t$26\t\t\t; LA\t%s+%d\n", DB, taglbl, offset);
|
|
printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "" : taglbl, offset);
|
|
}
|
|
void emit_indexbyte(void)
|
|
{
|
|
printf("\t%s\t$02\t\t\t; IDXB\n", DB);
|
|
}
|
|
void emit_indexword(void)
|
|
{
|
|
printf("\t%s\t$1E\t\t\t; IDXW\n", DB);
|
|
}
|
|
void emit_brfls(int tag)
|
|
{
|
|
printf("\t%s\t$4C\t\t\t; BRFLS\t_B%03d\n", DB, tag);
|
|
printf("\t%s\t_B%03d-*\n", DW, tag);
|
|
}
|
|
void emit_brtru(int tag)
|
|
{
|
|
printf("\t%s\t$4E\t\t\t; BRTRU\t_B%03d\n", DB, tag);
|
|
printf("\t%s\t_B%03d-*\n", DW, tag);
|
|
}
|
|
void emit_brnch(int tag)
|
|
{
|
|
printf("\t%s\t$50\t\t\t; BRNCH\t_B%03d\n", DB, tag);
|
|
printf("\t%s\t_B%03d-*\n", DW, tag);
|
|
}
|
|
void emit_breq(int tag)
|
|
{
|
|
printf("\t%s\t$3C\t\t\t; BREQ\t_B%03d\n", DB, tag);
|
|
printf("\t%s\t_B%03d-*\n", DW, tag);
|
|
}
|
|
void emit_brne(int tag)
|
|
{
|
|
printf("\t%s\t$3E\t\t\t; BRNE\t_B%03d\n", DB, tag);
|
|
printf("\t%s\t_B%03d-*\n", DW, tag);
|
|
}
|
|
void emit_brgt(int tag)
|
|
{
|
|
printf("\t%s\t$38\t\t\t; BRGT\t_B%03d\n", DB, tag);
|
|
printf("\t%s\t_B%03d-*\n", DW, tag);
|
|
}
|
|
void emit_brlt(int tag)
|
|
{
|
|
printf("\t%s\t$3A\t\t\t; BRLT\t_B%03d\n", DB, tag);
|
|
printf("\t%s\t_B%03d-*\n", DW, tag);
|
|
}
|
|
void emit_call(int tag, int type)
|
|
{
|
|
int fixup = fixup_new(tag, type, FIXUP_WORD);
|
|
char *taglbl = tag_string(tag, type);
|
|
printf("\t%s\t$54\t\t\t; CALL\t%s\n", DB, taglbl);
|
|
printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl);
|
|
}
|
|
void emit_ical(void)
|
|
{
|
|
printf("\t%s\t$56\t\t\t; ICAL\n", DB);
|
|
}
|
|
void emit_leave(int framesize)
|
|
{
|
|
if (framesize > 2)
|
|
printf("\t%s\t$5A\t\t\t; LEAVE\n", DB);
|
|
else
|
|
printf("\t%s\t$5C\t\t\t; RET\n", DB);
|
|
}
|
|
void emit_ret(void)
|
|
{
|
|
printf("\t%s\t$5C\t\t\t; RET\n", DB);
|
|
}
|
|
void emit_enter(int framesize, int cparams)
|
|
{
|
|
if (framesize > 2)
|
|
printf("\t%s\t$58,$%02X,$%02X\t\t; ENTER\t%d,%d\n", DB, framesize, cparams, framesize, cparams);
|
|
}
|
|
void emit_start(void)
|
|
{
|
|
printf("_INIT%c\n", LBL);
|
|
outflags |= INIT;
|
|
defs++;
|
|
}
|
|
void emit_dup(void)
|
|
{
|
|
printf("\t%s\t$32\t\t\t; DUP\n", DB);
|
|
}
|
|
void emit_push(void)
|
|
{
|
|
printf("\t%s\t$34\t\t\t; PUSH\n", DB);
|
|
}
|
|
void emit_pull(void)
|
|
{
|
|
printf("\t%s\t$36\t\t\t; PULL\n", DB);
|
|
}
|
|
void emit_swap(void)
|
|
{
|
|
printf("\t%s\t$2E\t\t\t; SWAP\n", DB);
|
|
}
|
|
void emit_drop(void)
|
|
{
|
|
printf("\t%s\t$30\t\t\t; DROP\n", DB);
|
|
}
|
|
int emit_unaryop(int op)
|
|
{
|
|
switch (op)
|
|
{
|
|
case NEG_TOKEN:
|
|
printf("\t%s\t$10\t\t\t; NEG\n", DB);
|
|
break;
|
|
case COMP_TOKEN:
|
|
printf("\t%s\t$12\t\t\t; COMP\n", DB);
|
|
break;
|
|
case LOGIC_NOT_TOKEN:
|
|
printf("\t%s\t$20\t\t\t; NOT\n", DB);
|
|
break;
|
|
case INC_TOKEN:
|
|
printf("\t%s\t$0C\t\t\t; INCR\n", DB);
|
|
break;
|
|
case DEC_TOKEN:
|
|
printf("\t%s\t$0E\t\t\t; DECR\n", DB);
|
|
break;
|
|
case BPTR_TOKEN:
|
|
emit_lb();
|
|
break;
|
|
case WPTR_TOKEN:
|
|
emit_lw();
|
|
break;
|
|
default:
|
|
printf("emit_unaryop(%c) ???\n", op & 0x7F);
|
|
return (0);
|
|
}
|
|
return (1);
|
|
}
|
|
int emit_op(t_token op)
|
|
{
|
|
switch (op)
|
|
{
|
|
case MUL_TOKEN:
|
|
printf("\t%s\t$06\t\t\t; MUL\n", DB);
|
|
break;
|
|
case DIV_TOKEN:
|
|
printf("\t%s\t$08\t\t\t; DIV\n", DB);
|
|
break;
|
|
case MOD_TOKEN:
|
|
printf("\t%s\t$0A\t\t\t; MOD\n", DB);
|
|
break;
|
|
case ADD_TOKEN:
|
|
printf("\t%s\t$02\t\t\t; ADD\n", DB);
|
|
break;
|
|
case SUB_TOKEN:
|
|
printf("\t%s\t$04\t\t\t; SUB\n", DB);
|
|
break;
|
|
case SHL_TOKEN:
|
|
printf("\t%s\t$1A\t\t\t; SHL\n", DB);
|
|
break;
|
|
case SHR_TOKEN:
|
|
printf("\t%s\t$1C\t\t\t; SHR\n", DB);
|
|
break;
|
|
case AND_TOKEN:
|
|
printf("\t%s\t$14\t\t\t; AND\n", DB);
|
|
break;
|
|
case OR_TOKEN:
|
|
printf("\t%s\t$16\t\t\t; IOR\n", DB);
|
|
break;
|
|
case EOR_TOKEN:
|
|
printf("\t%s\t$18\t\t\t; XOR\n", DB);
|
|
break;
|
|
case EQ_TOKEN:
|
|
printf("\t%s\t$40\t\t\t; ISEQ\n", DB);
|
|
break;
|
|
case NE_TOKEN:
|
|
printf("\t%s\t$42\t\t\t; ISNE\n", DB);
|
|
break;
|
|
case GE_TOKEN:
|
|
printf("\t%s\t$48\t\t\t; ISGE\n", DB);
|
|
break;
|
|
case LT_TOKEN:
|
|
printf("\t%s\t$46\t\t\t; ISLT\n", DB);
|
|
break;
|
|
case GT_TOKEN:
|
|
printf("\t%s\t$44\t\t\t; ISGT\n", DB);
|
|
break;
|
|
case LE_TOKEN:
|
|
printf("\t%s\t$4A\t\t\t; ISLE\n", DB);
|
|
break;
|
|
case LOGIC_OR_TOKEN:
|
|
printf("\t%s\t$22\t\t\t; LOR\n", DB);
|
|
break;
|
|
case LOGIC_AND_TOKEN:
|
|
printf("\t%s\t$24\t\t\t; LAND\n", DB);
|
|
break;
|
|
case COMMA_TOKEN:
|
|
break;
|
|
default:
|
|
return (0);
|
|
}
|
|
return (1);
|
|
}
|