( 54K . POP-2 ) |10 @Console &vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1 |00 @token/buf |100 @on-reset ( -> ) ;meta #06 DEO2 token/ BRK @meta $1 ( name ) "POP-2 0a ( desc ) "A 20 "POP-2 20 "Compiler 0a ( auth ) "By 20 "Devine 20 "Lu 20 "Linvega 0a ( date ) "11 20 "Aug 20 "2026 0000 @ ( vector* -- ) .Console/vector DEO2 dict/ stack/ !expr/ @token/ ( -- ) ;&on-console .Console/vector DEO2 !/ @token/on-console ( -> ) .Console/read DEI ( | handlers ) DUP LIT "" NEQ ?{ [ LIT2 00 _&string ] LDR EQU ,&string STR } [ LIT &string $1 ] ?{ DUP #20 GTH ?{ POP / BRK } } / BRK @token/ ( c -- ) [ LIT2 00 &ptr -&buf ] INCk ,&ptr STR STZ2 JMP2r @token/ ( str* -- ) &>wps LDAk DUP ?{ POP POP2 JMP2r } / INC2 !/>wps @token/push-label ( str* -- next* buf* ) &>wpl LDAk DUP chr/is-label ?{ POP ;&buf JMP2r } / INC2 !/>wpl @token/push-operand ( str* -- next* buf* ) &>wpo LDAk DUP chr/is-operand ?{ POP ;&buf JMP2r } / INC2 !/>wpo @token/ ( -- ) .&buf LDZ ?{ JMP2r } ;&buf / ( >> ) @token/ ( -- ) [ LIT2 00 -&buf ] STZ [ LIT2 -&buf _&ptr ] STR JMP2r @token/ ( token* -- ) DUP2 keywords/find INC2k ORA ?{ POP2 ( label: ) /is-label ?label/ expr/ expr/ #20 !expr/ } NIP2 INC2 INC2 LDA2 JMP2 @token/is-label ( -- t ) [ LIT2 ff _&ptr ] LDR ADD LDZ LIT ": EQU JMP2r @token/push-string ( str* -- str* ) &>wps2 LDAk ( | handlers ) DUP ?{ POP JMP2r } DUP LIT "" NEQ ?{ !/ } / INC2 !/>wps2 ( @|BlockComment ) @comment/ ( -- ) ;&on-console .Console/vector DEO2 ;&a !str/ &a 0a "( 00 @comment/on-console ( -> ) .Console/read DEI ( | handlers ) chr/not-sc ?{ POP ;&b str/ token/ BRK } #18 DEO BRK &b 20 ") 0a 00 ( @|BlockFunction ) @function/ ( -- ) ;&on-console ;dict/anon-jump !str/ @function/on-console ( -> ) .Console/read DEI ( | handlers ) DUP #20 GTH ?{ POP ;expr/buf prefab-label/ vars/ BRK } chr/not-sc ?{ POP ;expr/buf prefab-label/ token/ BRK } expr/ BRK ( @|BlockVars ) @vars/ ( -- ) [ LIT2 01 _&bindings ] STR ;&on-console ! @vars/ ( -- ) [ LIT2 00 _&bindings ] STR ;&on-console ! @vars/on-console ( -> ) .Console/read DEI ( | handlers ) chr/not-sc ?{ POP ;expr/buf / LIT &bindings $1 ?{ / } token/ BRK } expr/ BRK @vars/ ( expr* -- ) token/ ;dict/anon-jump str/ &>w LDAk DUP ?{ POP POP2 / LIT2 "} 18 DEO !chr/ } DUP LIT "" NEQ ?{ token/ INC2 token/push-string !/resume } DUP #20 GTH ?{ POP / !/resume } token/ &resume INC2 !/>w @vars/ ( -- ) ;token/buf LDAk ?{ POP2 JMP2r } &>wpt LDAk DUP ?{ POP POP2 ;token/buf DUP2 dict/alloc stack/ prefab-sublab/ #0002 prefab-pad/ !token/ } LIT ": NEQ ?{ LITr 00 STH2k STAr ;token/buf DUP2 dict/alloc stack/ prefab-sublab/ INC2 LDAk LIT "" NEQ ?{ prefab-string/emit POP2 !token/ } str/dec prefab-pad/ !token/ } INC2 !/>wpt @vars/ ( -- ) &>web stack/depth ?{ !chr/ } stack/pop prefab-binding/ !/>web ( @|BlockEnd ) @end/ ( -- ) ;dict/jmp2r str/ LIT2 "} 18 DEO chr/ !token/ ( @|BlockGoto ) @goto/ ( -- ) ;&on-console .Console/vector DEO2 !token/ @goto/on-console ( -> ) .Console/read DEI ( | handlers ) DUP chr/is-an ?{ POP / BRK } token/ BRK @goto/ ( -- ) ;token/buf LDAk ?{ POP2 JMP2r } str/walk-ws prefab-jump/ !token/ ( @|BlockLabel ) @label/ ( token* -- ) chr/ LIT2 "& 18 DEO LIT ": str/ chr/ !token/ ( @|BlockIfElse ) @if/ ( -- ) ;&on-console #00 ;&case STA #00 ;&else STA / !expr/ @if/on-console ( -> ) .Console/read DEI expr/push-until-keyword ?{ BRK } expr/realloc-keyword expr/ token/ token/ BRK @if/ ( -- ) ,&case LDR chr/ !chr/ @if/ ( -- ) [ LIT &else $1 ] INC ,&else STR JMP2r @if/ ( -- ) [ LIT &case $1 ] INC ,&case STR JMP2r @if/ ( -- v ) ,&ptr LDR2 #0001 SUB2 LDA !chr/ @if/ ( -- ) [ LIT &nest 00 ] INCk ,&nest STR [ LIT2 &ptr =&buf ] INC2k ,&ptr STR2 STA JMP2r @if/ ( -- ) ,&ptr LDR2 #0001 SUB2 ,&ptr STR2 JMP2r @if/ ( -- ) ;dict/ora str/ ;&a str/ / / ;&b str/ / / !/ @if/ ( -- ) ;&c str/ / ;dict/close str/ LIT2 "} 18 DEO !chr/ @if/ ( -- ) chr/ ;&d str/ / / ;dict/close !str/ &a "?/if- 00 &c "!/if- 00 &b "!{ 20 &d "&if- 00 @elseif/ ( -- ) ;&on-console if/ !if/ @elseif/on-console ( -> ) .Console/read DEI expr/push-until-keyword ?{ BRK } expr/realloc-keyword expr/ token/ token/ BRK @then/ ( -- ) if/ ;&on-console ! @then/on-console ( -> ) .Console/read DEI ( end ) chr/not-sc ?{ POP expr/ BRK } expr/push-until-keyword ?{ BRK } expr/realloc-keyword expr/ token/ token/ BRK @else/ ( -- ) if/ if/ ;&on-console ! @else/on-console ( -> ) .Console/read DEI expr/push-until-keyword ?{ BRK } expr/realloc-keyword expr/ token/ token/ BRK @close/ ( -- ) ;if/else LDA ?{ if/ } if/ !token/ ( @|BlockExpr ) @expr/ ( -- ) ;&on-console ! @expr/on-console ( -> ) .Console/read DEI ( end ) chr/not-sc ?{ POP / BRK } / BRK @expr/ ( -- ) ;&buf &>wp str/walk-ws LDAk ?{ &end POP2 !token/ } LDAk LIT "; EQU ?/end /walk-fragment !/>wp @expr/walk-fragment ( str* -- str* ) str/walk-ws LDAk ?{ JMP2r } ( | Main ) LDAk chr/is-label ?/walk-label LDAk chr/is-operand ?/walk-operator ( | Special ) LDAk LIT "{ NEQ ?{ INC2 ;dict/backarrow stack/ ;&nil !stack/ } LDAk LIT "} NEQ ?{ INC2 / !/ } LDAk LIT "( NEQ ?{ INC2 ;&nil !stack/ } LDAk LIT ") NEQ ?{ INC2 / !/ } LDAk LIT "" EQU ?/walk-string ( | Unknown ) ;dict/err-unknown-expr err/ DUP2 err/ INC2 JMP2r @expr/walk-label ( str* -- str* ) /walk-label-core ( | Post label ) !/ @expr/walk-label-core ( str* -- str* ) str/walk-ws LDAk ?{ JMP2r } token/ token/push-label ( | handlers ) DUP2 ;dict/goto str/cmp ?/ DUP2 str/is-dec ?/ DUP2 str/is-hex ?/ LDAk LIT "# NEQ ?{ INC2 !prefab-refrel/ } LDAk LIT "@ NEQ ?{ INC2 !prefab-refabs/ } ( | function ) OVR2 LDA LIT "( NEQ ?{ dict/alloc stack/ ;&nil !stack/ } prefab-refrel/ stack/is-allocator ?{ ;dict/lda2 !str/ } JMP2r @expr/ ( str* token* -- str* ) ( pop goto ) POP2 ( walk to label ) str/walk-ws ( write jump ) token/ token/push-label !prefab-jump/ @expr/walk-string ( str* -- str* ) LIT2 "{ 18 DEO chr/ prefab-string/emit LIT2 "} 18 DEO chr/ INC2 ;dict/sth2r str/ !/ @expr/walk-operator ( str* -- str* ) str/walk-ws LDAk ?{ JMP2r } token/ token/push-operand dict/alloc !stack/ @expr/ ( str* -- ) str/dec !prefab-lithex/ @expr/ ( str* -- ) INC2 INC2 str/hex !prefab-lithex/ @expr/ ( -- ) stack/pop LDAk ?{ POP2 JMP2r } LDA2k LIT2 "<< NEQ2 ?{ POP2 ;dict/sft2-l !str/ } LDA2k LIT2 ">> NEQ2 ?{ POP2 ;dict/sft2-r !str/ } LDA2k LIT2 "-> NEQ2 ?{ POP2 ;dict/sta2 !str/ } LDA2k LIT2 "<- NEQ2 ?{ POP2 ;dict/lda2 !str/ } LDA2k LIT2 "=> NEQ2 ?{ POP2 ;dict/deo2 !str/ } LDA2k LIT2 "<> NEQ2 ?{ POP2 ;dict/jsr2 !str/ } LDAk operators/find INC2k ORA ?{ POP2 !prefab-scope/ } INC2 LDA2 NIP2 !str/ &nil 00 @expr/ ( -- ) #0000 ;&buf STA2 ;&buf ,&ptr STR2 JMP2r @expr/ ( str* -- ) &>w LDAk DUP ?{ POP POP2 JMP2r } chr/not-sc ?{ POP POP2 !/ } / INC2 !/>w @expr/ ( c -- ) #00 [ LIT2 &ptr =&buf ] INC2k ,&ptr STR2 STA2 JMP2r @expr/push-until-keyword ( c -- reached ) / /get-last-word keywords/find INC2 ORA JMP2r @expr/realloc-keyword ( -- dict* ) /get-last-word STH2k dict/alloc ( cap ) #0000 STH2r STA2 JMP2r @expr/get-last-word ( -- str* ) ;&buf ,&ptr LDR2 &>l NEQ2k ?{ POP2 JMP2r } #0001 SUB2 LDAk #20 GTH ?/>l NIP2 INC2 JMP2r ( @|Prefabs ) @prefab-sublab/ ( str* -- ) LIT2 "& 18 DEO !str/ @prefab-binding/ ( str* -- ) LIT2 ", 18 DEO prefab-sublab/ ;dict/str2 !str/ @prefab-jump/ ( str* -- ) ;&a str/ !str/ &a "!/ 00 @prefab-pad/ ( length* -- ) LIT2 "$ 18 DEO !u16/ @prefab-string/emit ( str* -- ) INC2 &>w LDAk DUP LIT "" NEQ ?{ INC2 POP #00 } ?{ #00 !u8/ } LDAk LIT "\ EQU ?/ LDAk u8/ &resume INC2 !/>w @prefab-string/ ( str* -- str* ) INC2 LDAk ( | handlers ) DUP LIT "0 NEQ ?{ #00 u8/ } DUP LIT "n NEQ ?{ #0a u8/ } DUP LIT "t NEQ ?{ #09 u8/ } DUP LIT "s NEQ ?{ #20 u8/ } POP !/resume @prefab-refrel/ ( str* -- ) [ LIT2 "; 18 ] DEO [ LIT2 "& 18 ] DEO !str/ @prefab-lithex/ ( u16* -- ) LIT2 "# 18 DEO !u16/ @prefab-label/ ( str* -- ) LIT2 "@ 18 DEO !prefab-scope/ @prefab-refabs/ ( str* -- ) [ LIT2 "; 18 ] DEO ( >> ) @prefab-scope/ ( str* -- ) LIT2 "./ str/swap-chars ;dict/fn-prefix str/ !str/ ( @|Dict ) @dict/ ( -- ) #0000 ;&buf STA2 ;&buf ,&ptr STR2 JMP2r @dict/alloc ( src* -- ptr* ) ,&ptr LDR2 SWP2 &>w LDAk DUP [ LIT2 &ptr =&buf ] INC2k ,&ptr STR2 STA ?{ POP2 JMP2r } INC2 !/>w ( @|Stack ) @stack/depth ( -- depth ) ,&ptr LDR2 ;&buf SUB2 #01 SFT2 NIP JMP2r @stack/ ( -- ) ;&buf ,&ptr STR2 JMP2r @stack/ ( addr* -- ) [ LIT2 &ptr =&buf ] INC2k INC2 ,&ptr STR2 STA2 JMP2r @stack/pop ( -- addr* ) ,&ptr LDR2 ( | clamp ) DUP2 ;&buf NEQ2 ?{ POP2 #ffff JMP2r } #0002 SUB2 DUP2 ,&ptr STR2 LDA2 JMP2r @stack/is-allocator ( -- t ) ,&ptr LDR2 #0002 SUB2 LDA2 LDA2 LIT2 "-> EQU2 JMP2r ( @|Stdlib ) @chr/hex ( c -- val ) ( dec ) [ LIT "0 ] SUB DUP #09 GTH [ JMP JMP2r ] ( hex ) #27 SUB DUP #0a SUB #05 GTH [ JMP JMP2r ] ( nil ) POP #ff JMP2r @chr/not-sc ( c -- c t ) DUP LIT "; NEQ JMP2r @chr/is-num ( c -- t ) LIT "0 SUB #0a LTH JMP2r @chr/is-operand ( c -- t ) operators/find INC2 ORA JMP2r @chr/is-lc ( c -- lowercase ) LIT "A SUB #1a LTH JMP2r @chr/is-uc ( c -- uppercase ) LIT "a SUB #1a LTH JMP2r @chr/is-label ( c -- t ) DUP LIT "# EQU ?/pt DUP LIT "@ EQU ?/pt DUP LIT ". EQU ?/pt DUP LIT "_ EQU ?/pt ( >> ) @chr/is-an ( c -- t ) DUP /is-num ?/pt DUP /is-lc ?/pt DUP /is-uc ?/pt POP #00 JMP2r &pt POP #01 JMP2r %chr/is-dec ( c -- t ) { LIT "0 SUB #0a LTH } @chr/ ( num -- ) LIT "a ADD #18 DEO JMP2r @chr/ ( -- ) #0a18 DEO JMP2r @chr/ ( -- ) #2018 DEO JMP2r @str/walk-ws ( str* -- str* ) &>ww LDAk DUP ?{ POP JMP2r } #21 LTH ?{ JMP2r } INC2 !/>ww @str/swap-chars ( str* a b -- str* ) ,&b STR ,&a STR DUP2 &>wsc LDAk DUP ?{ POP POP2 JMP2r } LIT &a $1 NEQ ?{ LITr &b $1 STH2k STAr } INC2 !/>wsc @str/is-dec ( str* -- t ) LDAk ?{ POP2 #00 JMP2r } LDAk [ LIT "- ] NEQ ?{ INC2 LDAk chr/is-dec ?{ POP2 #00 JMP2r } } &>wid LDAk DUP ?{ POP POP2 #01 JMP2r } chr/is-dec ?{ POP2 #00 JMP2r } INC2 !/>wid @str/is-hex ( str* -- t ) LDA2 LIT2 "0x EQU2 JMP2r @str/hex ( str* -- value* ) [ LIT2r 0000 ] &>wh [ LITr 40 ] SFT2r LDAk chr/hex [ LITr 00 ] STH ADD2r INC2 LDAk ?/>wh POP2 STH2r JMP2r @str/dec ( str* -- val* ) [ LIT2r 0000 ] !{ &>ldec [ LITr 00 ] STH MUL2r [ LITr 00 ] STH ADD2r INC2 } ( str* . val* ) LDAk [ LIT "0 ] SUB #0a LTHk ?/>ldec POP2 POP2 STH2r JMP2r @str/ ( str* c -- ) STH &>wpu LDAk DUP ?{ POP POPr POP2 JMP2r } DUP STHkr NEQ ?{ POP POPr POP2 JMP2r } #18 DEO INC2 !/>wpu @str/ ( str* -- ) / !chr/ @str/ ( str* -- ) LDAk DUP ?{ POP POP2 JMP2r } #18 DEO INC2 !/ @str/

