1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2025-04-05 03:37:43 +00:00

PLASM code complete

This commit is contained in:
David Schmenk 2018-01-04 14:45:44 -08:00
parent 17fc60618a
commit a5910609ef
5 changed files with 236 additions and 239 deletions

View File

@ -37,7 +37,7 @@ word = @logb, @scalb, @trunc, @round, @sqrt, @squared
// ELEMS6502 functions
//
word = @cos, @sin, @tan, @atan
word = @log2X, log21X, @lnX, @ln1X, @pow2X, @pow21X, @powEX, @powE1X, @powE21X, @powXInt, @powXY
word = @log2X, @log21X, @lnX, @ln1X, @pow2X, @pow21X, @powEX, @powE1X, @powE21X, @powXInt, @powXY
word = @compXY, @annuityXY, @randNum
//
// Useful constants

View File

@ -24,6 +24,16 @@
// loop
//end
//
// Address tags
//
def new_tag(type)
tag_cnt++
if tag_cnt >= TAGNUM; exit_err(ERR_OVER|ERR_CODE|ERR_TABLE); fin
tag_addr=>[tag_cnt] = 0 // Unresolved, nothing to update yet
tag_type->[tag_cnt] = type
return tag_cnt
end
//
// New/release sequence ops
//
def new_op
@ -86,46 +96,29 @@ def emit_fill(size)#0
codeptr = codeptr + size
if codeptr - codebuff > codebufsz; exit_err(ERR_OVER|ERR_CODE|ERR_TABLE); fin
end
def emit_addr(tag)#0
word updtptr
if tag & IS_CTAG
tag = tag & MASK_CTAG
if ctag_tbl=>[tag] & IS_RESOLVED
updtptr = (ctag_tbl=>[tag] & MASK_CTAG) + codebuff
else
//
// Add to list of tags needing resolution
//
updtptr = ctag_tbl=>[tag] & MASK_CTAG
ctag_tbl=>[tag] = codeptr - codebuff
fin
emit_word(updtptr)
else
emit_word(tag + codebuff)
fin
def emit_addr(tag, offset)#0
fixup_tag=>[fixup_cnt] = tag
fixup_addr=>[fixup_cnt] = codeptr
fixup_cnt++
if fixup_cnt >= FIXUPNUM; exit_err(ERR_OVER|ERR_ID|ERR_TABLE); fin
emit_word(offset + tag_addr=>[tag])
end
def emit_reladdr(tag)#0
word updtptr
if tag & IS_CTAG
tag = tag & MASK_CTAG
if ctag_tbl=>[tag] & IS_RESOLVED
updtptr = ((ctag_tbl=>[tag] & MASK_CTAG) + codebuff) - codeptr
else
//
// Add to list of tags needing resolution
//
updtptr = ctag_tbl=>[tag] | IS_RELATIVE
ctag_tbl=>[tag] = codeptr - codebuff
fin
emit_word(updtptr)
if tag_type->[tag] & RESOLVED_FIXUP
updtptr = codeptr - tag_addr=>[tag]
else
emit_word(tag - (codeptr - codebuff))
//
// Add to list of tags needing resolution
//
updtptr = tag_addr=>[tag]
tag_addr=>[tag] = codeptr
fin
emit_word(updtptr)
end
def emit_data(vartype, consttype, constval, constsize)
byte i
byte type
word size, chrptr
if consttype == 0
@ -141,18 +134,17 @@ def emit_data(vartype, consttype, constval, constsize)
chrptr++
constsize--
loop
elsif consttype == CONSTADDR_TYPE
size = 2
emit_addr(constval, 0)
else
if vartype & BYTE_TYPE
size = 1
emit_byte(constval)
else
size = 2
if consttype == CONSTADDR_TYPE
emit_addr(constval)
else
emit_word(constval)
fin
fin
fin
return size
end
@ -183,21 +175,13 @@ def emit_dlw(offset)#0
end
def emit_dab(tag, offset)#0
emit_pending_seq
if tag & IS_CTAG and offset
exit_err(ERR_INVAL|ERR_CODE|ERR_CONST)
else
emit_byte($7C)
emit_addr(tag+offset)
fin
emit_byte($7C)
emit_addr(tag, offset)
end
def emit_daw(tag, offset)#0
emit_pending_seq
if tag & IS_CTAG and offset
exit_err(ERR_INVAL|ERR_CODE|ERR_CONST)
else
emit_byte($7E)
emit_addr(tag+offset)
fin
emit_byte($7E)
emit_addr(tag, offset)
end
def emit_brgt(tag)#0
emit_pending_seq
@ -234,27 +218,31 @@ def emit_enter(cparms)#0
emit_byte(cparms)
fin
end
def emit_ctag(ctag)#0
word updtptr, nextptr
def emit_tag(tag)#0
word fixups, updtptr, nextptr
emit_pending_seq
ctag = ctag & MASK_CTAG // Better be a ctag!
if ctag_tbl=>[ctag] & IS_RESOLVED;exit_err(ERR_DUP|ERR_ID); fin
updtptr = ctag_tbl=>[ctag] & MASK_CTAG
while updtptr
//
// Update list of addresses needing resolution
//
updtptr = updtptr + codebuff
nextptr = *updtptr & MASK_CTAG
if *updtptr & IS_RELATIVE
if tag_type->[tag] & RESOLVED_FIXUP; exit_err(ERR_DUP|ERR_ID); fin // DEBUG
//
// Update list of addresses needing resolution
//
if tag_type->[tag] & RELATIVE_FIXUP
updtptr = tag_addr=>[tag]
while updtptr
nextptr = *updtptr
*updtptr = codeptr - updtptr
else
*updtptr = codeptr
fin
updtptr = nextptr
loop
ctag_tbl=>[ctag] = (codeptr - codebuff) | IS_RESOLVED
updtptr = nextptr
loop
else
for fixups = fixup_cnt-1 downto 0
if fixup_tag->[fixups] == tag
updtptr = fixup_addr=>[fixups]
*updtptr = *updtptr + codeptr
fin
next
fin
tag_addr=>[tag] = codeptr
tag_type->[tag] = tag_type->[tag] | RESOLVED_FIXUP
end
//
// Emit the pending sequence
@ -323,12 +311,8 @@ def emit_pending_seq#0
// Global address codes
//
is GLOBAL_GROUP
if op=>optag & IS_CTAG and op=>opoffset
exit_err(ERR_INVAL|ERR_CODE|ERR_CONST)
else
emit_byte(op->opcode)
emit_addr(op=>optag+op=>opoffset)
fin
emit_byte(op->opcode)
emit_addr(op=>optag, op=>opoffset)
break
//
// Relative address codes
@ -341,7 +325,7 @@ def emit_pending_seq#0
// Code tags
//
is CODETAG_GROUP
emit_ctag(op=>optag)
emit_tag(op=>optag)
break
otherwise
return
@ -363,7 +347,7 @@ def emit_seq(seq)#0
string = FALSE
op = seq
while op
if op->opgroup == CONSTR_GROUP; string = TRUE; break; fin
if op->opcode == CONSTR_CODE; string = TRUE; break; fin
op = op=>opnext
loop
pending_seq = cat_seq(pending_seq, seq)
@ -384,7 +368,7 @@ end
// Emit lambda function
//
def emit_lambdafunc(tag, cparms, lambda_seq)#0
emit_ctag(tag)
emit_tag(tag)
framesize = cparms * 2
emit_enter(cparms)
emit_seq(lambda_seq)
@ -409,7 +393,7 @@ def idmatch(nameptr, len, idptr, idcnt)
loop
return NULL
end
def id_lookup(nameptr, len)
def lookup_id(nameptr, len)
word idptr
idptr = idmatch(nameptr, len, idlocal_tbl, locals)
@ -417,24 +401,24 @@ def id_lookup(nameptr, len)
idptr = idmatch(nameptr, len, idglobal_tbl, globals)
if idptr
if idptr=>idtype & EXTERN_TYPE
idptr=>idtype = idptr=>idtype | ACCESSED_TYPE
idptr=>idtype = idptr=>idtype | EXTACCESS_TYPE
fin
fin
fin
return idptr
end
def idglobal_lookup(nameptr, len)
def lookup_idglobal(nameptr, len)
word idptr
idptr = idmatch(nameptr, len, idglobal_tbl, globals)
if idptr
if idptr=>idtype & EXTERN_TYPE
idptr=>idtype = idptr=>idtype | ACCESSED_TYPE
idptr=>idtype = idptr=>idtype | EXTACCESS_TYPE
fin
fin
return idptr
end
def iddata_add(namestr, len, type, size)#0
def add_iddata(namestr, len, type, size)#0
if idmatch(namestr, len, idglobal_tbl, globals); exit_err(ERR_DUP|ERR_ID); fin
lastglobal=>idval = datasize
lastglobal=>idtype = type
@ -445,7 +429,7 @@ def iddata_add(namestr, len, type, size)#0
if lastglobal - idglobal_tbl > IDGLOBALSZ; exit_err(ERR_OVER|ERR_GLOBAL|ERR_ID|ERR_TABLE); fin
datasize = datasize + size
end
def iddata_size(type, varsize, initsize)#0
def size_iddata(type, varsize, initsize)#0
if varsize > initsize
datasize = datasize + varsize
emit_data(0, 0, 0, varsize - initsize)
@ -453,7 +437,7 @@ def iddata_size(type, varsize, initsize)#0
datasize = datasize + initsize
fin
end
def idglobal_add(namestr, len, type, value, cparms, cvals)#0
def add_idglobal(namestr, len, type, value, cparms, cvals)#0
if idmatch(namestr, len, idglobal_tbl, globals); exit_err(ERR_DUP|ERR_ID); fin
lastglobal=>idval = value
lastglobal=>idtype = type
@ -464,17 +448,17 @@ def idglobal_add(namestr, len, type, value, cparms, cvals)#0
lastglobal = lastglobal + t_id + len
if lastglobal - idglobal_tbl > IDGLOBALSZ; exit_err(ERR_OVER|ERR_GLOBAL|ERR_ID|ERR_TABLE); fin
end
def idconst_add(namestr, len, value)#0
idglobal_add(namestr, len, CONST_TYPE, value, 0, 0)
def add_idconst(namestr, len, value)#0
add_idglobal(namestr, len, CONST_TYPE, value, 0, 0)
end
def idfunc_add(namestr, len, type, tag, cfnparms, cfnvals)#0
idglobal_add(namestr, len, type|FUNC_TYPE, tag, cfnparms, cfnvals)
def add_idfunc(namestr, len, type, tag, cfnparms, cfnvals)#0
add_idglobal(namestr, len, type|FUNC_TYPE, tag, cfnparms, cfnvals)
def_cnt++
end
def idfunc_set(namestr, len, tag, cparms, cvals)#0
def set_idfunc(namestr, len, tag, cparms, cvals)#0
word idptr
idptr = idglobal_lookup(namestr, len)
idptr = lookup_idglobal(namestr, len)
if idptr
if not idptr=>idtype & FUNC_TYPE; exit_err(ERR_UNDECL|ERR_CODE); fin
idptr=>idval = tag
@ -484,11 +468,14 @@ def idfunc_set(namestr, len, tag, cparms, cvals)#0
exit_err(ERR_UNDECL|ERR_ID)
fin
end
def idglobal_init#0
word op, codebuffsz
def init_idglobal#0
word op
byte i
ctag_tbl = heapalloc(CTAGNUM*2)
tag_addr = heapalloc(TAGNUM*2)
tag_type = heapalloc(TAGNUM)
fixup_tag = heapalloc(FIXUPNUM*2)
fixup_addr = heapalloc(FIXUPNUM*2)
idglobal_tbl = heapalloc(IDGLOBALSZ)
idlocal_tbl = heapalloc(IDLOCALSZ)
codebufsz = heapavail - 4096
@ -506,7 +493,7 @@ def idglobal_init#0
next
op=>opnext = NULL
end
def idlocal_add(namestr, len, type, size)#0
def add_idlocal(namestr, len, type, size)#0
if idmatch(namestr, len, @idlocal_tbl, locals); exit_err(ERR_DUP|ERR_ID); fin
lastlocal=>idval = framesize
lastlocal=>idtype = type | LOCAL_TYPE
@ -517,18 +504,18 @@ def idlocal_add(namestr, len, type, size)#0
framesize = framesize + size
if framesize > 255; exit_err(ERR_OVER|ERR_LOCAL|ERR_FRAME); fin
end
def idlocal_init#0
def init_idlocal#0
locals = 0
framesize = 0
lastlocal = idlocal_tbl
end
def idlocal_save#0
def save_idlocal#0
savelocals = locals
savesize = framesize
savelast = lastlocal
idlocal_init
init_idlocal
end
def idlocal_restore#0
def restore_idlocal#0
locals = savelocals
framesize = savesize
lastlocal = savelast
@ -536,7 +523,7 @@ end
//
// Module dependency list
//
def moddep_add(strptr, strlen)#0
def add_moddep(strptr, strlen)#0
if strlen > 15; strlen = 15; fin
memcpy(@moddep_tbl[moddep_cnt*16] + 1, strptr, strlen)
moddep_tbl[moddep_cnt*16] = strlen
@ -544,22 +531,6 @@ def moddep_add(strptr, strlen)#0
if moddep_cnt > 8; parse_warn("Module dependency overflow"); fin
end
//
// Code tags. Upper bit is IS_RESOLVED flag, lower 15 is offset into codebuff
//
def ctag_new
codetag++
if codetag >= CTAGNUM; exit_err(ERR_OVER|ERR_CODE|ERR_TABLE); fin
ctag_tbl=>[codetag] = 0 // Unresolved, nothing to update yet
return codetag | IS_CTAG
end
def fixup_new(tag, type, size)#0
fixup_tag->[fixup_cnt] = tag
fixup_type->[fixup_cnt] = type
fixup_size->[fixup_cnt] = size
fixup_cnt++
if fixup_cnt >= FIXUPNUM; exit_err(ERR_OVER|ERR_ID|ERR_TABLE); fin
end
//
// Generate/add to a sequence of code
//
def gen_op(seq, code)
@ -567,7 +538,7 @@ def gen_op(seq, code)
if not seq
seq = new_op
op = seq
op = seq
else
op = seq
while op=>opnext; op = op=>opnext; loop
@ -583,7 +554,7 @@ def gen_const(seq, cval)
if not seq
seq = new_op
op = seq
op = seq
else
op = seq
while op=>opnext; op = op=>opnext; loop
@ -600,7 +571,7 @@ def gen_str(seq, cval)
if not seq
seq = new_op
op = seq
op = seq
else
op = seq
while op=>opnext; op = op=>opnext; loop
@ -617,15 +588,15 @@ def gen_oplcl(seq, code, offsz)
if not seq
seq = new_op
op = seq
op = seq
else
op = seq
while op=>opnext; op = op=>opnext; loop
op=>opnext = new_op
op = op=>opnext
fin
op->opcode = code
op->opgroup = LOCAL_GROUP
op->opcode = code
op->opgroup = LOCAL_GROUP
op=>opoffset = offsz
return seq
end
@ -634,16 +605,16 @@ def gen_opglbl(seq, code, tag, offsz)
if not seq
seq = new_op
op = seq
op = seq
else
op = seq
while op=>opnext; op = op=>opnext; loop
op=>opnext = new_op
op = op=>opnext
fin
op->opcode = code
op->opgroup = GLOBAL_GROUP
op=>optag = tag
op->opcode = code
op->opgroup = GLOBAL_GROUP
op=>optag = tag
op=>opoffset = offsz
return seq
end
@ -652,7 +623,7 @@ def gen_oprel(seq, code, tag)
if not seq
seq = new_op
op = seq
op = seq
else
op = seq
while op=>opnext; op = op=>opnext; loop
@ -669,7 +640,7 @@ def gen_ctag(seq, tag)
if not seq
seq = new_op
op = seq
op = seq
else
op = seq
while op=>opnext; op = op=>opnext; loop
@ -677,7 +648,7 @@ def gen_ctag(seq, tag)
op = op=>opnext
fin
op->opgroup = CODETAG_GROUP
op=>optag = IS_CTAG | tag
op=>optag = tag
return seq
end
def gen_uop(tkn, seq)
@ -686,7 +657,7 @@ def gen_uop(tkn, seq)
if not seq
seq = new_op
op = seq
op = seq
else
op = seq
while op=>opnext; op = op=>opnext; loop
@ -804,29 +775,31 @@ end
//
// Write Extended REL header
//
def writeheader(refnum)#0
word moddep
byte header[128]
def writeheader(refnum)
word moddep, modfix
byte len, header[128]
moddep = @header:12 // Beginning of module dependency list
while moddep_cnt
moddep_cnt--
moddep = moddep + stodci(@moddep_tbl[moddep_cnt*16], moddep)
loop
^moddep = 0 // Terminate dependency list
moddep++
header:0 = moddep - @header + codeptr - codebuff // sizeof header+data+bytecode
header:2 = $DA7F // Magic #
header:4 = modsysflags // Module SYSFLAGS
header:6 = datasize + MODADDR // Byte code offset
header:8 = def_cnt // DEFinition count
header:10 = entrypoint - codebuff + MODADDR // Init entrypoint
fileio:write(refnum, @header, moddep - @header)
^moddep = 0 // Terminate dependency list
len = moddep + 1 - @header
modfix = len + MODADDR - codebuff
header:0 = len + codeptr - codebuff // sizeof header+data+bytecode
header:2 = $DA7F // Magic #
header:4 = modsysflags // Module SYSFLAGS
header:6 = len + datasize // Byte code offset
header:8 = def_cnt // DEFinition count
header:10 = entrypoint + modfix // Init entrypoint
fileio:write(refnum, @header, len)
return modfix
end
//
// Write DeFinition Directory
//
def writeDFD(refnum)#0
def writeDFD(refnum, modfix)#0
word dirptr, idptr, idcnt
byte defdir[128]
@ -834,7 +807,7 @@ def writeDFD(refnum)#0
while idcnt
if idptr=>idtype & FUNC_TYPE and not idptr=>idtype & EXTERN_TYPE
dirptr->0 = $02
dirptr=>1 = (ctag_tbl=>[idptr=>idval] & MASK_CTAG) + MODADDR
dirptr=>1 = tag_addr=>[idptr=>idval] + modfix
dirptr = dirptr + 4
fin
idptr = idptr + idptr->idname + t_id
@ -845,7 +818,7 @@ end
//
// Build External Symbol Directory on heap
//
def buildESD#2
def buildESD(modfix)#2
byte symnum
word dirptr, idptr, idcnt, dirlen
@ -854,9 +827,9 @@ def buildESD#2
if idptr=>idtype & EXPORT_TYPE
dirptr = dirptr + stodci(idptr=>idname, dirptr)
dirptr->0 = $08
dirptr=>1 = (ctag_tbl[idptr=>idval] & MASK_CTAG) + MODADDR
dirptr=>1 = tag_addr=>[idptr=>idval] + modfix
dirptr = dirptr + 3
elsif idptr=>idtype & (EXTERN_TYPE|ACCESSED_TYPE) == EXTERN_TYPE|ACCESSED_TYPE
elsif idptr=>idtype & EXTACCESS_TYPE
dirptr = dirptr + stodci(idptr=>idname, dirptr)
dirptr->0 = $10
dirptr->1 = symnum
@ -875,16 +848,31 @@ end
//
// Write ReLocation Directory
//
def writeRLD(refnum)#0
word rld, i
def writeRLD(refnum, modfix)#0
word rld, fixups, updtptr, idptr, idcnt
byte tag
rld = heapmark
for i = 0 to fixup_cnt
if i & $7F == $40 // Write out blocks of entries
for fixups = fixup_cnt-1 downto 0
if fixups & $7F == $40 // Write out blocks of entries
fileio:write(refnum, heapmark, rld - heapmark)
rld = heapmark
fin
rld->0 = $01
tag = fixup_tag->[fixups]
if tag_type->[tag] & EXTERN_FIXUP
idptr = idglobal_tbl
for idcnt = globals-1 downto 0
if idptr=>idtype & EXPORT_TYPE and idptr=>idval == tag
rld->3 = idptr->extnum
break
fin
next
else
updtptr = fixup_addr=>[fixups]
*updtptr = *updtptr + modfix
fin
rld->0 = $01 | (tag & MASK_FIXUP)
rld=>1 = fixup_addr=>[fixups] + modfix
rld = rld + 4
next
^rld = 0
@ -894,11 +882,11 @@ end
// Write Extended REL file
//
def writemodule(refnum)#0
word esd, esdlen
word esd, esdlen, modfix
//
// Write module header
//
writeheader(refnum)
modfix = writeheader(refnum)
//
// Write data/code buffer
//
@ -906,15 +894,15 @@ def writemodule(refnum)#0
//
// Write bytecode definition directory
//
writeDFD(refnum)
writeDFD(refnum, modfix)
//
// Build EXERN/ENTRY directory
//
esd, esdlen = buildESD
esd, esdlen = buildESD(modfix)
//
// Write relocation directory
//
writeRLD(refnum)
writeRLD(refnum, modfix)
//
// Write EXTERN/EBTRY directory
//

