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

View File

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

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

View File

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

View File

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

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 t_token scantoken, prevtoken;
extern int tokenlen;

View File

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

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

View File

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

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

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

View File

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

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

View File

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

View File

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

View File

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

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