Upgrade to PLASMA 1.1 compiler/VM

This commit is contained in:
David Schmenk 2018-03-14 13:58:23 -07:00
parent 073457d56d
commit 6205d1310f
19 changed files with 2666 additions and 2444 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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)
{ {

View File

@ -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;

View File

@ -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)
{ {
/* /*

View File

@ -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);

View File

@ -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"

View File

@ -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.
*/ */

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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])

View File

@ -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

View File

@ -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)