mirror of
https://github.com/badvision/lawless-legends.git
synced 2025-02-20 21:29:13 +00:00
Merge branch 'master' of https://github.com/badvision/lawless-legends
This commit is contained in:
commit
7a43bf0d95
Binary file not shown.
@ -1,13 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "tokens.h"
|
||||
#include "lex.h"
|
||||
#include "symbols.h"
|
||||
#include "codegen.h"
|
||||
#include "plasm.h"
|
||||
/*
|
||||
* Symbol table and fixup information.
|
||||
*/
|
||||
#define ID_LEN 32
|
||||
#define ID_LEN 32
|
||||
static int consts = 0;
|
||||
static int externs = 0;
|
||||
static int globals = 0;
|
||||
@ -29,8 +36,10 @@ 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
|
||||
static t_opseq optbl[256];
|
||||
static t_opseq *freeop_lst = &optbl[0];
|
||||
#define FIXUP_BYTE 0x00
|
||||
#define FIXUP_WORD 0x80
|
||||
int id_match(char *name, int len, char *id)
|
||||
{
|
||||
if (len == id[0])
|
||||
@ -147,13 +156,13 @@ int idglobal_add(char *name, int len, int type, int size)
|
||||
if (!(type & EXTERN_TYPE))
|
||||
{
|
||||
emit_idglobal(globals, size, name);
|
||||
idglobal_tag[globals] = globals;
|
||||
globals++;
|
||||
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++;
|
||||
idglobal_tag[globals++] = externs++;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
@ -161,6 +170,11 @@ 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));
|
||||
}
|
||||
void idlocal_reset(void)
|
||||
{
|
||||
locals = 0;
|
||||
localsize = 0;
|
||||
}
|
||||
int idfunc_add(char *name, int len, int type, int tag)
|
||||
{
|
||||
if (globals > 1024)
|
||||
@ -254,14 +268,10 @@ int fixup_new(int tag, int type, int size)
|
||||
/*
|
||||
* 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 = ':';
|
||||
static const char *DB = ".BYTE";
|
||||
static const char *DW = ".WORD";
|
||||
static const char *DS = ".RES";
|
||||
static char LBL = (char) ':';
|
||||
char *supper(char *s)
|
||||
{
|
||||
static char su[80];
|
||||
@ -304,8 +314,7 @@ void emit_dci(char *str, int len)
|
||||
}
|
||||
void emit_flags(int flags)
|
||||
{
|
||||
outflags = flags;
|
||||
if (outflags & ACME)
|
||||
if (flags & ACME)
|
||||
{
|
||||
DB = "!BYTE";
|
||||
DW = "!WORD";
|
||||
@ -315,6 +324,8 @@ void emit_flags(int flags)
|
||||
}
|
||||
void emit_header(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (outflags & ACME)
|
||||
printf("; ACME COMPATIBLE OUTPUT\n");
|
||||
else
|
||||
@ -323,7 +334,7 @@ void emit_header(void)
|
||||
{
|
||||
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$DA7F\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);
|
||||
@ -333,6 +344,12 @@ void emit_header(void)
|
||||
{
|
||||
printf("\tJMP\t_INIT\t\t\t; MODULE INITIALIZATION ROUTINE\n");
|
||||
}
|
||||
/*
|
||||
* Init free op sequence table
|
||||
*/
|
||||
for (i = 0; i < sizeof(optbl)/sizeof(t_opseq)-1; i++)
|
||||
optbl[i].nextop = &optbl[i+1];
|
||||
optbl[i].nextop = NULL;
|
||||
}
|
||||
void emit_rld(void)
|
||||
{
|
||||
@ -447,9 +464,16 @@ void emit_idglobal(int tag, int size, char *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)
|
||||
void emit_idfunc(int tag, int type, char *name, int is_bytecode)
|
||||
{
|
||||
printf("%s%c\t\t\t\t\t; %s()\n", tag_string(tag, type), LBL, name);
|
||||
if (name)
|
||||
printf("%s%c\t\t\t\t\t; %s()\n", tag_string(tag, type), LBL, name);
|
||||
if (!(outflags & MODULE))
|
||||
{
|
||||
//printf("%s%c\n", name, LBL);
|
||||
if (is_bytecode)
|
||||
printf("\tJSR\tINTERP\n");
|
||||
}
|
||||
}
|
||||
void emit_idconst(char *name, int value)
|
||||
{
|
||||
@ -518,17 +542,6 @@ int emit_data(int vartype, int consttype, long constval, int constsize)
|
||||
}
|
||||
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");
|
||||
}
|
||||
locals = 0;
|
||||
localsize = 0;
|
||||
}
|
||||
void emit_codetag(int tag)
|
||||
{
|
||||
printf("_B%03d%c\n", tag, LBL);
|
||||
@ -565,17 +578,31 @@ void emit_llw(int 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);
|
||||
if (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);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\t%s\t$68,$%02X,$%02X\t\t; LAB\t%d\n", DB, offset&0xFF,(offset>>8)&0xFF, 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);
|
||||
if (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);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\t%s\t$6A,$%02X,$%02X\t\t; LAW\t%d\n", DB, offset&0xFF,(offset>>8)&0xFF, offset);
|
||||
}
|
||||
}
|
||||
void emit_sb(void)
|
||||
{
|
||||
@ -603,31 +630,45 @@ void emit_dlw(int 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);
|
||||
if (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);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\t%s\t$78,$%02X,$%02X\t\t; SAB\t%d\n", DB, offset&0xFF,(offset>>8)&0xFF, offset);
|
||||
}
|
||||
}
|
||||
void emit_saw(int tag, int offset, int type)
|
||||
{
|
||||
if (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);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\t%s\t$7A,$%02X,$%02X\t\t; SAW\t%d\n", DB, offset&0xFF,(offset>>8)&0xFF, offset);
|
||||
}
|
||||
}
|
||||
void emit_dab(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("\t%s\t$7C\t\t\t; DAB\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)
|
||||
void emit_daw(int tag, int offset, 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);
|
||||
printf("\t%s\t$7E\t\t\t; DAW\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_localaddr(int index)
|
||||
{
|
||||
@ -724,27 +765,23 @@ void emit_start(void)
|
||||
outflags |= INIT;
|
||||
defs++;
|
||||
}
|
||||
void emit_dup(void)
|
||||
void emit_push_exp(void)
|
||||
{
|
||||
printf("\t%s\t$32\t\t\t; DUP\n", DB);
|
||||
printf("\t%s\t$34\t\t\t; PUSH EXP\n", DB);
|
||||
}
|
||||
void emit_push(void)
|
||||
void emit_pull_exp(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);
|
||||
printf("\t%s\t$36\t\t\t; PULL EXP\n", DB);
|
||||
}
|
||||
void emit_drop(void)
|
||||
{
|
||||
printf("\t%s\t$30\t\t\t; DROP\n", DB);
|
||||
}
|
||||
int emit_unaryop(int op)
|
||||
void emit_dup(void)
|
||||
{
|
||||
printf("\t%s\t$32\t\t\t; DUP\n", DB);
|
||||
}
|
||||
int emit_unaryop(t_token op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
@ -840,3 +877,482 @@ int emit_op(t_token op)
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
/*
|
||||
* New/release sequence ops
|
||||
*/
|
||||
t_opseq *new_op(void)
|
||||
{
|
||||
t_opseq* op = freeop_lst;
|
||||
if (!op)
|
||||
{
|
||||
fprintf(stderr, "Compiler out of sequence ops!\n");
|
||||
return (NULL);
|
||||
}
|
||||
freeop_lst = freeop_lst->nextop;
|
||||
op->nextop = NULL;
|
||||
return (op);
|
||||
}
|
||||
void release_op(t_opseq *op)
|
||||
{
|
||||
if (op)
|
||||
{
|
||||
op->nextop = freeop_lst;
|
||||
freeop_lst = op;
|
||||
}
|
||||
}
|
||||
void release_seq(t_opseq *seq)
|
||||
{
|
||||
t_opseq *op;
|
||||
while (seq)
|
||||
{
|
||||
op = seq;
|
||||
seq = seq->nextop;
|
||||
/*
|
||||
* Free this op
|
||||
*/
|
||||
op->nextop = freeop_lst;
|
||||
freeop_lst = op;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Crunch sequence (peephole optimize)
|
||||
*/
|
||||
int crunch_seq(t_opseq *seq)
|
||||
{
|
||||
t_opseq *opnext, *opnextnext;
|
||||
t_opseq *op = seq;
|
||||
int crunched = 0;
|
||||
int freeops = 0;
|
||||
int shiftcnt;
|
||||
|
||||
while (op && (opnext = op->nextop))
|
||||
{
|
||||
switch (op->code)
|
||||
{
|
||||
case CONST_CODE:
|
||||
if (op->val == 1)
|
||||
{
|
||||
if (opnext->code == BINARY_CODE(ADD_TOKEN))
|
||||
{
|
||||
op->code = INC_CODE;
|
||||
freeops = 1;
|
||||
break;
|
||||
}
|
||||
if (opnext->code == BINARY_CODE(SUB_TOKEN))
|
||||
{
|
||||
op->code = DEC_CODE;
|
||||
freeops = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (opnext->code)
|
||||
{
|
||||
case NEG_CODE:
|
||||
op->val = -(op->val);
|
||||
freeops = 1;
|
||||
break;
|
||||
case COMP_CODE:
|
||||
op->val = ~(op->val);
|
||||
freeops = 1;
|
||||
break;
|
||||
case LOGIC_NOT_CODE:
|
||||
op->val = op->val ? 0 : 1;
|
||||
freeops = 1;
|
||||
break;
|
||||
case UNARY_CODE(BPTR_TOKEN):
|
||||
case LB_CODE:
|
||||
op->offsz = op->val;
|
||||
op->code = LAB_CODE;
|
||||
freeops = 1;
|
||||
break;
|
||||
case UNARY_CODE(WPTR_TOKEN):
|
||||
case LW_CODE:
|
||||
op->offsz = op->val;
|
||||
op->code = LAW_CODE;
|
||||
freeops = 1;
|
||||
break;
|
||||
case SB_CODE:
|
||||
op->offsz = op->val;
|
||||
op->code = SAB_CODE;
|
||||
freeops = 1;
|
||||
break;
|
||||
case SW_CODE:
|
||||
op->offsz = op->val;
|
||||
op->code = SAW_CODE;
|
||||
freeops = 1;
|
||||
break;
|
||||
case BINARY_CODE(MUL_TOKEN):
|
||||
for (shiftcnt = 0; shiftcnt < 16; shiftcnt++)
|
||||
{
|
||||
if (op->val == (1 << shiftcnt))
|
||||
{
|
||||
op->val = shiftcnt;
|
||||
opnext->code = BINARY_CODE(SHL_TOKEN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BINARY_CODE(DIV_TOKEN):
|
||||
for (shiftcnt = 0; shiftcnt < 16; shiftcnt++)
|
||||
{
|
||||
if (op->val == (1 << shiftcnt))
|
||||
{
|
||||
op->val = shiftcnt;
|
||||
opnext->code = BINARY_CODE(SHR_TOKEN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CONST_CODE: // Collapse constant operation
|
||||
if ((opnextnext = opnext->nextop))
|
||||
switch (opnextnext->code)
|
||||
{
|
||||
case BINARY_CODE(MUL_TOKEN):
|
||||
op->val *= opnext->val;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(DIV_TOKEN):
|
||||
op->val /= opnext->val;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(MOD_TOKEN):
|
||||
op->val %= opnext->val;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(ADD_TOKEN):
|
||||
op->val += opnext->val;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(SUB_TOKEN):
|
||||
op->val -= opnext->val;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(SHL_TOKEN):
|
||||
op->val <<= opnext->val;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(SHR_TOKEN):
|
||||
op->val >>= opnext->val;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(AND_TOKEN):
|
||||
op->val &= opnext->val;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(OR_TOKEN):
|
||||
op->val |= opnext->val;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(EOR_TOKEN):
|
||||
op->val ^= opnext->val;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(EQ_TOKEN):
|
||||
op->val = op->val == opnext->val ? 1 : 0;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(NE_TOKEN):
|
||||
op->val = op->val != opnext->val ? 1 : 0;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(GE_TOKEN):
|
||||
op->val = op->val >= opnext->val ? 1 : 0;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(LT_TOKEN):
|
||||
op->val = op->val < opnext->val ? 1 : 0;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(GT_TOKEN):
|
||||
op->val = op->val > opnext->val ? 1 : 0;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(LE_TOKEN):
|
||||
op->val = op->val <= opnext->val ? 1 : 0;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(LOGIC_OR_TOKEN):
|
||||
op->val = op->val || opnext->val ? 1 : 0;
|
||||
freeops = 2;
|
||||
break;
|
||||
case BINARY_CODE(LOGIC_AND_TOKEN):
|
||||
op->val = op->val && opnext->val ? 1 : 0;
|
||||
freeops = 2;
|
||||
break;
|
||||
}
|
||||
break; // CONST_CODE
|
||||
}
|
||||
break; // CONST_CODE
|
||||
case LADDR_CODE:
|
||||
switch (opnext->code)
|
||||
{
|
||||
case CONST_CODE:
|
||||
if ((opnextnext = opnext->nextop))
|
||||
switch (opnextnext->code)
|
||||
{
|
||||
case ADD_CODE:
|
||||
case INDEXB_CODE:
|
||||
op->offsz += opnext->val;
|
||||
freeops = 2;
|
||||
break;
|
||||
case INDEXW_CODE:
|
||||
op->offsz += opnext->val * 2;
|
||||
freeops = 2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case LB_CODE:
|
||||
op->code = LLB_CODE;
|
||||
freeops = 1;
|
||||
break;
|
||||
case LW_CODE:
|
||||
op->code = LLW_CODE;
|
||||
freeops = 1;
|
||||
break;
|
||||
case SB_CODE:
|
||||
op->code = SLB_CODE;
|
||||
freeops = 1;
|
||||
break;
|
||||
case SW_CODE:
|
||||
op->code = SLW_CODE;
|
||||
freeops = 1;
|
||||
break;
|
||||
}
|
||||
break; // LADDR_CODE
|
||||
case GADDR_CODE:
|
||||
switch (opnext->code)
|
||||
{
|
||||
case CONST_CODE:
|
||||
if ((opnextnext = opnext->nextop))
|
||||
switch (opnextnext->code)
|
||||
{
|
||||
case ADD_CODE:
|
||||
case INDEXB_CODE:
|
||||
op->offsz += opnext->val;
|
||||
freeops = 2;
|
||||
break;
|
||||
case INDEXW_CODE:
|
||||
op->offsz += opnext->val * 2;
|
||||
freeops = 2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case LB_CODE:
|
||||
op->code = LAB_CODE;
|
||||
freeops = 1;
|
||||
break;
|
||||
case LW_CODE:
|
||||
op->code = LAW_CODE;
|
||||
freeops = 1;
|
||||
break;
|
||||
case SB_CODE:
|
||||
op->code = SAB_CODE;
|
||||
freeops = 1;
|
||||
break;
|
||||
case SW_CODE:
|
||||
op->code = SAW_CODE;
|
||||
freeops = 1;
|
||||
break;
|
||||
case ICAL_CODE:
|
||||
op->code = CALL_CODE;
|
||||
freeops = 1;
|
||||
break;
|
||||
}
|
||||
break; // GADDR_CODE
|
||||
}
|
||||
//
|
||||
// Free up crunched ops
|
||||
//
|
||||
while (freeops)
|
||||
{
|
||||
op->nextop = opnext->nextop;
|
||||
opnext->nextop = freeop_lst;
|
||||
freeop_lst = opnext;
|
||||
opnext = op->nextop;
|
||||
crunched = 1;
|
||||
freeops--;
|
||||
}
|
||||
op = opnext;
|
||||
}
|
||||
return (crunched);
|
||||
}
|
||||
/*
|
||||
* Generate a sequence of code
|
||||
*/
|
||||
t_opseq *gen_seq(t_opseq *seq, int opcode, long cval, int tag, int offsz, int type)
|
||||
{
|
||||
t_opseq *op;
|
||||
|
||||
if (!seq)
|
||||
{
|
||||
op = seq = new_op();
|
||||
}
|
||||
else
|
||||
{
|
||||
op = seq;
|
||||
while (op->nextop)
|
||||
op = op->nextop;
|
||||
op->nextop = new_op();
|
||||
op = op->nextop;
|
||||
}
|
||||
op->code = opcode;
|
||||
op->val = cval;
|
||||
op->tag = tag;
|
||||
op->offsz = offsz;
|
||||
op->type = type;
|
||||
return (seq);
|
||||
}
|
||||
/*
|
||||
* Append one sequence to the end of another
|
||||
*/
|
||||
t_opseq *cat_seq(t_opseq *seq1, t_opseq *seq2)
|
||||
{
|
||||
t_opseq *op;
|
||||
|
||||
if (!seq1)
|
||||
return (seq2);
|
||||
for (op = seq1; op->nextop; op = op->nextop);
|
||||
op->nextop = seq2;
|
||||
return (seq1);
|
||||
}
|
||||
/*
|
||||
* Emit a sequence of ops
|
||||
*/
|
||||
int emit_seq(t_opseq *seq)
|
||||
{
|
||||
t_opseq *op;
|
||||
|
||||
if (!seq)
|
||||
return (0);
|
||||
if (outflags & OPTIMIZE)
|
||||
while (crunch_seq(seq));
|
||||
while (seq)
|
||||
{
|
||||
op = seq;
|
||||
switch (op->code)
|
||||
{
|
||||
case NEG_CODE:
|
||||
case COMP_CODE:
|
||||
case LOGIC_NOT_CODE:
|
||||
case INC_CODE:
|
||||
case DEC_CODE:
|
||||
case BPTR_CODE:
|
||||
case WPTR_CODE:
|
||||
emit_unaryop(op->code);
|
||||
break;
|
||||
case MUL_CODE:
|
||||
case DIV_CODE:
|
||||
case MOD_CODE:
|
||||
case ADD_CODE:
|
||||
case SUB_CODE:
|
||||
case SHL_CODE:
|
||||
case SHR_CODE:
|
||||
case AND_CODE:
|
||||
case OR_CODE:
|
||||
case EOR_CODE:
|
||||
case EQ_CODE:
|
||||
case NE_CODE:
|
||||
case GE_CODE:
|
||||
case LT_CODE:
|
||||
case GT_CODE:
|
||||
case LE_CODE:
|
||||
case LOGIC_OR_CODE:
|
||||
case LOGIC_AND_CODE:
|
||||
emit_op(op->code);
|
||||
break;
|
||||
case CONST_CODE:
|
||||
emit_const(op->val);
|
||||
break;
|
||||
case STR_CODE:
|
||||
emit_conststr(op->val, op->offsz);
|
||||
break;
|
||||
case LB_CODE:
|
||||
emit_lb();
|
||||
break;
|
||||
case LW_CODE:
|
||||
emit_lw();
|
||||
break;
|
||||
case LLB_CODE:
|
||||
emit_llb(op->offsz);
|
||||
break;
|
||||
case LLW_CODE:
|
||||
emit_llw(op->offsz);
|
||||
break;
|
||||
case LAB_CODE:
|
||||
emit_lab(op->tag, op->offsz, op->type);
|
||||
break;
|
||||
case LAW_CODE:
|
||||
emit_law(op->tag, op->offsz, op->type);
|
||||
break;
|
||||
case SB_CODE:
|
||||
emit_sb();
|
||||
break;
|
||||
case SW_CODE:
|
||||
emit_sw();
|
||||
break;
|
||||
case SLB_CODE:
|
||||
emit_slb(op->offsz);
|
||||
break;
|
||||
case SLW_CODE:
|
||||
emit_slw(op->offsz);
|
||||
break;
|
||||
case DLB_CODE:
|
||||
emit_dlb(op->offsz);
|
||||
break;
|
||||
case DLW_CODE:
|
||||
emit_dlw(op->offsz);
|
||||
break;
|
||||
case SAB_CODE:
|
||||
emit_sab(op->tag, op->offsz, op->type);
|
||||
break;
|
||||
case SAW_CODE:
|
||||
emit_saw(op->tag, op->offsz, op->type);
|
||||
break;
|
||||
case DAB_CODE:
|
||||
emit_dab(op->tag, op->offsz, op->type);
|
||||
break;
|
||||
case DAW_CODE:
|
||||
emit_daw(op->tag, op->offsz, op->type);
|
||||
break;
|
||||
case CALL_CODE:
|
||||
emit_call(op->tag, op->type);
|
||||
break;
|
||||
case ICAL_CODE:
|
||||
emit_ical();
|
||||
break;
|
||||
case LADDR_CODE:
|
||||
emit_localaddr(op->offsz);
|
||||
break;
|
||||
case GADDR_CODE:
|
||||
emit_globaladdr(op->tag, op->offsz, op->type);
|
||||
break;
|
||||
case INDEXB_CODE:
|
||||
emit_indexbyte();
|
||||
break;
|
||||
case INDEXW_CODE:
|
||||
emit_indexword();
|
||||
break;
|
||||
case DROP_CODE:
|
||||
emit_drop();
|
||||
break;
|
||||
case DUP_CODE:
|
||||
emit_dup();
|
||||
break;
|
||||
case PUSH_EXP_CODE:
|
||||
emit_push_exp();
|
||||
break;
|
||||
case PULL_EXP_CODE:
|
||||
emit_pull_exp();
|
||||
break;
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
seq = seq->nextop;
|
||||
/*
|
||||
* Free this op
|
||||
*/
|
||||
op->nextop = freeop_lst;
|
||||
freeop_lst = op;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
@ -1,15 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
||||
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
typedef struct _opseq {
|
||||
int code;
|
||||
long val;
|
||||
int tag;
|
||||
int offsz;
|
||||
int type;
|
||||
struct _opseq *nextop;
|
||||
} t_opseq;
|
||||
#define UNARY_CODE(tkn) ((tkn)|0x0100)
|
||||
#define BINARY_CODE(tkn) ((tkn)|0x0200)
|
||||
#define NEG_CODE 0x0100|NEG_TOKEN
|
||||
#define COMP_CODE 0x0100|COMP_TOKEN
|
||||
#define LOGIC_NOT_CODE 0x0100|LOGIC_NOT_TOKEN
|
||||
#define INC_CODE 0x0100|INC_TOKEN
|
||||
#define DEC_CODE 0x0100|DEC_TOKEN
|
||||
#define BPTR_CODE 0x0100|BPTR_TOKEN
|
||||
#define WPTR_CODE 0x0100|WPTR_TOKEN
|
||||
#define MUL_CODE 0x0200|MUL_TOKEN
|
||||
#define DIV_CODE 0x0200|DIV_TOKEN
|
||||
#define MOD_CODE 0x0200|MOD_TOKEN
|
||||
#define ADD_CODE 0x0200|ADD_TOKEN
|
||||
#define SUB_CODE 0x0200|SUB_TOKEN
|
||||
#define SHL_CODE 0x0200|SHL_TOKEN
|
||||
#define SHR_CODE 0x0200|SHR_TOKEN
|
||||
#define AND_CODE 0x0200|AND_TOKEN
|
||||
#define OR_CODE 0x0200|OR_TOKEN
|
||||
#define EOR_CODE 0x0200|EOR_TOKEN
|
||||
#define EQ_CODE 0x0200|EQ_TOKEN
|
||||
#define NE_CODE 0x0200|NE_TOKEN
|
||||
#define GE_CODE 0x0200|GE_TOKEN
|
||||
#define LT_CODE 0x0200|LT_TOKEN
|
||||
#define GT_CODE 0x0200|GT_TOKEN
|
||||
#define LE_CODE 0x0200|LE_TOKEN
|
||||
#define LOGIC_OR_CODE 0x0200|LOGIC_OR_TOKEN
|
||||
#define LOGIC_AND_CODE 0x0200|LOGIC_AND_TOKEN
|
||||
#define CONST_CODE 0x0300
|
||||
#define STR_CODE 0x0301
|
||||
#define LB_CODE 0x0302
|
||||
#define LW_CODE 0x0303
|
||||
#define LLB_CODE 0x0304
|
||||
#define LLW_CODE 0x0305
|
||||
#define LAB_CODE 0x0306
|
||||
#define LAW_CODE 0x0307
|
||||
#define SB_CODE 0x0308
|
||||
#define SW_CODE 0x0309
|
||||
#define SLB_CODE 0x030A
|
||||
#define SLW_CODE 0x030B
|
||||
#define DLB_CODE 0x030C
|
||||
#define DLW_CODE 0x030D
|
||||
#define SAB_CODE 0x030E
|
||||
#define SAW_CODE 0x030F
|
||||
#define DAB_CODE 0x0310
|
||||
#define DAW_CODE 0x0311
|
||||
#define CALL_CODE 0x0312
|
||||
#define ICAL_CODE 0x0313
|
||||
#define LADDR_CODE 0x0314
|
||||
#define GADDR_CODE 0x0315
|
||||
#define INDEXB_CODE 0x0316
|
||||
#define INDEXW_CODE 0x0317
|
||||
#define DROP_CODE 0x0318
|
||||
#define DUP_CODE 0x0319
|
||||
#define PUSH_EXP_CODE 0x031A
|
||||
#define PULL_EXP_CODE 0x031B
|
||||
|
||||
#define gen_uop(seq,op) gen_seq(seq,UNARY_CODE(op),0,0,0,0)
|
||||
#define gen_op(seq,op) gen_seq(seq,BINARY_CODE(op),0,0,0,0)
|
||||
#define gen_const(seq,val) gen_seq(seq,CONST_CODE,val,0,0,0)
|
||||
#define gen_str(seq,str,len) gen_seq(seq,STR_CODE,str,0,len,0)
|
||||
#define gen_lcladr(seq,idx) gen_seq(seq,LADDR_CODE,0,0,idx,0)
|
||||
#define gen_gbladr(seq,tag,typ) gen_seq(seq,GADDR_CODE,0,tag,0,typ)
|
||||
#define gen_idxb(seq) gen_seq(seq,ADD_CODE,0,0,0,0)
|
||||
#define gen_idxw(seq) gen_seq(seq,INDEXW_CODE,0,0,0,0)
|
||||
#define gen_lb(seq) gen_seq(seq,LB_CODE,0,0,0,0)
|
||||
#define gen_lw(seq) gen_seq(seq,LW_CODE,0,0,0,0)
|
||||
#define gen_sb(seq) gen_seq(seq,SB_CODE,0,0,0,0)
|
||||
#define gen_sw(seq) gen_seq(seq,SW_CODE,0,0,0,0)
|
||||
#define gen_icall(seq) gen_seq(seq,ICAL_CODE,0,0,0,0)
|
||||
#define gen_pushexp(seq) gen_seq(seq,PUSH_EXP_CODE,0,0,0,0)
|
||||
#define gen_pullexp(seq) gen_seq(seq,PULL_EXP_CODE,0,0,0,0)
|
||||
#define gen_drop(seq) gen_seq(seq,DROP_CODE,0,0,0,0)
|
||||
|
||||
#define ACME 1
|
||||
#define MODULE 2
|
||||
void emit_flags(int flags);
|
||||
void emit_header(void);
|
||||
void emit_trailer(void);
|
||||
@ -20,9 +98,8 @@ void emit_comment(char *s);
|
||||
void emit_asm(char *s);
|
||||
void emit_idlocal(char *name, int value);
|
||||
void emit_idglobal(int value, int size, char *name);
|
||||
void emit_idfunc(int tag, int type, char *name);
|
||||
void emit_idfunc(int tag, int type, char *name, int is_bytecode);
|
||||
void emit_idconst(char *name, int value);
|
||||
void emit_def(char *name, int is_bytecode);
|
||||
int emit_data(int vartype, int consttype, long constval, int constsize);
|
||||
void emit_codetag(int tag);
|
||||
void emit_const(int cval);
|
||||
@ -40,16 +117,16 @@ void emit_slw(int index);
|
||||
void emit_dlb(int index);
|
||||
void emit_dlw(int index);
|
||||
void emit_sab(int tag, int offset, int type);
|
||||
void emit_saw(int tag, int ofset, int type);
|
||||
void emit_dab(int tag, int type);
|
||||
void emit_daw(int tag, int type);
|
||||
void emit_saw(int tag, int offset, int type);
|
||||
void emit_dab(int tag, int offset, int type);
|
||||
void emit_daw(int tag, int offset, int type);
|
||||
void emit_call(int tag, int type);
|
||||
void emit_ical(void);
|
||||
void emit_localaddr(int index);
|
||||
void emit_globaladdr(int tag, int offset, int type);
|
||||
void emit_indexbyte(void);
|
||||
void emit_indexword(void);
|
||||
int emit_unaryop(int op);
|
||||
int emit_unaryop(t_token op);
|
||||
int emit_op(t_token op);
|
||||
void emit_brtru(int tag);
|
||||
void emit_brfls(int tag);
|
||||
@ -57,14 +134,19 @@ void emit_brgt(int tag);
|
||||
void emit_brlt(int tag);
|
||||
void emit_brne(int tag);
|
||||
void emit_brnch(int tag);
|
||||
void emit_swap(void);
|
||||
void emit_dup(void);
|
||||
void emit_push(void);
|
||||
void emit_pull(void);
|
||||
void emit_empty(void);
|
||||
void emit_push_exp(void);
|
||||
void emit_pull_exp(void);
|
||||
void emit_drop(void);
|
||||
void emit_dup(void);
|
||||
void emit_leave(void);
|
||||
void emit_ret(void);
|
||||
void emit_enter(int cparams);
|
||||
void emit_start(void);
|
||||
void emit_rld(void);
|
||||
void emit_esd(void);
|
||||
void release_seq(t_opseq *seq);
|
||||
int crunch_seq(t_opseq *seq);
|
||||
t_opseq *gen_seq(t_opseq *seq, int opcode, long cval, int tag, int offsz, int type);
|
||||
t_opseq *cat_seq(t_opseq *seq1, t_opseq *seq2);
|
||||
int emit_seq(t_opseq *seq);
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
||||
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "tokens.h"
|
||||
#include "symbols.h"
|
||||
#include <ctype.h>
|
||||
#include "plasm.h"
|
||||
|
||||
char *statement, *tokenstr, *scanpos = "";
|
||||
char *statement, *tokenstr, *scanpos = (char*) "";
|
||||
t_token scantoken, prevtoken;
|
||||
int tokenlen;
|
||||
long constval;
|
||||
@ -37,35 +37,37 @@ t_token keywords[] = {
|
||||
DEFAULT_TOKEN, 'O', 'T', 'H', 'E', 'R', 'W', 'I', 'S', 'E',
|
||||
ENDCASE_TOKEN, 'W', 'E', 'N', 'D',
|
||||
FOR_TOKEN, 'F', 'O', 'R',
|
||||
TO_TOKEN, 'T', 'O',
|
||||
DOWNTO_TOKEN, 'D', 'O', 'W', 'N', 'T', 'O',
|
||||
STEP_TOKEN, 'S', 'T', 'E', 'P',
|
||||
TO_TOKEN, 'T', 'O',
|
||||
DOWNTO_TOKEN, 'D', 'O', 'W', 'N', 'T', 'O',
|
||||
STEP_TOKEN, 'S', 'T', 'E', 'P',
|
||||
NEXT_TOKEN, 'N', 'E', 'X', 'T',
|
||||
REPEAT_TOKEN, 'R', 'E', 'P', 'E', 'A', 'T',
|
||||
UNTIL_TOKEN, 'U', 'N', 'T', 'I', 'L',
|
||||
BREAK_TOKEN, 'B', 'R', 'E', 'A', 'K',
|
||||
CONTINUE_TOKEN, 'C', 'O', 'N', 'T', 'I', 'N', 'U', 'E',
|
||||
ASM_TOKEN, 'A', 'S', 'M',
|
||||
DEF_TOKEN, 'D', 'E', 'F',
|
||||
EXPORT_TOKEN, 'E', 'X', 'P', 'O', 'R', 'T',
|
||||
IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T',
|
||||
UNTIL_TOKEN, 'U', 'N', 'T', 'I', 'L',
|
||||
BREAK_TOKEN, 'B', 'R', 'E', 'A', 'K',
|
||||
CONTINUE_TOKEN, 'C', 'O', 'N', 'T', 'I', 'N', 'U', 'E',
|
||||
ASM_TOKEN, 'A', 'S', 'M',
|
||||
DEF_TOKEN, 'D', 'E', 'F',
|
||||
EXPORT_TOKEN, 'E', 'X', 'P', 'O', 'R', 'T',
|
||||
IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T',
|
||||
INCLUDE_TOKEN, 'I', 'N', 'C', 'L', 'U', 'D', 'E',
|
||||
RETURN_TOKEN, 'R', 'E', 'T', 'U', 'R', 'N',
|
||||
END_TOKEN, 'E', 'N', 'D',
|
||||
DONE_TOKEN, 'D', 'O', 'N', 'E',
|
||||
DONE_TOKEN, 'D', 'O', 'N', 'E',
|
||||
LOGIC_NOT_TOKEN, 'N', 'O', 'T',
|
||||
LOGIC_AND_TOKEN, 'A', 'N', 'D',
|
||||
LOGIC_OR_TOKEN, 'O', 'R',
|
||||
LOGIC_OR_TOKEN, 'O', 'R',
|
||||
BYTE_TOKEN, 'B', 'Y', 'T', 'E',
|
||||
WORD_TOKEN, 'W', 'O', 'R', 'D',
|
||||
WORD_TOKEN, 'W', 'O', 'R', 'D',
|
||||
CONST_TOKEN, 'C', 'O', 'N', 'S', 'T',
|
||||
STRUC_TOKEN, 'S', 'T', 'R', 'U', 'C',
|
||||
PREDEF_TOKEN, 'P', 'R', 'E', 'D', 'E', 'F',
|
||||
SYSFLAGS_TOKEN, 'S', 'Y', 'S', 'F', 'L', 'A', 'G', 'S',
|
||||
SYSFLAGS_TOKEN, 'S', 'Y', 'S', 'F', 'L', 'A', 'G', 'S',
|
||||
EOL_TOKEN
|
||||
};
|
||||
|
||||
void parse_error(char *errormsg)
|
||||
extern int outflags;
|
||||
|
||||
void parse_error(const char *errormsg)
|
||||
{
|
||||
char *error_carrot = statement;
|
||||
|
||||
@ -75,7 +77,18 @@ void parse_error(char *errormsg)
|
||||
fprintf(stderr, "^\nError: %s\n", errormsg);
|
||||
exit(1);
|
||||
}
|
||||
void parse_warn(const char *warnmsg)
|
||||
{
|
||||
if (outflags & WARNINGS)
|
||||
{
|
||||
char *error_carrot = statement;
|
||||
|
||||
fprintf(stderr, "\n%s %4d: %s\n%*s ", filename, lineno, statement, (int)strlen(filename), "");
|
||||
for (error_carrot = statement; error_carrot != tokenstr; error_carrot++)
|
||||
putc(*error_carrot == '\t' ? '\t' : ' ', stderr);
|
||||
fprintf(stderr, "^\nWarning: %s\n", warnmsg);
|
||||
}
|
||||
}
|
||||
int hexdigit(char ch)
|
||||
{
|
||||
ch = toupper(ch);
|
||||
@ -103,8 +116,8 @@ t_token scan(void)
|
||||
else if (*scanpos == '\0' || *scanpos == '\n' || *scanpos == ';')
|
||||
scantoken = EOL_TOKEN;
|
||||
else if ((scanpos[0] >= 'a' && scanpos[0] <= 'z')
|
||||
|| (scanpos[0] >= 'A' && scanpos[0] <= 'Z')
|
||||
|| (scanpos[0] == '_'))
|
||||
|| (scanpos[0] >= 'A' && scanpos[0] <= 'Z')
|
||||
|| (scanpos[0] == '_'))
|
||||
{
|
||||
/*
|
||||
* ID, either variable name or reserved word.
|
||||
@ -116,9 +129,9 @@ t_token scan(void)
|
||||
scanpos++;
|
||||
}
|
||||
while ((*scanpos >= 'a' && *scanpos <= 'z')
|
||||
|| (*scanpos >= 'A' && *scanpos <= 'Z')
|
||||
|| (*scanpos == '_')
|
||||
|| (*scanpos >= '0' && *scanpos <= '9'));
|
||||
|| (*scanpos >= 'A' && *scanpos <= 'Z')
|
||||
|| (*scanpos == '_')
|
||||
|| (*scanpos >= '0' && *scanpos <= '9'));
|
||||
scantoken = ID_TOKEN;
|
||||
tokenlen = scanpos - tokenstr;
|
||||
/*
|
||||
@ -401,7 +414,7 @@ int scan_lookahead(void)
|
||||
char *backpos = scanpos;
|
||||
char *backstr = tokenstr;
|
||||
int prevtoken = scantoken;
|
||||
int prevlen = tokenlen;
|
||||
int prevlen = tokenlen;
|
||||
int look = scan();
|
||||
scanpos = backpos;
|
||||
tokenstr = backstr;
|
||||
@ -415,10 +428,13 @@ int next_line(void)
|
||||
int len;
|
||||
t_token token;
|
||||
char* new_filename;
|
||||
if (inputfile == NULL) {
|
||||
// First-time init
|
||||
if (inputfile == NULL)
|
||||
{
|
||||
/*
|
||||
* First-time init
|
||||
*/
|
||||
inputfile = stdin;
|
||||
filename = "<stdin>";
|
||||
filename = (char*) "<stdin>";
|
||||
}
|
||||
if (*scanpos == ';')
|
||||
{
|
||||
@ -429,11 +445,17 @@ int next_line(void)
|
||||
{
|
||||
statement = inputline;
|
||||
scanpos = inputline;
|
||||
// Read next line from the current file, and strip newline from the end.
|
||||
if (fgets(inputline, 512, inputfile) == NULL) {
|
||||
/*
|
||||
* Read next line from the current file, and strip newline from the end.
|
||||
*/
|
||||
if (fgets(inputline, 512, inputfile) == NULL)
|
||||
{
|
||||
inputline[0] = 0;
|
||||
// At end of file, return to previous file if any, else return EOF_TOKEN
|
||||
if (outer_inputfile != NULL) {
|
||||
/*
|
||||
* At end of file, return to previous file if any, else return EOF_TOKEN
|
||||
*/
|
||||
if (outer_inputfile != NULL)
|
||||
{
|
||||
fclose(inputfile);
|
||||
free(filename);
|
||||
inputfile = outer_inputfile;
|
||||
@ -441,7 +463,8 @@ int next_line(void)
|
||||
lineno = outer_lineno - 1; // -1 because we're about to incr again
|
||||
outer_inputfile = NULL;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
scantoken = EOF_TOKEN;
|
||||
return EOF_TOKEN;
|
||||
}
|
||||
@ -454,15 +477,20 @@ int next_line(void)
|
||||
printf("; %s: %04d: %s\n", filename, lineno, inputline);
|
||||
}
|
||||
token = scan();
|
||||
// Handle single level of file inclusion
|
||||
if (token == INCLUDE_TOKEN) {
|
||||
/*
|
||||
* Handle single level of file inclusion
|
||||
*/
|
||||
if (token == INCLUDE_TOKEN)
|
||||
{
|
||||
token = scan();
|
||||
if (token != STRING_TOKEN) {
|
||||
if (token != STRING_TOKEN)
|
||||
{
|
||||
parse_error("Missing include filename");
|
||||
scantoken = EOF_TOKEN;
|
||||
return EOF_TOKEN;
|
||||
}
|
||||
if (outer_inputfile != NULL) {
|
||||
if (outer_inputfile != NULL)
|
||||
{
|
||||
parse_error("Only one level of includes allowed");
|
||||
scantoken = EOF_TOKEN;
|
||||
return EOF_TOKEN;
|
||||
@ -470,11 +498,12 @@ int next_line(void)
|
||||
outer_inputfile = inputfile;
|
||||
outer_filename = filename;
|
||||
outer_lineno = lineno;
|
||||
new_filename = malloc(tokenlen-1);
|
||||
new_filename = (char*) malloc(tokenlen-1);
|
||||
strncpy(new_filename, (char*)constval, tokenlen-2);
|
||||
new_filename[tokenlen-2] = 0;
|
||||
inputfile = fopen(new_filename, "r");
|
||||
if (inputfile == NULL) {
|
||||
if (inputfile == NULL)
|
||||
{
|
||||
parse_error("Error opening include file");
|
||||
scantoken = EOF_TOKEN;
|
||||
return EOF_TOKEN;
|
||||
|
@ -1,19 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
||||
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
extern char *statement, *scanpos, *tokenstr;
|
||||
extern t_token scantoken, prevtoken;
|
||||
extern int tokenlen;
|
||||
extern long constval;
|
||||
extern char inputline[];
|
||||
void parse_error(char *errormsg);
|
||||
void parse_error(const char *errormsg);
|
||||
void parse_warn(const char *warnmsg);
|
||||
int next_line(void);
|
||||
void scan_rewind(char *backptr);
|
||||
int scan_lookahead(void);
|
||||
|
@ -6,7 +6,7 @@ PLVM02 = PLVM02\#4000
|
||||
CMD = CMD\#FF2000
|
||||
PLASM = plasm
|
||||
JAR = $(PLASM).jar
|
||||
INCS = tokens.h symbols.h lex.h parse.h codegen.h
|
||||
INCS = plasm.h tokens.h symbols.h lex.h parse.h codegen.h
|
||||
SRCS = plasm.c parse.c lex.c codegen.c
|
||||
#
|
||||
# Image filetypes for Virtual ][
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,10 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
||||
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
int parse_module(void);
|
||||
|
@ -1,18 +1,16 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
||||
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tokens.h"
|
||||
#include "lex.h"
|
||||
#include "codegen.h"
|
||||
#include "parse.h"
|
||||
#include "plasm.h"
|
||||
|
||||
int outflags = 0;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@ -20,23 +18,28 @@ int main(int argc, char **argv)
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (argv[i][0] == '-')
|
||||
{
|
||||
{
|
||||
j = 1;
|
||||
while (argv[i][j])
|
||||
{
|
||||
switch(argv[i][j++])
|
||||
{
|
||||
case 'A':
|
||||
flags |= ACME;
|
||||
outflags |= ACME;
|
||||
break;
|
||||
case 'M':
|
||||
flags |= MODULE;
|
||||
outflags |= MODULE;
|
||||
break;
|
||||
case 'O':
|
||||
outflags |= OPTIMIZE;
|
||||
break;
|
||||
case 'W':
|
||||
outflags |= WARNINGS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
emit_flags(flags);
|
||||
emit_flags(outflags);
|
||||
if (parse_module())
|
||||
{
|
||||
fprintf(stderr, "Compilation complete.\n");
|
||||
|
25
Platform/Apple/tools/PLASMA/src/plasm.h
Executable file
25
Platform/Apple/tools/PLASMA/src/plasm.h
Executable file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Global flags.
|
||||
*/
|
||||
#define ACME (1<<0)
|
||||
#define MODULE (1<<1)
|
||||
#define OPTIMIZE (1<<2)
|
||||
#define BYTECODE_SEG (1<<3)
|
||||
#define INIT (1<<4)
|
||||
#define SYSFLAGS (1<<5)
|
||||
#define WARNINGS (1<<6)
|
||||
extern int outflags;
|
||||
#include "tokens.h"
|
||||
#include "lex.h"
|
||||
#include "symbols.h"
|
||||
#include "parse.h"
|
||||
#include "codegen.h"
|
@ -1,13 +1,12 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
||||
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@ -27,32 +26,32 @@ int show_state = 0;
|
||||
/*
|
||||
* Bytecode memory
|
||||
*/
|
||||
#define BYTE_PTR(bp) ((byte)((bp)[0]))
|
||||
#define WORD_PTR(bp) ((word)((bp)[0] | ((bp)[1] << 8)))
|
||||
#define UWORD_PTR(bp) ((uword)((bp)[0] | ((bp)[1] << 8)))
|
||||
#define TO_UWORD(w) ((uword)((w)))
|
||||
#define MOD_ADDR 0x1000
|
||||
#define DEF_CALL 0x0800
|
||||
#define DEF_CALLSZ 0x0800
|
||||
#define DEF_ENTRYSZ 6
|
||||
#define MEM_SIZE 65536
|
||||
#define BYTE_PTR(bp) ((byte)((bp)[0]))
|
||||
#define WORD_PTR(bp) ((word)((bp)[0] | ((bp)[1] << 8)))
|
||||
#define UWORD_PTR(bp) ((uword)((bp)[0] | ((bp)[1] << 8)))
|
||||
#define TO_UWORD(w) ((uword)((w)))
|
||||
#define MOD_ADDR 0x1000
|
||||
#define DEF_CALL 0x0800
|
||||
#define DEF_CALLSZ 0x0800
|
||||
#define DEF_ENTRYSZ 6
|
||||
#define MEM_SIZE 65536
|
||||
byte mem_data[MEM_SIZE];
|
||||
uword sp = 0x01FE, fp = 0xFFFF, heap = 0x0200, deftbl = DEF_CALL, lastdef = DEF_CALL;
|
||||
#define PHA(b) (mem_data[sp--]=(b))
|
||||
#define PLA() (mem_data[++sp])
|
||||
#define EVAL_STACKSZ 16
|
||||
#define PUSH(v) (*(--esp))=(v)
|
||||
#define POP ((word)(*(esp++)))
|
||||
#define UPOP ((uword)(*(esp++)))
|
||||
#define TOS (esp[0])
|
||||
#define PHA(b) (mem_data[sp--]=(b))
|
||||
#define PLA (mem_data[++sp])
|
||||
#define EVAL_STACKSZ 16
|
||||
#define PUSH(v) (*(--esp))=(v)
|
||||
#define POP ((word)(*(esp++)))
|
||||
#define UPOP ((uword)(*(esp++)))
|
||||
#define TOS (esp[0])
|
||||
word eval_stack[EVAL_STACKSZ];
|
||||
word *esp = eval_stack + EVAL_STACKSZ;
|
||||
|
||||
#define SYMTBLSZ 1024
|
||||
#define SYMSZ 16
|
||||
#define MODTBLSZ 128
|
||||
#define MODSZ 16
|
||||
#define MODLSTSZ 32
|
||||
#define SYMTBLSZ 1024
|
||||
#define SYMSZ 16
|
||||
#define MODTBLSZ 128
|
||||
#define MODSZ 16
|
||||
#define MODLSTSZ 32
|
||||
byte symtbl[SYMTBLSZ];
|
||||
byte *lastsym = symtbl;
|
||||
byte modtbl[MODTBLSZ];
|
||||
@ -63,7 +62,7 @@ byte *lastmod = modtbl;
|
||||
void interp(code *ip);
|
||||
/*
|
||||
* Utility routines.
|
||||
*
|
||||
*
|
||||
* A DCI string is one that has the high bit set for every character except the last.
|
||||
* More efficient than C or Pascal strings.
|
||||
*/
|
||||
@ -136,7 +135,7 @@ void dump_tbl(byte *tbl)
|
||||
putchar(':');
|
||||
while (len++ < 15)
|
||||
putchar(' ');
|
||||
printf("$%04X\n", tbl[0] | (tbl[1] << 8));
|
||||
printf("$%04X\n", tbl[0] | (tbl[1] << 8));
|
||||
tbl += 2;
|
||||
}
|
||||
}
|
||||
@ -258,7 +257,7 @@ int load_mod(byte *mod)
|
||||
moddep = header + 1;
|
||||
modsize = header[0] | (header[1] << 8);
|
||||
magic = header[2] | (header[3] << 8);
|
||||
if (magic == 0xDA7E)
|
||||
if (magic == 0xDA7F)
|
||||
{
|
||||
/*
|
||||
* This is a relocatable bytecode module.
|
||||
@ -292,7 +291,7 @@ int load_mod(byte *mod)
|
||||
}
|
||||
/*
|
||||
* Alloc heap space for relocated module (data + bytecode).
|
||||
*/
|
||||
*/
|
||||
moddep += 1;
|
||||
hdrlen = moddep - header;
|
||||
len -= hdrlen;
|
||||
@ -391,7 +390,7 @@ int load_mod(byte *mod)
|
||||
{
|
||||
if (show_state) printf("BYTE");
|
||||
mem_data[addr] = fixup;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -512,18 +511,18 @@ void call(uword pc)
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* OPCODE TABLE
|
||||
*
|
||||
OPTBL: DW ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E
|
||||
DW NEG,COMP,AND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E
|
||||
DW NOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E
|
||||
DW DROP,DUP,PUSH,PULL,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E
|
||||
DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E
|
||||
DW BRNCH,IBRNCH,CALL,ICAL,ENTER,LEAVE,RET,??? ; 50 52 54 56 58 5A 5C 5E
|
||||
DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E
|
||||
DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E
|
||||
OPTBL: DW ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E
|
||||
DW NEG,COMP,AND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E
|
||||
DW NOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E
|
||||
DW DROP,DUP,PUSH,PULL,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E
|
||||
DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E
|
||||
DW BRNCH,IBRNCH,CALL,ICAL,ENTER,LEAVE,RET,??? ; 50 52 54 56 58 5A 5C 5E
|
||||
DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E
|
||||
DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E
|
||||
*/
|
||||
void interp(code *ip)
|
||||
{
|
||||
@ -543,9 +542,9 @@ void interp(code *ip)
|
||||
}
|
||||
switch (*ip++)
|
||||
{
|
||||
/*
|
||||
* 0x00-0x0F
|
||||
*/
|
||||
/*
|
||||
* 0x00-0x0F
|
||||
*/
|
||||
case 0x00: // ZERO : TOS = 0
|
||||
PUSH(0);
|
||||
break;
|
||||
@ -666,13 +665,11 @@ void interp(code *ip)
|
||||
PUSH(val);
|
||||
break;
|
||||
case 0x34: // PUSH : TOSP = TOS
|
||||
val = POP;
|
||||
PHA(val >> 8);
|
||||
val = esp - eval_stack;
|
||||
PHA(val);
|
||||
break;
|
||||
case 0x36: // PULL : TOS = TOSP
|
||||
PUSH(mem_data[sp] | (mem_data[sp + 1] << 8));
|
||||
sp += 2;
|
||||
esp = eval_stack + PLA;
|
||||
break;
|
||||
case 0x38: // BRGT : TOS-1 > TOS ? IP += (IP)
|
||||
val = POP;
|
||||
@ -785,7 +782,7 @@ void interp(code *ip)
|
||||
printf("\n");
|
||||
break;
|
||||
case 0x5A: // LEAVE : DEL FRAME, IP = TOFP
|
||||
fp += PLA();
|
||||
fp += PLA;
|
||||
case 0x5C: // RET : IP = TOFP
|
||||
return;
|
||||
case 0x5E: // ???
|
||||
@ -832,14 +829,14 @@ void interp(code *ip)
|
||||
/*
|
||||
* 0x70-0x7F
|
||||
*/
|
||||
case 0x70: // SB : BYTE (TOS) = TOS-1
|
||||
val = POP;
|
||||
case 0x70: // SB : BYTE (TOS-1) = TOS
|
||||
ea = UPOP;
|
||||
val = POP;
|
||||
mem_data[ea] = val;
|
||||
break;
|
||||
case 0x72: // SW : WORD (TOS) = TOS-1
|
||||
val = POP;
|
||||
case 0x72: // SW : WORD (TOS-1) = TOS
|
||||
ea = UPOP;
|
||||
val = POP;
|
||||
mem_data[ea] = val;
|
||||
mem_data[ea + 1] = val >> 8;
|
||||
break;
|
||||
@ -899,7 +896,7 @@ int main(int argc, char **argv)
|
||||
{
|
||||
byte dci[32];
|
||||
int i;
|
||||
|
||||
|
||||
if (--argc)
|
||||
{
|
||||
argv++;
|
||||
|
@ -160,7 +160,7 @@ VMCORE = *
|
||||
OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E
|
||||
!WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E
|
||||
!WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E
|
||||
!WORD DROP,DUP,PUSH,PULL,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E
|
||||
!WORD DROP,DUP,PUSHEP,PULLEP,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E
|
||||
!WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E
|
||||
!WORD BRNCH,IBRNCH,CALL,ICAL,ENTER,LEAVE,RET,NEXTOP ; 50 52 54 56 58 5A 5C 5E
|
||||
!WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E
|
||||
@ -174,7 +174,7 @@ OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E
|
||||
OPXTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E
|
||||
!WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E
|
||||
!WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E
|
||||
!WORD DROP,DUP,PUSH,PULL,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E
|
||||
!WORD DROP,DUP,PUSHEP,PULLEP,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E
|
||||
!WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E
|
||||
!WORD BRNCH,IBRNCH,CALLX,ICALX,ENTER,LEAVEX,RETX,NEXTOP; 50 52 54 56 58 5A 5C 5E
|
||||
!WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLB,DLW ; 60 62 64 66 68 6A 6C 6E
|
||||
@ -564,23 +564,16 @@ DUP DEX
|
||||
STA ESTKH,X
|
||||
JMP NEXTOP
|
||||
;*
|
||||
;* PUSH FROM EVAL STACK TO CALL STACK
|
||||
;* PUSH EVAL STACK POINTER TO CALL STACK
|
||||
;*
|
||||
PUSH LDA ESTKL,X
|
||||
PUSHEP TXA
|
||||
PHA
|
||||
LDA ESTKH,X
|
||||
PHA
|
||||
; INX
|
||||
; JMP NEXTOP
|
||||
JMP DROP
|
||||
JMP NEXTOP
|
||||
;*
|
||||
;* PULL FROM CALL STACK TO EVAL STACK
|
||||
;* PULL EVAL STACK POINTER FROM CALL STACK
|
||||
;*
|
||||
PULL DEX
|
||||
PLA
|
||||
STA ESTKH,X
|
||||
PLA
|
||||
STA ESTKL,X
|
||||
PULLEP PLA
|
||||
TAX
|
||||
JMP NEXTOP
|
||||
;*
|
||||
;* CONSTANT
|
||||
@ -892,11 +885,11 @@ LAWX +INC_IP
|
||||
;*
|
||||
;* STORE VALUE TO ADDRESS
|
||||
;*
|
||||
SB LDA ESTKL+1,X
|
||||
SB LDA ESTKL,X
|
||||
STA TMPL
|
||||
LDA ESTKH+1,X
|
||||
LDA ESTKH,X
|
||||
STA TMPH
|
||||
LDA ESTKL,X
|
||||
LDA ESTKL+1,X
|
||||
STY IPY
|
||||
BIT LCRWEN+LCBNK2
|
||||
BIT LCRWEN+LCBNK2
|
||||
@ -907,18 +900,18 @@ SB LDA ESTKL+1,X
|
||||
; INX
|
||||
; JMP NEXTOP
|
||||
JMP DROP
|
||||
SW LDA ESTKL+1,X
|
||||
SW LDA ESTKL,X
|
||||
STA TMPL
|
||||
LDA ESTKH+1,X
|
||||
LDA ESTKH,X
|
||||
STA TMPH
|
||||
STY IPY
|
||||
BIT LCRWEN+LCBNK2
|
||||
BIT LCRWEN+LCBNK2
|
||||
LDY #$00
|
||||
LDA ESTKL,X
|
||||
LDA ESTKL+1,X
|
||||
STA (TMP),Y
|
||||
INY
|
||||
LDA ESTKH,X
|
||||
LDA ESTKH+1,X
|
||||
STA (TMP),Y
|
||||
LDY IPY
|
||||
INX
|
||||
|
@ -1,13 +1,3 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Symbol table types.
|
||||
*/
|
||||
@ -20,7 +10,7 @@
|
||||
#define DEF_TYPE (1 << 4)
|
||||
#define BRANCH_TYPE (1 << 5)
|
||||
#define LOCAL_TYPE (1 << 6)
|
||||
#define EXTERN_TYPE (1 << 7)
|
||||
#define EXTERN_TYPE (1 << 7)
|
||||
#define ADDR_TYPE (VAR_TYPE | FUNC_TYPE | EXTERN_TYPE)
|
||||
#define WPTR_TYPE (1 << 8)
|
||||
#define BPTR_TYPE (1 << 9)
|
||||
@ -28,8 +18,16 @@
|
||||
#define STRING_TYPE (1 << 10)
|
||||
#define TAG_TYPE (1 << 11)
|
||||
#define EXPORT_TYPE (1 << 12)
|
||||
#define PREDEF_TYPE (1 << 13)
|
||||
#define PREDEF_TYPE (1 << 13)
|
||||
#define FUNC_TYPE (ASM_TYPE | DEF_TYPE | PREDEF_TYPE)
|
||||
#define FUNC_PARMS (0x0F << 16)
|
||||
#define FUNC_VALS (0x0F << 20)
|
||||
#define FUNC_PARMVALS (FUNC_PARMS|FUNC_VALS)
|
||||
#define funcparms_type(p) (((p)&0x0F)<<16)
|
||||
#define funcparms_cnt(t) (((t)>>16)&0x0F)
|
||||
#define funcvals_type(v) (((v)&0x0F)<<20)
|
||||
#define funcvals_cnt(t) (((t)>>20)&0x0F)
|
||||
|
||||
int id_match(char *name, int len, char *id);
|
||||
int idlocal_lookup(char *name, int len);
|
||||
int idglobal_lookup(char *name, int len);
|
||||
@ -37,6 +35,7 @@ int idconst_lookup(char *name, int len);
|
||||
int idlocal_add(char *name, int len, int type, int size);
|
||||
int idglobal_add(char *name, int len, int type, int size);
|
||||
int id_add(char *name, int len, int type, int size);
|
||||
void idlocal_reset(void);
|
||||
int idfunc_set(char *name, int len, int type, int tag);
|
||||
int idfunc_add(char *name, int len, int type, int tag);
|
||||
int idconst_add(char *name, int len, int value);
|
||||
|
@ -35,7 +35,7 @@
|
||||
relative="true" parallel="false" failonerror="true" verbose="true"
|
||||
addsourcefile="false">
|
||||
<fileset dir="${src.dir}" includes="*.pla" excludes="heaptest*,playtype*"/>
|
||||
<arg value="-AM"/>
|
||||
<arg value="-AMW"/>
|
||||
<redirector logError="yes">
|
||||
<!-- redirect STDIN; fileset collects relative to its dir, but we need -->
|
||||
<!-- relative to basedir -->
|
||||
|
Loading…
x
Reference in New Issue
Block a user