( str* -- ) LIT2 "[ 18 DEO / LIT2 "] 18 DEO !chr/ @str/cmp ( a* b* -- f ) STH2 &>wc LDAk ?{ &d LDA LDAr STHr EQU JMP2r } LDAk LDAkr STHr NEQ ?/d INC2 INC2r !/>wc @err/ ( str* -- ) / #0a19 DEO JMP2r @err/ ( str* -- ) LDAk DUP ?{ POP POP2 JMP2r } #19 DEO INC2 !/ @u16/ ( u16* -- ) SWP u8/ ( >> ) @u8/ ( byte -- ) DUP #04 SFT / ( >> ) & ( byte -- ) #0f AND DUP #09 GTH #27 MUL ADD ( >> ) & ( d -- ) [ LIT "0 ] ADD #18 DEO JMP2r @u8/ ( byte -- ) / !chr/ @u16/ ( byte -- ) / !chr/ ( @|LUTs ) @keywords/find ( token* -- ffff|addr* ) STH2 ;&lutend ;&lut &>l LDA2k STH2kr str/cmp ?{ #0004 ADD2 GTH2k ?/>l POP2 #ffff } NIP2 POP2r JMP2r @keywords/lut [4 =dict/function =function/ =dict/end =end/ =dict/vars =vars/ =dict/comment =comment/ =dict/goto =goto/ =dict/if =if/ =dict/then =then/ =dict/elseif =elseif/ =dict/else =else/ =dict/close =close/ &lutend ] @operators/find ( c -- ffff|addr* ) STH ;&lutend ;&lut &>l LDAk STHkr EQU ?{ #0003 ADD2 GTH2k ?/>l POP2 #ffff } NIP2 POPr JMP2r @operators/lut [4 "+ =dict/add2 "- =dict/sub2 "* =dict/mul2 "/ =dict/div2 "% =dict/mod2 "| =dict/ora2 "& =dict/and2 "^ =dict/eor2 "~ =dict/jsr2 "= =dict/equ2-s "! =dict/neq2-s "> =dict/gth2-s "< =dict/lth2-s ", =&nil &lutend ] &nil 00 ( @|Assets ) @dict/comment "comment 00 &function "function 00 &vars "vars 00 &goto "goto 00 &end "end 00 &if "if 00 &elseif "elseif 00 &then "then 00 &else "else 00 &close "close 00 &err-unknown-expr "Unknown 20 "expression: 20 00 &fn-prefix "fn- 00 &anon-jump "!{ 00 &backarrow "<- 00 &ora "ORA 00 &sft2-l "NIP 20 "#40 20 "SFT 20 "SFT2 00 &sft2-r "NIP 20 "SFT2 00 &jmp2r "JMP2r 00 &sth2r "STH2r 00 &deo2 "NIP 20 "DEO2 00 &mod2 "DIV2k 20 "MUL2 20 "SUB2 00 &equ2-s "EQU2 20 "#00 20 "SWP 00 &neq2-s "NEQ2 20 "#00 20 "SWP 00 >h2-s "GTH2 20 "#00 20 "SWP 00 <h2-s "LTH2 20 "#00 20 "SWP 00 [6 &str2 "STR2 00 &sta2 "STA2 00 &lda2 "LDA2 00 &add2 "ADD2 00 &sub2 "SUB2 00 &mul2 "MUL2 00 &div2 "DIV2 00 &ora2 "ORA2 00 &and2 "AND2 00 &eor2 "EOR2 00 &jsr2 "JSR2 00 ] @if/buf $100 @stack/buf $400 @dict/buf $1000 @expr/buf