mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-07-05 01:28:57 +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
|
||||
//
|
||||
// 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_80COL = $02
|
||||
const MACHID_MEM = $03
|
||||
const MACHID_48K = $10
|
||||
const MACHID_64K = $20
|
||||
const MACHID_128K = $30
|
||||
const MACHID_MODEL = $C8
|
||||
@ -30,16 +39,23 @@ import cmdsys
|
||||
const modkeep = $2000
|
||||
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
|
||||
//
|
||||
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 heapmark()#1, heapallocalign(size, pow2, freeaddr), heapalloc(size)#1, heaprelease(newheap)#1, heapavail()#1
|
||||
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0
|
||||
predef isugt(a,b)#1, isuge(a,b)#1, isult(a,b)#1, isule(a,b)#1
|
||||
predef modload(mod)#1, modexec(modfile)#1, modaddr(str)#1
|
||||
predef heapmark()#1, heapallocalign(size, pow2, freeaddr)#1
|
||||
predef heapalloc(size)#1, heaprelease(newheap)#1, heapavail()#1
|
||||
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0, strcpy(dst,src)#1, strcat(dst,src)#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
|
||||
|
@ -1,12 +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.
|
||||
*/
|
||||
/**************************************************************************************
|
||||
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 <string.h>
|
||||
@ -26,6 +26,7 @@ static int defs = 0;
|
||||
static int asmdefs = 0;
|
||||
static int codetags = 1; // Fix check for break_tag and cont_tag
|
||||
static int fixups = 0;
|
||||
static int lastglobalsize = 0;
|
||||
static char idconst_name[1024][ID_LEN+1];
|
||||
static int idconst_value[1024];
|
||||
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;
|
||||
while (len--)
|
||||
{
|
||||
if (name[len] != id[1 + len])
|
||||
if (toupper(name[len]) != id[1 + len])
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
@ -82,7 +83,11 @@ int idglobal_lookup(char *name, int len)
|
||||
int i;
|
||||
for (i = 0; i < globals; i++)
|
||||
if (id_match(name, len, &(idglobal_name[i][0])))
|
||||
{
|
||||
if (idglobal_type[i] & EXTERN_TYPE)
|
||||
idglobal_type[i] |= ACCESSED_TYPE;
|
||||
return (i);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
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;
|
||||
if (len > ID_LEN) len = ID_LEN;
|
||||
while (len--)
|
||||
idconst_name[consts][1 + len] = name[len];
|
||||
idconst_name[consts][1 + len] = toupper(name[len]);
|
||||
idconst_value[consts] = value;
|
||||
consts++;
|
||||
return (1);
|
||||
@ -128,7 +133,7 @@ int idlocal_add(char *name, int len, int type, int size)
|
||||
idlocal_name[locals][0] = len;
|
||||
if (len > ID_LEN) len = ID_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_offset[locals] = localsize;
|
||||
localsize += size;
|
||||
@ -158,7 +163,7 @@ int idglobal_add(char *name, int len, int type, int size)
|
||||
idglobal_name[globals][0] = len;
|
||||
if (len > ID_LEN) len = ID_LEN;
|
||||
while (len--)
|
||||
idglobal_name[globals][1 + len] = name[len];
|
||||
idglobal_name[globals][1 + len] = toupper(name[len]);
|
||||
idglobal_type[globals] = 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;
|
||||
if (len > ID_LEN) len = ID_LEN;
|
||||
while (len--)
|
||||
idglobal_name[globals][1 + len] = name[len];
|
||||
idglobal_name[globals][1 + len] = toupper(name[len]);
|
||||
idglobal_type[globals] = type;
|
||||
idglobal_tag[globals++] = tag;
|
||||
if (type & EXTERN_TYPE)
|
||||
@ -236,6 +241,14 @@ void idglobal_size(int type, int size, int constsize)
|
||||
else if (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 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("_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_SUBSEG\t\t\t; BYTECODE SUB-SEGMENT\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");
|
||||
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]);
|
||||
printf("\t%s\t$10\t\t\t; EXTERNAL SYMBOL FLAG\n", DB);
|
||||
printf("\t%s\t%d\t\t\t; ESD INDEX\n", DW, idglobal_tag[i]);
|
||||
}
|
||||
else if (idglobal_type[i] & EXPORT_TYPE)
|
||||
else if (idglobal_type[i] & EXPORT_TYPE)
|
||||
{
|
||||
emit_dci(&idglobal_name[i][1], idglobal_name[i][0]);
|
||||
printf("\t%s\t$08\t\t\t; ENTRY SYMBOL FLAG\n", DB);
|
||||
@ -454,7 +467,10 @@ void emit_moddep(char *name, int len)
|
||||
if (outflags & MODULE)
|
||||
{
|
||||
if (name)
|
||||
{
|
||||
emit_dci(name, len);
|
||||
idglobal_add(name, len, EXTERN_TYPE | WORD_TYPE, 2); // Add to symbol table
|
||||
}
|
||||
else
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
outflags |= BYTECODE_SEG;
|
||||
}
|
||||
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)
|
||||
{
|
||||
lastglobalsize = size;
|
||||
if (size == 0)
|
||||
printf("_D%03d%c\t\t\t\t\t; %s\n", tag, LBL, name);
|
||||
else
|
||||
@ -508,7 +529,7 @@ void emit_lambdafunc(int tag, char *name, int cparams, t_opseq *lambda_seq)
|
||||
emit_seq(lambda_seq);
|
||||
emit_pending_seq();
|
||||
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
|
||||
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)
|
||||
{
|
||||
emit_pending_seq();
|
||||
printf("\t%s\t$3C\t\t\t; BREQ\t_B%03d\n", DB, tag);
|
||||
printf("\t%s\t_B%03d-*\n", DW, tag);
|
||||
}
|
||||
@ -803,7 +825,7 @@ void emit_leave(void)
|
||||
{
|
||||
emit_pending_seq();
|
||||
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
|
||||
printf("\t%s\t$5C\t\t\t; RET\n", DB);
|
||||
}
|
||||
@ -823,14 +845,6 @@ void emit_start(void)
|
||||
outflags |= INIT;
|
||||
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)
|
||||
{
|
||||
emit_pending_seq();
|
||||
@ -1001,7 +1015,6 @@ int try_dupify(t_opseq *op)
|
||||
{
|
||||
if (op->code != opn->code)
|
||||
return crunched;
|
||||
|
||||
switch (op->code)
|
||||
{
|
||||
case CONST_CODE:
|
||||
@ -1017,19 +1030,16 @@ int try_dupify(t_opseq *op)
|
||||
case GADDR_CODE:
|
||||
case LAB_CODE:
|
||||
case LAW_CODE:
|
||||
if ((op->tag != opn->tag) || (op->offsz != opn->offsz) ||
|
||||
(op->type != opn->type))
|
||||
if ((op->tag != opn->tag) || (op->offsz != opn->offsz) /*|| (op->type != opn->type)*/)
|
||||
return crunched;
|
||||
break;
|
||||
|
||||
default:
|
||||
return crunched;
|
||||
}
|
||||
|
||||
opn->code = DUP_CODE;
|
||||
crunched = 1;
|
||||
crunched = 1;
|
||||
}
|
||||
|
||||
return crunched;
|
||||
}
|
||||
/*
|
||||
@ -1658,13 +1668,6 @@ int emit_pending_seq()
|
||||
case DUP_CODE:
|
||||
emit_dup();
|
||||
break;
|
||||
break;
|
||||
case PUSH_EXP_CODE:
|
||||
emit_push_exp();
|
||||
break;
|
||||
case PULL_EXP_CODE:
|
||||
emit_pull_exp();
|
||||
break;
|
||||
case BRNCH_CODE:
|
||||
emit_brnch(op->tag);
|
||||
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 {
|
||||
int code;
|
||||
long val;
|
||||
@ -68,8 +59,6 @@ typedef struct _opseq {
|
||||
#define INDEXW_CODE 0x0317
|
||||
#define DROP_CODE 0x0318
|
||||
#define DUP_CODE 0x0319
|
||||
#define PUSH_EXP_CODE 0x031A
|
||||
#define PULL_EXP_CODE 0x031B
|
||||
#define BRNCH_CODE 0x031C
|
||||
#define BRFALSE_CODE 0x031D
|
||||
#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_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 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)
|
||||
@ -146,8 +133,6 @@ void emit_brlt(int tag);
|
||||
void emit_brne(int tag);
|
||||
void emit_brnch(int tag);
|
||||
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);
|
||||
|
@ -1,18 +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.
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
import STDLIB
|
||||
predef puts
|
||||
end
|
||||
|
||||
byte hellostr[] = "Hello, world.\n"
|
||||
|
||||
puts(@hellostr)
|
||||
include "cmdsys.plh"
|
||||
puts("Hello, world.\n")
|
||||
done
|
||||
|
@ -1,12 +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.
|
||||
*/
|
||||
/**************************************************************************************
|
||||
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 <stdlib.h>
|
||||
@ -50,13 +50,18 @@ t_token keywords[] = {
|
||||
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',
|
||||
DROP_TOKEN, 'D', 'R', 'O', 'P',
|
||||
END_TOKEN, 'E', 'N', 'D',
|
||||
DONE_TOKEN, 'D', 'O', 'N', 'E',
|
||||
LOGIC_NOT_TOKEN, 'N', 'O', 'T',
|
||||
LOGIC_AND_TOKEN, 'A', 'N', 'D',
|
||||
LOGIC_OR_TOKEN, 'O', 'R',
|
||||
BYTE_TOKEN, 'R', 'E', 'S',
|
||||
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, 'V', 'A', 'R',
|
||||
CONST_TOKEN, 'C', 'O', 'N', 'S', 'T',
|
||||
STRUC_TOKEN, 'S', 'T', 'R', 'U', 'C',
|
||||
PREDEF_TOKEN, 'P', 'R', 'E', 'D', 'E', 'F',
|
||||
@ -415,11 +420,6 @@ t_token scan(void)
|
||||
scantoken = TERNARY_TOKEN;
|
||||
scanpos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
scantoken = TERNARY_TOKEN;
|
||||
scanpos++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
@ -433,7 +433,7 @@ t_token scan(void)
|
||||
}
|
||||
void scan_rewind(char *backptr)
|
||||
{
|
||||
scanpos = backptr;
|
||||
scanpos = tokenstr = backptr;
|
||||
}
|
||||
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 t_token scantoken, prevtoken;
|
||||
extern int tokenlen;
|
||||
|
@ -1,12 +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.
|
||||
*/
|
||||
/**************************************************************************************
|
||||
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 <string.h>
|
||||
#include "plasm.h"
|
||||
@ -237,8 +237,12 @@ int parse_constval(void)
|
||||
type = id_type(tokenstr, tokenlen);
|
||||
if (type & CONST_TYPE)
|
||||
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);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
break;
|
||||
@ -371,11 +375,11 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
||||
}
|
||||
else if (scantoken == BPTR_TOKEN || scantoken == WPTR_TOKEN)
|
||||
{
|
||||
deref++;
|
||||
if (!type)
|
||||
type |= scantoken == BPTR_TOKEN ? BPTR_TYPE : WPTR_TYPE;
|
||||
else if (scantoken == BPTR_TOKEN)
|
||||
if (type & BPTR_TYPE)
|
||||
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)
|
||||
{
|
||||
@ -401,35 +405,41 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
||||
if (scantoken == INT_TOKEN || scantoken == CHAR_TOKEN)
|
||||
{
|
||||
value = constval;
|
||||
type |= CONST_TYPE;
|
||||
valseq = gen_const(NULL, value);
|
||||
deref--;
|
||||
}
|
||||
else if (scantoken == ID_TOKEN)
|
||||
{
|
||||
if ((type |= id_type(tokenstr, tokenlen)) & CONST_TYPE)
|
||||
{
|
||||
value = id_const(tokenstr, tokenlen);
|
||||
value = id_const(tokenstr, tokenlen);
|
||||
valseq = gen_const(NULL, value);
|
||||
deref--;
|
||||
}
|
||||
else //if (type & (VAR_TYPE | FUNC_TYPE))
|
||||
else
|
||||
{
|
||||
value = id_tag(tokenstr, tokenlen);
|
||||
if (type & LOCAL_TYPE)
|
||||
valseq = gen_lcladr(NULL, value);
|
||||
else
|
||||
valseq = gen_gbladr(NULL, value, type);
|
||||
}
|
||||
if (type & FUNC_TYPE)
|
||||
{
|
||||
cfnparms = funcparms_cnt(type);
|
||||
cfnvals = funcvals_cnt(type);
|
||||
if (type & FUNC_TYPE)
|
||||
{
|
||||
cfnparms = funcparms_cnt(type);
|
||||
cfnvals = funcvals_cnt(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (scantoken == LAMBDA_TOKEN)
|
||||
{
|
||||
type |= CONST_TYPE;
|
||||
value = parse_lambda();
|
||||
if (!rvalue) // Lambdas can't be LVALUEs
|
||||
{
|
||||
release_seq(uopseq);
|
||||
return (codeseq);
|
||||
}
|
||||
value = parse_lambda();
|
||||
valseq = gen_gbladr(NULL, value, FUNC_TYPE);
|
||||
deref--;
|
||||
}
|
||||
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");
|
||||
if (scantoken != CLOSE_PAREN_TOKEN)
|
||||
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
|
||||
{
|
||||
release_seq(uopseq);
|
||||
release_seq(codeseq);
|
||||
return (NULL);
|
||||
}
|
||||
/*
|
||||
* 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);
|
||||
if (scantoken != CLOSE_PAREN_TOKEN)
|
||||
parse_error("Missing function call closing parenthesis");
|
||||
if (scan() == POUND_TOKEN)
|
||||
if (type & FUNC_TYPE)
|
||||
{
|
||||
/*
|
||||
* Set function pointer return vals count - can't do this to regular function call
|
||||
*/
|
||||
if (type & FUNC_TYPE)
|
||||
parse_error("Overriding function return count");
|
||||
if (!parse_const(&cfnvals))
|
||||
parse_error("Invalid def return value count");
|
||||
if (cfnparms != value) // Can't check parm count on function pointers
|
||||
parse_error("Parameter count mismatch");
|
||||
}
|
||||
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 (deref)
|
||||
deref--;
|
||||
if (scan() == POUND_TOKEN)
|
||||
{
|
||||
/*
|
||||
* 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);
|
||||
if (stackdepth)
|
||||
*stackdepth = cfnvals;
|
||||
cfnvals = 1;
|
||||
type &= ~(FUNC_TYPE | VAR_TYPE);
|
||||
*stackdepth += cfnvals - 1;
|
||||
cfnparms = 0; cfnvals = 1;
|
||||
type &= PTR_TYPE;
|
||||
deref--;
|
||||
}
|
||||
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)
|
||||
{
|
||||
/*
|
||||
* Function call dereference
|
||||
* Function address dereference
|
||||
*/
|
||||
valseq = gen_icall(valseq);
|
||||
if (stackdepth)
|
||||
*stackdepth = cfnvals;
|
||||
cfnparms = 0; cfnvals = 1;
|
||||
}
|
||||
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_lw(valseq);
|
||||
valseq = gen_lw(valseq); // Multi-dimenstion arrays are array pointers to arrays
|
||||
}
|
||||
if (scantoken != CLOSE_BRACKET_TOKEN)
|
||||
parse_error("Missing closing bracket");
|
||||
if (type & (WPTR_TYPE | WORD_TYPE))
|
||||
if (type & WORD_TYPE)
|
||||
{
|
||||
valseq = gen_idxw(valseq);
|
||||
type = (type & PTR_TYPE) | WORD_TYPE;
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
@ -526,23 +550,27 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
||||
/*
|
||||
* Function call dereference
|
||||
*/
|
||||
if (cfnparms)
|
||||
parse_error("Parameter count mismatch");
|
||||
valseq = gen_icall(valseq);
|
||||
if (stackdepth)
|
||||
*stackdepth = cfnvals;
|
||||
type &= ~FUNC_TYPE;
|
||||
*stackdepth += cfnvals - 1;
|
||||
cfnparms = 0; cfnvals = 1;
|
||||
}
|
||||
else if (type & (VAR_TYPE | PTR_TYPE))
|
||||
else if (type & WORD_TYPE)
|
||||
{
|
||||
/*
|
||||
* Pointer dereference
|
||||
*/
|
||||
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 (scantoken == EOL_TOKEN || scantoken == CLOSE_PAREN_TOKEN)
|
||||
parse_error("Syntax");
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
/*
|
||||
* Function call dereference
|
||||
* Function address dereference
|
||||
*/
|
||||
valseq = gen_icall(valseq);
|
||||
if (stackdepth)
|
||||
*stackdepth = cfnvals;
|
||||
type &= ~FUNC_TYPE;
|
||||
cfnparms = 0; cfnvals = 1;
|
||||
}
|
||||
type = (type & (VAR_TYPE | CONST_TYPE))
|
||||
? ((scantoken == DOT_TOKEN) ? BYTE_TYPE : WORD_TYPE)
|
||||
: ((scantoken == DOT_TOKEN) ? BPTR_TYPE : WPTR_TYPE);
|
||||
else if (!(type & VAR_TYPE))
|
||||
deref++;
|
||||
type = (type & PTR_TYPE) | ((scantoken == DOT_TOKEN) ? BYTE_TYPE : WORD_TYPE); // Type override
|
||||
if (!parse_const(&const_offset))
|
||||
{
|
||||
if (scantoken == EOL_TOKEN || scantoken == CLOSE_PAREN_TOKEN)
|
||||
parse_error("Syntax");
|
||||
/*
|
||||
* Setting type override for following operations
|
||||
*/
|
||||
@ -596,35 +619,54 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
||||
else
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Probably parsing RVALUE as LVALUE
|
||||
*/
|
||||
if (deref < 0)
|
||||
{
|
||||
release_seq(valseq);
|
||||
release_seq(uopseq);
|
||||
return (NULL);
|
||||
}
|
||||
/*
|
||||
* Resolve outstanding dereference pointer loads
|
||||
*/
|
||||
while (deref > rvalue)
|
||||
{
|
||||
deref--;
|
||||
if (type & FUNC_TYPE)
|
||||
{
|
||||
if (cfnparms)
|
||||
parse_error("Parameter count mismatch");
|
||||
valseq = gen_icall(valseq);
|
||||
if (stackdepth)
|
||||
*stackdepth = cfnvals;
|
||||
*stackdepth += cfnvals - 1;
|
||||
cfnparms = 0; cfnvals = 1;
|
||||
type &= ~FUNC_TYPE;
|
||||
}
|
||||
else if (type & VAR_TYPE)
|
||||
else //if (type & VAR_TYPE)
|
||||
valseq = gen_lw(valseq);
|
||||
//else
|
||||
// {fprintf(stderr,"deref=%d",deref);parse_error("What are we dereferencing #1?");}
|
||||
deref--;
|
||||
}
|
||||
if (deref)
|
||||
{
|
||||
if (type & FUNC_TYPE)
|
||||
{
|
||||
if (cfnparms)
|
||||
parse_error("Parameter count mismatch");
|
||||
valseq = gen_icall(valseq);
|
||||
if (stackdepth)
|
||||
*stackdepth = cfnvals;
|
||||
*stackdepth += cfnvals - 1;
|
||||
cfnparms = 0; cfnvals = 1;
|
||||
type &= ~FUNC_TYPE;
|
||||
}
|
||||
else if (type & (BYTE_TYPE | BPTR_TYPE))
|
||||
valseq = gen_lb(valseq);
|
||||
else if (type & (WORD_TYPE | WPTR_TYPE))
|
||||
valseq = gen_lw(valseq);
|
||||
else
|
||||
parse_error("What are we dereferencing?");
|
||||
}
|
||||
/*
|
||||
* Output pre-operations
|
||||
@ -644,6 +686,8 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
||||
release_seq(valseq);
|
||||
return (NULL); // Function or const cannot be LVALUE, must be RVALUE
|
||||
}
|
||||
if (stackdepth)
|
||||
(*stackdepth)--;
|
||||
}
|
||||
return (cat_seq(codeseq, valseq));
|
||||
}
|
||||
@ -735,8 +779,7 @@ t_opseq *parse_set(t_opseq *codeseq)
|
||||
}
|
||||
if (lparms == 0 || scantoken != SET_TOKEN)
|
||||
{
|
||||
tokenstr = setptr;
|
||||
scan_rewind(tokenstr);
|
||||
scan_rewind(setptr);
|
||||
while (lparms--)
|
||||
release_seq(setseq[lparms]);
|
||||
while (lambda_cnt > lambda_set)
|
||||
@ -750,18 +793,15 @@ t_opseq *parse_set(t_opseq *codeseq)
|
||||
rseq = parse_list(NULL, &rparms);
|
||||
if (lparms > rparms)
|
||||
parse_error("Set value list underflow");
|
||||
if ((lparms != rparms) && (rparms - lparms != 1))
|
||||
codeseq = gen_pushexp(codeseq);
|
||||
codeseq = cat_seq(codeseq, rseq);
|
||||
for (i = lparms - 1; i >= 0; i--)
|
||||
codeseq = cat_seq(codeseq, setseq[i]);
|
||||
if (lparms != rparms)
|
||||
if (lparms < rparms)
|
||||
{
|
||||
if (rparms - lparms == 1)
|
||||
parse_warn("Silently dropping extra rvalues");
|
||||
for (i = rparms - lparms; i > 0; i--)
|
||||
codeseq = gen_drop(codeseq);
|
||||
else
|
||||
codeseq = gen_pullexp(codeseq);
|
||||
}
|
||||
while (lparms--)
|
||||
codeseq = cat_seq(codeseq, setseq[lparms]);
|
||||
return (codeseq);
|
||||
}
|
||||
int parse_stmnt(void)
|
||||
@ -779,13 +819,17 @@ int parse_stmnt(void)
|
||||
switch (scantoken)
|
||||
{
|
||||
case IF_TOKEN:
|
||||
if (!(seq = parse_expr(NULL, NULL)))
|
||||
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||
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_endif = tag_new(BRANCH_TYPE);
|
||||
seq = gen_brfls(seq, tag_else);
|
||||
emit_seq(seq);
|
||||
//scan();
|
||||
do
|
||||
{
|
||||
while (parse_stmnt()) next_line();
|
||||
@ -793,8 +837,13 @@ int parse_stmnt(void)
|
||||
break;
|
||||
emit_brnch(tag_endif);
|
||||
emit_codetag(tag_else);
|
||||
if (!(seq = parse_expr(NULL, NULL)))
|
||||
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||
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);
|
||||
seq = gen_brfls(seq, tag_else);
|
||||
emit_seq(seq);
|
||||
@ -823,11 +872,16 @@ int parse_stmnt(void)
|
||||
tag_prevbrk = break_tag;
|
||||
break_tag = tag_wend;
|
||||
emit_codetag(tag_while);
|
||||
if (!(seq = parse_expr(NULL, NULL)))
|
||||
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||
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);
|
||||
emit_seq(seq);
|
||||
while (parse_stmnt()) next_line();
|
||||
while (parse_stmnt()) next_line();
|
||||
if (scantoken != LOOP_TOKEN)
|
||||
parse_error("Missing WHILE/END");
|
||||
emit_brnch(tag_while);
|
||||
@ -848,8 +902,13 @@ int parse_stmnt(void)
|
||||
parse_error("Missing REPEAT/UNTIL");
|
||||
emit_codetag(cont_tag);
|
||||
cont_tag = tag_prevcnt;
|
||||
if (!(seq = parse_expr(NULL, NULL)))
|
||||
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||
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);
|
||||
emit_seq(seq);
|
||||
emit_codetag(break_tag);
|
||||
@ -868,8 +927,14 @@ int parse_stmnt(void)
|
||||
addr = id_tag(tokenstr, tokenlen);
|
||||
if (scan() != SET_TOKEN)
|
||||
parse_error("Missing FOR =");
|
||||
if (!emit_seq(parse_expr(NULL, NULL)))
|
||||
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||
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);
|
||||
if (type & LOCAL_TYPE)
|
||||
type & BYTE_TYPE ? emit_dlb(addr) : emit_dlw(addr);
|
||||
@ -881,13 +946,25 @@ int parse_stmnt(void)
|
||||
step = -1;
|
||||
else
|
||||
parse_error("Missing FOR TO");
|
||||
if (!emit_seq(parse_expr(NULL, NULL)))
|
||||
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||
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);
|
||||
if (scantoken == STEP_TOKEN)
|
||||
{
|
||||
if (!emit_seq(parse_expr(NULL, NULL)))
|
||||
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||
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);
|
||||
}
|
||||
else
|
||||
@ -908,15 +985,27 @@ int parse_stmnt(void)
|
||||
break_tag = tag_new(BRANCH_TYPE);
|
||||
tag_choice = 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");
|
||||
if (cfnvals > 1)
|
||||
{
|
||||
parse_warn("Expression value overflow");
|
||||
while (cfnvals-- > 1) seq = gen_drop(seq);
|
||||
}
|
||||
emit_seq(seq);
|
||||
next_line();
|
||||
while (scantoken != ENDCASE_TOKEN)
|
||||
{
|
||||
if (scantoken == OF_TOKEN)
|
||||
{
|
||||
if (!emit_seq(parse_expr(NULL, NULL)))
|
||||
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||
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_codetag(tag_of);
|
||||
while (parse_stmnt()) next_line();
|
||||
@ -947,18 +1036,18 @@ int parse_stmnt(void)
|
||||
break_tag = tag_prevbrk;
|
||||
stack_loop--;
|
||||
break;
|
||||
case CONTINUE_TOKEN:
|
||||
if (cont_tag)
|
||||
emit_brnch(cont_tag);
|
||||
else
|
||||
parse_error("CONTINUE without loop");
|
||||
break;
|
||||
case BREAK_TOKEN:
|
||||
if (break_tag)
|
||||
emit_brnch(break_tag);
|
||||
else
|
||||
parse_error("BREAK without loop");
|
||||
break;
|
||||
case CONTINUE_TOKEN:
|
||||
if (cont_tag)
|
||||
emit_brnch(cont_tag);
|
||||
else
|
||||
parse_error("CONTINUE without loop");
|
||||
break;
|
||||
case RETURN_TOKEN:
|
||||
if (infunc)
|
||||
{
|
||||
@ -979,13 +1068,21 @@ int parse_stmnt(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!emit_seq(parse_expr(NULL, NULL)))
|
||||
if (!(seq = parse_expr(NULL, &cfnvals)))
|
||||
emit_const(0);
|
||||
else
|
||||
{
|
||||
if (cfnvals > 1)
|
||||
{
|
||||
parse_warn("Expression value overflow");
|
||||
while (cfnvals-- > 1) seq = gen_drop(seq);
|
||||
}
|
||||
emit_seq(seq);
|
||||
}
|
||||
emit_ret();
|
||||
}
|
||||
break;
|
||||
case EOL_TOKEN:
|
||||
//case COMMENT_TOKEN:
|
||||
return (1);
|
||||
case ELSE_TOKEN:
|
||||
case ELSEIF_TOKEN:
|
||||
@ -1013,23 +1110,18 @@ int parse_stmnt(void)
|
||||
{
|
||||
emit_seq(rseq);
|
||||
emit_unaryop(scantoken);
|
||||
tokenstr = idptr;
|
||||
scan_rewind(tokenstr);
|
||||
scan_rewind(idptr);
|
||||
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));
|
||||
stackdepth--;
|
||||
}
|
||||
emit_seq(rseq);
|
||||
}
|
||||
else
|
||||
parse_error("Invalid LVALUE");
|
||||
}
|
||||
else
|
||||
parse_error("Syntax error");
|
||||
@ -1037,22 +1129,14 @@ int parse_stmnt(void)
|
||||
}
|
||||
return (scan() == EOL_TOKEN);
|
||||
}
|
||||
int parse_var(int type)
|
||||
int parse_var(int type, long basesize)
|
||||
{
|
||||
char *idstr;
|
||||
long constval;
|
||||
int consttype, constsize, arraysize, idlen = 0;
|
||||
long size = 1;
|
||||
int consttype, constsize, arraysize, idlen = 0;
|
||||
|
||||
if (scan() == OPEN_BRACKET_TOKEN)
|
||||
{
|
||||
size = 0;
|
||||
parse_constexpr(&size, &constsize);
|
||||
if (scantoken != CLOSE_BRACKET_TOKEN)
|
||||
parse_error("Missing closing bracket");
|
||||
scan();
|
||||
}
|
||||
if (scantoken == ID_TOKEN)
|
||||
if (scan() == ID_TOKEN)
|
||||
{
|
||||
idstr = tokenstr;
|
||||
idlen = tokenlen;
|
||||
@ -1065,8 +1149,7 @@ int parse_var(int type)
|
||||
scan();
|
||||
}
|
||||
}
|
||||
if (type & WORD_TYPE)
|
||||
size *= 2;
|
||||
size *= basesize;
|
||||
if (scantoken == SET_TOKEN)
|
||||
{
|
||||
if (type & (EXTERN_TYPE | LOCAL_TYPE))
|
||||
@ -1092,13 +1175,23 @@ int parse_var(int type)
|
||||
else
|
||||
parse_error("Bad variable initializer");
|
||||
}
|
||||
else if (idlen)
|
||||
id_add(idstr, idlen, type, size);
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
int parse_struc(void)
|
||||
{
|
||||
long size;
|
||||
long basesize, size;
|
||||
int type, constsize, offset = 0;
|
||||
char *idstr, strucid[80];
|
||||
int idlen = 0, struclen = 0;
|
||||
@ -1114,17 +1207,19 @@ int parse_struc(void)
|
||||
{
|
||||
if (scantoken == EOL_TOKEN)
|
||||
continue;
|
||||
size = 1;
|
||||
basesize = 1;
|
||||
type = scantoken == BYTE_TOKEN ? BYTE_TYPE : WORD_TYPE;
|
||||
if (scan() == OPEN_BRACKET_TOKEN)
|
||||
{
|
||||
size = 0;
|
||||
parse_constexpr(&size, &constsize);
|
||||
basesize = 0;
|
||||
parse_constexpr(&basesize, &constsize);
|
||||
if (scantoken != CLOSE_BRACKET_TOKEN)
|
||||
parse_error("Missing closing bracket");
|
||||
scan();
|
||||
}
|
||||
do {
|
||||
do
|
||||
{
|
||||
size = 1;
|
||||
idlen = 0;
|
||||
if (scantoken == ID_TOKEN)
|
||||
{
|
||||
@ -1139,6 +1234,7 @@ int parse_struc(void)
|
||||
scan();
|
||||
}
|
||||
}
|
||||
size *= basesize;
|
||||
if (type & WORD_TYPE)
|
||||
size *= 2;
|
||||
if (idlen)
|
||||
@ -1149,7 +1245,7 @@ int parse_struc(void)
|
||||
if (struclen)
|
||||
idconst_add(strucid, struclen, offset);
|
||||
if (scantoken != END_TOKEN)
|
||||
return (0);
|
||||
parse_error("Missing STRUC/END");
|
||||
scan();
|
||||
return (1);
|
||||
}
|
||||
@ -1164,7 +1260,7 @@ int parse_vars(int type)
|
||||
{
|
||||
case SYSFLAGS_TOKEN:
|
||||
if (type & (EXTERN_TYPE | LOCAL_TYPE))
|
||||
parse_error("sysflags must be global");
|
||||
parse_error("SYSFLAGS must be global");
|
||||
if (!parse_constexpr(&value, &size))
|
||||
parse_error("Bad constant");
|
||||
emit_sysflags(value);
|
||||
@ -1181,8 +1277,7 @@ int parse_vars(int type)
|
||||
idconst_add(idstr, idlen, value);
|
||||
break;
|
||||
case STRUC_TOKEN:
|
||||
if (!parse_struc())
|
||||
parse_error("Bad structure definition");
|
||||
parse_struc();
|
||||
break;
|
||||
case EXPORT_TOKEN:
|
||||
if (type & (EXTERN_TYPE | LOCAL_TYPE))
|
||||
@ -1203,86 +1298,63 @@ int parse_vars(int type)
|
||||
*/
|
||||
case BYTE_TOKEN:
|
||||
case WORD_TOKEN:
|
||||
type |= (scantoken == BYTE_TOKEN) ? BYTE_TYPE : WORD_TYPE;
|
||||
if (!parse_var(type))
|
||||
return (0);
|
||||
while (scantoken == COMMA_TOKEN)
|
||||
type |= (scantoken == BYTE_TOKEN) ? BYTE_TYPE : WORD_TYPE;
|
||||
cfnvals = 1; // Just co-opt a long variable for this case
|
||||
if (scan() == OPEN_BRACKET_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;
|
||||
case PREDEF_TOKEN:
|
||||
/*
|
||||
* Pre definition.
|
||||
*/
|
||||
if (scan() == ID_TOKEN)
|
||||
do
|
||||
{
|
||||
type |= 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
|
||||
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++;
|
||||
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)
|
||||
{
|
||||
if (scan() == ID_TOKEN)
|
||||
{
|
||||
cfnparms++;
|
||||
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));
|
||||
cfnparms++;
|
||||
scan();
|
||||
}
|
||||
} while (scantoken == COMMA_TOKEN);
|
||||
if (scantoken != CLOSE_PAREN_TOKEN)
|
||||
parse_error("Bad function parameter list");
|
||||
scan();
|
||||
}
|
||||
else
|
||||
parse_error("Bad function pre-declaration");
|
||||
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
|
||||
parse_error("Bad function pre-declaration");
|
||||
else
|
||||
parse_error("Bad function pre-declaration");
|
||||
} while (scantoken == COMMA_TOKEN);
|
||||
case EOL_TOKEN:
|
||||
break;
|
||||
default:
|
||||
@ -1301,7 +1373,7 @@ int parse_mods(void)
|
||||
while (parse_vars(EXTERN_TYPE)) next_line();
|
||||
if (scantoken != END_TOKEN)
|
||||
parse_error("Missing END");
|
||||
return (scan() == EOL_TOKEN);
|
||||
scan();
|
||||
}
|
||||
if (scantoken == EOL_TOKEN)
|
||||
return (1);
|
||||
@ -1312,7 +1384,6 @@ int parse_lambda(void)
|
||||
{
|
||||
int func_tag;
|
||||
int cfnparms;
|
||||
char *expr;
|
||||
|
||||
if (!infunc)
|
||||
parse_error("Lambda functions only allowed inside definitions");
|
||||
@ -1337,7 +1408,6 @@ int parse_lambda(void)
|
||||
}
|
||||
else
|
||||
parse_error("Missing parameter list in lambda function");
|
||||
expr = scanpos;
|
||||
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);
|
||||
|
@ -1,12 +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.
|
||||
*/
|
||||
/**************************************************************************************
|
||||
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 "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.
|
||||
*/
|
||||
|
@ -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 <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@ -40,17 +49,47 @@ word *esp = eval_stack + EVAL_STACKSZ;
|
||||
|
||||
#define SYMTBLSZ 1024
|
||||
#define SYMSZ 16
|
||||
#define MODTBLSZ 128
|
||||
#define MODSZ 16
|
||||
#define MODLSTSZ 32
|
||||
byte symtbl[SYMTBLSZ];
|
||||
byte *lastsym = symtbl;
|
||||
byte modtbl[MODTBLSZ];
|
||||
byte *lastmod = modtbl;
|
||||
/*
|
||||
* Predef.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@ -181,19 +220,6 @@ uword add_sym(byte *sym, int addr)
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
mem_data[lastdef] = bank ? 2 : 1;
|
||||
@ -204,7 +230,7 @@ uword defcall_add(int bank, int addr)
|
||||
uword def_lookup(byte *cdd, int defaddr)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -248,7 +274,7 @@ int load_mod(byte *mod)
|
||||
moddep = header + 1;
|
||||
modsize = header[0] | (header[1] << 8);
|
||||
magic = header[2] | (header[3] << 8);
|
||||
if (magic == 0xDA7F)
|
||||
if (magic == 0x6502)
|
||||
{
|
||||
/*
|
||||
* This is a relocatable bytecode module.
|
||||
@ -263,7 +289,7 @@ int load_mod(byte *mod)
|
||||
*/
|
||||
while (*moddep)
|
||||
{
|
||||
if (lookup_mod(moddep) == 0)
|
||||
if (lookup_sym(moddep) == 0)
|
||||
{
|
||||
if (fd)
|
||||
{
|
||||
@ -324,7 +350,7 @@ int load_mod(byte *mod)
|
||||
/*
|
||||
* Add module to symbol table.
|
||||
*/
|
||||
add_mod(mod, modaddr);
|
||||
add_sym(mod, modaddr);
|
||||
/*
|
||||
* Print out the Re-Location Dictionary.
|
||||
*/
|
||||
@ -337,6 +363,7 @@ int load_mod(byte *mod)
|
||||
if (show_state) printf("\tDEF CODE");
|
||||
addr = rld[1] | (rld[2] << 8);
|
||||
addr += modfix - MOD_ADDR;
|
||||
rld[0] = 0; // Set call code to 0
|
||||
rld[1] = addr;
|
||||
rld[2] = addr >> 8;
|
||||
end = rld - mem_data + 4;
|
||||
@ -437,28 +464,33 @@ void interp(code *ip);
|
||||
void call(uword pc)
|
||||
{
|
||||
unsigned int i, s;
|
||||
int a, b;
|
||||
char c, sz[64];
|
||||
|
||||
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++])
|
||||
{
|
||||
case 0: // NULL call
|
||||
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
|
||||
case 0: // BYTECODE in mem_data
|
||||
interp(mem_data + (mem_data[pc] + (mem_data[pc + 1] << 8)));
|
||||
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
|
||||
c = POP;
|
||||
if (c == 0x0D)
|
||||
c = '\n';
|
||||
putchar(c);
|
||||
break;
|
||||
case 4: // LIBRARY STDLIB::PUTS
|
||||
case 4: // LIBRARY STDLIB::PUTNL
|
||||
putchar('\n');
|
||||
fflush(stdout);
|
||||
break;
|
||||
case 5: // LIBRARY STDLIB::PUTS
|
||||
s = POP;
|
||||
i = mem_data[s++];
|
||||
while (i--)
|
||||
@ -469,39 +501,31 @@ void call(uword pc)
|
||||
putchar(c);
|
||||
}
|
||||
break;
|
||||
case 5: // LIBRARY STDLIB::PUTSZ
|
||||
s = POP;
|
||||
while ((c = mem_data[s++]))
|
||||
{
|
||||
if (c == 0x0D)
|
||||
c = '\n';
|
||||
putchar(c);
|
||||
}
|
||||
case 6: // LIBRARY STDLIB::PUTI
|
||||
i = POP;
|
||||
printf("%d", i);
|
||||
break;
|
||||
case 6: // LIBRARY STDLIB::GETC
|
||||
case 7: // LIBRARY STDLIB::GETC
|
||||
PUSH(getchar());
|
||||
break;
|
||||
case 7: // LIBRARY STDLIB::GETS
|
||||
case 8: // LIBRARY STDLIB::GETS
|
||||
c = POP;
|
||||
putchar(c);
|
||||
gets(sz);
|
||||
for (i = 0; sz[i]; i++)
|
||||
mem_data[0x200 + i] = sz[i];
|
||||
mem_data[0x200 + i] = 0;
|
||||
mem_data[0x1FF] = i;
|
||||
PUSH(i);
|
||||
PUSH(0x1FF);
|
||||
break;
|
||||
case 8: // LIBRARY STDLIB::PUTNL
|
||||
putchar('\n');
|
||||
fflush(stdout);
|
||||
break;
|
||||
case 9: // LIBRARY STDLIB::MACHID
|
||||
PUSH(0x0000);
|
||||
break;
|
||||
case 10: // LIBRARY STDLIB::PUTI
|
||||
i = POP;
|
||||
printf("%d", i);
|
||||
case 24: // LIBRARY CMDSYS::DIVMOD
|
||||
a = POP;
|
||||
b = POP;
|
||||
PUSH(b / a);
|
||||
PUSH(b % a);
|
||||
break;
|
||||
default:
|
||||
printf("\nBad call code:$%02X\n", mem_data[pc - 1]);
|
||||
printf("\nUnimplemented call code:$%02X\n", mem_data[pc - 1]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@ -658,12 +682,9 @@ void interp(code *ip)
|
||||
val = TOS;
|
||||
PUSH(val);
|
||||
break;
|
||||
case 0x34: // PUSH : TOSP = TOS
|
||||
val = esp - eval_stack;
|
||||
PHA(val);
|
||||
case 0x34: // NOP
|
||||
break;
|
||||
case 0x36: // PULL : TOS = TOSP
|
||||
esp = eval_stack + PLA;
|
||||
case 0x36: // NOP
|
||||
break;
|
||||
case 0x38: // BRGT : TOS-1 > TOS ? IP += (IP)
|
||||
val = POP;
|
||||
@ -873,22 +894,11 @@ void interp(code *ip)
|
||||
*/
|
||||
default:
|
||||
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)
|
||||
{
|
||||
byte dci[32];
|
||||
@ -906,17 +916,16 @@ int main(int argc, char **argv)
|
||||
/*
|
||||
* Add default library.
|
||||
*/
|
||||
stodci("CMDSYS", dci);
|
||||
add_mod(dci, 0xFFFF);
|
||||
for (i = 0; syslib_exp[i]; i++)
|
||||
{
|
||||
mem_data[i] = i + 3;
|
||||
mem_data[i] = i;
|
||||
stodci(syslib_exp[i], dci);
|
||||
add_sym(dci, i);
|
||||
add_sym(dci, i+1);
|
||||
}
|
||||
if (argc)
|
||||
{
|
||||
stodci(*argv, dci);
|
||||
if (show_state) dump_sym();
|
||||
load_mod(dci);
|
||||
if (show_state) dump_sym();
|
||||
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
|
||||
SRCL = SRC
|
||||
SRCH = SRC+1
|
||||
DST = SRC+2
|
||||
DSTL = DST
|
||||
DSTH = DST+1
|
||||
ESTKSZ = $20
|
||||
ESTK = $C0
|
||||
ESTKL = ESTK
|
||||
ESTKH = ESTK+ESTKSZ/2
|
||||
VMZP = ESTK+ESTKSZ
|
||||
IFP = VMZP
|
||||
IFPL = IFP
|
||||
IFPH = IFP+1
|
||||
PP = IFP+2
|
||||
PPL = PP
|
||||
PPH = PP+1
|
||||
IPY = PP+2
|
||||
TMP = IPY+1
|
||||
TMPL = TMP
|
||||
TMPH = TMP+1
|
||||
NPARMS = TMPL
|
||||
FRMSZ = TMPH
|
||||
DVSIGN = TMP+2
|
||||
ESP = TMP+2
|
||||
DROP = $EF
|
||||
NEXTOP = $F0
|
||||
FETCHOP = NEXTOP+3
|
||||
IP = FETCHOP+1
|
||||
IPL = IP
|
||||
IPH = IPL+1
|
||||
OPIDX = FETCHOP+6
|
||||
OPPAGE = OPIDX+1
|
||||
SRC = $06
|
||||
SRCL = SRC
|
||||
SRCH = SRC+1
|
||||
DST = SRC+2
|
||||
DSTL = DST
|
||||
DSTH = DST+1
|
||||
ESGUARD = $BE
|
||||
ESTKSZ = $20
|
||||
ESTK = $C0
|
||||
ESTKH = ESTK
|
||||
ESTKL = ESTK+ESTKSZ/2
|
||||
VMZP = ESTK+ESTKSZ
|
||||
IFP = VMZP
|
||||
IFPL = IFP
|
||||
IFPH = IFP+1
|
||||
PP = IFP+2
|
||||
PPL = PP
|
||||
PPH = PP+1
|
||||
IPY = PP+2
|
||||
ESP = IPY+1
|
||||
JMPTMP = ESP+1
|
||||
TMP = JMPTMP+1
|
||||
TMPL = TMP
|
||||
TMPH = TMP+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.
|
||||
*/
|
||||
@ -29,6 +20,7 @@
|
||||
#define EXPORT_TYPE (1 << 12)
|
||||
#define PREDEF_TYPE (1 << 13)
|
||||
#define FUNC_TYPE (ASM_TYPE | DEF_TYPE | PREDEF_TYPE)
|
||||
#define ACCESSED_TYPE (1 << 15)
|
||||
#define FUNC_PARMS (0x0F << 16)
|
||||
#define FUNC_VALS (0x0F << 20)
|
||||
#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_type(char *name, int len);
|
||||
void idglobal_size(int type, int size, int constsize);
|
||||
void idlocal_size(int size);
|
||||
void idlocal_size(int size);
|
||||
int tag_new(int type);
|
||||
|
@ -81,8 +81,11 @@ def printfunc(a, b, lambda)#0
|
||||
puti(lambda(a,b))
|
||||
putln
|
||||
end
|
||||
def vals123#3
|
||||
return 1, 2, 3
|
||||
end
|
||||
export def main(range)#0
|
||||
byte a
|
||||
word a, b, c
|
||||
word lambda
|
||||
|
||||
a = 10
|
||||
@ -120,6 +123,19 @@ export def main(range)#0
|
||||
printfunc(1, 2, &(a,b) (a-b))
|
||||
lambda = &(x,y) x * y
|
||||
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
|
||||
|
||||
def dummy(zz)#2
|
||||
@ -165,17 +181,29 @@ putln
|
||||
puts(@constr); puti(constval); putln
|
||||
puts("Signed byte constant:"); puti(-3); putln
|
||||
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 "); 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 "); 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 "); 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")
|
||||
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 ")
|
||||
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 ")
|
||||
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 ")
|
||||
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
|
||||
done
|
||||
|
@ -5,14 +5,14 @@ include "cmdsys.plh"
|
||||
//
|
||||
// Module data.
|
||||
//
|
||||
predef puth(h)#0
|
||||
export word print[] = @puti, @puth, @putln, @puts, @putc
|
||||
predef puthex(h)#0
|
||||
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 loadstr[] = "testlib loaded!"
|
||||
//
|
||||
// Define functions.
|
||||
//
|
||||
def puth(h)#0
|
||||
def puthex(h)#0
|
||||
putc('$')
|
||||
putc(valstr[(h >> 12) & $0F])
|
||||
putc(valstr[(h >> 8) & $0F])
|
||||
|
@ -1,9 +1,8 @@
|
||||
import testlib
|
||||
predef puti
|
||||
word print
|
||||
const dec = 0
|
||||
const hex = 2
|
||||
const newln = 4
|
||||
const str = 6
|
||||
const char = 8
|
||||
const chr = 8
|
||||
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 IS_TOKEN(c) (0x80&(c))
|
||||
/*
|
||||
@ -44,8 +35,8 @@
|
||||
#define PREDEF_TOKEN TOKEN(22)
|
||||
#define DEF_TOKEN TOKEN(23)
|
||||
#define ASM_TOKEN TOKEN(24)
|
||||
#define IMPORT_TOKEN TOKEN(25)
|
||||
#define EXPORT_TOKEN TOKEN(26)
|
||||
#define IMPORT_TOKEN TOKEN(25)
|
||||
#define EXPORT_TOKEN TOKEN(26)
|
||||
#define DONE_TOKEN TOKEN(27)
|
||||
#define RETURN_TOKEN TOKEN(28)
|
||||
#define BREAK_TOKEN TOKEN(29)
|
||||
@ -116,7 +107,8 @@
|
||||
#define COLON_TOKEN TOKEN(':')
|
||||
#define POUND_TOKEN TOKEN('#')
|
||||
#define COMMA_TOKEN TOKEN(',')
|
||||
#define COMMENT_TOKEN TOKEN(';')
|
||||
//#define COMMENT_TOKEN TOKEN(';')
|
||||
#define DROP_TOKEN TOKEN(';')
|
||||
#define EOL_TOKEN TOKEN(0)
|
||||
#define INCLUDE_TOKEN TOKEN(0x7E)
|
||||
#define EOF_TOKEN TOKEN(0x7F)
|
||||
|
Loading…
Reference in New Issue
Block a user