View File

@ -228,8 +228,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;

View File

@ -93,7 +93,7 @@ def parse_constterm
end
def parse_constval
byte mod, size
word type, idptr, ctag, value
word type, idptr, value
mod = 0
while not parse_constterm
@ -133,9 +133,9 @@ def parse_constval
break
is ID_TKN
size = 2
idptr = id_lookup(tknptr, tknlen)
type = idptr=>idtype
if type & ADDR_TYPE
idptr = lookup_id(tknptr, tknlen)
type = idptr=>idtype
if type & (FUNC_TYPE|ADDR_TYPE)
if mod <> 8; exit_err(ERR_INVAL|ERR_CONST); fin
type = CONSTADDR_TYPE
fin
@ -196,7 +196,7 @@ def parse_const(valptr)
*valptr = constval
break
is ID_TKN
idptr = id_lookup(tknptr, tknlen)
idptr = lookup_id(tknptr, tknlen)
if idptr=>idtype & CONST_TYPE
*valptr = idptr=>idval
break
@ -270,7 +270,7 @@ def parse_value(codeseq, rvalue)#2
//
when token
is ID_TKN
idptr = id_lookup(tknptr, tknlen)
idptr = lookup_id(tknptr, tknlen)
if not idptr; return NULL, 0; fin
if not idptr=>idtype; return NULL, 0; fin
type = type | idptr=>idtype
@ -512,8 +512,8 @@ def parse_expr(codeseq)#2
//
if token == TERNARY_TKN
if stackdepth <> 1; exit_err(ERR_OVER|ERR_SYNTAX); fin
tag_else = ctag_new
tag_endtri = ctag_new
tag_else = new_tag(RELATIVE_FIXUP)
tag_endtri = new_tag(RELATIVE_FIXUP)
codeseq = gen_oprel(codeseq, BRFALSE_CODE, tag_else)
codeseq, stkdepth1 = parse_expr(codeseq)
if token <> TRIELSE_TKN; exit_err(ERR_MISS|ERR_SYNTAX); fin
@ -586,8 +586,8 @@ def parse_stmnt
parse_warn("Expression value overflow")
while cfnvals > 1; cfnvals--; seq = gen_op(seq, DROP_CODE); loop
fin
tag_else = ctag_new
tag_endif = ctag_new
tag_else = new_tag(RELATIVE_FIXUP)
tag_endif = new_tag(RELATIVE_FIXUP)
seq = gen_oprel(seq, BRFALSE_CODE, tag_else)
emit_seq(seq)
repeat
@ -598,39 +598,39 @@ def parse_stmnt
break
fin
emit_branch(tag_endif)
emit_ctag(tag_else)
emit_tag(tag_else)
seq, cfnvals = parse_expr(NULL)
if !seq; exit_err(ERR_INVAL|ERR_STATE); fin
if cfnvals > 1
parse_warn("Expression value overflow")
while cfnvals > 1; cfnvals--; seq = gen_op(seq, DROP_CODE); loop
fin
tag_else = ctag_new
tag_else = new_tag(RELATIVE_FIXUP)
seq = gen_oprel(seq, BRFALSE_CODE, tag_else)
emit_seq(seq)
until FALSE
if token == ELSE_TKN
emit_branch(tag_endif)
emit_ctag(tag_else)
emit_tag(tag_else)
scan
while parse_stmnt
nextln
loop
emit_ctag(tag_endif)
emit_tag(tag_endif)
else
emit_ctag(tag_else)
emit_ctag(tag_endif)
emit_tag(tag_else)
emit_tag(tag_endif)
fin
if token <> FIN_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin
break
is WHILE_TKN
tag_while = ctag_new
tag_wend = ctag_new
tag_while = new_tag(RELATIVE_FIXUP)
tag_wend = new_tag(RELATIVE_FIXUP)
tag_prevcnt = cont_tag
cont_tag = tag_while
tag_prevbrk = break_tag
break_tag = tag_wend
emit_ctag(tag_while)
emit_tag(tag_while)
seq, cfnvals = parse_expr(NULL)
if !seq; exit_err(ERR_INVAL|ERR_STATE); fin
if cfnvals > 1
@ -644,23 +644,23 @@ def parse_stmnt
loop
if token <> LOOP_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin
emit_branch(tag_while)
emit_ctag(tag_wend)
emit_tag(tag_wend)
break_tag = tag_prevbrk
cont_tag = tag_prevcnt
break
is REPEAT_TKN
tag_repeat = ctag_new
tag_repeat = new_tag(RELATIVE_FIXUP)
tag_prevbrk = break_tag
break_tag = ctag_new
break_tag = new_tag(RELATIVE_FIXUP)
tag_prevcnt = cont_tag
cont_tag = ctag_new
emit_ctag(tag_repeat)
cont_tag = new_tag(RELATIVE_FIXUP)
emit_tag(tag_repeat)
scan
while parse_stmnt
nextln
loop
if token <> UNTIL_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin
emit_ctag(cont_tag)
emit_tag(cont_tag)
cont_tag = tag_prevcnt
seq, cfnvals = parse_expr(NULL)
if !seq; exit_err(ERR_INVAL|ERR_STATE); fin
@ -670,18 +670,18 @@ def parse_stmnt
fin
seq = gen_oprel(seq, BRFALSE_CODE, tag_repeat)
emit_seq(seq)
emit_ctag(break_tag)
emit_tag(break_tag)
break_tag = tag_prevbrk
break
is FOR_TKN
stack_loop++
tag_for = ctag_new
tag_for = new_tag(RELATIVE_FIXUP)
tag_prevcnt = cont_tag
cont_tag = tag_for
tag_prevbrk = break_tag
break_tag = ctag_new
break_tag = new_tag(RELATIVE_FIXUP)
if scan <> ID_TKN; exit_err(ERR_MISS|ERR_ID); fin
idptr = id_lookup(tknptr, tknlen)
idptr = lookup_id(tknptr, tknlen)
if idptr
type = idptr=>idtype
addr = idptr=>idval
@ -695,7 +695,7 @@ def parse_stmnt
parse_warn("Expression value overflow")
while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop
fin
emit_ctag(tag_for)
emit_tag(tag_for)
if type & LOCAL_TYPE
if type & BYTE_TYPE; emit_dlb(addr); else; emit_dlw(addr); fin
else
@ -733,7 +733,7 @@ def parse_stmnt
if token <> NEXT_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin
emit_branch(tag_for)
cont_tag = tag_prevcnt
emit_ctag(break_tag)
emit_tag(break_tag)
emit_byte(DROP_CODE)
break_tag = tag_prevbrk
stack_loop--
@ -741,9 +741,9 @@ def parse_stmnt
is CASE_TKN
stack_loop++
tag_prevbrk = break_tag
break_tag = ctag_new
tag_choice = ctag_new
tag_of = ctag_new
break_tag = new_tag(RELATIVE_FIXUP)
tag_choice = new_tag(RELATIVE_FIXUP)
tag_of = new_tag(RELATIVE_FIXUP)
seq, cfnvals = parse_expr(NULL)
if !seq; exit_err(ERR_INVAL|ERR_STATE); fin
if cfnvals > 1
@ -761,19 +761,19 @@ def parse_stmnt
while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop
fin
emit_brne(tag_choice)
emit_ctag(tag_of)
emit_tag(tag_of)
while parse_stmnt
nextln
loop
tag_of = ctag_new
tag_of = new_tag(RELATIVE_FIXUP)
if prevstmnt <> BREAK_TKN // Fall through to next OF if no break
emit_branch(tag_of)
fin
emit_ctag(tag_choice)
tag_choice = ctag_new
emit_tag(tag_choice)
tag_choice = new_tag(RELATIVE_FIXUP)
break
is DEFAULT_TKN
emit_ctag(tag_of)
emit_tag(tag_of)
tag_of = 0
scan
while parse_stmnt
@ -789,9 +789,9 @@ def parse_stmnt
wend
loop
if (tag_of)
emit_ctag(tag_of)
emit_tag(tag_of)
fin
emit_ctag(break_tag)
emit_tag(break_tag)
emit_byte(DROP_CODE)
break_tag = tag_prevbrk
stack_loop--
@ -904,7 +904,7 @@ def parse_var(type, basesize)#0
if token == SET_TKN
if type & (EXTERN_TYPE|LOCAL_TYPE); exit_err(ERR_INVAL|ERR_LOCAL|ERR_INIT); fin
if idlen
iddata_add(idptr, idlen, type, 0)
add_iddata(idptr, idlen, type, 0)
fin
constval, constsize, consttype = parse_constexpr
arraysize = emit_data(type, consttype, constval, constsize)
@ -912,12 +912,12 @@ def parse_var(type, basesize)#0
constval, constsize, consttype = parse_constexpr
arraysize = arraysize + emit_data(type, consttype, constval, constsize)
loop
iddata_size(PTR_TYPE, size, arraysize)
size_iddata(PTR_TYPE, size, arraysize)
elsif idlen
if infunc
idlocal_add(idptr, idlen, type, size)
add_idlocal(idptr, idlen, type, size)
else
iddata_add(idptr, idlen, type, size)
add_iddata(idptr, idlen, type, size)
fin
fin
end
@ -961,14 +961,14 @@ def parse_struc#0
size = size * 2
fin
if idlen
idconst_add(idstr, idlen, offset)
add_idconst(idstr, idlen, offset)
fin
offset = offset + size
until token <> COMMA_TKN
fin
loop
if struclen
idconst_add(@strucid, struclen, offset)
add_idconst(@strucid, struclen, offset)
fin
if token <> END_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin
scan
@ -988,7 +988,7 @@ def parse_vars(type)
idlen = tknlen
if scan <> SET_TKN; exit_err(ERR_INVAL|ERR_CONST); fin
value, size, type = parse_constexpr
idconst_add(idptr, idlen, value)
add_idconst(idptr, idlen, value)
break
is STRUC_TKN
parse_struc
@ -1038,7 +1038,7 @@ def parse_vars(type)
if not parse_const(@cfnvals); exit_err(ERR_INVAL|ERR_CONST); fin
scan
fin
idfunc_add(idptr, idlen, type, ctag_new, cfnparms, cfnvals)
add_idfunc(idptr, idlen, type, new_tag(type & EXTERN_TYPE ?? EXTERN_FIXUP|WORD_FIXUP :: WORD_FIXUP), cfnparms, cfnvals)
else
exit_err(ERR_MISS|ERR_ID)
fin
@ -1054,7 +1054,7 @@ end
def parse_mods
if token == IMPORT_TKN
if scan <> ID_TKN; exit_err(ERR_MISS|ERR_ID); fin
moddep_add(tknptr, tknlen)
add_moddep(tknptr, tknlen)
scan
while parse_vars(EXTERN_TYPE); nextln; loop
if token <> END_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin
@ -1067,7 +1067,7 @@ def parse_lambda
byte cfnparms
if not infunc; exit_err(ERR_INVAL|ERR_STATE); fin
idlocal_save
save_idlocal
//
// Parse parameters and return value count
//
@ -1076,7 +1076,7 @@ def parse_lambda
repeat
if scan == ID_TKN
cfnparms++
idlocal_add(tknptr, tknlen, WORD_TYPE, 2)
add_idlocal(tknptr, tknlen, WORD_TYPE, 2)
scan
fin
until token <> COMMA_TKN
@ -1098,24 +1098,24 @@ def parse_lambda
strcpy(@lambda_id[lambda_cnt * 8], "_LAMB__")
lambda_id[lambda_cnt * 8 + 6] = (lambda_num >> 3) & $07 + '0'
lambda_id[lambda_cnt * 8 + 7] = lambda_num & $07 + '0'
if idglobal_lookup(@lambda_id[lambda_cnt * 8], 7) >= 0
if lookup_idglobal(@lambda_id[lambda_cnt * 8], 7) >= 0
//
// Lambda ID already exists (from failed scanning for '=')
//
func_tag = lambda_tag[lambda_cnt]
idfunc_set(@lambda_id[lambda_cnt * 8 + 1], 7, func_tag, cfnparms, 1) // Override any predef type & tag
set_idfunc(@lambda_id[lambda_cnt * 8 + 1], 7, func_tag, cfnparms, 1) // Override any predef type & tag
else
//
// Creat new Lambda ID
//
func_tag = ctag_new
func_tag = new_tag(WORD_FIXUP)
lambda_tag[lambda_cnt] = func_tag
lambda_cparms[lambda_cnt] = cfnparms
idfunc_add(@lambda_id[lambda_cnt * 8 + 1], 7, FUNC_TYPE, func_tag, cfnparms, 1)
add_idfunc(@lambda_id[lambda_cnt * 8 + 1], 7, FUNC_TYPE, func_tag, cfnparms, 1)
fin
lambda_cnt++
if lambda_cnt >= LAMBDANUM; parse_warn("Lambda function overflow"); fin
idlocal_restore
restore_idlocal
return func_tag
end
def parse_defs
@ -1135,12 +1135,12 @@ def parse_defs
infunc = TRUE
idstr = tknptr
idlen = tknlen
idlocal_init
init_idlocal
if scan == OPEN_PAREN_TKN
repeat
if scan == ID_TKN
cfnparms++
idlocal_add(tknptr, tknlen, WORD_TYPE, 2)
add_idlocal(tknptr, tknlen, WORD_TYPE, 2)
scan
fin
until token <> COMMA_TKN
@ -1151,17 +1151,17 @@ def parse_defs
if not parse_const(@infuncvals); exit_err(ERR_INVAL|ERR_CONST); fin
scan
fin
idptr = idglobal_lookup(idstr, idlen)
idptr = lookup_idglobal(idstr, idlen)
if idptr
if not idptr=>idtype & PREDEF_TYPE; exit_err(ERR_DUP|ERR_ID); fin
if idptr->funcparms <> cfnparms or idptr->funcvals <> infuncvals; exit_err(ERR_DUP|ERR_CODE|ERR_ID); fin
func_tag = idptr=>idval
idptr=>idtype = idptr=>idtype | type
else
func_tag = ctag_new
idfunc_add(idstr, idlen, type, func_tag, cfnparms, infuncvals)
func_tag = new_tag(WORD_FIXUP)
add_idfunc(idstr, idlen, type, func_tag, cfnparms, infuncvals)
fin
emit_ctag(func_tag)
retfunc_tag = ctag_new
emit_tag(func_tag)
while parse_vars(LOCAL_TYPE); nextln; loop
emit_enter(cfnparms)
prevstmnt = 0
@ -1185,8 +1185,8 @@ def parse_defs
return token == EOL_TKN ?? TRUE :: FALSE
end
def parse_module#0
idglobal_init
idlocal_init
init_idglobal
init_idlocal
if nextln
//
// Compile module
@ -1196,7 +1196,7 @@ def parse_module#0
while parse_defs; nextln; loop
entrypoint = codeptr
prevstmnt = 0
idlocal_init
init_idlocal
emit_enter(0)
if token <> DONE_TKN
while parse_stmnt; nextln; loop

