mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-07-07 14:29:16 +00:00
Upgrade to PLASMA 1.1 compiler/VM
This commit is contained in:
parent
073457d56d
commit
6205d1310f
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,17 @@
|
|||||||
import cmdsys
|
import cmdsys
|
||||||
|
//
|
||||||
|
// Useful values for everyone
|
||||||
|
//
|
||||||
|
const _SYSVER_ = $0100 // Version built against
|
||||||
|
const FALSE = 0
|
||||||
|
const TRUE = not FALSE
|
||||||
|
const NULL = 0
|
||||||
|
//
|
||||||
|
// Machine ID values
|
||||||
|
//
|
||||||
const MACHID_CLOCK = $01
|
const MACHID_CLOCK = $01
|
||||||
const MACHID_80COL = $02
|
const MACHID_80COL = $02
|
||||||
const MACHID_MEM = $03
|
const MACHID_MEM = $03
|
||||||
const MACHID_48K = $10
|
|
||||||
const MACHID_64K = $20
|
const MACHID_64K = $20
|
||||||
const MACHID_128K = $30
|
const MACHID_128K = $30
|
||||||
const MACHID_MODEL = $C8
|
const MACHID_MODEL = $C8
|
||||||
@ -30,16 +39,23 @@ import cmdsys
|
|||||||
const modkeep = $2000
|
const modkeep = $2000
|
||||||
const modinitkeep = $4000
|
const modinitkeep = $4000
|
||||||
//
|
//
|
||||||
// System vars
|
// CMD exported interface table
|
||||||
//
|
//
|
||||||
word sysvars
|
struc t_cmdsys
|
||||||
|
word sysver
|
||||||
|
word syspath
|
||||||
|
word cmdline
|
||||||
|
word modexec
|
||||||
|
byte refcons
|
||||||
|
byte devcons
|
||||||
|
end
|
||||||
//
|
//
|
||||||
// CMD exported functions
|
// CMD exported functions
|
||||||
//
|
//
|
||||||
predef putc(c)#0, putln()#0, puts(s)#0, puti(i)#0, getc()#1, gets(p)#1, toupper(c)#1
|
predef putc(c)#0, putln()#0, puts(s)#0, puti(i)#0, getc()#1, gets(p)#1, putb(b)#0, puth(h)#0
|
||||||
predef call(addr,areg,xreg,yreg,status)#1, syscall(cmd,params)#1
|
predef call(addr,areg,xreg,yreg,status)#1, syscall(cmd,params)#1
|
||||||
predef heapmark()#1, heapallocalign(size, pow2, freeaddr), heapalloc(size)#1, heaprelease(newheap)#1, heapavail()#1
|
predef heapmark()#1, heapallocalign(size, pow2, freeaddr)#1
|
||||||
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0
|
predef heapalloc(size)#1, heaprelease(newheap)#1, heapavail()#1
|
||||||
predef isugt(a,b)#1, isuge(a,b)#1, isult(a,b)#1, isule(a,b)#1
|
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0, strcpy(dst,src)#1, strcat(dst,src)#1
|
||||||
predef modload(mod)#1, modexec(modfile)#1, modaddr(str)#1
|
predef toupper(c)#1, sext(a)#1, divmod(a,b)#2, isugt(a,b)#1, isuge(a,b)#1, isult(a,b)#1, isule(a,b)#1
|
||||||
end
|
end
|
||||||
|
@ -1,12 +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.
|
(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>.
|
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
|
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
|
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
|
ANY KIND, either express or implied. See the License for the specific language
|
||||||
* governing permissions and limitations under the License.
|
governing permissions and limitations under the License.
|
||||||
*/
|
**************************************************************************************/
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -26,6 +26,7 @@ static int defs = 0;
|
|||||||
static int asmdefs = 0;
|
static int asmdefs = 0;
|
||||||
static int codetags = 1; // Fix check for break_tag and cont_tag
|
static int codetags = 1; // Fix check for break_tag and cont_tag
|
||||||
static int fixups = 0;
|
static int fixups = 0;
|
||||||
|
static int lastglobalsize = 0;
|
||||||
static char idconst_name[1024][ID_LEN+1];
|
static char idconst_name[1024][ID_LEN+1];
|
||||||
static int idconst_value[1024];
|
static int idconst_value[1024];
|
||||||
static char idglobal_name[1024][ID_LEN+1];
|
static char idglobal_name[1024][ID_LEN+1];
|
||||||
@ -54,7 +55,7 @@ int id_match(char *name, int len, char *id)
|
|||||||
if (len > 16) len = 16;
|
if (len > 16) len = 16;
|
||||||
while (len--)
|
while (len--)
|
||||||
{
|
{
|
||||||
if (name[len] != id[1 + len])
|
if (toupper(name[len]) != id[1 + len])
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
return (1);
|
return (1);
|
||||||
@ -82,7 +83,11 @@ int idglobal_lookup(char *name, int len)
|
|||||||
int i;
|
int i;
|
||||||
for (i = 0; i < globals; i++)
|
for (i = 0; i < globals; i++)
|
||||||
if (id_match(name, len, &(idglobal_name[i][0])))
|
if (id_match(name, len, &(idglobal_name[i][0])))
|
||||||
|
{
|
||||||
|
if (idglobal_type[i] & EXTERN_TYPE)
|
||||||
|
idglobal_type[i] |= ACCESSED_TYPE;
|
||||||
return (i);
|
return (i);
|
||||||
|
}
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
int idconst_add(char *name, int len, int value)
|
int idconst_add(char *name, int len, int value)
|
||||||
@ -99,7 +104,7 @@ int idconst_add(char *name, int len, int value)
|
|||||||
idconst_name[consts][0] = len;
|
idconst_name[consts][0] = len;
|
||||||
if (len > ID_LEN) len = ID_LEN;
|
if (len > ID_LEN) len = ID_LEN;
|
||||||
while (len--)
|
while (len--)
|
||||||
idconst_name[consts][1 + len] = name[len];
|
idconst_name[consts][1 + len] = toupper(name[len]);
|
||||||
idconst_value[consts] = value;
|
idconst_value[consts] = value;
|
||||||
consts++;
|
consts++;
|
||||||
return (1);
|
return (1);
|
||||||
@ -128,7 +133,7 @@ int idlocal_add(char *name, int len, int type, int size)
|
|||||||
idlocal_name[locals][0] = len;
|
idlocal_name[locals][0] = len;
|
||||||
if (len > ID_LEN) len = ID_LEN;
|
if (len > ID_LEN) len = ID_LEN;
|
||||||
while (len--)
|
while (len--)
|
||||||
idlocal_name[locals][1 + len] = name[len];
|
idlocal_name[locals][1 + len] = toupper(name[len]);
|
||||||
idlocal_type[locals] = type | LOCAL_TYPE;
|
idlocal_type[locals] = type | LOCAL_TYPE;
|
||||||
idlocal_offset[locals] = localsize;
|
idlocal_offset[locals] = localsize;
|
||||||
localsize += size;
|
localsize += size;
|
||||||
@ -158,7 +163,7 @@ int idglobal_add(char *name, int len, int type, int size)
|
|||||||
idglobal_name[globals][0] = len;
|
idglobal_name[globals][0] = len;
|
||||||
if (len > ID_LEN) len = ID_LEN;
|
if (len > ID_LEN) len = ID_LEN;
|
||||||
while (len--)
|
while (len--)
|
||||||
idglobal_name[globals][1 + len] = name[len];
|
idglobal_name[globals][1 + len] = toupper(name[len]);
|
||||||
idglobal_type[globals] = type;
|
idglobal_type[globals] = type;
|
||||||
if (!(type & EXTERN_TYPE))
|
if (!(type & EXTERN_TYPE))
|
||||||
{
|
{
|
||||||
@ -210,7 +215,7 @@ int idfunc_add(char *name, int len, int type, int tag)
|
|||||||
idglobal_name[globals][0] = len;
|
idglobal_name[globals][0] = len;
|
||||||
if (len > ID_LEN) len = ID_LEN;
|
if (len > ID_LEN) len = ID_LEN;
|
||||||
while (len--)
|
while (len--)
|
||||||
idglobal_name[globals][1 + len] = name[len];
|
idglobal_name[globals][1 + len] = toupper(name[len]);
|
||||||
idglobal_type[globals] = type;
|
idglobal_type[globals] = type;
|
||||||
idglobal_tag[globals++] = tag;
|
idglobal_tag[globals++] = tag;
|
||||||
if (type & EXTERN_TYPE)
|
if (type & EXTERN_TYPE)
|
||||||
@ -236,6 +241,14 @@ void idglobal_size(int type, int size, int constsize)
|
|||||||
else if (size)
|
else if (size)
|
||||||
emit_data(0, 0, 0, size);
|
emit_data(0, 0, 0, size);
|
||||||
}
|
}
|
||||||
|
void idlocal_size(int size)
|
||||||
|
{
|
||||||
|
localsize += size;
|
||||||
|
if (localsize > 255)
|
||||||
|
{
|
||||||
|
parse_error("Local variable size overflow\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
int id_tag(char *name, int len)
|
int id_tag(char *name, int len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -359,7 +372,7 @@ void emit_header(void)
|
|||||||
{
|
{
|
||||||
printf("\t%s\t_SEGEND-_SEGBEGIN\t; LENGTH OF HEADER + CODE/DATA + BYTECODE SEGMENT\n", DW);
|
printf("\t%s\t_SEGEND-_SEGBEGIN\t; LENGTH OF HEADER + CODE/DATA + BYTECODE SEGMENT\n", DW);
|
||||||
printf("_SEGBEGIN%c\n", LBL);
|
printf("_SEGBEGIN%c\n", LBL);
|
||||||
printf("\t%s\t$DA7F\t\t\t; MAGIC #\n", DW);
|
printf("\t%s\t$6502\t\t\t; MAGIC #\n", DW);
|
||||||
printf("\t%s\t_SYSFLAGS\t\t\t; SYSTEM FLAGS\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_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_DEFCNT\t\t\t; BYTECODE DEF COUNT\n", DW);
|
||||||
@ -418,13 +431,13 @@ void emit_esd(void)
|
|||||||
printf(";\n; EXTERNAL/ENTRY SYMBOL DICTIONARY\n;\n");
|
printf(";\n; EXTERNAL/ENTRY SYMBOL DICTIONARY\n;\n");
|
||||||
for (i = 0; i < globals; i++)
|
for (i = 0; i < globals; i++)
|
||||||
{
|
{
|
||||||
if (idglobal_type[i] & EXTERN_TYPE)
|
if (idglobal_type[i] & ACCESSED_TYPE) // Only refer to accessed externals
|
||||||
{
|
{
|
||||||
emit_dci(&idglobal_name[i][1], idglobal_name[i][0]);
|
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$10\t\t\t; EXTERNAL SYMBOL FLAG\n", DB);
|
||||||
printf("\t%s\t%d\t\t\t; ESD INDEX\n", DW, idglobal_tag[i]);
|
printf("\t%s\t%d\t\t\t; ESD INDEX\n", DW, idglobal_tag[i]);
|
||||||
}
|
}
|
||||||
else if (idglobal_type[i] & EXPORT_TYPE)
|
else if (idglobal_type[i] & EXPORT_TYPE)
|
||||||
{
|
{
|
||||||
emit_dci(&idglobal_name[i][1], idglobal_name[i][0]);
|
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$08\t\t\t; ENTRY SYMBOL FLAG\n", DB);
|
||||||
@ -454,7 +467,10 @@ void emit_moddep(char *name, int len)
|
|||||||
if (outflags & MODULE)
|
if (outflags & MODULE)
|
||||||
{
|
{
|
||||||
if (name)
|
if (name)
|
||||||
|
{
|
||||||
emit_dci(name, len);
|
emit_dci(name, len);
|
||||||
|
idglobal_add(name, len, EXTERN_TYPE | WORD_TYPE, 2); // Add to symbol table
|
||||||
|
}
|
||||||
else
|
else
|
||||||
printf("\t%s\t$00\t\t\t; END OF MODULE DEPENDENCIES\n", DB);
|
printf("\t%s\t$00\t\t\t; END OF MODULE DEPENDENCIES\n", DB);
|
||||||
}
|
}
|
||||||
@ -467,7 +483,11 @@ void emit_sysflags(int val)
|
|||||||
void emit_bytecode_seg(void)
|
void emit_bytecode_seg(void)
|
||||||
{
|
{
|
||||||
if ((outflags & MODULE) && !(outflags & BYTECODE_SEG))
|
if ((outflags & MODULE) && !(outflags & BYTECODE_SEG))
|
||||||
|
{
|
||||||
|
if (lastglobalsize == 0) // Pad a byte if last label is at end of data segment
|
||||||
|
printf("\t%s\t$00\t\t\t; PAD BYTE\n", DB);
|
||||||
printf("_SUBSEG%c\t\t\t\t; BYTECODE STARTS\n", LBL);
|
printf("_SUBSEG%c\t\t\t\t; BYTECODE STARTS\n", LBL);
|
||||||
|
}
|
||||||
outflags |= BYTECODE_SEG;
|
outflags |= BYTECODE_SEG;
|
||||||
}
|
}
|
||||||
void emit_comment(char *s)
|
void emit_comment(char *s)
|
||||||
@ -484,6 +504,7 @@ void emit_idlocal(char *name, int value)
|
|||||||
}
|
}
|
||||||
void emit_idglobal(int tag, int size, char *name)
|
void emit_idglobal(int tag, int size, char *name)
|
||||||
{
|
{
|
||||||
|
lastglobalsize = size;
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
printf("_D%03d%c\t\t\t\t\t; %s\n", tag, LBL, name);
|
printf("_D%03d%c\t\t\t\t\t; %s\n", tag, LBL, name);
|
||||||
else
|
else
|
||||||
@ -508,7 +529,7 @@ void emit_lambdafunc(int tag, char *name, int cparams, t_opseq *lambda_seq)
|
|||||||
emit_seq(lambda_seq);
|
emit_seq(lambda_seq);
|
||||||
emit_pending_seq();
|
emit_pending_seq();
|
||||||
if (cparams)
|
if (cparams)
|
||||||
printf("\t%s\t$5A\t\t\t; LEAVE\n", DB);
|
printf("\t%s\t$5A,$%02X\t\t\t; LEAVE\t%d\n", DB, cparams*2, cparams*2);
|
||||||
else
|
else
|
||||||
printf("\t%s\t$5C\t\t\t; RET\n", DB);
|
printf("\t%s\t$5C\t\t\t; RET\n", DB);
|
||||||
}
|
}
|
||||||
@ -759,6 +780,7 @@ void emit_brnch(int tag)
|
|||||||
}
|
}
|
||||||
void emit_breq(int tag)
|
void emit_breq(int tag)
|
||||||
{
|
{
|
||||||
|
emit_pending_seq();
|
||||||
printf("\t%s\t$3C\t\t\t; BREQ\t_B%03d\n", DB, 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);
|
printf("\t%s\t_B%03d-*\n", DW, tag);
|
||||||
}
|
}
|
||||||
@ -803,7 +825,7 @@ void emit_leave(void)
|
|||||||
{
|
{
|
||||||
emit_pending_seq();
|
emit_pending_seq();
|
||||||
if (localsize)
|
if (localsize)
|
||||||
printf("\t%s\t$5A\t\t\t; LEAVE\n", DB);
|
printf("\t%s\t$5A,$%02X\t\t\t; LEAVE\t%d\n", DB, localsize, localsize);
|
||||||
else
|
else
|
||||||
printf("\t%s\t$5C\t\t\t; RET\n", DB);
|
printf("\t%s\t$5C\t\t\t; RET\n", DB);
|
||||||
}
|
}
|
||||||
@ -823,14 +845,6 @@ void emit_start(void)
|
|||||||
outflags |= INIT;
|
outflags |= INIT;
|
||||||
defs++;
|
defs++;
|
||||||
}
|
}
|
||||||
void emit_push_exp(void)
|
|
||||||
{
|
|
||||||
printf("\t%s\t$34\t\t\t; PUSH EXP\n", DB);
|
|
||||||
}
|
|
||||||
void emit_pull_exp(void)
|
|
||||||
{
|
|
||||||
printf("\t%s\t$36\t\t\t; PULL EXP\n", DB);
|
|
||||||
}
|
|
||||||
void emit_drop(void)
|
void emit_drop(void)
|
||||||
{
|
{
|
||||||
emit_pending_seq();
|
emit_pending_seq();
|
||||||
@ -1001,7 +1015,6 @@ int try_dupify(t_opseq *op)
|
|||||||
{
|
{
|
||||||
if (op->code != opn->code)
|
if (op->code != opn->code)
|
||||||
return crunched;
|
return crunched;
|
||||||
|
|
||||||
switch (op->code)
|
switch (op->code)
|
||||||
{
|
{
|
||||||
case CONST_CODE:
|
case CONST_CODE:
|
||||||
@ -1017,19 +1030,16 @@ int try_dupify(t_opseq *op)
|
|||||||
case GADDR_CODE:
|
case GADDR_CODE:
|
||||||
case LAB_CODE:
|
case LAB_CODE:
|
||||||
case LAW_CODE:
|
case LAW_CODE:
|
||||||
if ((op->tag != opn->tag) || (op->offsz != opn->offsz) ||
|
if ((op->tag != opn->tag) || (op->offsz != opn->offsz) /*|| (op->type != opn->type)*/)
|
||||||
(op->type != opn->type))
|
|
||||||
return crunched;
|
return crunched;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return crunched;
|
return crunched;
|
||||||
}
|
}
|
||||||
|
|
||||||
opn->code = DUP_CODE;
|
opn->code = DUP_CODE;
|
||||||
crunched = 1;
|
crunched = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return crunched;
|
return crunched;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -1658,13 +1668,6 @@ int emit_pending_seq()
|
|||||||
case DUP_CODE:
|
case DUP_CODE:
|
||||||
emit_dup();
|
emit_dup();
|
||||||
break;
|
break;
|
||||||
break;
|
|
||||||
case PUSH_EXP_CODE:
|
|
||||||
emit_push_exp();
|
|
||||||
break;
|
|
||||||
case PULL_EXP_CODE:
|
|
||||||
emit_pull_exp();
|
|
||||||
break;
|
|
||||||
case BRNCH_CODE:
|
case BRNCH_CODE:
|
||||||
emit_brnch(op->tag);
|
emit_brnch(op->tag);
|
||||||
break;
|
break;
|
||||||
|
@ -1,12 +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.
|
|
||||||
*/
|
|
||||||
typedef struct _opseq {
|
typedef struct _opseq {
|
||||||
int code;
|
int code;
|
||||||
long val;
|
long val;
|
||||||
@ -68,8 +59,6 @@ typedef struct _opseq {
|
|||||||
#define INDEXW_CODE 0x0317
|
#define INDEXW_CODE 0x0317
|
||||||
#define DROP_CODE 0x0318
|
#define DROP_CODE 0x0318
|
||||||
#define DUP_CODE 0x0319
|
#define DUP_CODE 0x0319
|
||||||
#define PUSH_EXP_CODE 0x031A
|
|
||||||
#define PULL_EXP_CODE 0x031B
|
|
||||||
#define BRNCH_CODE 0x031C
|
#define BRNCH_CODE 0x031C
|
||||||
#define BRFALSE_CODE 0x031D
|
#define BRFALSE_CODE 0x031D
|
||||||
#define BRTRUE_CODE 0x031E
|
#define BRTRUE_CODE 0x031E
|
||||||
@ -89,8 +78,6 @@ typedef struct _opseq {
|
|||||||
#define gen_sb(seq) gen_seq(seq,SB_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_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_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 gen_drop(seq) gen_seq(seq,DROP_CODE,0,0,0,0)
|
||||||
#define gen_brfls(seq,tag) gen_seq(seq,BRFALSE_CODE,0,tag,0,0)
|
#define gen_brfls(seq,tag) gen_seq(seq,BRFALSE_CODE,0,tag,0,0)
|
||||||
#define gen_brtru(seq,tag) gen_seq(seq,BRTRUE_CODE,0,tag,0,0)
|
#define gen_brtru(seq,tag) gen_seq(seq,BRTRUE_CODE,0,tag,0,0)
|
||||||
@ -146,8 +133,6 @@ void emit_brlt(int tag);
|
|||||||
void emit_brne(int tag);
|
void emit_brne(int tag);
|
||||||
void emit_brnch(int tag);
|
void emit_brnch(int tag);
|
||||||
void emit_empty(void);
|
void emit_empty(void);
|
||||||
void emit_push_exp(void);
|
|
||||||
void emit_pull_exp(void);
|
|
||||||
void emit_drop(void);
|
void emit_drop(void);
|
||||||
void emit_dup(void);
|
void emit_dup(void);
|
||||||
void emit_leave(void);
|
void emit_leave(void);
|
||||||
|
@ -1,18 +1,3 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////
|
include "cmdsys.plh"
|
||||||
// Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
puts("Hello, world.\n")
|
||||||
// (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.
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
import STDLIB
|
|
||||||
predef puts
|
|
||||||
end
|
|
||||||
|
|
||||||
byte hellostr[] = "Hello, world.\n"
|
|
||||||
|
|
||||||
puts(@hellostr)
|
|
||||||
done
|
done
|
||||||
|
@ -1,12 +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.
|
(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>.
|
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
|
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
|
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
|
ANY KIND, either express or implied. See the License for the specific language
|
||||||
* governing permissions and limitations under the License.
|
governing permissions and limitations under the License.
|
||||||
*/
|
**************************************************************************************/
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -50,13 +50,18 @@ t_token keywords[] = {
|
|||||||
IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T',
|
IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T',
|
||||||
INCLUDE_TOKEN, 'I', 'N', 'C', 'L', 'U', 'D', 'E',
|
INCLUDE_TOKEN, 'I', 'N', 'C', 'L', 'U', 'D', 'E',
|
||||||
RETURN_TOKEN, 'R', 'E', 'T', 'U', 'R', 'N',
|
RETURN_TOKEN, 'R', 'E', 'T', 'U', 'R', 'N',
|
||||||
|
DROP_TOKEN, 'D', 'R', 'O', 'P',
|
||||||
END_TOKEN, 'E', 'N', 'D',
|
END_TOKEN, 'E', 'N', 'D',
|
||||||
DONE_TOKEN, 'D', 'O', 'N', 'E',
|
DONE_TOKEN, 'D', 'O', 'N', 'E',
|
||||||
LOGIC_NOT_TOKEN, 'N', 'O', 'T',
|
LOGIC_NOT_TOKEN, 'N', 'O', 'T',
|
||||||
LOGIC_AND_TOKEN, 'A', 'N', 'D',
|
LOGIC_AND_TOKEN, 'A', 'N', 'D',
|
||||||
LOGIC_OR_TOKEN, 'O', 'R',
|
LOGIC_OR_TOKEN, 'O', 'R',
|
||||||
|
BYTE_TOKEN, 'R', 'E', 'S',
|
||||||
BYTE_TOKEN, 'B', 'Y', 'T', 'E',
|
BYTE_TOKEN, 'B', 'Y', 'T', 'E',
|
||||||
|
BYTE_TOKEN, 'C', 'H', 'A', 'R',
|
||||||
|
BYTE_TOKEN, 'R', 'E', 'S',
|
||||||
WORD_TOKEN, 'W', 'O', 'R', 'D',
|
WORD_TOKEN, 'W', 'O', 'R', 'D',
|
||||||
|
WORD_TOKEN, 'V', 'A', 'R',
|
||||||
CONST_TOKEN, 'C', 'O', 'N', 'S', 'T',
|
CONST_TOKEN, 'C', 'O', 'N', 'S', 'T',
|
||||||
STRUC_TOKEN, 'S', 'T', 'R', 'U', 'C',
|
STRUC_TOKEN, 'S', 'T', 'R', 'U', 'C',
|
||||||
PREDEF_TOKEN, 'P', 'R', 'E', 'D', 'E', 'F',
|
PREDEF_TOKEN, 'P', 'R', 'E', 'D', 'E', 'F',
|
||||||
@ -415,11 +420,6 @@ t_token scan(void)
|
|||||||
scantoken = TERNARY_TOKEN;
|
scantoken = TERNARY_TOKEN;
|
||||||
scanpos += 2;
|
scanpos += 2;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
scantoken = TERNARY_TOKEN;
|
|
||||||
scanpos++;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
@ -433,7 +433,7 @@ t_token scan(void)
|
|||||||
}
|
}
|
||||||
void scan_rewind(char *backptr)
|
void scan_rewind(char *backptr)
|
||||||
{
|
{
|
||||||
scanpos = backptr;
|
scanpos = tokenstr = backptr;
|
||||||
}
|
}
|
||||||
int scan_lookahead(void)
|
int scan_lookahead(void)
|
||||||
{
|
{
|
||||||
|
@ -1,12 +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.
|
|
||||||
*/
|
|
||||||
extern char *statement, *scanpos, *tokenstr;
|
extern char *statement, *scanpos, *tokenstr;
|
||||||
extern t_token scantoken, prevtoken;
|
extern t_token scantoken, prevtoken;
|
||||||
extern int tokenlen;
|
extern int tokenlen;
|
||||||
|
@ -1,12 +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.
|
(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>.
|
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
|
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
|
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
|
ANY KIND, either express or implied. See the License for the specific language
|
||||||
* governing permissions and limitations under the License.
|
governing permissions and limitations under the License.
|
||||||
*/
|
**************************************************************************************/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "plasm.h"
|
#include "plasm.h"
|
||||||
@ -237,8 +237,12 @@ int parse_constval(void)
|
|||||||
type = id_type(tokenstr, tokenlen);
|
type = id_type(tokenstr, tokenlen);
|
||||||
if (type & CONST_TYPE)
|
if (type & CONST_TYPE)
|
||||||
value = id_const(tokenstr, tokenlen);
|
value = id_const(tokenstr, tokenlen);
|
||||||
else if ((type & (FUNC_TYPE | EXTERN_TYPE)) || ((type & ADDR_TYPE) && (mod == 8)))
|
else if (type & (FUNC_TYPE | ADDR_TYPE))
|
||||||
|
{
|
||||||
|
if (mod != 8)
|
||||||
|
parse_error("Invalid address constant");
|
||||||
value = id_tag(tokenstr, tokenlen);
|
value = id_tag(tokenstr, tokenlen);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return (0);
|
return (0);
|
||||||
break;
|
break;
|
||||||
@ -371,11 +375,11 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
}
|
}
|
||||||
else if (scantoken == BPTR_TOKEN || scantoken == WPTR_TOKEN)
|
else if (scantoken == BPTR_TOKEN || scantoken == WPTR_TOKEN)
|
||||||
{
|
{
|
||||||
deref++;
|
if (type & BPTR_TYPE)
|
||||||
if (!type)
|
|
||||||
type |= scantoken == BPTR_TOKEN ? BPTR_TYPE : WPTR_TYPE;
|
|
||||||
else if (scantoken == BPTR_TOKEN)
|
|
||||||
parse_error("Byte value used as pointer");
|
parse_error("Byte value used as pointer");
|
||||||
|
else
|
||||||
|
type = scantoken == BPTR_TOKEN ? BPTR_TYPE : WPTR_TYPE;
|
||||||
|
deref++;
|
||||||
}
|
}
|
||||||
else if (scantoken == NEG_TOKEN || scantoken == COMP_TOKEN || scantoken == LOGIC_NOT_TOKEN)
|
else if (scantoken == NEG_TOKEN || scantoken == COMP_TOKEN || scantoken == LOGIC_NOT_TOKEN)
|
||||||
{
|
{
|
||||||
@ -401,35 +405,41 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
if (scantoken == INT_TOKEN || scantoken == CHAR_TOKEN)
|
if (scantoken == INT_TOKEN || scantoken == CHAR_TOKEN)
|
||||||
{
|
{
|
||||||
value = constval;
|
value = constval;
|
||||||
type |= CONST_TYPE;
|
|
||||||
valseq = gen_const(NULL, value);
|
valseq = gen_const(NULL, value);
|
||||||
|
deref--;
|
||||||
}
|
}
|
||||||
else if (scantoken == ID_TOKEN)
|
else if (scantoken == ID_TOKEN)
|
||||||
{
|
{
|
||||||
if ((type |= id_type(tokenstr, tokenlen)) & CONST_TYPE)
|
if ((type |= id_type(tokenstr, tokenlen)) & CONST_TYPE)
|
||||||
{
|
{
|
||||||
value = id_const(tokenstr, tokenlen);
|
value = id_const(tokenstr, tokenlen);
|
||||||
valseq = gen_const(NULL, value);
|
valseq = gen_const(NULL, value);
|
||||||
|
deref--;
|
||||||
}
|
}
|
||||||
else //if (type & (VAR_TYPE | FUNC_TYPE))
|
else
|
||||||
{
|
{
|
||||||
value = id_tag(tokenstr, tokenlen);
|
value = id_tag(tokenstr, tokenlen);
|
||||||
if (type & LOCAL_TYPE)
|
if (type & LOCAL_TYPE)
|
||||||
valseq = gen_lcladr(NULL, value);
|
valseq = gen_lcladr(NULL, value);
|
||||||
else
|
else
|
||||||
valseq = gen_gbladr(NULL, value, type);
|
valseq = gen_gbladr(NULL, value, type);
|
||||||
}
|
if (type & FUNC_TYPE)
|
||||||
if (type & FUNC_TYPE)
|
{
|
||||||
{
|
cfnparms = funcparms_cnt(type);
|
||||||
cfnparms = funcparms_cnt(type);
|
cfnvals = funcvals_cnt(type);
|
||||||
cfnvals = funcvals_cnt(type);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (scantoken == LAMBDA_TOKEN)
|
else if (scantoken == LAMBDA_TOKEN)
|
||||||
{
|
{
|
||||||
type |= CONST_TYPE;
|
if (!rvalue) // Lambdas can't be LVALUEs
|
||||||
value = parse_lambda();
|
{
|
||||||
|
release_seq(uopseq);
|
||||||
|
return (codeseq);
|
||||||
|
}
|
||||||
|
value = parse_lambda();
|
||||||
valseq = gen_gbladr(NULL, value, FUNC_TYPE);
|
valseq = gen_gbladr(NULL, value, FUNC_TYPE);
|
||||||
|
deref--;
|
||||||
}
|
}
|
||||||
else if (scantoken == OPEN_PAREN_TOKEN)
|
else if (scantoken == OPEN_PAREN_TOKEN)
|
||||||
{
|
{
|
||||||
@ -437,9 +447,22 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
parse_error("Bad expression in parenthesis");
|
parse_error("Bad expression in parenthesis");
|
||||||
if (scantoken != CLOSE_PAREN_TOKEN)
|
if (scantoken != CLOSE_PAREN_TOKEN)
|
||||||
parse_error("Missing closing parenthesis");
|
parse_error("Missing closing parenthesis");
|
||||||
|
deref--;
|
||||||
|
}
|
||||||
|
else if (scantoken == DROP_TOKEN)
|
||||||
|
{
|
||||||
|
if (rvalue)
|
||||||
|
parse_error("DROP is LVALUE only");
|
||||||
|
codeseq = gen_drop(codeseq);
|
||||||
|
scan();
|
||||||
|
return (codeseq);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
release_seq(uopseq);
|
||||||
|
release_seq(codeseq);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Parse post operators.
|
* Parse post operators.
|
||||||
*/
|
*/
|
||||||
@ -453,33 +476,36 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
valseq = cat_seq(parse_list(NULL, &value), valseq);
|
valseq = cat_seq(parse_list(NULL, &value), valseq);
|
||||||
if (scantoken != CLOSE_PAREN_TOKEN)
|
if (scantoken != CLOSE_PAREN_TOKEN)
|
||||||
parse_error("Missing function call closing parenthesis");
|
parse_error("Missing function call closing parenthesis");
|
||||||
if (scan() == POUND_TOKEN)
|
if (type & FUNC_TYPE)
|
||||||
{
|
{
|
||||||
/*
|
if (cfnparms != value) // Can't check parm count on function pointers
|
||||||
* Set function pointer return vals count - can't do this to regular function call
|
parse_error("Parameter count mismatch");
|
||||||
*/
|
|
||||||
if (type & FUNC_TYPE)
|
|
||||||
parse_error("Overriding function return count");
|
|
||||||
if (!parse_const(&cfnvals))
|
|
||||||
parse_error("Invalid def return value count");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
scan_rewind(tokenstr);
|
|
||||||
if ((type & FUNC_TYPE) && (cfnparms != value))
|
|
||||||
parse_error("Parameter count mismatch");
|
|
||||||
if (stackdepth)
|
|
||||||
*stackdepth = cfnvals + cfnparms - value;
|
|
||||||
if (type & (VAR_TYPE | PTR_TYPE)) //!(type & (FUNC_TYPE | CONST_TYPE)))
|
|
||||||
{
|
{
|
||||||
valseq = gen_lw(valseq);
|
if (scan() == POUND_TOKEN)
|
||||||
if (deref)
|
{
|
||||||
deref--;
|
/*
|
||||||
|
* Set function pointer return vals count - can't do this to regular function call
|
||||||
|
*/
|
||||||
|
if (!parse_const(&cfnvals))
|
||||||
|
parse_error("Invalid def return value count");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
scan_rewind(tokenstr);
|
||||||
|
if (type & WORD_TYPE)
|
||||||
|
valseq = gen_lw(valseq);
|
||||||
|
else if (type & BYTE_TYPE)
|
||||||
|
parse_error("Using BYTE value as a pointer");
|
||||||
|
else
|
||||||
|
deref++;
|
||||||
}
|
}
|
||||||
valseq = gen_icall(valseq);
|
valseq = gen_icall(valseq);
|
||||||
if (stackdepth)
|
if (stackdepth)
|
||||||
*stackdepth = cfnvals;
|
*stackdepth += cfnvals - 1;
|
||||||
cfnvals = 1;
|
cfnparms = 0; cfnvals = 1;
|
||||||
type &= ~(FUNC_TYPE | VAR_TYPE);
|
type &= PTR_TYPE;
|
||||||
|
deref--;
|
||||||
}
|
}
|
||||||
else if (scantoken == OPEN_BRACKET_TOKEN)
|
else if (scantoken == OPEN_BRACKET_TOKEN)
|
||||||
{
|
{
|
||||||
@ -489,31 +515,29 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
if (type & FUNC_TYPE)
|
if (type & FUNC_TYPE)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Function call dereference
|
* Function address dereference
|
||||||
*/
|
*/
|
||||||
valseq = gen_icall(valseq);
|
cfnparms = 0; cfnvals = 1;
|
||||||
if (stackdepth)
|
|
||||||
*stackdepth = cfnvals;
|
|
||||||
}
|
}
|
||||||
while ((idxseq = parse_expr(NULL, stackdepth)))
|
while ((valseq = parse_expr(valseq, stackdepth)) && scantoken == COMMA_TOKEN)
|
||||||
{
|
{
|
||||||
valseq = cat_seq(valseq, idxseq);
|
|
||||||
if (scantoken != COMMA_TOKEN)
|
|
||||||
break;
|
|
||||||
valseq = gen_idxw(valseq);
|
valseq = gen_idxw(valseq);
|
||||||
valseq = gen_lw(valseq);
|
valseq = gen_lw(valseq); // Multi-dimenstion arrays are array pointers to arrays
|
||||||
}
|
}
|
||||||
if (scantoken != CLOSE_BRACKET_TOKEN)
|
if (scantoken != CLOSE_BRACKET_TOKEN)
|
||||||
parse_error("Missing closing bracket");
|
parse_error("Missing closing bracket");
|
||||||
if (type & (WPTR_TYPE | WORD_TYPE))
|
if (type & WORD_TYPE)
|
||||||
{
|
{
|
||||||
valseq = gen_idxw(valseq);
|
valseq = gen_idxw(valseq);
|
||||||
type = (type & PTR_TYPE) | WORD_TYPE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
valseq = gen_idxb(valseq);
|
valseq = gen_idxb(valseq);
|
||||||
type = (type & PTR_TYPE) | BYTE_TYPE;
|
if (!(type & BYTE_TYPE))
|
||||||
|
{
|
||||||
|
type = (type & PTR_TYPE) | BYTE_TYPE;
|
||||||
|
deref++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (scantoken == PTRB_TOKEN || scantoken == PTRW_TOKEN)
|
else if (scantoken == PTRB_TOKEN || scantoken == PTRW_TOKEN)
|
||||||
@ -526,23 +550,27 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
/*
|
/*
|
||||||
* Function call dereference
|
* Function call dereference
|
||||||
*/
|
*/
|
||||||
|
if (cfnparms)
|
||||||
|
parse_error("Parameter count mismatch");
|
||||||
valseq = gen_icall(valseq);
|
valseq = gen_icall(valseq);
|
||||||
if (stackdepth)
|
if (stackdepth)
|
||||||
*stackdepth = cfnvals;
|
*stackdepth += cfnvals - 1;
|
||||||
type &= ~FUNC_TYPE;
|
cfnparms = 0; cfnvals = 1;
|
||||||
}
|
}
|
||||||
else if (type & (VAR_TYPE | PTR_TYPE))
|
else if (type & WORD_TYPE)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Pointer dereference
|
* Pointer dereference
|
||||||
*/
|
*/
|
||||||
valseq = gen_lw(valseq);
|
valseq = gen_lw(valseq);
|
||||||
}
|
}
|
||||||
type = (scantoken == PTRB_TOKEN) ? BPTR_TYPE : WPTR_TYPE;
|
else if (type & BYTE_TYPE)
|
||||||
|
parse_error("Using BYTE value as a pointer");
|
||||||
|
else
|
||||||
|
deref++;
|
||||||
|
type = (type & PTR_TYPE) | (scantoken == PTRB_TOKEN) ? BYTE_TYPE : WORD_TYPE; // Type override
|
||||||
if (!parse_const(&const_offset))
|
if (!parse_const(&const_offset))
|
||||||
{
|
{
|
||||||
if (scantoken == EOL_TOKEN || scantoken == CLOSE_PAREN_TOKEN)
|
|
||||||
parse_error("Syntax");
|
|
||||||
/*
|
/*
|
||||||
* Setting type override for following operations
|
* Setting type override for following operations
|
||||||
*/
|
*/
|
||||||
@ -565,20 +593,15 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
if (type & FUNC_TYPE)
|
if (type & FUNC_TYPE)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Function call dereference
|
* Function address dereference
|
||||||
*/
|
*/
|
||||||
valseq = gen_icall(valseq);
|
cfnparms = 0; cfnvals = 1;
|
||||||
if (stackdepth)
|
|
||||||
*stackdepth = cfnvals;
|
|
||||||
type &= ~FUNC_TYPE;
|
|
||||||
}
|
}
|
||||||
type = (type & (VAR_TYPE | CONST_TYPE))
|
else if (!(type & VAR_TYPE))
|
||||||
? ((scantoken == DOT_TOKEN) ? BYTE_TYPE : WORD_TYPE)
|
deref++;
|
||||||
: ((scantoken == DOT_TOKEN) ? BPTR_TYPE : WPTR_TYPE);
|
type = (type & PTR_TYPE) | ((scantoken == DOT_TOKEN) ? BYTE_TYPE : WORD_TYPE); // Type override
|
||||||
if (!parse_const(&const_offset))
|
if (!parse_const(&const_offset))
|
||||||
{
|
{
|
||||||
if (scantoken == EOL_TOKEN || scantoken == CLOSE_PAREN_TOKEN)
|
|
||||||
parse_error("Syntax");
|
|
||||||
/*
|
/*
|
||||||
* Setting type override for following operations
|
* Setting type override for following operations
|
||||||
*/
|
*/
|
||||||
@ -596,35 +619,54 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Probably parsing RVALUE as LVALUE
|
||||||
|
*/
|
||||||
|
if (deref < 0)
|
||||||
|
{
|
||||||
|
release_seq(valseq);
|
||||||
|
release_seq(uopseq);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Resolve outstanding dereference pointer loads
|
* Resolve outstanding dereference pointer loads
|
||||||
*/
|
*/
|
||||||
while (deref > rvalue)
|
while (deref > rvalue)
|
||||||
{
|
{
|
||||||
deref--;
|
|
||||||
if (type & FUNC_TYPE)
|
if (type & FUNC_TYPE)
|
||||||
{
|
{
|
||||||
|
if (cfnparms)
|
||||||
|
parse_error("Parameter count mismatch");
|
||||||
valseq = gen_icall(valseq);
|
valseq = gen_icall(valseq);
|
||||||
if (stackdepth)
|
if (stackdepth)
|
||||||
*stackdepth = cfnvals;
|
*stackdepth += cfnvals - 1;
|
||||||
|
cfnparms = 0; cfnvals = 1;
|
||||||
type &= ~FUNC_TYPE;
|
type &= ~FUNC_TYPE;
|
||||||
}
|
}
|
||||||
else if (type & VAR_TYPE)
|
else //if (type & VAR_TYPE)
|
||||||
valseq = gen_lw(valseq);
|
valseq = gen_lw(valseq);
|
||||||
|
//else
|
||||||
|
// {fprintf(stderr,"deref=%d",deref);parse_error("What are we dereferencing #1?");}
|
||||||
|
deref--;
|
||||||
}
|
}
|
||||||
if (deref)
|
if (deref)
|
||||||
{
|
{
|
||||||
if (type & FUNC_TYPE)
|
if (type & FUNC_TYPE)
|
||||||
{
|
{
|
||||||
|
if (cfnparms)
|
||||||
|
parse_error("Parameter count mismatch");
|
||||||
valseq = gen_icall(valseq);
|
valseq = gen_icall(valseq);
|
||||||
if (stackdepth)
|
if (stackdepth)
|
||||||
*stackdepth = cfnvals;
|
*stackdepth += cfnvals - 1;
|
||||||
|
cfnparms = 0; cfnvals = 1;
|
||||||
type &= ~FUNC_TYPE;
|
type &= ~FUNC_TYPE;
|
||||||
}
|
}
|
||||||
else if (type & (BYTE_TYPE | BPTR_TYPE))
|
else if (type & (BYTE_TYPE | BPTR_TYPE))
|
||||||
valseq = gen_lb(valseq);
|
valseq = gen_lb(valseq);
|
||||||
else if (type & (WORD_TYPE | WPTR_TYPE))
|
else if (type & (WORD_TYPE | WPTR_TYPE))
|
||||||
valseq = gen_lw(valseq);
|
valseq = gen_lw(valseq);
|
||||||
|
else
|
||||||
|
parse_error("What are we dereferencing?");
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Output pre-operations
|
* Output pre-operations
|
||||||
@ -644,6 +686,8 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
release_seq(valseq);
|
release_seq(valseq);
|
||||||
return (NULL); // Function or const cannot be LVALUE, must be RVALUE
|
return (NULL); // Function or const cannot be LVALUE, must be RVALUE
|
||||||
}
|
}
|
||||||
|
if (stackdepth)
|
||||||
|
(*stackdepth)--;
|
||||||
}
|
}
|
||||||
return (cat_seq(codeseq, valseq));
|
return (cat_seq(codeseq, valseq));
|
||||||
}
|
}
|
||||||
@ -735,8 +779,7 @@ t_opseq *parse_set(t_opseq *codeseq)
|
|||||||
}
|
}
|
||||||
if (lparms == 0 || scantoken != SET_TOKEN)
|
if (lparms == 0 || scantoken != SET_TOKEN)
|
||||||
{
|
{
|
||||||
tokenstr = setptr;
|
scan_rewind(setptr);
|
||||||
scan_rewind(tokenstr);
|
|
||||||
while (lparms--)
|
while (lparms--)
|
||||||
release_seq(setseq[lparms]);
|
release_seq(setseq[lparms]);
|
||||||
while (lambda_cnt > lambda_set)
|
while (lambda_cnt > lambda_set)
|
||||||
@ -750,18 +793,15 @@ t_opseq *parse_set(t_opseq *codeseq)
|
|||||||
rseq = parse_list(NULL, &rparms);
|
rseq = parse_list(NULL, &rparms);
|
||||||
if (lparms > rparms)
|
if (lparms > rparms)
|
||||||
parse_error("Set value list underflow");
|
parse_error("Set value list underflow");
|
||||||
if ((lparms != rparms) && (rparms - lparms != 1))
|
|
||||||
codeseq = gen_pushexp(codeseq);
|
|
||||||
codeseq = cat_seq(codeseq, rseq);
|
codeseq = cat_seq(codeseq, rseq);
|
||||||
for (i = lparms - 1; i >= 0; i--)
|
if (lparms < rparms)
|
||||||
codeseq = cat_seq(codeseq, setseq[i]);
|
|
||||||
if (lparms != rparms)
|
|
||||||
{
|
{
|
||||||
if (rparms - lparms == 1)
|
parse_warn("Silently dropping extra rvalues");
|
||||||
|
for (i = rparms - lparms; i > 0; i--)
|
||||||
codeseq = gen_drop(codeseq);
|
codeseq = gen_drop(codeseq);
|
||||||
else
|
|
||||||
codeseq = gen_pullexp(codeseq);
|
|
||||||
}
|
}
|
||||||
|
while (lparms--)
|
||||||
|
codeseq = cat_seq(codeseq, setseq[lparms]);
|
||||||
return (codeseq);
|
return (codeseq);
|
||||||
}
|
}
|
||||||
int parse_stmnt(void)
|
int parse_stmnt(void)
|
||||||
@ -779,13 +819,17 @@ int parse_stmnt(void)
|
|||||||
switch (scantoken)
|
switch (scantoken)
|
||||||
{
|
{
|
||||||
case IF_TOKEN:
|
case IF_TOKEN:
|
||||||
if (!(seq = parse_expr(NULL, NULL)))
|
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||||
parse_error("Bad expression");
|
parse_error("Bad expression");
|
||||||
|
if (cfnvals > 1)
|
||||||
|
{
|
||||||
|
parse_warn("Expression value overflow");
|
||||||
|
while (cfnvals-- > 1) seq = gen_drop(seq);
|
||||||
|
}
|
||||||
tag_else = tag_new(BRANCH_TYPE);
|
tag_else = tag_new(BRANCH_TYPE);
|
||||||
tag_endif = tag_new(BRANCH_TYPE);
|
tag_endif = tag_new(BRANCH_TYPE);
|
||||||
seq = gen_brfls(seq, tag_else);
|
seq = gen_brfls(seq, tag_else);
|
||||||
emit_seq(seq);
|
emit_seq(seq);
|
||||||
//scan();
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
while (parse_stmnt()) next_line();
|
while (parse_stmnt()) next_line();
|
||||||
@ -793,8 +837,13 @@ int parse_stmnt(void)
|
|||||||
break;
|
break;
|
||||||
emit_brnch(tag_endif);
|
emit_brnch(tag_endif);
|
||||||
emit_codetag(tag_else);
|
emit_codetag(tag_else);
|
||||||
if (!(seq = parse_expr(NULL, NULL)))
|
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||||
parse_error("Bad expression");
|
parse_error("Bad expression");
|
||||||
|
if (cfnvals > 1)
|
||||||
|
{
|
||||||
|
parse_warn("Expression value overflow");
|
||||||
|
while (cfnvals-- > 1) seq = gen_drop(seq);
|
||||||
|
}
|
||||||
tag_else = tag_new(BRANCH_TYPE);
|
tag_else = tag_new(BRANCH_TYPE);
|
||||||
seq = gen_brfls(seq, tag_else);
|
seq = gen_brfls(seq, tag_else);
|
||||||
emit_seq(seq);
|
emit_seq(seq);
|
||||||
@ -823,11 +872,16 @@ int parse_stmnt(void)
|
|||||||
tag_prevbrk = break_tag;
|
tag_prevbrk = break_tag;
|
||||||
break_tag = tag_wend;
|
break_tag = tag_wend;
|
||||||
emit_codetag(tag_while);
|
emit_codetag(tag_while);
|
||||||
if (!(seq = parse_expr(NULL, NULL)))
|
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||||
parse_error("Bad expression");
|
parse_error("Bad expression");
|
||||||
|
if (cfnvals > 1)
|
||||||
|
{
|
||||||
|
parse_warn("Expression value overflow");
|
||||||
|
while (cfnvals-- > 1) seq = gen_drop(seq);
|
||||||
|
}
|
||||||
seq = gen_brfls(seq, tag_wend);
|
seq = gen_brfls(seq, tag_wend);
|
||||||
emit_seq(seq);
|
emit_seq(seq);
|
||||||
while (parse_stmnt()) next_line();
|
while (parse_stmnt()) next_line();
|
||||||
if (scantoken != LOOP_TOKEN)
|
if (scantoken != LOOP_TOKEN)
|
||||||
parse_error("Missing WHILE/END");
|
parse_error("Missing WHILE/END");
|
||||||
emit_brnch(tag_while);
|
emit_brnch(tag_while);
|
||||||
@ -848,8 +902,13 @@ int parse_stmnt(void)
|
|||||||
parse_error("Missing REPEAT/UNTIL");
|
parse_error("Missing REPEAT/UNTIL");
|
||||||
emit_codetag(cont_tag);
|
emit_codetag(cont_tag);
|
||||||
cont_tag = tag_prevcnt;
|
cont_tag = tag_prevcnt;
|
||||||
if (!(seq = parse_expr(NULL, NULL)))
|
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||||
parse_error("Bad expression");
|
parse_error("Bad expression");
|
||||||
|
if (cfnvals > 1)
|
||||||
|
{
|
||||||
|
parse_warn("Expression value overflow");
|
||||||
|
while (cfnvals-- > 1) seq = gen_drop(seq);
|
||||||
|
}
|
||||||
seq = gen_brfls(seq, tag_repeat);
|
seq = gen_brfls(seq, tag_repeat);
|
||||||
emit_seq(seq);
|
emit_seq(seq);
|
||||||
emit_codetag(break_tag);
|
emit_codetag(break_tag);
|
||||||
@ -868,8 +927,14 @@ int parse_stmnt(void)
|
|||||||
addr = id_tag(tokenstr, tokenlen);
|
addr = id_tag(tokenstr, tokenlen);
|
||||||
if (scan() != SET_TOKEN)
|
if (scan() != SET_TOKEN)
|
||||||
parse_error("Missing FOR =");
|
parse_error("Missing FOR =");
|
||||||
if (!emit_seq(parse_expr(NULL, NULL)))
|
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||||
parse_error("Bad FOR expression");
|
parse_error("Bad FOR expression");
|
||||||
|
if (cfnvals > 1)
|
||||||
|
{
|
||||||
|
parse_warn("Expression value overflow");
|
||||||
|
while (cfnvals-- > 1) seq = gen_drop(seq);
|
||||||
|
}
|
||||||
|
emit_seq(seq);
|
||||||
emit_codetag(tag_for);
|
emit_codetag(tag_for);
|
||||||
if (type & LOCAL_TYPE)
|
if (type & LOCAL_TYPE)
|
||||||
type & BYTE_TYPE ? emit_dlb(addr) : emit_dlw(addr);
|
type & BYTE_TYPE ? emit_dlb(addr) : emit_dlw(addr);
|
||||||
@ -881,13 +946,25 @@ int parse_stmnt(void)
|
|||||||
step = -1;
|
step = -1;
|
||||||
else
|
else
|
||||||
parse_error("Missing FOR TO");
|
parse_error("Missing FOR TO");
|
||||||
if (!emit_seq(parse_expr(NULL, NULL)))
|
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||||
parse_error("Bad FOR TO expression");
|
parse_error("Bad FOR TO expression");
|
||||||
|
if (cfnvals > 1)
|
||||||
|
{
|
||||||
|
parse_warn("Expression value overflow");
|
||||||
|
while (cfnvals-- > 1) seq = gen_drop(seq);
|
||||||
|
}
|
||||||
|
emit_seq(seq);
|
||||||
step > 0 ? emit_brgt(break_tag) : emit_brlt(break_tag);
|
step > 0 ? emit_brgt(break_tag) : emit_brlt(break_tag);
|
||||||
if (scantoken == STEP_TOKEN)
|
if (scantoken == STEP_TOKEN)
|
||||||
{
|
{
|
||||||
if (!emit_seq(parse_expr(NULL, NULL)))
|
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||||
parse_error("Bad FOR STEP expression");
|
parse_error("Bad FOR STEP expression");
|
||||||
|
if (cfnvals > 1)
|
||||||
|
{
|
||||||
|
parse_warn("Expression value overflow");
|
||||||
|
while (cfnvals-- > 1) seq = gen_drop(seq);
|
||||||
|
}
|
||||||
|
emit_seq(seq);
|
||||||
emit_op(step > 0 ? ADD_TOKEN : SUB_TOKEN);
|
emit_op(step > 0 ? ADD_TOKEN : SUB_TOKEN);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -908,15 +985,27 @@ int parse_stmnt(void)
|
|||||||
break_tag = tag_new(BRANCH_TYPE);
|
break_tag = tag_new(BRANCH_TYPE);
|
||||||
tag_choice = tag_new(BRANCH_TYPE);
|
tag_choice = tag_new(BRANCH_TYPE);
|
||||||
tag_of = tag_new(BRANCH_TYPE);
|
tag_of = tag_new(BRANCH_TYPE);
|
||||||
if (!emit_seq(parse_expr(NULL, NULL)))
|
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||||
parse_error("Bad CASE expression");
|
parse_error("Bad CASE expression");
|
||||||
|
if (cfnvals > 1)
|
||||||
|
{
|
||||||
|
parse_warn("Expression value overflow");
|
||||||
|
while (cfnvals-- > 1) seq = gen_drop(seq);
|
||||||
|
}
|
||||||
|
emit_seq(seq);
|
||||||
next_line();
|
next_line();
|
||||||
while (scantoken != ENDCASE_TOKEN)
|
while (scantoken != ENDCASE_TOKEN)
|
||||||
{
|
{
|
||||||
if (scantoken == OF_TOKEN)
|
if (scantoken == OF_TOKEN)
|
||||||
{
|
{
|
||||||
if (!emit_seq(parse_expr(NULL, NULL)))
|
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||||
parse_error("Bad CASE OF expression");
|
parse_error("Bad CASE OF expression");
|
||||||
|
if (cfnvals > 1)
|
||||||
|
{
|
||||||
|
parse_warn("Expression value overflow");
|
||||||
|
while (cfnvals-- > 1) seq = gen_drop(seq);
|
||||||
|
}
|
||||||
|
emit_seq(seq);
|
||||||
emit_brne(tag_choice);
|
emit_brne(tag_choice);
|
||||||
emit_codetag(tag_of);
|
emit_codetag(tag_of);
|
||||||
while (parse_stmnt()) next_line();
|
while (parse_stmnt()) next_line();
|
||||||
@ -947,18 +1036,18 @@ int parse_stmnt(void)
|
|||||||
break_tag = tag_prevbrk;
|
break_tag = tag_prevbrk;
|
||||||
stack_loop--;
|
stack_loop--;
|
||||||
break;
|
break;
|
||||||
case CONTINUE_TOKEN:
|
|
||||||
if (cont_tag)
|
|
||||||
emit_brnch(cont_tag);
|
|
||||||
else
|
|
||||||
parse_error("CONTINUE without loop");
|
|
||||||
break;
|
|
||||||
case BREAK_TOKEN:
|
case BREAK_TOKEN:
|
||||||
if (break_tag)
|
if (break_tag)
|
||||||
emit_brnch(break_tag);
|
emit_brnch(break_tag);
|
||||||
else
|
else
|
||||||
parse_error("BREAK without loop");
|
parse_error("BREAK without loop");
|
||||||
break;
|
break;
|
||||||
|
case CONTINUE_TOKEN:
|
||||||
|
if (cont_tag)
|
||||||
|
emit_brnch(cont_tag);
|
||||||
|
else
|
||||||
|
parse_error("CONTINUE without loop");
|
||||||
|
break;
|
||||||
case RETURN_TOKEN:
|
case RETURN_TOKEN:
|
||||||
if (infunc)
|
if (infunc)
|
||||||
{
|
{
|
||||||
@ -979,13 +1068,21 @@ int parse_stmnt(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!emit_seq(parse_expr(NULL, NULL)))
|
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||||
emit_const(0);
|
emit_const(0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (cfnvals > 1)
|
||||||
|
{
|
||||||
|
parse_warn("Expression value overflow");
|
||||||
|
while (cfnvals-- > 1) seq = gen_drop(seq);
|
||||||
|
}
|
||||||
|
emit_seq(seq);
|
||||||
|
}
|
||||||
emit_ret();
|
emit_ret();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EOL_TOKEN:
|
case EOL_TOKEN:
|
||||||
//case COMMENT_TOKEN:
|
|
||||||
return (1);
|
return (1);
|
||||||
case ELSE_TOKEN:
|
case ELSE_TOKEN:
|
||||||
case ELSEIF_TOKEN:
|
case ELSEIF_TOKEN:
|
||||||
@ -1013,23 +1110,18 @@ int parse_stmnt(void)
|
|||||||
{
|
{
|
||||||
emit_seq(rseq);
|
emit_seq(rseq);
|
||||||
emit_unaryop(scantoken);
|
emit_unaryop(scantoken);
|
||||||
tokenstr = idptr;
|
scan_rewind(idptr);
|
||||||
scan_rewind(tokenstr);
|
|
||||||
emit_seq(parse_value(NULL, LVALUE, NULL));
|
emit_seq(parse_value(NULL, LVALUE, NULL));
|
||||||
}
|
}
|
||||||
else if (scantoken != SET_TOKEN)
|
else
|
||||||
{
|
{
|
||||||
if (stackdepth > 1)
|
while (stackdepth)
|
||||||
{
|
{
|
||||||
rseq = cat_seq(gen_pushexp(NULL), rseq);
|
|
||||||
rseq = cat_seq(rseq, gen_pullexp(NULL));
|
|
||||||
}
|
|
||||||
else if (stackdepth == 1)
|
|
||||||
rseq = cat_seq(rseq, gen_drop(NULL));
|
rseq = cat_seq(rseq, gen_drop(NULL));
|
||||||
|
stackdepth--;
|
||||||
|
}
|
||||||
emit_seq(rseq);
|
emit_seq(rseq);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
parse_error("Invalid LVALUE");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
parse_error("Syntax error");
|
parse_error("Syntax error");
|
||||||
@ -1037,22 +1129,14 @@ int parse_stmnt(void)
|
|||||||
}
|
}
|
||||||
return (scan() == EOL_TOKEN);
|
return (scan() == EOL_TOKEN);
|
||||||
}
|
}
|
||||||
int parse_var(int type)
|
int parse_var(int type, long basesize)
|
||||||
{
|
{
|
||||||
char *idstr;
|
char *idstr;
|
||||||
long constval;
|
long constval;
|
||||||
int consttype, constsize, arraysize, idlen = 0;
|
|
||||||
long size = 1;
|
long size = 1;
|
||||||
|
int consttype, constsize, arraysize, idlen = 0;
|
||||||
|
|
||||||
if (scan() == OPEN_BRACKET_TOKEN)
|
if (scan() == ID_TOKEN)
|
||||||
{
|
|
||||||
size = 0;
|
|
||||||
parse_constexpr(&size, &constsize);
|
|
||||||
if (scantoken != CLOSE_BRACKET_TOKEN)
|
|
||||||
parse_error("Missing closing bracket");
|
|
||||||
scan();
|
|
||||||
}
|
|
||||||
if (scantoken == ID_TOKEN)
|
|
||||||
{
|
{
|
||||||
idstr = tokenstr;
|
idstr = tokenstr;
|
||||||
idlen = tokenlen;
|
idlen = tokenlen;
|
||||||
@ -1065,8 +1149,7 @@ int parse_var(int type)
|
|||||||
scan();
|
scan();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type & WORD_TYPE)
|
size *= basesize;
|
||||||
size *= 2;
|
|
||||||
if (scantoken == SET_TOKEN)
|
if (scantoken == SET_TOKEN)
|
||||||
{
|
{
|
||||||
if (type & (EXTERN_TYPE | LOCAL_TYPE))
|
if (type & (EXTERN_TYPE | LOCAL_TYPE))
|
||||||
@ -1092,13 +1175,23 @@ int parse_var(int type)
|
|||||||
else
|
else
|
||||||
parse_error("Bad variable initializer");
|
parse_error("Bad variable initializer");
|
||||||
}
|
}
|
||||||
else if (idlen)
|
else
|
||||||
id_add(idstr, idlen, type, size);
|
{
|
||||||
|
if (idlen)
|
||||||
|
id_add(idstr, idlen, type, size);
|
||||||
|
else if (!(type & EXTERN_TYPE))
|
||||||
|
{
|
||||||
|
if (type & LOCAL_TYPE)
|
||||||
|
idlocal_size(size);
|
||||||
|
else
|
||||||
|
emit_data(0, 0, 0, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
int parse_struc(void)
|
int parse_struc(void)
|
||||||
{
|
{
|
||||||
long size;
|
long basesize, size;
|
||||||
int type, constsize, offset = 0;
|
int type, constsize, offset = 0;
|
||||||
char *idstr, strucid[80];
|
char *idstr, strucid[80];
|
||||||
int idlen = 0, struclen = 0;
|
int idlen = 0, struclen = 0;
|
||||||
@ -1114,17 +1207,19 @@ int parse_struc(void)
|
|||||||
{
|
{
|
||||||
if (scantoken == EOL_TOKEN)
|
if (scantoken == EOL_TOKEN)
|
||||||
continue;
|
continue;
|
||||||
size = 1;
|
basesize = 1;
|
||||||
type = scantoken == BYTE_TOKEN ? BYTE_TYPE : WORD_TYPE;
|
type = scantoken == BYTE_TOKEN ? BYTE_TYPE : WORD_TYPE;
|
||||||
if (scan() == OPEN_BRACKET_TOKEN)
|
if (scan() == OPEN_BRACKET_TOKEN)
|
||||||
{
|
{
|
||||||
size = 0;
|
basesize = 0;
|
||||||
parse_constexpr(&size, &constsize);
|
parse_constexpr(&basesize, &constsize);
|
||||||
if (scantoken != CLOSE_BRACKET_TOKEN)
|
if (scantoken != CLOSE_BRACKET_TOKEN)
|
||||||
parse_error("Missing closing bracket");
|
parse_error("Missing closing bracket");
|
||||||
scan();
|
scan();
|
||||||
}
|
}
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
|
size = 1;
|
||||||
idlen = 0;
|
idlen = 0;
|
||||||
if (scantoken == ID_TOKEN)
|
if (scantoken == ID_TOKEN)
|
||||||
{
|
{
|
||||||
@ -1139,6 +1234,7 @@ int parse_struc(void)
|
|||||||
scan();
|
scan();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
size *= basesize;
|
||||||
if (type & WORD_TYPE)
|
if (type & WORD_TYPE)
|
||||||
size *= 2;
|
size *= 2;
|
||||||
if (idlen)
|
if (idlen)
|
||||||
@ -1149,7 +1245,7 @@ int parse_struc(void)
|
|||||||
if (struclen)
|
if (struclen)
|
||||||
idconst_add(strucid, struclen, offset);
|
idconst_add(strucid, struclen, offset);
|
||||||
if (scantoken != END_TOKEN)
|
if (scantoken != END_TOKEN)
|
||||||
return (0);
|
parse_error("Missing STRUC/END");
|
||||||
scan();
|
scan();
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -1164,7 +1260,7 @@ int parse_vars(int type)
|
|||||||
{
|
{
|
||||||
case SYSFLAGS_TOKEN:
|
case SYSFLAGS_TOKEN:
|
||||||
if (type & (EXTERN_TYPE | LOCAL_TYPE))
|
if (type & (EXTERN_TYPE | LOCAL_TYPE))
|
||||||
parse_error("sysflags must be global");
|
parse_error("SYSFLAGS must be global");
|
||||||
if (!parse_constexpr(&value, &size))
|
if (!parse_constexpr(&value, &size))
|
||||||
parse_error("Bad constant");
|
parse_error("Bad constant");
|
||||||
emit_sysflags(value);
|
emit_sysflags(value);
|
||||||
@ -1181,8 +1277,7 @@ int parse_vars(int type)
|
|||||||
idconst_add(idstr, idlen, value);
|
idconst_add(idstr, idlen, value);
|
||||||
break;
|
break;
|
||||||
case STRUC_TOKEN:
|
case STRUC_TOKEN:
|
||||||
if (!parse_struc())
|
parse_struc();
|
||||||
parse_error("Bad structure definition");
|
|
||||||
break;
|
break;
|
||||||
case EXPORT_TOKEN:
|
case EXPORT_TOKEN:
|
||||||
if (type & (EXTERN_TYPE | LOCAL_TYPE))
|
if (type & (EXTERN_TYPE | LOCAL_TYPE))
|
||||||
@ -1203,86 +1298,63 @@ int parse_vars(int type)
|
|||||||
*/
|
*/
|
||||||
case BYTE_TOKEN:
|
case BYTE_TOKEN:
|
||||||
case WORD_TOKEN:
|
case WORD_TOKEN:
|
||||||
type |= (scantoken == BYTE_TOKEN) ? BYTE_TYPE : WORD_TYPE;
|
type |= (scantoken == BYTE_TOKEN) ? BYTE_TYPE : WORD_TYPE;
|
||||||
if (!parse_var(type))
|
cfnvals = 1; // Just co-opt a long variable for this case
|
||||||
return (0);
|
if (scan() == OPEN_BRACKET_TOKEN)
|
||||||
while (scantoken == COMMA_TOKEN)
|
|
||||||
{
|
{
|
||||||
if (!parse_var(type))
|
//
|
||||||
return (0);
|
// Get base size for variables
|
||||||
|
//
|
||||||
|
cfnvals = 0;
|
||||||
|
parse_constexpr(&cfnvals, &size);
|
||||||
|
if (scantoken != CLOSE_BRACKET_TOKEN)
|
||||||
|
parse_error("Missing closing bracket");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
scan_rewind(tokenstr);
|
||||||
|
if (type & WORD_TYPE)
|
||||||
|
cfnvals *= 2;
|
||||||
|
do parse_var(type, cfnvals); while (scantoken == COMMA_TOKEN);
|
||||||
break;
|
break;
|
||||||
case PREDEF_TOKEN:
|
case PREDEF_TOKEN:
|
||||||
/*
|
/*
|
||||||
* Pre definition.
|
* Pre definition.
|
||||||
*/
|
*/
|
||||||
if (scan() == ID_TOKEN)
|
do
|
||||||
{
|
{
|
||||||
type |= PREDEF_TYPE;
|
if (scan() == ID_TOKEN)
|
||||||
idstr = tokenstr;
|
|
||||||
idlen = tokenlen;
|
|
||||||
cfnparms = 0;
|
|
||||||
cfnvals = 1; // Default to one return value for compatibility
|
|
||||||
if (scan() == OPEN_PAREN_TOKEN)
|
|
||||||
{
|
{
|
||||||
do
|
type = (type & ~FUNC_PARMVALS) | PREDEF_TYPE;
|
||||||
|
idstr = tokenstr;
|
||||||
|
idlen = tokenlen;
|
||||||
|
cfnparms = 0;
|
||||||
|
cfnvals = 1; // Default to one return value for compatibility
|
||||||
|
if (scan() == OPEN_PAREN_TOKEN)
|
||||||
{
|
{
|
||||||
if (scan() == ID_TOKEN)
|
do
|
||||||
{
|
{
|
||||||
cfnparms++;
|
if (scan() == ID_TOKEN)
|
||||||
scan();
|
|
||||||
}
|
|
||||||
} while (scantoken == COMMA_TOKEN);
|
|
||||||
if (scantoken != CLOSE_PAREN_TOKEN)
|
|
||||||
parse_error("Bad function parameter list");
|
|
||||||
scan();
|
|
||||||
}
|
|
||||||
if (scantoken == POUND_TOKEN)
|
|
||||||
{
|
|
||||||
if (!parse_const(&cfnvals))
|
|
||||||
parse_error("Invalid def return value count");
|
|
||||||
scan();
|
|
||||||
}
|
|
||||||
type |= funcparms_type(cfnparms) | funcvals_type(cfnvals);
|
|
||||||
idfunc_add(idstr, idlen, type, tag_new(type));
|
|
||||||
while (scantoken == COMMA_TOKEN)
|
|
||||||
{
|
|
||||||
if (scan() == ID_TOKEN)
|
|
||||||
{
|
|
||||||
idstr = tokenstr;
|
|
||||||
idlen = tokenlen;
|
|
||||||
type &= ~FUNC_PARMVALS;
|
|
||||||
cfnparms = 0;
|
|
||||||
cfnvals = 1; // Default to one return value for compatibility
|
|
||||||
if (scan() == OPEN_PAREN_TOKEN)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
if (scan() == ID_TOKEN)
|
cfnparms++;
|
||||||
{
|
scan();
|
||||||
cfnparms++;
|
}
|
||||||
scan();
|
} while (scantoken == COMMA_TOKEN);
|
||||||
}
|
if (scantoken != CLOSE_PAREN_TOKEN)
|
||||||
} while (scantoken == COMMA_TOKEN);
|
parse_error("Bad function parameter list");
|
||||||
if (scantoken != CLOSE_PAREN_TOKEN)
|
scan();
|
||||||
parse_error("Bad function parameter list");
|
|
||||||
scan();
|
|
||||||
}
|
|
||||||
if (scantoken == POUND_TOKEN)
|
|
||||||
{
|
|
||||||
if (!parse_const(&cfnvals))
|
|
||||||
parse_error("Invalid def return value count");
|
|
||||||
scan();
|
|
||||||
}
|
|
||||||
type |= funcparms_type(cfnparms) | funcvals_type(cfnvals);
|
|
||||||
idfunc_add(idstr, idlen, type, tag_new(type));
|
|
||||||
}
|
}
|
||||||
else
|
if (scantoken == POUND_TOKEN)
|
||||||
parse_error("Bad function pre-declaration");
|
{
|
||||||
|
if (!parse_const(&cfnvals))
|
||||||
|
parse_error("Invalid def return value count");
|
||||||
|
scan();
|
||||||
|
}
|
||||||
|
type |= funcparms_type(cfnparms) | funcvals_type(cfnvals);
|
||||||
|
idfunc_add(idstr, idlen, type, tag_new(type));
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
parse_error("Bad function pre-declaration");
|
||||||
parse_error("Bad function pre-declaration");
|
} while (scantoken == COMMA_TOKEN);
|
||||||
case EOL_TOKEN:
|
case EOL_TOKEN:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1301,7 +1373,7 @@ int parse_mods(void)
|
|||||||
while (parse_vars(EXTERN_TYPE)) next_line();
|
while (parse_vars(EXTERN_TYPE)) next_line();
|
||||||
if (scantoken != END_TOKEN)
|
if (scantoken != END_TOKEN)
|
||||||
parse_error("Missing END");
|
parse_error("Missing END");
|
||||||
return (scan() == EOL_TOKEN);
|
scan();
|
||||||
}
|
}
|
||||||
if (scantoken == EOL_TOKEN)
|
if (scantoken == EOL_TOKEN)
|
||||||
return (1);
|
return (1);
|
||||||
@ -1312,7 +1384,6 @@ int parse_lambda(void)
|
|||||||
{
|
{
|
||||||
int func_tag;
|
int func_tag;
|
||||||
int cfnparms;
|
int cfnparms;
|
||||||
char *expr;
|
|
||||||
|
|
||||||
if (!infunc)
|
if (!infunc)
|
||||||
parse_error("Lambda functions only allowed inside definitions");
|
parse_error("Lambda functions only allowed inside definitions");
|
||||||
@ -1337,7 +1408,6 @@ int parse_lambda(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
parse_error("Missing parameter list in lambda function");
|
parse_error("Missing parameter list in lambda function");
|
||||||
expr = scanpos;
|
|
||||||
if (scan_lookahead() == OPEN_PAREN_TOKEN)
|
if (scan_lookahead() == OPEN_PAREN_TOKEN)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -1,10 +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
|
|
||||||
* governing permissions and limitations under the License.
|
|
||||||
*/
|
|
||||||
int parse_module(void);
|
int parse_module(void);
|
||||||
|
@ -1,12 +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.
|
(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>.
|
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
|
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
|
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
|
ANY KIND, either express or implied. See the License for the specific language
|
||||||
* governing permissions and limitations under the License.
|
governing permissions and limitations under the License.
|
||||||
*/
|
**************************************************************************************/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "plasm.h"
|
#include "plasm.h"
|
||||||
|
|
||||||
|
@ -1,12 +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.
|
|
||||||
*/
|
|
||||||
/*
|
/*
|
||||||
* Global flags.
|
* Global flags.
|
||||||
*/
|
*/
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
/**************************************************************************************
|
||||||
|
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 <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -40,17 +49,47 @@ word *esp = eval_stack + EVAL_STACKSZ;
|
|||||||
|
|
||||||
#define SYMTBLSZ 1024
|
#define SYMTBLSZ 1024
|
||||||
#define SYMSZ 16
|
#define SYMSZ 16
|
||||||
#define MODTBLSZ 128
|
|
||||||
#define MODSZ 16
|
|
||||||
#define MODLSTSZ 32
|
|
||||||
byte symtbl[SYMTBLSZ];
|
byte symtbl[SYMTBLSZ];
|
||||||
byte *lastsym = symtbl;
|
byte *lastsym = symtbl;
|
||||||
byte modtbl[MODTBLSZ];
|
|
||||||
byte *lastmod = modtbl;
|
|
||||||
/*
|
/*
|
||||||
* Predef.
|
* Predef.
|
||||||
*/
|
*/
|
||||||
void interp(code *ip);
|
void interp(code *ip);
|
||||||
|
/*
|
||||||
|
* CMDSYS exports
|
||||||
|
*/
|
||||||
|
char *syslib_exp[] = {
|
||||||
|
"CMDSYS",
|
||||||
|
"MACHID",
|
||||||
|
"PUTC",
|
||||||
|
"PUTLN",
|
||||||
|
"PUTS",
|
||||||
|
"PUTI",
|
||||||
|
"GETC",
|
||||||
|
"GETS",
|
||||||
|
"PUTB",
|
||||||
|
"PUTH",
|
||||||
|
"TOUPPER",
|
||||||
|
"CALL",
|
||||||
|
"SYSCALL",
|
||||||
|
"HEAPMARK",
|
||||||
|
"HEAPALLOCALLIGN",
|
||||||
|
"HEAPALLOC",
|
||||||
|
"HEAPRELEASE",
|
||||||
|
"HEAPAVAIL",
|
||||||
|
"MEMSET",
|
||||||
|
"MEMCPY",
|
||||||
|
"STRCPY",
|
||||||
|
"STRCAT",
|
||||||
|
"SEXT",
|
||||||
|
"DIVMOD",
|
||||||
|
"ISUGT",
|
||||||
|
"ISUGE",
|
||||||
|
"ISULT",
|
||||||
|
"ISULE",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility routines.
|
* Utility routines.
|
||||||
*
|
*
|
||||||
@ -181,19 +220,6 @@ uword add_sym(byte *sym, int addr)
|
|||||||
/*
|
/*
|
||||||
* Module routines.
|
* Module routines.
|
||||||
*/
|
*/
|
||||||
void dump_mod(void)
|
|
||||||
{
|
|
||||||
printf("\nSystem Module Table:\n");
|
|
||||||
dump_tbl(modtbl);
|
|
||||||
}
|
|
||||||
uword lookup_mod(byte *mod)
|
|
||||||
{
|
|
||||||
return lookup_tbl(mod, modtbl);
|
|
||||||
}
|
|
||||||
uword add_mod(byte *mod, int addr)
|
|
||||||
{
|
|
||||||
return add_tbl(mod, addr, &lastmod);
|
|
||||||
}
|
|
||||||
uword defcall_add(int bank, int addr)
|
uword defcall_add(int bank, int addr)
|
||||||
{
|
{
|
||||||
mem_data[lastdef] = bank ? 2 : 1;
|
mem_data[lastdef] = bank ? 2 : 1;
|
||||||
@ -204,7 +230,7 @@ uword defcall_add(int bank, int addr)
|
|||||||
uword def_lookup(byte *cdd, int defaddr)
|
uword def_lookup(byte *cdd, int defaddr)
|
||||||
{
|
{
|
||||||
int i, calldef = 0;
|
int i, calldef = 0;
|
||||||
for (i = 0; cdd[i * 4] == 0x02; i++)
|
for (i = 0; cdd[i * 4] == 0x00; i++)
|
||||||
{
|
{
|
||||||
if ((cdd[i * 4 + 1] | (cdd[i * 4 + 2] << 8)) == defaddr)
|
if ((cdd[i * 4 + 1] | (cdd[i * 4 + 2] << 8)) == defaddr)
|
||||||
{
|
{
|
||||||
@ -248,7 +274,7 @@ int load_mod(byte *mod)
|
|||||||
moddep = header + 1;
|
moddep = header + 1;
|
||||||
modsize = header[0] | (header[1] << 8);
|
modsize = header[0] | (header[1] << 8);
|
||||||
magic = header[2] | (header[3] << 8);
|
magic = header[2] | (header[3] << 8);
|
||||||
if (magic == 0xDA7F)
|
if (magic == 0x6502)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This is a relocatable bytecode module.
|
* This is a relocatable bytecode module.
|
||||||
@ -263,7 +289,7 @@ int load_mod(byte *mod)
|
|||||||
*/
|
*/
|
||||||
while (*moddep)
|
while (*moddep)
|
||||||
{
|
{
|
||||||
if (lookup_mod(moddep) == 0)
|
if (lookup_sym(moddep) == 0)
|
||||||
{
|
{
|
||||||
if (fd)
|
if (fd)
|
||||||
{
|
{
|
||||||
@ -324,7 +350,7 @@ int load_mod(byte *mod)
|
|||||||
/*
|
/*
|
||||||
* Add module to symbol table.
|
* Add module to symbol table.
|
||||||
*/
|
*/
|
||||||
add_mod(mod, modaddr);
|
add_sym(mod, modaddr);
|
||||||
/*
|
/*
|
||||||
* Print out the Re-Location Dictionary.
|
* Print out the Re-Location Dictionary.
|
||||||
*/
|
*/
|
||||||
@ -337,6 +363,7 @@ int load_mod(byte *mod)
|
|||||||
if (show_state) printf("\tDEF CODE");
|
if (show_state) printf("\tDEF CODE");
|
||||||
addr = rld[1] | (rld[2] << 8);
|
addr = rld[1] | (rld[2] << 8);
|
||||||
addr += modfix - MOD_ADDR;
|
addr += modfix - MOD_ADDR;
|
||||||
|
rld[0] = 0; // Set call code to 0
|
||||||
rld[1] = addr;
|
rld[1] = addr;
|
||||||
rld[2] = addr >> 8;
|
rld[2] = addr >> 8;
|
||||||
end = rld - mem_data + 4;
|
end = rld - mem_data + 4;
|
||||||
@ -437,28 +464,33 @@ void interp(code *ip);
|
|||||||
void call(uword pc)
|
void call(uword pc)
|
||||||
{
|
{
|
||||||
unsigned int i, s;
|
unsigned int i, s;
|
||||||
|
int a, b;
|
||||||
char c, sz[64];
|
char c, sz[64];
|
||||||
|
|
||||||
if (show_state)
|
if (show_state)
|
||||||
printf("\nCall code:$%02X\n", mem_data[pc]);
|
printf("\nCall: %s\n", mem_data[pc] ? syslib_exp[mem_data[pc] - 1] : "BYTECODE");
|
||||||
switch (mem_data[pc++])
|
switch (mem_data[pc++])
|
||||||
{
|
{
|
||||||
case 0: // NULL call
|
case 0: // BYTECODE in mem_data
|
||||||
printf("NULL call code\n");
|
|
||||||
break;
|
|
||||||
case 1: // BYTECODE in mem_code
|
|
||||||
//interp(mem_code + (mem_data[pc] + (mem_data[pc + 1] << 8)));
|
|
||||||
break;
|
|
||||||
case 2: // BYTECODE in mem_data
|
|
||||||
interp(mem_data + (mem_data[pc] + (mem_data[pc + 1] << 8)));
|
interp(mem_data + (mem_data[pc] + (mem_data[pc + 1] << 8)));
|
||||||
break;
|
break;
|
||||||
|
case 1: // CMDSYS call
|
||||||
|
printf("CMD call code!\n");
|
||||||
|
break;
|
||||||
|
case 2: // MACHID
|
||||||
|
printf("MACHID call code!\n");
|
||||||
|
break;
|
||||||
case 3: // LIBRARY STDLIB::PUTC
|
case 3: // LIBRARY STDLIB::PUTC
|
||||||
c = POP;
|
c = POP;
|
||||||
if (c == 0x0D)
|
if (c == 0x0D)
|
||||||
c = '\n';
|
c = '\n';
|
||||||
putchar(c);
|
putchar(c);
|
||||||
break;
|
break;
|
||||||
case 4: // LIBRARY STDLIB::PUTS
|
case 4: // LIBRARY STDLIB::PUTNL
|
||||||
|
putchar('\n');
|
||||||
|
fflush(stdout);
|
||||||
|
break;
|
||||||
|
case 5: // LIBRARY STDLIB::PUTS
|
||||||
s = POP;
|
s = POP;
|
||||||
i = mem_data[s++];
|
i = mem_data[s++];
|
||||||
while (i--)
|
while (i--)
|
||||||
@ -469,39 +501,31 @@ void call(uword pc)
|
|||||||
putchar(c);
|
putchar(c);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5: // LIBRARY STDLIB::PUTSZ
|
case 6: // LIBRARY STDLIB::PUTI
|
||||||
s = POP;
|
i = POP;
|
||||||
while ((c = mem_data[s++]))
|
printf("%d", i);
|
||||||
{
|
|
||||||
if (c == 0x0D)
|
|
||||||
c = '\n';
|
|
||||||
putchar(c);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 6: // LIBRARY STDLIB::GETC
|
case 7: // LIBRARY STDLIB::GETC
|
||||||
PUSH(getchar());
|
PUSH(getchar());
|
||||||
break;
|
break;
|
||||||
case 7: // LIBRARY STDLIB::GETS
|
case 8: // LIBRARY STDLIB::GETS
|
||||||
|
c = POP;
|
||||||
|
putchar(c);
|
||||||
gets(sz);
|
gets(sz);
|
||||||
for (i = 0; sz[i]; i++)
|
for (i = 0; sz[i]; i++)
|
||||||
mem_data[0x200 + i] = sz[i];
|
mem_data[0x200 + i] = sz[i];
|
||||||
mem_data[0x200 + i] = 0;
|
mem_data[0x200 + i] = 0;
|
||||||
mem_data[0x1FF] = i;
|
mem_data[0x1FF] = i;
|
||||||
PUSH(i);
|
PUSH(0x1FF);
|
||||||
break;
|
break;
|
||||||
case 8: // LIBRARY STDLIB::PUTNL
|
case 24: // LIBRARY CMDSYS::DIVMOD
|
||||||
putchar('\n');
|
a = POP;
|
||||||
fflush(stdout);
|
b = POP;
|
||||||
break;
|
PUSH(b / a);
|
||||||
case 9: // LIBRARY STDLIB::MACHID
|
PUSH(b % a);
|
||||||
PUSH(0x0000);
|
|
||||||
break;
|
|
||||||
case 10: // LIBRARY STDLIB::PUTI
|
|
||||||
i = POP;
|
|
||||||
printf("%d", i);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("\nBad call code:$%02X\n", mem_data[pc - 1]);
|
printf("\nUnimplemented call code:$%02X\n", mem_data[pc - 1]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -658,12 +682,9 @@ void interp(code *ip)
|
|||||||
val = TOS;
|
val = TOS;
|
||||||
PUSH(val);
|
PUSH(val);
|
||||||
break;
|
break;
|
||||||
case 0x34: // PUSH : TOSP = TOS
|
case 0x34: // NOP
|
||||||
val = esp - eval_stack;
|
|
||||||
PHA(val);
|
|
||||||
break;
|
break;
|
||||||
case 0x36: // PULL : TOS = TOSP
|
case 0x36: // NOP
|
||||||
esp = eval_stack + PLA;
|
|
||||||
break;
|
break;
|
||||||
case 0x38: // BRGT : TOS-1 > TOS ? IP += (IP)
|
case 0x38: // BRGT : TOS-1 > TOS ? IP += (IP)
|
||||||
val = POP;
|
val = POP;
|
||||||
@ -873,22 +894,11 @@ void interp(code *ip)
|
|||||||
*/
|
*/
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Illegal opcode 0x%02X @ 0x%04X\n", ip[-1], ip - mem_data);
|
fprintf(stderr, "Illegal opcode 0x%02X @ 0x%04X\n", ip[-1], ip - mem_data);
|
||||||
|
exit(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *syslib_exp[] = {
|
|
||||||
"PUTC",
|
|
||||||
"PUTS",
|
|
||||||
"PUTSZ",
|
|
||||||
"GETC",
|
|
||||||
"GETS",
|
|
||||||
"PUTLN",
|
|
||||||
"MACHID",
|
|
||||||
"PUTI",
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
byte dci[32];
|
byte dci[32];
|
||||||
@ -906,17 +916,16 @@ int main(int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
* Add default library.
|
* Add default library.
|
||||||
*/
|
*/
|
||||||
stodci("CMDSYS", dci);
|
|
||||||
add_mod(dci, 0xFFFF);
|
|
||||||
for (i = 0; syslib_exp[i]; i++)
|
for (i = 0; syslib_exp[i]; i++)
|
||||||
{
|
{
|
||||||
mem_data[i] = i + 3;
|
mem_data[i] = i;
|
||||||
stodci(syslib_exp[i], dci);
|
stodci(syslib_exp[i], dci);
|
||||||
add_sym(dci, i);
|
add_sym(dci, i+1);
|
||||||
}
|
}
|
||||||
if (argc)
|
if (argc)
|
||||||
{
|
{
|
||||||
stodci(*argv, dci);
|
stodci(*argv, dci);
|
||||||
|
if (show_state) dump_sym();
|
||||||
load_mod(dci);
|
load_mod(dci);
|
||||||
if (show_state) dump_sym();
|
if (show_state) dump_sym();
|
||||||
argc--;
|
argc--;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -10,39 +10,30 @@
|
|||||||
|
|
||||||
;**********************************************************
|
;**********************************************************
|
||||||
;*
|
;*
|
||||||
;* VM ZERO PAGE LOCATIONS
|
;* VM ZERO PAGE LOCATIONS
|
||||||
;*
|
;*
|
||||||
;**********************************************************
|
;**********************************************************
|
||||||
SRC = $06
|
SRC = $06
|
||||||
SRCL = SRC
|
SRCL = SRC
|
||||||
SRCH = SRC+1
|
SRCH = SRC+1
|
||||||
DST = SRC+2
|
DST = SRC+2
|
||||||
DSTL = DST
|
DSTL = DST
|
||||||
DSTH = DST+1
|
DSTH = DST+1
|
||||||
ESTKSZ = $20
|
ESGUARD = $BE
|
||||||
ESTK = $C0
|
ESTKSZ = $20
|
||||||
ESTKL = ESTK
|
ESTK = $C0
|
||||||
ESTKH = ESTK+ESTKSZ/2
|
ESTKH = ESTK
|
||||||
VMZP = ESTK+ESTKSZ
|
ESTKL = ESTK+ESTKSZ/2
|
||||||
IFP = VMZP
|
VMZP = ESTK+ESTKSZ
|
||||||
IFPL = IFP
|
IFP = VMZP
|
||||||
IFPH = IFP+1
|
IFPL = IFP
|
||||||
PP = IFP+2
|
IFPH = IFP+1
|
||||||
PPL = PP
|
PP = IFP+2
|
||||||
PPH = PP+1
|
PPL = PP
|
||||||
IPY = PP+2
|
PPH = PP+1
|
||||||
TMP = IPY+1
|
IPY = PP+2
|
||||||
TMPL = TMP
|
ESP = IPY+1
|
||||||
TMPH = TMP+1
|
JMPTMP = ESP+1
|
||||||
NPARMS = TMPL
|
TMP = JMPTMP+1
|
||||||
FRMSZ = TMPH
|
TMPL = TMP
|
||||||
DVSIGN = TMP+2
|
TMPH = TMP+1
|
||||||
ESP = TMP+2
|
|
||||||
DROP = $EF
|
|
||||||
NEXTOP = $F0
|
|
||||||
FETCHOP = NEXTOP+3
|
|
||||||
IP = FETCHOP+1
|
|
||||||
IPL = IP
|
|
||||||
IPH = IPL+1
|
|
||||||
OPIDX = FETCHOP+6
|
|
||||||
OPPAGE = OPIDX+1
|
|
||||||
|
@ -1,12 +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.
|
* Symbol table types.
|
||||||
*/
|
*/
|
||||||
@ -29,6 +20,7 @@
|
|||||||
#define EXPORT_TYPE (1 << 12)
|
#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_TYPE (ASM_TYPE | DEF_TYPE | PREDEF_TYPE)
|
||||||
|
#define ACCESSED_TYPE (1 << 15)
|
||||||
#define FUNC_PARMS (0x0F << 16)
|
#define FUNC_PARMS (0x0F << 16)
|
||||||
#define FUNC_VALS (0x0F << 20)
|
#define FUNC_VALS (0x0F << 20)
|
||||||
#define FUNC_PARMVALS (FUNC_PARMS|FUNC_VALS)
|
#define FUNC_PARMVALS (FUNC_PARMS|FUNC_VALS)
|
||||||
@ -54,4 +46,6 @@ int id_tag(char *name, int len);
|
|||||||
int id_const(char *name, int len);
|
int id_const(char *name, int len);
|
||||||
int id_type(char *name, int len);
|
int id_type(char *name, int len);
|
||||||
void idglobal_size(int type, int size, int constsize);
|
void idglobal_size(int type, int size, int constsize);
|
||||||
|
void idlocal_size(int size);
|
||||||
|
void idlocal_size(int size);
|
||||||
int tag_new(int type);
|
int tag_new(int type);
|
||||||
|
@ -81,8 +81,11 @@ def printfunc(a, b, lambda)#0
|
|||||||
puti(lambda(a,b))
|
puti(lambda(a,b))
|
||||||
putln
|
putln
|
||||||
end
|
end
|
||||||
|
def vals123#3
|
||||||
|
return 1, 2, 3
|
||||||
|
end
|
||||||
export def main(range)#0
|
export def main(range)#0
|
||||||
byte a
|
word a, b, c
|
||||||
word lambda
|
word lambda
|
||||||
|
|
||||||
a = 10
|
a = 10
|
||||||
@ -120,6 +123,19 @@ export def main(range)#0
|
|||||||
printfunc(1, 2, &(a,b) (a-b))
|
printfunc(1, 2, &(a,b) (a-b))
|
||||||
lambda = &(x,y) x * y
|
lambda = &(x,y) x * y
|
||||||
puti(lambda(2,3));putln
|
puti(lambda(2,3));putln
|
||||||
|
a = vals123
|
||||||
|
drop, b, drop = vals123
|
||||||
|
drop, drop, c = vals123
|
||||||
|
puts("a, b, c = "); puti(a); puts(", "); puti(b); puts(", "); puti(c); putln
|
||||||
|
puts(" 7 / 3 = "); puti(7/3); puts(" ; 7 % 3 = "); puti(7%3); putln
|
||||||
|
puts(" 7 / -3 = "); puti(7/-3); puts("; 7 % -3 = "); puti(7%-3); putln
|
||||||
|
puts("-7 / 3 = "); puti(-7/3); puts("; -7 % 3 = "); puti(-7%3); putln
|
||||||
|
puts("-7 / -3 = "); puti(-7/-3); puts(" ; -7 % -3 = "); puti(-7%-3); putln
|
||||||
|
puts("-1 / 3 = "); puti(-1/3); puts(" ; -1 % 3 = "); puti(-1%3); putln
|
||||||
|
a,b=divmod(7,3); puts("divmod( 7, 3) = "); puti(a); puts(", "); puti(b); putln
|
||||||
|
a,b=divmod(7,-3); puts("divmod( 7,-3) = "); puti(a); puts(", "); puti(b); putln
|
||||||
|
a,b=divmod(-7,3); puts("divmod(-7, 3) = "); puti(a); puts(", "); puti(b); putln
|
||||||
|
a,b=divmod(-7,-3);puts("divmod(-7,-3) = "); puti(a); puts(", "); puti(b); putln
|
||||||
end
|
end
|
||||||
|
|
||||||
def dummy(zz)#2
|
def dummy(zz)#2
|
||||||
@ -165,17 +181,29 @@ putln
|
|||||||
puts(@constr); puti(constval); putln
|
puts(@constr); puti(constval); putln
|
||||||
puts("Signed byte constant:"); puti(-3); putln
|
puts("Signed byte constant:"); puti(-3); putln
|
||||||
puts("Hello from in-line string!\$7F\n")
|
puts("Hello from in-line string!\$7F\n")
|
||||||
puti(array:0); puts(" == "); puti(array:1); puts (" is "); puts(array:0 == array:1 ?? "TRUE\n" :: "FALSE\n")
|
puti(array:0); puts(" == "); puti(array:1); puts (" is ")
|
||||||
puti(array:0); puts(" <> "); puti(array:1); puts (" is "); puts(array:0 <> array:1 ?? "TRUE\n" :: "FALSE\n")
|
puts(array:0 == array:1 ?? "TRUE\n" :: "FALSE\n")
|
||||||
puti(array:0); puts(" >= "); puti(array:1); puts (" is "); puts(array:0 >= array:1 ?? "TRUE\n" :: "FALSE\n")
|
puti(array:0); puts(" <> "); puti(array:1); puts (" is ")
|
||||||
puti(array:0); puts(" <= "); puti(array:1); puts (" is "); puts(array:0 <= array:1 ?? "TRUE\n" :: "FALSE\n")
|
puts(array:0 <> array:1 ?? "TRUE\n" :: "FALSE\n")
|
||||||
puti(array:0); puts(" > "); puti(array:1); puts (" is "); puts(array:0 > array:1 ?? "TRUE\n" :: "FALSE\n")
|
puti(array:0); puts(" >= "); puti(array:1); puts (" is ")
|
||||||
puti(array:0); puts(" < "); puti(array:1); puts (" is "); puts(array:0 < array:1 ?? "TRUE\n" :: "FALSE\n")
|
puts(array:0 >= array:1 ?? "TRUE\n" :: "FALSE\n")
|
||||||
puti(array:0); puts(" == "); puti(array:0); puts (" is "); puts(array:0 == array:0 ?? "TRUE\n" :: "FALSE\n")
|
puti(array:0); puts(" <= "); puti(array:1); puts (" is ")
|
||||||
puti(array:0); puts(" <> "); puti(array:0); puts (" is "); puts(array:0 <> array:0 ?? "TRUE\n" :: "FALSE\n")
|
puts(array:0 <= array:1 ?? "TRUE\n" :: "FALSE\n")
|
||||||
puti(array:0); puts(" >= "); puti(array:0); puts (" is "); puts(array:0 >= array:0 ?? "TRUE\n" :: "FALSE\n")
|
puti(array:0); puts(" > "); puti(array:1); puts (" is ")
|
||||||
puti(array:0); puts(" <= "); puti(array:0); puts (" is "); puts(array:0 <= array:0 ?? "TRUE\n" :: "FALSE\n")
|
puts(array:0 > array:1 ?? "TRUE\n" :: "FALSE\n")
|
||||||
puti(array:0); puts(" > "); puti(array:0); puts (" is "); puts(array:0 > array:0 ?? "TRUE\n" :: "FALSE\n")
|
puti(array:0); puts(" < "); puti(array:1); puts (" is ")
|
||||||
puti(array:0); puts(" < "); puti(array:0); puts (" is "); puts(array:0 < array:0 ?? "TRUE\n" :: "FALSE\n")
|
puts(array:0 < array:1 ?? "TRUE\n" :: "FALSE\n")
|
||||||
|
puti(array:0); puts(" == "); puti(array:0); puts (" is ")
|
||||||
|
puts(array:0 == array:0 ?? "TRUE\n" :: "FALSE\n")
|
||||||
|
puti(array:0); puts(" <> "); puti(array:0); puts (" is ")
|
||||||
|
puts(array:0 <> array:0 ?? "TRUE\n" :: "FALSE\n")
|
||||||
|
puti(array:0); puts(" >= "); puti(array:0); puts (" is ")
|
||||||
|
puts(array:0 >= array:0 ?? "TRUE\n" :: "FALSE\n")
|
||||||
|
puti(array:0); puts(" <= "); puti(array:0); puts (" is ")
|
||||||
|
puts(array:0 <= array:0 ?? "TRUE\n" :: "FALSE\n")
|
||||||
|
puti(array:0); puts(" > "); puti(array:0); puts (" is ")
|
||||||
|
puts(array:0 > array:0 ?? "TRUE\n" :: "FALSE\n")
|
||||||
|
puti(array:0); puts(" < "); puti(array:0); puts (" is ")
|
||||||
|
puts(array:0 < array:0 ?? "TRUE\n" :: "FALSE\n")
|
||||||
ptr = 0
|
ptr = 0
|
||||||
done
|
done
|
||||||
|
@ -5,14 +5,14 @@ include "cmdsys.plh"
|
|||||||
//
|
//
|
||||||
// Module data.
|
// Module data.
|
||||||
//
|
//
|
||||||
predef puth(h)#0
|
predef puthex(h)#0
|
||||||
export word print[] = @puti, @puth, @putln, @puts, @putc
|
export word print[] = @puti, @puthex, @putln, @puts, @putc
|
||||||
byte valstr[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
|
byte valstr[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
|
||||||
byte loadstr[] = "testlib loaded!"
|
byte loadstr[] = "testlib loaded!"
|
||||||
//
|
//
|
||||||
// Define functions.
|
// Define functions.
|
||||||
//
|
//
|
||||||
def puth(h)#0
|
def puthex(h)#0
|
||||||
putc('$')
|
putc('$')
|
||||||
putc(valstr[(h >> 12) & $0F])
|
putc(valstr[(h >> 12) & $0F])
|
||||||
putc(valstr[(h >> 8) & $0F])
|
putc(valstr[(h >> 8) & $0F])
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import testlib
|
import testlib
|
||||||
predef puti
|
|
||||||
word print
|
word print
|
||||||
const dec = 0
|
const dec = 0
|
||||||
const hex = 2
|
const hex = 2
|
||||||
const newln = 4
|
const newln = 4
|
||||||
const str = 6
|
const str = 6
|
||||||
const char = 8
|
const chr = 8
|
||||||
end
|
end
|
||||||
|
@ -1,12 +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.
|
|
||||||
*/
|
|
||||||
#define TOKEN(c) (0x80|(c))
|
#define TOKEN(c) (0x80|(c))
|
||||||
#define IS_TOKEN(c) (0x80&(c))
|
#define IS_TOKEN(c) (0x80&(c))
|
||||||
/*
|
/*
|
||||||
@ -44,8 +35,8 @@
|
|||||||
#define PREDEF_TOKEN TOKEN(22)
|
#define PREDEF_TOKEN TOKEN(22)
|
||||||
#define DEF_TOKEN TOKEN(23)
|
#define DEF_TOKEN TOKEN(23)
|
||||||
#define ASM_TOKEN TOKEN(24)
|
#define ASM_TOKEN TOKEN(24)
|
||||||
#define IMPORT_TOKEN TOKEN(25)
|
#define IMPORT_TOKEN TOKEN(25)
|
||||||
#define EXPORT_TOKEN TOKEN(26)
|
#define EXPORT_TOKEN TOKEN(26)
|
||||||
#define DONE_TOKEN TOKEN(27)
|
#define DONE_TOKEN TOKEN(27)
|
||||||
#define RETURN_TOKEN TOKEN(28)
|
#define RETURN_TOKEN TOKEN(28)
|
||||||
#define BREAK_TOKEN TOKEN(29)
|
#define BREAK_TOKEN TOKEN(29)
|
||||||
@ -116,7 +107,8 @@
|
|||||||
#define COLON_TOKEN TOKEN(':')
|
#define COLON_TOKEN TOKEN(':')
|
||||||
#define POUND_TOKEN TOKEN('#')
|
#define POUND_TOKEN TOKEN('#')
|
||||||
#define COMMA_TOKEN TOKEN(',')
|
#define COMMA_TOKEN TOKEN(',')
|
||||||
#define COMMENT_TOKEN TOKEN(';')
|
//#define COMMENT_TOKEN TOKEN(';')
|
||||||
|
#define DROP_TOKEN TOKEN(';')
|
||||||
#define EOL_TOKEN TOKEN(0)
|
#define EOL_TOKEN TOKEN(0)
|
||||||
#define INCLUDE_TOKEN TOKEN(0x7E)
|
#define INCLUDE_TOKEN TOKEN(0x7E)
|
||||||
#define EOF_TOKEN TOKEN(0x7F)
|
#define EOF_TOKEN TOKEN(0x7F)
|
||||||
|
Loading…
Reference in New Issue
Block a user