From a5910609ef2b644a3cf4e521b5effa4cc66153e4 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 4 Jan 2018 14:45:44 -0800 Subject: [PATCH] PLASM code complete --- src/libsrc/fpu.pla | 2 +- src/toolsrc/codegen.pla | 296 +++++++++++++++++++--------------------- src/toolsrc/parse.c | 6 +- src/toolsrc/parse.pla | 134 +++++++++--------- src/toolsrc/plasm.pla | 37 ++--- 5 files changed, 236 insertions(+), 239 deletions(-) diff --git a/src/libsrc/fpu.pla b/src/libsrc/fpu.pla index 73cb454..7b78699 100644 --- a/src/libsrc/fpu.pla +++ b/src/libsrc/fpu.pla @@ -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 diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index 4e11ca2..0a3b9df 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -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 // diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index 2df3e2f..75fab93 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -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; diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index 26e3239..5819b83 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -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 diff --git a/src/toolsrc/plasm.pla b/src/toolsrc/plasm.pla index e9a0c6f..b2e5512 100644 --- a/src/toolsrc/plasm.pla +++ b/src/toolsrc/plasm.pla @@ -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