From 9587423c46317d0d27670990bef9c6c816ba82d8 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 8 Jan 2024 11:28:09 -0800 Subject: [PATCH] End SRCing file input early --- doc/PLFORTH.md | 4 + images/apple/PLFORTH.PO | Bin 143360 -> 143360 bytes src/toolsrc/plforth.pla | 273 +++++++++++++++++++--------------------- 3 files changed, 135 insertions(+), 142 deletions(-) diff --git a/doc/PLFORTH.md b/doc/PLFORTH.md index f0d4e15..91f0db3 100644 --- a/doc/PLFORTH.md +++ b/doc/PLFORTH.md @@ -55,8 +55,12 @@ While running code, `` will break out and return to the interpreter. ### Word to run a script: +`SRC`: Source filename on stack as input. Can be nested + `SRC" ssss"`: Source file `ssss` as input. Can be nested +`ENDSRC`: End sourcing file as input if stack flag non-zero + ### Word for compiler modes: `PBC`: Compile into PLASMA Byte Code diff --git a/images/apple/PLFORTH.PO b/images/apple/PLFORTH.PO index 5f2f6cc8c33149aa5eec69daad285d3fc951a887..a08ca3c1fe3c4285abbc0a23c4ff26b73b6e39d8 100755 GIT binary patch delta 10795 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 NL`%;p(emZN{|)*za@YU> delta 10850 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 IQNGLhZzMIP%K!iX diff --git a/src/toolsrc/plforth.pla b/src/toolsrc/plforth.pla index 252a462..c8f65c4 100644 --- a/src/toolsrc/plforth.pla +++ b/src/toolsrc/plforth.pla @@ -6,7 +6,7 @@ include "inc/longjmp.plh" // // Internal variables // -word vlist, fence +word vlist word startheap, arg, infunc, inptr, IIP, W word keyinbuf = $1FF const SRCREFS = 2 @@ -82,13 +82,13 @@ byte = $60 // RTS // // Mask and flags for dictionary entries // -const param_flag = $02 -const itc_flag = $04 -const inline_flag = $08 -const inlinew_flag = $10 -const imm_flag = $20 -const componly_flag = $40 -const hidden_flag = $80 +const inline_flag = $01 +const inlinew_flag = $02 +const param_flag = $04 +const itc_flag = $10 +const imm_flag = $20 +const componly_flag = $40 +const interponly_flag = $80 // // Predefine instrinsics // @@ -106,12 +106,12 @@ predef _begin_#0, _again_#0, _until_#0, _while_#0, _repeat_#0 predef _case_#0, _of_#0, _endof_#0, _endcase_#0, _literal_(a)#0 predef _dodo_(a,b)#0, _do_#0, _doloop_#0, _doplusloop_(a)#0, _plusloop_#0, _loop_#0, _leave_#0, _j_#1 predef _create_#0, _itcdoes_(a)#0, _does_#0, _compoff_#0, _compon_#0 -predef _forcecomp_#0, pfillw(a)#0, pfillb(a)#0, _colon_#0, _semi_#0 -predef _immediate_#0, _exit_#0, _pad_#1, _trailing_(a,b)#2 +predef _compile_#0, pfillw(a)#0, pfillb(a)#0, _colon_#0, _semi_#0 +predef _componly_#0, _interponly_#0, _immediate_#0, _exit_#0, _pad_#1, _trailing_(a,b)#2 predef _tors_(a)#0, _fromrs_#1, _toprs_#1, _lookup_#1 predef _move_(a,b,c)#0, _fill_(a,b,c)#0, _plasma_(a)#0 -predef _var_(a)#0, _const_(a)#0, _lit_#1, _slit_#1, _find_(a)#2, _tick_#1 -predef _forget_#0, _terminal_#1, _prat_(a)#0 +predef _var_(a)#0, _const_(a)#0, _lit_#1, _slit_#1, _find_(a)#2 +predef _tick_#1, _comptick_#0, _forget_#0, _terminal_#1, _prat_(a)#0 predef _char_#0, _str_#0, _prstr_#0, _prpstr_#0 predef _prval_(a)#0, _prbyte_(a)#0, _prhex_(a)#0 predef _accept_(a,b)#1, _query_#0, _expect_(a,b)#0, _type_(a,b)#0 @@ -119,7 +119,7 @@ predef _vlist_#0, _tron_#0, _troff_#0, _stepon_#0, _stepoff_#0 predef _itc_#0, _pbc_#0, _comment_#0, _src_(a)#0, _srcstr_#0, _endsrc_(a)#0 predef _brk_#0, _brkon_#0, _brkoff_#0, _word_(a)#1, _count_(a)#2 predef _space_#0, _spaces_(a)#0, _show_#0, _showstack_#0, _showrstack_#0 -predef _showhash_#0, _cont_#0, _exitforth_#0, _bye_#0, _quit_#0 +predef _cont_#0, _exitforth_#0, _bye_#0, _quit_#0 predef _abort_(a)#0, _doabortstr_(a,b)#0, _abortstr_#0 predef compword(dentry)#0, execword(dentry)#0 // DROP @@ -300,15 +300,15 @@ byte = 0 word = @d_toprstk, 0, @_lookup_ // PLASMA LINKEAGE char d_plasma = "PLASMA" -byte = 0 +byte = imm_flag word = @d_lookup, 0, @_plasma_ // VARIABLE char d_var = "VARIABLE" -byte = 0 +byte = imm_flag word = @d_plasma, 0, @_var_ // CONSTANT char d_const = "CONSTANT" -byte = 0 +byte = imm_flag word = @d_var, 0, @_const_ // MOVE char d_move = "MOVE" @@ -332,39 +332,39 @@ byte = 0 word = @d_pad, 0, @_allot_ // BRANCH ( not in vocabulary ) char d_branch = "(BRANCH)" -byte = componly_flag | param_flag | inline_flag +byte = param_flag | inline_flag word = 0, 0, @_branch_, $C4 // BRANCH IF 0 ( not in vocabulary ) char d_0branch = "(0BRANCH)" -byte = componly_flag | param_flag | inline_flag +byte = param_flag | inline_flag word = 0, 0, @_0branch_, $C2 // IF char d_if = "IF" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_allot, 0, @_if_ // ELSE char d_else = "ELSE" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_if, 0, @_else_ // THEN char d_then = "THEN" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_else, 0, @_then_ // CASE char d_case = "CASE" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_then, 0, @_case_ // OF char d_of = "OF" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_case, 0, @_of_ // ENDOF char d_endof = "ENDOF" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_of, 0, @_endof_ // ENDCASE char d_endcase = "ENDCASE" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_endof, 0, @_endcase_ // COMPILED DO ( not in vocabulary ) char d_dodo = "(DO)" @@ -372,7 +372,7 @@ byte = 0 word = 0, 0, @_dodo_ // DO char d_do = "DO" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_endcase, 0, @_do_ // LEAVE char d_leave = "LEAVE" @@ -380,19 +380,19 @@ byte = componly_flag word = @d_do, 0, @_leave_ // COMPILED LOOP ( not in vocabulary ) char d_doloop = "(DOLOOP)" -byte = componly_flag | param_flag +byte = param_flag word = 0, 0, @_doloop_ // LOOP char d_loop = "LOOP" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_leave, 0, @_loop_ // COMPILED LOOP+ ( not in vocabulary ) char d_doplusloop = "(+DOLOOP)" -byte = componly_flag | param_flag +byte = param_flag word = 0, 0, @_doplusloop_ // LOOP char d_plusloop = "+LOOP" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_loop, 0, @_plusloop_ // I char d_i = "I" @@ -404,23 +404,23 @@ byte = componly_flag word = @d_i, 0, @_j_ // BEGIN char d_begin = "BEGIN" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_j, 0, @_begin_ // AGAIN char d_again = "AGAIN" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_begin, 0, @_again_ // UNTIL char d_until = "UNTIL" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_again, 0, @_until_ // WHILE char d_while = "WHILE" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_until, 0, @_while_ // REPEAT char d_repeat = "REPEAT" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_while, 0, @_repeat_ // FORGET char d_forget = "FORGET" @@ -432,11 +432,11 @@ byte = 0 word = @d_forget, 0, @_create_ // RECREATE/DOES COMPILE TIME ( not in vocabulary ) char d_createdoes = "(CREATEDOES)" -byte = componly_flag +byte = 0 word = 0, 0, @_itcdoes_ // DOES char d_does = "DOES>" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_create, 0, @_does_ // COMMA char d_comma = "," @@ -448,35 +448,39 @@ byte = 0 word = @d_comma, 0, @pfillb // COLON char d_colon = ":" -byte = 0 +byte = interponly_flag word = @d_commab, 0, @_colon_ // COMP OFF char d_compoff = "[" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_colon, 0, @_compoff_ // COMP ON char d_compon = "]" -byte = imm_flag +byte = interponly_flag word = @d_compoff, 0, @_compon_ -// COMPILE -char d_comp = "COMPILE" -byte = 0 -word = @d_compon, 0, @compword // COMPILE NEXT WORD -char d_forcecomp = "[COMPILE]" +char d_compile = "[COMPILE]" +byte = imm_flag | componly_flag +word = @d_compon, 0, @_compile_ +// COMPILE ONLY +char d_componly = "COMPONLY" byte = imm_flag -word = @d_comp, 0, @_forcecomp_ +word = @d_compile, 0, @_componly_ +// INTERPRET ONLY +char d_interponly = "INTERPONLY" +byte = imm_flag +word = @d_componly, 0, @_interponly_ // IMMEDIATE char d_immediate = "IMMEDIATE" byte = imm_flag -word = @d_forcecomp, 0, @_immediate_ +word = @d_interponly, 0, @_immediate_ // EXIT char d_exit = "EXIT" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_immediate, 0, @_exit_ // SEMI char d_semi = ";" -byte = imm_flag +byte = imm_flag | componly_flag word = @d_exit, 0, @_semi_ // COUNT char d_count = "COUNT" @@ -488,12 +492,12 @@ byte = 0 word = @d_count, 0, @_find_ // TICK char d_tick = "'" -byte = imm_flag +byte = interponly_flag word = @d_find, 0, @_tick_ -// CFA -char d_cfa = "CFA" -byte = 0 -word = @d_tick, 0, @_cfa_ +// COMPILED TICK +char d_comptick = "[']" +byte = imm_flag | componly_flag +word = @d_tick, 0, @_comptick_ // INLINE LITERAL NUMBER ( not in vocabulary ) char d_lit = "LIT" byte = param_flag @@ -501,7 +505,7 @@ word = 0, 0, @_lit_ // COMPILED LITERAL VALUE FROM STACK char d_literal = "LITERAL" byte = imm_flag -word = @d_cfa, 0, @_literal_ +word = @d_comptick, 0, @_literal_ // ?TERMINAL char d_terminal = "?TERMINAL" byte = 0 @@ -596,7 +600,7 @@ byte = 0 word = @d_prpstr, 0, @_src_ // READ SOURCE FILE FROM INPUT char d_srcstr = "SRC\"" -byte = 0 +byte = imm_flag word = @d_src, 0, @_srcstr_ // END SOURCE FILE char d_endsrc = "ENDSRC" @@ -604,7 +608,7 @@ byte = 0 word = @d_srcstr, 0, @_endsrc_ // CONTINUE AFTER BRK char d_cont = "CONT" -byte = 0 +byte = interponly_flag word = @d_endsrc, 0, @_cont_ // QUIT char d_quit = "QUIT" @@ -630,7 +634,6 @@ word = @d_abortstr, 0, @_exitforth_ char d_comment = "(" byte = imm_flag word = @d_exitforth, 0, @_comment_ - // // PLFORTH custom words // @@ -640,7 +643,7 @@ byte = 0 word = @d_comment, 0, @_bye_ // SHOW DEFINITION char d_show = "SHOW" -byte = 0 +byte = interponly_flag word = @d_bye, 0, @_show_ // SHOW STACK char d_showstack = "SHOWSTACK" @@ -650,14 +653,10 @@ word = @d_show, 0, @_showstack_ char d_showrstack = "SHOWRSTACK" byte = 0 word = @d_showstack, 0, @_showrstack_ -// SHOW HASH -char d_showhash = "SHOWHASH" -byte = 0 -word = @d_showrstack, 0, @_showhash_ // TRACE ON char d_tron = "TRON" byte = 0 -word = @d_showhash, 0, @_tron_ +word = @d_showrstack, 0, @_tron_ // TRACE OFF char d_troff = "TROFF" byte = 0 @@ -676,7 +675,7 @@ byte = 0 word = @d_stepoff, 0, @_brk_ // BREAK ON char d_brkon = "BRKON" -byte = 0 +byte = imm_flag word = @d_brk, 0, @_brkon_ // BREAK OFF char d_brkoff = "BRKOFF" @@ -684,11 +683,11 @@ byte = 0 word = @d_brkon, 0, @_brkoff_ // COMPILE USING ITC char d_itc = "ITC" -byte = 0 +byte = interponly_flag word = @d_brkoff, 0, @_itc_ // COMPILE USING PLASMA BYTECODES char d_pbc = "PBC" -byte = 0 +byte = interponly_flag word = @d_itc, 0, @_pbc_ // // Start of vocabulary @@ -701,6 +700,15 @@ word = @d_pbc, 0, @_vlist_ // Helper routines // predef interpret#0 +def push(a)#1 // Stack hack - call as (@push)(a)#0 to leave a on eval stack + return a +end +def pfillw(a)#0 + *(heapalloc(2)) = a +end +def pfillb(a)#0 + *(heapalloc(1)) = a +end // // Input routines // @@ -769,7 +777,7 @@ def nextword(delim)#2 return wordptr, len end // -// Find match in dictionary +// Hash table routines // def hashname(chars, len)#1 return (len ^ ((^chars << 1) ^ ^(chars + len / 2) << 2)) & HASH_MASK @@ -796,6 +804,36 @@ def buildhashtbl#0 dentry = *(dentry + ^dentry + 2) loop end +// +// Warm start +// +def warmstart#0 + (@_reset_estack)()#0 + brk = 0 + brkcfa = 0 + RSP = RSTK_SIZE + if state & comp_flag // Undo compilation state + heaprelease(vlist) + vlist = *_lfa_(vlist) + fin + state = 0 + while !endsrc; loop + infunc = @keyin + inptr = keyinbuf + ^inptr = 0 +end +// +// Cold start +// +def coldstart#0 + warmstart + vlist = @d_vlist + heaprelease(startheap) + buildhashtbl +end +// +// Find match in dictionary +// def find(matchchars, matchlen)#1 word dentry byte i @@ -897,6 +935,11 @@ end // Execute code in CFA // def execword(dentry)#0 + if ^_ffa_(dentry) & componly_flag and not (state & comp_flag) + puts(dentry) + puts(" : Compile only word\n") + _quit_ + fin when conio:keypressed() is $83 // CTRL-C getc // Clear KB @@ -935,48 +978,14 @@ def execwords(wlist)#0 loop IIP = prevIP end -def push(a)#1 // Stack hack - call as (@push)(a)#0 to leave a on eval stack - return a -end -def pfillw(a)#0 - *(heapalloc(2)) = a -end -def pfillb(a)#0 - *(heapalloc(1)) = a -end -// -// Warm start -// -def warmstart#0 - (@_reset_estack)()#0 - brk = 0 - brkcfa = 0 - RSP = RSTK_SIZE - if state & comp_flag // Undo compilation state - heaprelease(vlist) - vlist = *_lfa_(vlist) - fin - state = 0 - while !endsrc; loop - infunc = @keyin - inptr = keyinbuf - ^inptr = 0 -end -// -// Cold start -// -def coldstart#0 - warmstart - vlist = @d_vlist - fence = startheap - heaprelease(startheap) - buildhashtbl -end // // Compile a word/literal into the dictionary: ITC and PBC // def compword(dentry)#0 - if state & comp_itc_flag + if ^_ffa_(dentry) & interponly_flag + puts("INTERP only word\n") + _quit_ + elsif state & comp_itc_flag pfillw(dentry) elsif state & comp_pbc_flag if ^_ffa_(dentry) & itc_flag // Check if calling ITC word @@ -992,9 +1001,6 @@ def compword(dentry)#0 pfillb($54) // CALL CFA directly pfillw(*_cfa_(dentry)) fin - else - puts("[COMPILE] not compiling\n") - _quit_ fin if state & trace_flag putc('['); puts(dentry); puts("] ") @@ -1036,14 +1042,7 @@ def interpret#0 inchars, inlen = nextword(' ') dentry = find(inchars, inlen) if dentry - if (not (state & comp_flag)) or (^_ffa_(dentry) & imm_flag) - if ^_ffa_(dentry) & componly_flag - inchars-- - ^inchars = inlen - puts(inchars) - puts(" : Compile only word\n") - _quit_ - fin + if ^_ffa_(dentry) & imm_flag or not (state & comp_flag) execword(dentry) else compword(dentry) @@ -1186,13 +1185,13 @@ def _lfa_(dentry)#1 return dentry + ^dentry + 2 end def _hfa_(dentry)#1 - return dentry + ^dentry + 4 + return dentry + ^dentry + 4 end def _cfa_(dentry)#1 - return dentry + ^dentry + 6 + return dentry + ^dentry + 6 end def _pfa_(dentry)#1 - return dentry + ^dentry + 8 + return dentry + ^dentry + 8 end def _tors_(a)#0 if RSP == 0 @@ -1345,11 +1344,7 @@ def _does_#0 fin end def _literal_(a)#0 - if state & comp_flag - compliteral(a) - else - pfillw(a) // Not really sure what to do here - fin + compliteral(a) end def _docolon_#0 execwords(W + 2) // Exec PFA @@ -1383,13 +1378,12 @@ def _semi_#0 addhash(vlist) state = state & ~comp_flag end -def _forcecomp_#0 +def _compile_#0 word dentry dentry = find(nextword(' ')) if dentry - compliteral(dentry) - compword(@d_comp) + compword(dentry) else puts(dentry) puts(" not found\n") @@ -1413,6 +1407,12 @@ def _compon_#0 _quit_ fin end +def _componly_#0 + ^_ffa_(vlist) = ^_ffa_(vlist) | componly_flag +end +def _interponly_#0 + ^_ffa_(vlist) = ^_ffa_(vlist) | interponly_flag +end def _immediate_#0 ^_ffa_(vlist) = ^_ffa_(vlist) | imm_flag end @@ -1592,6 +1592,9 @@ end def _tick_#1 return find(nextword(' ')) end +def _comptick_#0 + compliteral(find(nextword(' '))) +end def _forget_#0 word dentry @@ -1860,20 +1863,6 @@ def _showrstack_#0 depth-- loop end -def _showhash_#0 - word count, dentry - byte i - - for i = 0 to HASH_MASK - count = 0 - dentry = hashtbl[i] - while dentry - count++ - dentry = *_hfa_(dentry) - loop - puti(count); putc(' ') - next -end def _tron_#0 state = state | trace_flag end