View File

@ -124,11 +124,20 @@ const XWORD_TYPE = $0044 // (WPTR_TYPE | WORD_TYPE)
const CONSTADDR_TYPE = $0061 // (CONST_TYPE | PTR_TYPE)
const STR_TYPE = $0080
const PREDEF_TYPE = $0100
const EXTERN_TYPE = $0200
const EXPORT_TYPE = $0400
const ACCESSED_TYPE = $0800
const FIXUP_BYTE = $00
const FIXUP_WORD = $80
const EXPORT_TYPE = $0200
const EXTERN_TYPE = $0400
const EXTACCESS_TYPE = $0800
const RELATIVE_TYPE = $8000
//
// Fixup flags mask
//
const RESOLVED_FIXUP = $01
const RELATIVE_FIXUP = $02
const MASK_FIXUP = $90
const WORD_FIXUP = $80
const BYTE_FIXUP = $00
const SIZE_FIXUP = $80
const EXTERN_FIXUP = $10
//
// Keywords
//
@ -223,18 +232,15 @@ end
//
// Generated code buffers
//
const IS_RESOLVED = $8000
const IS_RELATIVE = $8000
const IS_CTAG = $8000
const MASK_CTAG = $7FFF
const OPSEQNUM = 256
const CTAGNUM = 1024
const TAGNUM = 1024
const FIXUPNUM = 2048
const IDGLOBALSZ = 2048
const IDLOCALSZ = 512
const FIXUPNUM = 2048
word codetag = -1
word idglobal_tbl, idlocal_tbl, ctag_tbl
word fixup_tag, fixup_type, fixup_size
word fixup_cnt, tag_cnt = -1
word fixup_tag, fixup_addr
word tag_addr, tag_type
word idglobal_tbl, idlocal_tbl
word pending_seq
word globals, lastglobal, lastlocal, savelast
word codebufsz, datasize, framesize, savesize
@ -242,7 +248,7 @@ byte locals, savelocals
word codebuff, codeptr, entrypoint
word modsysflags
byte[16] moddep_tbl[8]
byte moddep_cnt, def_cnt, fixup_cnt
byte moddep_cnt, def_cnt
predef emit_pending_seq#0
//
// Module relocation base address
@ -291,7 +297,6 @@ byte infunc
byte stack_loop
byte prevstmnt
word infuncvals
word retfunc_tag
word break_tag
word cont_tag
byte lambda_cnt, lambda_num