From c8331edece70a52e77f2f2012e9e217b269cf24d Mon Sep 17 00:00:00 2001 From: Jeremy Penner Date: Sat, 9 Feb 2019 21:52:12 -0500 Subject: [PATCH] Implement Jorth interpreter in Jorth so its task can be suspended --- boot.jor | 42 +++++++++++++++ defs.jor | 25 --------- game.exe | Bin 106094 -> 107158 bytes game.prj | Bin 5265 -> 5137 bytes jorth.c | 153 ++++++++++++++++++++++++++++++++++--------------------- jorth.h | 1 + temp.jor | 13 +++++ 7 files changed, 150 insertions(+), 84 deletions(-) create mode 100755 boot.jor create mode 100755 temp.jor diff --git a/boot.jor b/boot.jor new file mode 100755 index 0000000..f764b7a --- /dev/null +++ b/boot.jor @@ -0,0 +1,42 @@ +2 const cell +: cells cell * ; + +key ) const ')' + +10 const '\n' +key const sp + +128 const F_IMMEDIATE + +: cr '\n' emit ; +: bl sp emit ; + +: if ' BZ_ , here 0 , ; immediate +: else ' GOTO_ , 0 , here swap ! here cell - ; immediate +: then here swap ! ; immediate + +: begin here ; immediate +: while ' BZ_ , here 0 , ; immediate +: repeat ' GOTO_ , swap , here swap ! ; immediate +: again ' GOTO_ , , ; immediate +: until ' BZ_ , , ; immediate + +: ( begin key ')' = until ; immediate +: lit ' LIT_ , , ; + +: interpretword F_IMMEDIATE & state not or if execute else , then ; +: interpretnumber state if lit then ; +: interpretunknown type s" ?" type cr ; +: compileword lookup dup + if interpretword + else drop number + if interpretnumber + else interpretunknown + then + then ; +: interpreter + begin word dup b@ while compileword repeat + s" ok" type cr drop ; +: load-input swap-input r> r> interpreter r< r< swap-input ; +: loadstring ' key-string load-input drop drop ; +: loadfile ' key-file load-input drop close ; diff --git a/defs.jor b/defs.jor index cc50ffd..10f3b98 100755 --- a/defs.jor +++ b/defs.jor @@ -2,29 +2,6 @@ s" jorth.log" open const LOGFILE : log-emit LOGFILE fputc ; -2 const cell -: cells cell * ; - -key ) const ')' - -10 const '\n' -key const sp - -: cr '\n' emit ; -: bl sp emit ; - -: if ' BZ_ , here 0 , ; immediate -: else ' GOTO_ , 0 , here swap ! here cell - ; immediate -: then here swap ! ; immediate - -: begin here ; immediate -: while ' BZ_ , here 0 , ; immediate -: repeat ' GOTO_ , swap , here swap ! ; immediate -: again ' GOTO_ , , ; immediate -: until ' BZ_ , , ; immediate - -: ( begin key ')' = until ; immediate - ' cells @ const docolon ( get the colon execution token ) : :noname here docolon , ] ; @@ -39,8 +16,6 @@ key const sp 1 + ( cp i+1 ) repeat drop drop then drop ; -: lit ' LIT_ , , ; - ( tasks ) : mailbox 2 cells + ; : task-ip task-user-size cells + ; diff --git a/game.exe b/game.exe index 368ef8a33e4fd0aba51cc2c9b6afdf07cd50051e..d0674565a90858421dc1e139bfa6c5669c84869d 100755 GIT binary patch delta 23386 zcmbuH2Y6J)+xDM1o3bt2Qb_N;Lm<>ZNFaa&SXwH*gES$bNZCMWVG)59f{IE96%eEy zBE1Dg5s@w;AnHmWK!Ajr{q8xNfPdfbeXsZWzQZ-M_xz@wXUd+PGof<7(~1*Lx-NM} zww9bJkcezH7q_Ll*2<>dM1T4a?TFg>u;*qblqFjPAupj>-Ygpl6P*u{P|_NK@?rNT zM9Nwx=1mCR;qdeQ4lVCb@G3?G6*w1zTFgQV?^F5vhTV(#@#Uj0cF_;sB_1D8iDm^Q z-4mNweiNeQQxc5UE{O=}Wv+^YIW~{Oa7TB>$vhZKwzPBTAta<&RysrmR=3Js_XU-B zY$1)EL7gAbthuV+~OMj<8_1CX~N&+tPUW25JTFV6aP=niRQsN*o zv_@w6TORY)rRP#n3p>;)qJw#l{Di~kXRX+>%&zWA<# zWr@PeGFj0lqCV{>&vT_R2c4lFSd1Y{jjpz{}RydZLCml9gS3JXA?SV0!s8G+#P+Q-tMb7olEHjjzuIp^PjWAzHMy=FD!!yff zrN8ThfAgD9EmxEwLh>_9tun@R^%bgl_%zpgn(;DKDDZcL4zLQjRLZ!gxpivj)7<`c zE7lo9tV%UnKZ(t?TO{M@e^}L?=B0HTj~CE2;dSv@QZpylR;U*`tTYa?8c|zsTZXE- zz_F+m6;?>KKCh{>TYXheQjOxNe518C0mF^M@(#79@~vOl{@Ih_Go-qVRG0se>as#2Wl*>)qz4@jb(s3KxkfLnWYX9eA-wxs{P$ZH9=Kt zwx!BWrmowTDmCk7wdIOBNH|z+d8v+awN#@+cBRg0b3$F{Y@77ls;#j!bBRsZh+0FKi}j%jfl>`L+sosc8ou z=b9UhWbL>9lQ zhXpPY>;kyjR##o>qg<19yRAY7+t~|w{*0$b#}u`pLU&P(I#wXZljl-q{iECpN9!_M z#U&|qmZ)oMdYEgy@ygtKTPjby1fdJh%*oqQt;cJ4 z)A@p)VUz5b^w2WF(8M(OA=ae2JFzd0=x!IW0gRrH+(TYfXsqjMtQTKMna(`0-=l4k zgS8c+_r4N+k+LD=E_;eC4|1*do=Nw^6E%34D~2J37Acn5Q!GS^)Akf*|7EW61`S_p z)`+Pk4kgKAYL<25152vwaQ2~PvulXSsjfyb5GH+g-(I~aN8oOKV7bOmHzHKu3UvJr(1SY8_BI z&^8lTPcS8n36=@=F;MDLaT}7&0O}6304VOMxDHj00?Gm^1oD0=Ucfxd1{we~2*~-V zxK(AewgVag)D7ryjaV#$4S~i1wF0_XBQ62*zn^Oo3&5hl&eVvXfT@sd8juIjH#K6V z-e`SVnJdl$k^yb5v8Fv2o1!7NK#M`|Rl@Q$;%yhB^+%w&Kv#iGHR64w+7Gk{s2pf? zjkp`=bD+gQyMS^{HP%PZ#4Q+t7T_hop8}`Xi06TdfK~vRff8%PGBj@t&__U1fc$F2 zKY{XqRsjtKQr3tD2cxwE(5FB>fNHA6)y0Til0CWLp8_*4)xz(c5(P%vi zv;*h|pb7S}z5?0_R0h<)T5RKJGFn%G?FQQfmRT(pAZH2CUZ4+vnpcaT15E-d1DXXC zUM*e+8Vqz0Xe^Lxwdm?(v>Jhq0ObQwwb&6T1?V_XN1%I8#2G-*K&OD3+{4m%^@+F# ztO3~fV8KXM{zSYFp(vP{SCDEiMSc) zG|&a0i$K$!hzEc~pi4lr@kHzjlmT=Ps5?;gW3dP*38)IFHPG*m#glTQ z$r=b&4Hg4-_OW;!$y|V*0eJ!)cq~oM=M}l)OCU#}FCL52F*^SOVrf_!Dsru*kHtkm z=Ydo}zX8p8EXD&J0dfcW9_XFNVlgKAHlRSDeL$vukHytsAA^N~Z3OH5Sd?QnEdYuE zvH&%EEI!6eF9d1?R0I_ESWLs@90b%9Xbg}6sZeD%pcJ4yAloC+2dP>CwFT+`boY^X z3ezwOC?gHyuQAw_N8&xS!UOCrBntvM`ABrdN+JWw1kwQQd?X%5st0#+#cn_^?%-?o zk=Pumeg*0UWCeQfkvInEJD_Z!3qbEa5*GpO1+tYYH`PuYyGWCoCf9#HWMrY$-b`=Hv=hvihBFaqxCG%DxhD0imJrMKnH*}0-XXHQzf1)v&a$vRf`V(t@we+a2K-P0elU(=6UhZ@|m67zV zIO{Gk@eePfH4|xmL7Hr2e)&+m0U3**3Yz!kkYIyue%dOxxb^K+DyZOJ(Z-(L zdpP-LW%oXi?6~+>^W6#`vxhb9uG#-?+JgDk{55yeQokYL!+YW;lh~xU8&8urNbjCmpt{ zD(g#M5SqL0L0XANRhmYO^ETGwqEJ-&uSV9K3o)Uc&!u)gm&!`p&ML*J-gq8#&#ilA z$vSAWt+|ud(&=tm0iL+;q%DLcR+=Axy*9?3H1o-dy652vvbWC>_V_%I3Lf&{!VHH> zsdKW-lN>7K3-NvNvn@BH$a2O#@e^U<4)fa|GSnuK4HPPe3B0Tkc8$H z&wNgWI`J{O&*p7^kPLRu6`%W98u~^Hy7ZlWefK$;rnHB(*1g+ass%P(H(dgO>E;ai zy5Mv%6Pp3E$SB69V?p$XF{Fg}{hXD(`e1K#T{x?`Bg=3wqL?yws=1RVJ3H%WY`VE> zp#yHDhzezYuckGj>Da<}iq2gVE-CX z^`YJiGF~psc)5#GzX{~Myujm-<#0%Yuy@lPg@S;{l zh2G|VPi6gTWw6XbXLG-5ySBtdG*Abomt<6%GoH$v&~{^lZ|~6blGfqrub-KV@48`U z;@@^J$#`kbs6{Jom_0(%W6-$g=8Tv2aJUqH`o@xnV96s9e(Kl#j8_Ao|;`9Z}1^Yx#8H_xAG`7$yTeQ`Fj2|HwQii&Ii<2hqG4-s-v zQ)9OFU~lyH+QXLiQE^E}d#jv|_b%|aB_Ho?OFr6LR3K$T4{72b?M+mUSi*Akj|IoF zAu7dmvUjLy;ZJ+0_?F3hb;10Ty(>Hx9zioMFN9VX@hCfAcw}ux7G`MwegV#Tx%oLi zV&~|jQ$`k5(CUn=m8!!9Pw`n{UlG^Xn^V|SEF%1JGm0mBl;u^79%eFXg55rcY zNJcz8KEdYD5G)+rRa&mc`I&T51Jv-PHDt9710_sLDU1rSuB*3Vy+kBhRoq&=m1epZ zx7KX+oT=gM^h9gHs3K5`n}K~$G=7Gm{vLQ-xf8#WHJYtI-6(sX#hmS79sSbY1NNGH z>{ZFE6KrDb7CaZe%3VWS9oO58Yicda;~N?@=k3X*pVIwnF?1}K<0II~WeIUQ-ap-{ zdDqG?B0v1ul9CW&I`y+XgZ1L?;7> z-2gNfXgg5vYoagEGN8pkp8%y@6T1MJfR+O-1WLFj&W*s+E6^&S$w0o>#GxTbmJ7B9 zYzUa*nz#wl?Uub&nVDJWG$ApxbH}WVlXE&|@o!b5b!0^@HfCK4!%xoXkfq#?$FgiZ zsddc4qY28|jsmXS%(c$Dl~gU|u_`LCY9oiOaJ_Z>Ez3KJ(Lu0tp`-Q8s|satYjkR% z%$oB`GHH_+{KwDga?Ae2j^1V2frXBE3aM~~L9?+IWH^+}H{7#1m0A27hQ>MM*=$+X z6>7e{#P@G2l=ft{Qp3G9W!W}OS+?qMVFmxKZu!wNu3<8JY1!EDB0FxG(P)onY+e{0 zR^dzJb1EuunDuQcy8m!aP>Q8<(&xJ4IYrYQXu8sTviPJf#UXE}L*wa;t=u`QiII69 z&*`}Cc#i7ubdA~nOpeXzOwK~*U4)I$vY=@%_ct+K|A=|m z)HNE(3ImWSl?pxilbYBl&$zH1c1^9{^Yw+#2|Mp$iErko>v3;a-D3h@7{v2C^P9D1 z{ZHi}{rgV2u#?lQ@RK>VS0V|<8mE&vBos)d$5)rMa2?MvTALBJoK|1vdGhP?TzsA9 zqCJm5{OeB2bKdf_d0c369u;b4)t=8Ol$Sdt=ke|=ZrvDAJ*)P34xhM<^DLcOgs>)- zF)cz|4(6n#6wkyqwnw)0yycS?1B9zBEVdRt{KL0p$B>+sMzMKIJmkxZk1M5Rz&1&4 zo8Dud_4Fd`-l)+-msn@+Vy)4eH znh6ehmbR_@_{V@&`!GJdQ-a{PO4;Sd#~8X2PfgXV{<+26&*7)vYvv=hOY8nfH>UO9 zY=|YhO_KMJdoG2%Bk@$bqj-q$+v*{9t7BxWZ!_4dUEabu8F_eutI(TI)?DWMydkDP z%AML-0#l<=`_9bNPnnxEFwGZLXU$bLCy5ojyCy!*Qrq?wZ{Dl4_WYw=dJ6w2PLJdt zThj;g4@0}jF01ocVT?uj%M{O|L#r(-+I4kZo!7`#{K9>b>~Fd3r{Cjko3?b^S<|j5 zV~&=DjK;e2>f+-Lf4_WX{ZajQ^(*VQmWdfDZ1v6^8Iu`XZHekQDb}ka|L4$N)n4EJ zRz~mkz1#P1ADj`^zG3^A_Qv+}G6FlKx6f<8t9{eD%o?>0e}Kd?sf38|y#q79Z=7N4gx|JxA{MJyy0Lzd}~_Uj9Bu z+Lek&`yYb#MNrwY{9UO(1pR$vhoy(HYk#~%%gQ!CHurHVu5g&3Y3aW|zrfL&h9O~< zQU89&n){dK7ldGgyxM^kIF%&t&#wr?n}PfS7xQ&%FT#fUIv@m+4zDZAhhBFuzo)g| z-TY%VZA)wDJv<&YaCNImUf&jDs zLCXi-+s1rak)I#Ns6df)t_QZ_5Xvzo{nFEDoeP;_vlY0RFPETICI0)D^>BCVS4Ta} zm)GpiFXp{7;T zlnWPHPH%Ccp^vFA7g{<_1{5&s2{E7!kdQC1ulGOC@CEwd}$!H;lhswPyrYIlt-U) z5kR?gor^#^ORi23LG&YaJd`j?hFd zBIzV8;UWsNWHT4h)Q1jm5kue8Z7yQzG(G1cj`mTI93q~+p?EG5=sRl7MIvQUS1uaT z2`b{E5q(J~xk#d~>AH!l#x#+txM)HPC{6*9O#Nvv7foq5ZR4UD9i=!WM05Izin(Y( zYiTtXEonO)=Aspq(>*RyNF-MkL~EKw&ADhpBd9MIskDX0aM6}NqeUuA1b zrys~k4bhHF6v;(<8cS2S$iOPFk&6zrm`-rfk>=9{E;`X(y3fU1w2dBf(V4y=xeG)l zl~E2CU1%OH=AtXjq4ivJqe)cef_glSw3Kdh)SU{csRp74O{4i-^rRWIoQqyGh1PM= zo8G0}Tx4PWI>kjcZKnHNPT8pFkS z+CkH}c!%Dn&0I_%Go9gLA{A357X>tdA~4@Q3uzoR=3)}PO>McDOvk7z7gOjE{ow^M zmG;mBF5WfKRXT*zCZ5yi3Qfb26VK`N3w_DO47yC;axs%`(=9Gc^gBK0qKN(=oiD^J zdP&(_%%)n};0IAmuSgLHF^ANwJQ!jwY1kDm=8=y1hCs|GR~E;`0y1e?7FQ+Y!kUCa zEF?X9KMcZ52G%efViEbVxe*ZWQ52gN1+ka{SX4B``xMC1xL88bY(5uDDTe*Z#WG4{ ze{o@0k>)zp>wa`Ti~WPg0~gF zm4g~XY=djV#aD0xx!6w6X<`$I9rTpKlOeu_TVUd9Cv~H5x!8p|8a9R44cC#2J=B8+ zaj_S!e=~R@+(a(+!EI;`uMAGp0^T>&ov06G==HevWTrSGt_Hc0u?kE@E!ky#dJGgsXoQ6}i zhW9<(LoR-x-sIQ@;tU)F>i-eyD~`@m2ot&ZiGo=<7w6zEbMZ5rjf?Yety1A#fa}7= zMYu^^T!MSV#br3}w(zdNHRj?fDOfHSzrelA#Wf0NYavYZD?)#8bREu+4(~ULW&OCg z0XK?^n{bo3xCIx}4&Lu@?YX!OC+h_754hQH!TXcC(l=cEMcM2Q7gjij&hY+*YsAGJ zxM$tqnJTCc>u-d*3pa?1d-b9cQ8PKY4>yO42le71#CA@q;7sUsdIWc|2fW8{5k28O zfosi0HC!4OHEs%f%~*nOxLD%;v%dF^3Cc zgl`rI2C;w({sg&@3mL>BF0d7b?<@#Mh$UP&)eC2a`j>Jf2U^C30^$QMln^VqP(gge zg&JZN7cLO1xzIqY=R(Vrn5hstHW!l*LeEyxwp0iMn@!ufaAhI%H5YCWySQ*?MJC$A zl?VHPL@pYz)l|lXCp$y?x$t7|&_OP|*+@Ffg%2A;N4fB24s@FfKL~3YggEJQml;vh1(h=(Z4he&|f&qX4{K`t6X95!*)2Z%}(AnjsK5WiThZNMixi9AsrX7Az6ZbQXve7?pK`&7~4wi#+tJL|%)Y^=V#< zUiIy$6DCsTvDo@-bs~$!*~x41y2RHaAC=W&9ti(`!u0={|9_ReH;X4H7~i2cOR$SR zX#GpxdQ;!}`{)PpoTL8rar|DTTO7a=?b!yxo_OFUhXJgioeW})>|!uWvPTU;8mY3O z5K{JGtT7$u(_}bnQlBf?o;b_In%dC_){IW^F*t%Xr^{T7WG(Dbqv}h1yS|B|>zg>H zzKLV&#kl&!BkHSvO**6RrIw9nE$fA;m0fjaDRz;=THD1t^>s|BFM1+tV~-ljQti#} zkI8N0Hp^md?NJ3R%^p?A((PmDwa8-a>PJjC#?*E+(;#b}@zF+lAM` zX9r(!ou;BelHk)s67RAoyU4AJa-LCt_cI~nh*X;D45KW9kfsSwW0Jaj7W>IQ9R7#Y zugy3cH!bCVEsEJWJK=&iNzL1O7Ym{^lO-{aU8gua=&qc@uF+Ho&k|IB$HZ67g-|>Z z&4;MuVgdV&9&j<2{Yq9o8pfeSsjcrpNJDoqgfzaEVbzk%kj?(I-|HGgRdbv5gpj&? zExSWkIa$Xl=qVTL*z1DTbZ2haj^}gl8c@o4{Uh;zzmktLyo?JsN$kO#3L^7 z(wZJ~v4h>GG%mhoYJ2mSpde`~?u3wTaTkPSnB5SPVg48QV|sH#dyox3B}lm!;y=wG zvWNf03=iIz;UaGtH^XHvxEUl;iLv|5@} zulw~B2>hGA%J_b+MC;qSGdqhdoo%g*oV1K|?yj1f4HHzOqy8H}2q|`q` zNaQTKN;1q(5U;oy&!I%Ar+$Wz#@Bhqq!q~Fzh=LHa`+Q~l1~%9Zb?;0E#p;4bzNiv zGf9!>%sDFq$3xAEo zQm$I0k=nt_k!t1kkZzg@4Uq~RBw(BRHQ{O0GNG|O%EXm~*0Ux|vS&6+ws)QbvPlhk zeM62y3)Yc8%pXHy$sS69KRm-!uWdG!4Ym`N(A_RxTk&1i)K1hw54(71sy8gFE66#w zF28eYB>Cr+%9x@p!%wZce;pD25Mcpf?(haxv4ttn2TXE{5Ek*f%mHEUK0w%pJL4sA zSB`L(7PvN<^8Z*1Sy%o5f&>uO;q;GcA7Yc@3NTE#NA zH0%1D&0g26>q}O+t@L6(t1{(d=eZ9yo%>?HxgYsB_s1slKVb=TY>H^Jr`|kD(*ZW9gLhI6CV*o~}5*LpPl#V&A!d{&Fs)r_PhH z^*n`You`tc{9SU9Pa_Zcbn=(a#7?w{LghsiYm(2#Zgepho=Lp)9{p9b_2>D`~Ab+2x%a>w{dKt}=V>4g=0evK2PV40>Xq&v0MEOcOD*p&O z*B{fj@>O(R{s~=^e@55ktLdhE4Ly)=z!vsKs+Mn}TKQ&@DX_P$P<%mZ#h2uv*g`&v zt>mZpih>l|DMax#MJsk;t9v&!QtY7?ioMiIAyQk#KI)_>qppf?sFz|tx>1U-3PCs`!D{D9+F(#aa47an6LD z^YgSzae?+JF4F2e^8|I zFKo73sgd$;YNfnG?UWUisk}?wmG`KZvXb(Y52&y5Aq`Si(Fo-udRzIJ#we?)P+3Eh zmCwkee1ScB(@UDCd_^miwe%?#iPcKR*5M7;9;J*OR64T5N+)()DQ7<@73_ji$u29M z*%hUl-BP-+J4!9Pr_{3tN&|CLxiXE)jpKt9)2fl^<)a@@FZk zK-NJO#JZ~jST9uw%TtB1z9v;T8=#6{BUF*>ZB;ZIql#hURk3WgDvm8wC9p-RME1U_ zAzP(t#MY^j*q5p%Y^$m%+o5X4%2dtSVO0xuLe-L;Q?+8hs!~{$sx^C|YQtpew#-SL z#uVywrdGFOUU=O0S7)$r^;;}b-I>L!Gg)JGS7vIV?#9}vjjWTpJL|6Q!SdC;*dTRp zHbR}n#;UVffjXB>QTJgp)P31JbwBo=x<6a49>6|P4`iRI2eY;6p=_giIQvpPg6&d| zWc$>^*naif?3j8CJE0!SPN~PSv+D8eXLSL)pe|&W)sxsQ^<;KOJ%!y|?o_GB!~24Z|y8_O|9A z8>2bI3N^dgWX%yaO>>mZ(Hv*Kd^0@ zGwf^4Pi(j591}G^v%{M6?3m^PJE^(EPH8T))0!*nlIAM=Rr3q`P4g?er}>TD*W6%L znw#v2<`#RZ`JIvWHj`=pU{2bOc<{fgm<+v zVYb#mn5%UZ-q$(_rCMjr41AWU67#Ag$Qb0sG!w_30}GgAygMB z#Ok7jcwLN;tcw*|>*9nAUA)j)mmnB*i9)Wfp)g3-NEoe45+>=I2-9`Rf=Sm@Sg30* zEYh_Q-q*DhKGLNKt8}K;!e_cR!WX)>!WLbc@RcrI_*&Oa*sW_X9MEM5hjkrRvEq#RvY#U8w>}9&4xq57Qr)R8em}i`9s%N}xk!OPJGtWfXZqJ6Y zQ=W}vzj!9eDm@#^m{${-n^&?d!mFvQg;z6K7q8~B0bVU+6TMo>=6SV}edyI%w#BQB zNw&)?Rkqiwt?ZCjn(U}oy6iizcCsJ5a6sHEL-w;*N7*l4on*gzWy=2W>LRmxb(K|m z8D$T=ddh0NddZaDSu!{8-m+lt99fii05*?;sEv0pWqJovo_8pX^bVtO-VxYKilmv| zQ8d>(nm+W7q1E28wA&je0lZC#c(sc6{@zLSqjzKa%{!SMcsHfz-p$C_r#b0;T9B_# zD+>2Xp=Lg<=`Ei&G{7g7hWn(^IG=Qy?9(1^WHWF?p##nK=}2auPPD?OGp+Z@q|H8E z@shS1ZTB(KA)oG4?$Z z$38lG>SMsGTz7iqgY6~X1|;+KBu8H_lKc9Q($|;NzW$`~4a8gCAoB1HCNJMG^7jp= zK;H-o_Kl)2-)M^QjiDspIBMyeNa?-}DZ{rBb@WZ5&c2PQt8Wv$7xHaNJ$=3LhB%NW zprF}!`@7sXl-8o44Jc^0ZzP>UVLza-8z}5A-&neb0;_%F=_THtI{GD&t6xL%^=m}Y zeo2(%*O=P)HKERa$<)iQIgP|SMw4GFD)CF9&-~ip1#~)X^UI*^ex2x`-&-d7-Y=7W z^6N_1{kqYgenxWg?@m7cJt@w=7d7$kO)36a)WbiU2KeXDQ2$&S?Vm>r{PStOe;+#P z-uOoe0%m_)L`DWnLTPKH1eH3%%Ckic0K6*!xk1Qt`8N=qt$_nX?NffDi2&rKL#$NOMw=;8~6b|3tUbtXa#A5N+~7?FROz-q@h6{ z(cGX_v@+-uS{L*wZ43I0_64n>W2T_BbS`KeT@PAMcY-!hb46z+o)ymSCk&SgE|I(O+ABmQorC`G%|QM6$I}gQ*asW5B`RZ1bb0=us3}d>_eA= z{pd zA4&-AM@>QpQA+4gxM4IVbR>-r9Yu3O-=>A3qv^xYF|;;xEUgb6M_+}$VS3@V$z0j%T6ZS3zgiWWIuo)B=Hj^5MnW$M<5p@omO;f{)X-3#Q zDhXRa?}wF8Y1l&gJj_hrge{_DVT*!y%XYzaLMTT1HiWfT+s0W}O?POZXMP+@o} zZ3cE!;Y46S0BPA~sQG#AeEh*g}O7 zTWMOvHZnzQr@0Y3=)H)qsWf6It%<;&P(A8*JL)pS-I&bLP3XPoWLg~E zl$J#|qmQC-_9?n0eG%P?zKTwv9nr06Z*(f{i*8HbM5ocA=yW;~-Ofa(qC3)e$apUL zExHojnXX1V(67;sbR*h{{)m>-U(wj!idK;jqb7Nb3+ZDtO zT&Zo08+DBFpv;&C)Gfx7`owtA$QW;$6yrxzV*F`ZOaLv338alN!L&IhguaXkrLSU4 zVYE9Yoc1H(!5CjUhJ+`O@LMGO0iRZcE0OqdOjCLqgA*08%}E~Hg8XA!QE+SuMa8zJ zX0dIkLu@K#$F`;6u|^sd+l$_b?M;(ovuH+aHWkO_P)Teqy&s!L%VYED8C{HDLzm;%(l7Drs5X8*QNjk2 zC2S<`giYj|u$cl9KBx4AFQ{|Em((R;3mFr((%^(`CK{UX6^%&PPU924rU?l<@n1Xa zqA3Zx$(*ol6abu6ThdHiDxK1@ki>Ec$T^*{zSbK&r#pRpJ`~~c^Z*;fkq{EJWk^h zFVnQdD>O6l7b;G?M)MMXrIm@->Epzkv^wz?txLR38x#Mat%-lq_QbzvU*g}iKk*J7 zPrO0piTCKI#7er5SUP$v^K?n!XB=?#5rU|7=~BFLG_|QiJA_6!oWys{aE3=npo}{H zyAY4_OnkQt$3lb{!j>H`0Vh3O@&1~T3ffJk!|5eE4+ZZGjnjA(0iIdMn}T_odzOwI$0oC0r8md1241}p6NFS1 zvIzM0%is`8S*7~%h|WfI7-+gfWPL0SiZ-E~(zZN07twq>cY{OX>*x!J&MSR~N9Q9t z4iQ?%H_>ezn^2$9H9Wd6q8lQ5>OZ1CM|8i^pLleCMDr6vwIKMm{B@Nnxo-W$5@KX_MpBfNy+&JeDVwt|F5>1BdoxIQfes zK=M>Og@00RzvF!9Z{=_9_`2LpO4AqqO*tR1_Nz+X5-0N*4&36TlDug>#^z))Uiu0& z5TucU4-@+}SkW2h_5?BwMtFoGqn=~4(L@u`prIhU6jNXGIAxZkhr@5A>`s%Ac?5JT zB_BQZt5|98zEKFyQ@-iG)yhCA!D#sF>e6sYVP`%;JRiQKuyZ{`Vi16)KUzNR^CLuULW$#KJGe#94C78ndf4qvn zueD!`RD2fm6I(>@tMI*FcWqVW@;3uGK8&M>D&D*H%Sjz9iJ9;fYI~s^M5^&j2rCvr z$E)AsNV=w|l#} z4R{jiy03PWJ{Q8TQVVtn|FPOWZWck;sNakm6aFU!nuWexj0la(o0jIdBvUb3x&*wB zOC$L9Yq5)c3N1r$sSBS%_G^6|{{X>F|KMdV(KH9;tN=gg5?+@YC;nV|;#dMsuB`;J zy6}l-zwm#j&^%=L2*H+`%z8}oH5y5;g1=D1*L?f6ypDg0;L3mSbs7UsLNHnlzNsz^ z&#_x$Z}eJdQDd^3mq(n^*jFfgGt+5JC`ZzDU*jcxZiHW@vEMxha;@Deo1svZ<%1;d`aH_V|0SK>T%0`C z*}LF4bdBy!7x?Jy{3N)){tZvl+sDKy@b>yQW5TGnPu=gpd+L4Q+pn?uB6<(g@_Pge z^?Y%wn}3!1Xeq@R_zzLp5}21?o`x`53VjyZ#}G`*>UavY1^OI#s^N{P`y1>HIuAa` z@TNgy>i9+Q@&Dk{OollAN>Ms(Ycjl90XG}MX*u{+WY~hr>aR0~Kw1HQ4d9&N%{ozO zXilZz*TJg{P3n{5FulE7Z-7L*Dqr))b=-6dsOdi<+SWzf25RhIg+jiUMaK^4Z4F+jaPCVC2T-tO8PGR6z^7b_D5ifIqOYRDV6^8%(%fz`gRZ&to3e`F5b) zXxuAk58t-5udae@->$3-Z;5T-gM8E3VKkaw8~la{-!mQYWZV4mh0}POBOUf_;=hue zKn58ihWcl)YtZ~s1RfOrW**Y1Uqj$-!HV?!;O~!t->_Rq;|$G$_+eK2RUT}=8GZox zyI?Ij*8T0-mEd%8#^0UsW5BnAoAI~#QU;T6h@R94xF8}RL_?aoKTeAai6T9;7CbQ| zoZRX%WQF`j-r#!hej%601FyOb&?Oyy|U(=#uCE*V;GwRK3+7vaLx}*F+@O@F^>yzVWyve?D1tTIh+TO=JHZ8in zlqeLuJ${SVU-P50sJFnRgT?0P9@G_3W9+StLqxY2{Ha!5hAA7T|#(@<2*4_i=dFb%Kc!Lc35Gy(yBo+1jr&FimGu^+OL z$iR;zzZ1KRXOk{jy#2v}A53EL9CM>f<_|A#b>1~*_8@Nm2q}RMS zv6rOz*_3&SrHf}UPt#is6!?P%eul&WadFvZRtbDi?6Va5)+*qb~)14%>k)3Bjnuk)8?fpl~M|C7X#toyjU|gu>+H?cj$( z6x4L@(3v>8#BxjV%K2L9up;JJy0{3()H6$eD`Ekq*Nd3E)M*wgD@~mRb$AxLT$)%6 z6*!kUl&+f1M%yC-i&LO>;waBwrQ`77 z^;caa8bq|3AD2P5;fU;CrHAIS{_JjPz&!RNYfyTB9t&VTrP}$dgCZ0QBQG$lwEuk8 zfJK&0p3k~PHGrizxieu^4Tn$igFkx0zZN!9qcMv%GLi+vXz(oH!m3{A?-yk z=UG;8uM`J2i&ny;4|(t-cts!c;3^*cgnOUz;AcGDYOXeL#t%Bu-@Ji$xL3j48J%ZX zy7{?D`i^0({()hU?#8e>-(^^e@8MoeR0+T6KEG{#MiA|XXM@NC8GYeRy?s79GN1(V+|$9mZhM5qnF_OwGdiUxfD` z)*pZ54S&$cg1Ru&YcyrtgwmypSeDBK{Bbx>HlbkP+e1r#U&Nk;P98U5$k>5nhH}jH zu+amDPvn8Y`w+m_2s;eWNVtlLDz zz7?dix8!DfFqs|KS`{62x6k5cM_7{WvOJkDbl;(On<%qQQRaB6o>)pl_okP2epW2E zGo*fKyQEBPf9kO$mvnx%&?WDCY#BW0NLJ|$DbeP~7AYXII;TE!ocxdQ6UV;Cw(hFg zwg)Ps`|!sWhumq?sDpUOV_UpBDDeBHmeSfHr?WugZ0cwqXE`A!YU0dsI3C#st3!Lq zojz5HCWp+9gOAXLUFk(ucPcOzwV`~C&!l#?eq=kN4)vP;Z(a4s#x+rV$Rk^vCef;W=4|E&M5*5}QH>gPXb{@Zsyw7p zmOr%A(OVBKb@kSrx&3as*|8_lVv!P#fA}9}aiw|U_*%qs*tU0Fe74lgsn4o3CGzEF zt7G~@izCaKsjkj&mgu7t zmSoZNJGKUTf2*>_GPv}2DUD<`=hP>4_HayVW3iOpk(#r%+M=#5a06HICWl0V;?B=p z10*}AG<9owRR_m+k4lfb$ewSj=ECawVNh3kQfWsnvVJL5QCeGiLiR;^X{9IwS61u81w+8H$DX_Z=PMJoi# zp43@PTpFD6b#{4svtuP<{K+xH73nzk*sg>+59;2>QhLXvXQB<_lna_kh26Ywail$T zTzOir=NlY_52b;67EvpmsFYh_uww{qa#qP4*{&XQWIvM5Y{;|1c2wYF*Px~#)YRv( zRPM6-mMS;LB4^c4u5Pm%+M7jsF;RRHCHf3DY;vf{S##fP$Lg4(qaGr*cxqjT)hE3e zE-tD8W=H4yuB)o(hCDk*j9(9oU-79TSXy43`K;8fIP=K~xmqenOl4vum>oK_+w2sV zv^y^8x5F)^nV98DGoKW@4Z)zYC3!|$PqAM!k^@pXYo6{YaYsBe@i96FNSz+Q`+g7h;ear7+%+{TWYg)zF(c1mccPo(F z?`f6JVXtv4aP^_)uIn6~Q{;{rh@SA&@!36>~CZtA?KCQOrL-K<3Hl$EUE354vyIIW+g0=*j8rp(t`$Z(XdCOv72C4Rz z#gSia_d@&6Ls|jpcSu94?Oh<9fV2wISxCLA?b{*kgtP|IK}fBu?I$3WLs|=|0+OlP zehboDkk&(5am!+L_*C2F3bW&NXdgkFk7T^s-U8AnNSh!{hIIRZy$hr)NSh(O1nJiY z_C!b-kaj@o3F)f`_FPB}AlV_cg0$;_y#!J)r2UZMAgy~KT^346Us$1eLtFg7o`!)@ zebZt;4v9gU^}yZ>(p5;6kZ#?yI7UCP55NUg3F$nfUm)c?uup}wAJQdAUqb5mzt-YQVpb;kZSMSFF+a$ z=`o~NA^m>e-WH?1J0!}$)Bx%1efv?gq6H*5qz;e{-nUJ?}f-sJ44T-3m1T>gQ0K-?tyfxxWu71ky%G(f92+IqcF(>V(r`%0kj6u*x@W%+sSl)7NCP3AyJvrlD$^jfhtw6)v3qu<(dgftq`PmucEvsXge11TTUQAp|c>=z(yfMkWV4N~$w`&&TVw@P0W zC)};q(iurS=LWHC`(8h@V+t~qA=MmYczU<0@tgC>iK{Hw;)3f9aeHulE;&`l=Q1a` z#4O}lg*?C3S{zdz7NuQFr~DJrcbU0gpT6#)**RJJecax(sML2u#*Na@O&JRp zZ1Bu0-;|O5Iq?-WkBfabWgyNrC^)J`MF!=k?v0=uJ83VY5?w{ccURPhaUTJ#B=gxV zXX@4rXX@sR@`?=HYhWhDJ&OAY_X?XmIA+*}jM7Z`=bTWcT~3LI*HwseGl~w&wiezh z&2-=9@m;MDGH#V*x<@+&-l|JblIc;0@~!Gy^`$S2wyfKnQS7@lLuU{7H_=2!uy04tI0Ib|K#@Kc`^^AbT4(}4ov~wd z=pOgBshwbybuBtc#lv*#T1mo1n9*b1cIOWe@n?4;u5bFSQR z;>p1ar3>Mwy0Gl8O>{i-G5xi&-Vo+GGl=saAgeSLXV=2c!bIlM6XK&TqBy&{B=a%G zd@QTE?sh%HW{3}I*s4>BqI7VzZ16J~Ox8+~FFP)ulj+QSRy6yW&&=;jGpl9p7c+`8 zt4lL$1=$A02WMT$C{DYU@%(nO=!Q3L%>UghxFyF;v@k`f@0E8~v4q*{A5)BNdtzJbysT(z$(dbLbj4bFe&K?7SyjFzU!WQ1O2C>z z5#`cLzE~^I#zi`0aF}9%B`^0|-02^8muFKIt&wLhS0Bo+#b=dkf-HA6r=YpLknn6| zw$IDLU7#OYBekoqk7Zq9R?Od-{mzadEc7ByS~}RakPaWZpd6`$E^+{h6F%-8TSmIn8|m36-1k)shpi4s{-Fv6K3XBHcUa=%6}&kDUslNApOhj_ z!?$bcl)+wU!p*N73jt5<1DD}m?VQEoR_%EB%x=sv+ud#7q;zo$1$o>28#LyX6}BD? zn!6=Ih_Eee(3tJBecm9@x3a=)C$rhn_5s#dhGQNPuEJK;AjEoFYQfj=r7302evFnF zJ+)<2fZ6=(3e1~`M5~I@zOJCzK1FFKEBt5cL_7V_T4+=iF2&8ldL0@+%d`F*MBE8? zaVF&_E6!Zr`!-9g?CTi&#P!YRswv1-mCP~8Y2R0Y8-k~n@&gra>z(HEeYUj?8+iu( z=t?d6*rh)(NWEjn0+ak=3KTen70)*pUw<#1T9*~^p6j&na) z>> znaAh3XNxaW+|^ZCFqdcxVvo;r%T{g0omLLM&)u`}e2%ilp@5}V@E~=yNwt*6p{&Bp zjvUT{^^Sn6w%LsnB4FqOH^=FxRjQ&i^lE|3k^5A#X)`P?9;jaPhV84yT>_`&gu9l2 zyh=l-nc+a<){x8 zREg)?HD_!yo20UbwjE7=WOHpLO?UZUx5UsPH5PV0row#roUhW+|Fd(wTibG*eQcPU zTR2lrGgYO>i;f%G9=7Z-rp{z+>5jLWn_1x8+%D_p=Bf|P)Rl%V%5}Og$}LgsBrGV- zwbix|-5uW2$8BV)*}lZqs$~zTXTNk5o?c* zlVXk$mxN0<*jl#=F&J*{th>g=Tw!0bV^pg&He`M-(!cGFVhh~o#LmlgKD84!*SOEi zC7xfu_9jhUb8~UKPFUDkvrOd4tIzZ9^E~gm@^ERrPRg^y=GG=T`o4tBbDqu371!-ui!HlN6l-jo(I!eeGq+jmqS;s<_RVpev2AMe5E7UTd*^ z)iyNwiN&1lcvpvos^fzP9hMWuiZDZVQJUvXCq@_=ErSu6yXVbvPn&mI3x3#Q>y;KF zK3+@Pg8>uQE&_hnb~}aSY!@It0@H^;o00w(i?j`I-y|>+-6VPy_p;lHhVx5nB3(wu zu-MlA$`3;Lr-SMfYP}QlE_~_HAt@v2n$s|7Zc6wQSgk?_E4j#Y?5^btqrui2h9Bf;c z*~@G2fX2?E$39bJe|gBxTupI)v^sN#ymNELxUEf>riL?`qNDP^o;-D&)cjTb)N$Na z*rhESyyHNZsf-P_rFNT=q{$S2H5tz`|i_BEr-3nqha?0-1z%|qQ`!yw%k?izMearJ$*R8IKbv>?!tcAF~mHY zwNZC_&^5gqbsN|1^=^B*9qM+hTYR@$-A;C^?Dl=P(cOJ}?CpNOySe8g=`W~TL^pI> z>0tSpt2GO7!ft(2k`7zQkXwaChc9jqIl;%KiqZ)f_c zh`&znunpK9zx2a$G_bAHneSbCt{AN<4xM2$^!M=|S||IKo-3b`SKOJ4h?f0F>1N~==!+Fj zh3p72@3L*_|BmFEG zm~Q)I*(_VLvIyJ2vH)9QSwF9_q*uqiVmn*b%WwFIk&{zKkDo*n z3tr8qzMafH!Y7XyH+)CuV$L`se->yEj(L@LhegR}%;&R-;0i*N@ndmg_X z;S7$ul)B?E!gxnlAEdMY3SW5cDcXuhUgn-CsrTlM&|jSJNtr z7NDW`sJQ?wEu(G%bhMHN3DDCanjpYHTd7EZk=~`n0z7Fgy)VFv-l0zgc+&{lE5L{L z&>sSP$xfc=N`F7fvr?KMe;Q3=1O(7f+&BXQ=~encKoE^0l^Ylq(>KzMv8T$uyNJ1*A|hsXYJLb@RUgPR@;7)hH*X#~7No5@eW zC|XP%1-wd&XtaRQG@nWYjG+QLBEUM9CQ+rJ*JvDF5HOAo(scpj>2uoa2be(H>6n0t z^aE}82TY>xX0X;eeq1Wc!gv^)qf z!%DUEBn0$2DcIg{z)VuIlLBUun&~3|vq{Io1)!f#Q^3}G#eKOc!L62un91qf><*F3n+%o5U`M}v8+;1F(tC|0!qll+QkD(DV~iH zu!s`adjj61&TN~2w`e4*67V)7En&3*(3pL;jRl<2RF7My!F(AS-l&BK7?y5U;|u#0Uyx= z8rcM}k?v7IQ^3b?uM5~j{b-+nPf$m6Ge8AgYXP59Hf0Ie4A(am-WIr#0=B{}Zw_x8 z9BTn@J7v*5tDqflhL-SlQZ8i)_zZ5cfL(Bl1?+~~D8LSPUBDi=h*t3S!g;rb_c>fM z0sG*x1?-2LCg1?v#{v$*eJ0=#+_Bb}e=v&@T^7<|xMu>6z+Gzt?4T`>R91?o$iLAYA`vI_z(!PN-33>VWC-fwU>dcwOxIjnClz*V>`0oUr` zcSKDT${%o31^ihL4!|0r`~^3@H@xd`$IbApRq*`!z`FsLBH$)mV*$6|QU%ck>wtxqKxdN&I^90lY<_o9=EEMq23Mvuw2(U=NW58Pi zo&XjLcv=t70PhIJ30NY47~#$XzyQkyhBZ6wJB+ z*9ypkEvL=t03~~awhB*NnBK}R3i4&aY+e??k8zS`1N_n0X*qxZzzhL_fSI{~ zAi!(^!GJ;mA%M98LIH;@fH1&y0pWlf0wMsn1VjR=1w;X?d;lmKBo`0^n3e~K1@o&Y#F<+vx zbl6-f@HzBBx5`ERDi;B|)hBum-Rs-&9Qv>%S3%FACrfrI&*6E2&!I0WdxlZV{|(mv zDgA#?dax97hdJdvSOXXILxY~6K~~3E zOR=!VE*QX?xT5lqMyhNeK*~OdHKn6sT{*K5?gz+<}PUnzLe&RVKs!cq-6qL zVy#?JL+eW%R^P;z>zg>dzKJ91VPt*cA@$WiS2EC>QtMw~tz9LLva&XW5kvAQGXD289b8cZSw~mmY=*sEPGR$& ztdlElG|P0wjl%<*G-97aPu8V=pw+>6*43430_#=}-CZ!A^>D$&dV5S__y!Smi3>-} zobHoZl+{Jz5|X5R7ViQx&P*tZsr6=@2JnEUnqF6;Y6d`RqDUhRo!8k(X;|_9lK6Rd z%*0%0mGTRcU=};|0z{KEqOqGWMM_t>1cmHp3iroVKAZhSV*&m}sD7iEM&|)U8kz&B z5HOdWr_BPa>>O zr}IL2pZ!6#0zP1W(jNjuE-}6|tC2WRm}(8$ffkag9Ez_1kywct#5RV!#M5?vAb z*8#2xSPzg&{1D&}$_Bu70Ut3Bx+!2Ilv@J2LAfKKFW_$h9|P_R$OhaKu!;Re_XT{y zu2Y793Z@aQ$NW=*f~2eBQ-E}en*m~S;9CHaVgBz=2`>+Ea$$xaMXkaN=L85dNTwEM_*E#v3>O6mGyEn%m_ah$4p>+^jhz6=ik|@_EA9eF zR@}{Qx~yntx9En*Zr#IfyUe(k-Eo=mbN08(di#(~vd1UvE~Sdp!f28ih0UbC7dDed z)Bm*D|CJf6FNQ;%8TLcL>_hGcFuo)>h!H1&>%v8p>v9F;vn#Hs!*y*{9RWy}((`T= zQDQ>Vh$wMBnxpKIYYZM^*1FXHkm{72JS^8cCtTNEU24y4OOOk66FMrxU;L#nKjJ#|%f z28z@##{p8m2s4N@^0TN_YR7l%S^d`%#=q2%|ED@ciBk2&bw#Tx@t#0B*YE2q`vD-8 zEZQp7D%vVtO8=SNDo*Hm{vYe|t9}AVC7xzXnwsV3phy$Z&j9HZ&%>UNg*|_PBGvIL zK&nHOBdXUtFXsZzUK;Rc0MfK^5#TQ7A9)E#nm~#H(!6n+aVCxPOHia*F9W0#`VAme ze+3{}SahdUJ-X9X{dK0tfWsHe^KY8x-!D~|>7}S!0DSXd{<)3wkiKy50Hp8YzX3AQ zXWeifQs;?+3UPldjeH62u>iI*4vFrvNG22#ry#`Q|_*Q~fJm{jad* zKf}9o2C#{;rm3uSeV1No?DMRyy$V?MhEBcSU=7x{==CN$2LBK%|FA``8>~k~i(dEH z+;uH_RkL6Fmkk`u?pg<833(6|x(}x1?nAJO{1UzIK9sh)zl??C;q;mN2s-Be3f>iu zqHo+^rL*p%>Ad?Gy6Qfbs@%t6WqCaP?LL9HViFdYCzFRFpY)0X@>5KqaK%(IDW+qs zc?P8@UZ+&WEG#$Arq&88Wh&-i#d$7uwd#P_ddGE6T~KSWC=fJ$ZO+z!LUHWboKX{vIDwpvNY%hIxEKaUKnwmrTre2bj;%ned%$Q&U&1t^B&*RU5_8E zRO9g@IX%u{1^s7ID$kRb@)rtH{z_5G3uIDWq(tQ?Vl!0HY_2Mn&9kaZY@sTiy`xHCWvWEBN|nSuRwc8YsucE>ssTHzYRJy3 z8nX+kChW4RDZ8p_#_p(6*#lK`_EgoHIaO_#o4PGitJ^W7I-U8d+p}nPQV(UD)FW7hdL-MTeueE(k78e_Uu8$tW7u)^ zSoW2A9Q#H+o}E@tVCU2m*#-4vc1fMjepeT;>uO9tnyE~!nZ|-OGgyS?bt{X}%w(-J zvsi{^HtVk`WI38SY@nuy4b#kHBQ$TY@tXN;l4b#$saeRZnqoFzQ^Hng7P0pssd2tYaS9^-QJxkZH9Wn6Gvt^VfdNg0-7il=c%Ar`^mFv|CuRb}MV9 z-NssIx3kvTovf|)GnTI1#d>IWv%Xq8>#yC*hH3Y);oAM|73~2wT6>Varai<8v|q4k z+QaO1?NK&MdyExokF%xP6YPEMmu!ty`xRTO{hDpko@AeDPqQuBZ`pQjCEKSx!;Wgt zvJ=|x+1J`1*-7nB>|5>ht-Z`@w7;=O+AHj- z_9|28t}&JFcjl@4gZb$GWPUma3)5X^k-91tt-HzMbhlZ&?r&yI(%oeZboW?m-F?yLu`JyamZN*h@^sJGYdR;Jr6WF1$N2)CjF;%-e5uZjzpqp9)jALU zkxt3C=u~{SPR;k}H2e#lmLJpU_-UP<|EM$YpLIrlQRl_4>Ad-0Iv;*Z=g05s{H^?n zE`ZDRfn1{x;zoTi_tl5+Kz%5W(ueUxeK=3iNAM>4NZvvp&C~QTyuCh__t2YoFMT}k zqfg)i^+|lNKA8{Ir|_}*hJ2j95ud1U%=7h4_*8vUZq+yAbM>kG4Sfr~K;M#==v(o3 z^=gSEV+<4cWWz*0 z-7tyIGEC-HLq4Bln97R{)40trov$*?;A;%8^Rr!+c(8Sjf*AO89w0DZgM?#IG6Nx>8Z2IC?AvGH@h-FTSqF&^RjjYs(*<8gk(c!D1{e#uW8 zzv7j~ulaYzZ}>09ll+456u)dd%^k){e%*M6-!z`(GSBb0ujltX-t!0E#`8zs+w&(r z%<~*C@cfxC^gPes^ZbQx_O$-Wzwo@kfAYM@uX|qNPdzVlgV%37*6Rvy>2;O&@Vdr_ zc>T^NdHuoP@cNT4_j2%0y#C?`ysq;zURC^>*9~6db(5>SZ}AZC+q|Lo9p1tFZ=UUa zm%r+LkI(eJ&)@cbz}I?L^Uu6%_?O!G}9_RCvxAJ+$d-^!} zOFkrqmb45c*xYgN?E9{O4i6%E$is3k>&Vm zWutv{vRS@*na$TA+u&=I?eX=Lo%HpRUGnvo-Szd6x%v6Z{Qdl7iGKdFG`|2@AHP7^ zaK9j#b*f*mti&%w_P$@3Y^z_m%K1;#t+1M_+fbQJ{IrX zC*pPcG`wkFgqQ3#ykFmlH|m@H8(Q(wvk}?x#{4kem7m4i@vC?-eiQG+AK`VlJfIcn z1KLnPKwC--NTap^?WkWsIt>WOpkV~-js^6mlL0w&Hb8-wsd!0$ERu zSn>*tBcH%{>~lz<(7;5B4NRt#z=o6>*oayNHm25rO(-p}DYXx5Mjfqz%_%c55btio zX#@%?2#lhIfzh-S1uaKG8v{-BISM<3!oEXc=L3`IG79`FFokXhHlSJ*>>kvJ^g)d& zB&Z3+1~sL|LCq*FD3v+~wWNVTt!YwF8=4u^mX-vy!>i#AR34N`>w>z{wxDigJs8x3 zjt2FjGeN!S=O8mZ4C+I=;C>Vy+@DOrS=2B%n>q#OP`}_@$_=*Akl+FIdT<_<1rMap zf(OwL!9(cJ;FqW-cql1ChLK;$aEc2VNzFoDq3$80XlTf*G&N*2y%{ow7KeeTNQ*E}^eOZFDL0UAhsvlpp<&CZRoDv3 z4O>am!d6jf*!#3B>;ozfTTK;V<+Llzx|WWGt)nwx>*+$+hxAw22D%&e5!HrmBt`fp zGK7ChiQ$_mC438|hHs$Bjh04^qq4~Hv^H`gSwD%K zL^~rV)85E@IviO*Uqw!#Q<2zL5ILQ6Q8UOhY9@t7&7$zA*%XI0<;18$N{gCHW21^_ zLezYk8MTn+Mio;@R0*w$Dy7X)i)dHWTXZ1mZTdE9G5s0!4mqQiP-yhK6dk>k8bmLn zQPE|zGI}}OdsaFSy^4-SzfTvVKcMR9)#MhlhBPtdXyeavUHGiDck5wn{v#O$S;F`v_;nEj-P zJwVFXgJg_7L;?v9wdz!Y!eoMP! zE9v{#Gju2R2MUP$kz(V1qU5-rsYTp*N{{=6GUI-wZgCfBRGfmw#d*-gI3>-9Q_-S0 z4K0r|(#kj=s)+NYPviV(N1Q+HiwmG5ae;I)E||{7h0ssdxKO$m7e)`_B1nyW7Y0)_ z1)E|h%oIzprZ`G5nW%{=ftr~Tsf8(t+MAN8uPKFwni|jqQzM#YYCH`PK9b&xkD?FaqiJn? zjFmRV$I=!g+!h~9yO7Y1g!_>25I%oF_%|f}Grl=h#kZh)@h$0bd@C|0v>~5_wiKL@ zMu`dSs8vEbbxUYZ0}{+MD4{JqLZo;%sszTFEVG4k?o6 zk}9c){F2_Fkfiw(owR@&CoQBF)}&%eODdsWNu|_3X%P)bdW&94dYi^4y+ad|mQa3@ zjpigRrFluqXi-ubtxj4&B$w;AsHJ=k~fnzH+c)?C2ysdleg1|Q1lwW8{%C9s%CWr|oj5=Toe-ff9xGor2>!&2-Xz%h_VP&2StdmO?;B~5r`n4p>h$K&JA(DlTS4#S(o?Ys(~B|@Fe0KSB0AS)7zDiw*bDkg(7V>@6QFl1 z8$XFn4d@Oj4ABQ=V#(BX{2@!C9%ar+%rBrPqJ>HP_Rh zmzS_fvl*GohKT4sh{l#HI{%Mom0L6FTlThy?uY0Gi0{FLHNrZ$`OgVfoC*8iFWneu67>7q6OJ$4Ync(v3*$0eauv zM`Gb^uj6*$&)hwq>nGgf$byR6L;1$tH8@1%EqC$G4%=qo{&pAkbscg=91TGFPFOz2 za^8y!i3-u1M4jPM6yj}#>u8}cNYE92>$)^T=u)S52Y3I6o~vj~c~~LG8(XaSC5fcc zQKHDCK}<$s56@ynx>&w<9hHjKcwf#)?9%yOAq?g^)E=oc6b1D|(BRRiUdF0jM|v50 z7L-g6VGq~whKH3#pn@C(OFgF7%UF2Jme>Mcsq90ekavLCzTu^8`8?48rK>vzLK&od z(H&Ej;ZmBx@MqMe5ki?V8N1^cy##(w880O1II4`LG0=x0bVB*Uy4RtPg+3hmO-Zji ze}gKTUPHu4M0l&h;k%BeDwo+uA=q5(QLQ^Vs=_3~+)bTT;$5Zd!0MX>W8sffy_f*z zsVp=O<&T5DP$g{UIxbjMkrGXSf4QzuAvjfL8V@s00=ucZ2}wG7t5awa3d%>Qzxu@) z&r-V@GzEI0`bC3Qsa+>94f<;Jixa3&yR2)Sfru??KlrZWxY|vEnee~*$Flf0YHvxO z4ga)S%pk7gk~)JXqb~~){9WCqPQ}JPO)3?jp>v_cXc|A)b2Ni!D)f0!25NGx;#~o~ zfxt|S>kLH7otiH6I`jqLJ(>pIJ2;6kmKuw2I$t!q#(M{v9L#h^YZ>J{T}CEU0FsQ8lB)!(b2U(t%0z;(py zQY82Qev&S+P90Vf9fzCCFt%Y8qdohWv)@9Lbyir;Y-TIMEOcAc* zzOEbgJ78}af=_fA^)hxxyR5PiN_+i_LDZ{G-vqtSKlH(MdIj{M|Io+jU6$JneWG5n zoH&2N)@t!x<=SIfqSr_)yk+`uiMPXFp?8^42)p#IuGtCRqkqvg7wYs~&@cZ(mm72< zo3!;*VR$hnJPlUYHM$p(K87GEk?4bO?OGpr_J0{RVgu_%QU_h8HLHxUNCCGr^A4f3!$xbhY$2bdB*vOZ|+=^d<`W z5_*vF#dY7&7%SeUNjp}%7$XtuIz}7A>22sI5gca>u9vZSyd^D$ej3VK#%3?(|070M zzg8mRxKZ^yLuH+Q7Rq=3&@a^K-$TFr5B<8aQkp=1gnrX_$~BpQ_xia`<{Wsxp9g&D zuwq|&9xXwO&Le!vuOGbw{snx+&viM8Wa0QBfH*F|HN>wJ>W{JbS%Ek%!A-;u5|$(H zW$-kt@T@@hiDSF}K3au$lUKlYe=#y#$GCuoRL=1F@*2XE0+MJgGK=E_thlTL{{b$? zD$M#ieIHh3J_I|UAHk|k{qX}W`aP(GkZDxH|zazWZf?ooNdicMH1G z8rYt8)K$xvKh6x&R@w5PJbn!6??E>OFJ}jl{ysQ2 zIFtPd7RQs21N1>>Er*ks!PtOQrr4bOhAF+y{zzGg2VilCJ-XkS6x3hX3decV2*QHDv{Uzz z=_N@MUb}c#qs4yRjQDuUsY^d5z9Hp;!=aChPbN#9{vIBh2Y@4?e}D(+`op>{z7^%c zTw(|BuJ~p&xGqCgd;%U}xU`S=9-gL$*6BV8U1%6s?B)%|!*KmEC}9PA8R-+C4^LPE z-*r?cy6zQ{pgc@;O>QDaku+L-Sh2wuuj7+m5drC#nAA}E6uTPolalLHT#88v5{rEc z>yupbzYxAjGD&(<=%yg?Z2;SqREd zlHcyIxy+j}b6L|O_Up2F%mimBGtFaWXw&DhFxJ0p#XR;!*|0a*xw4G;Y(m-I`OLrU z{Cw78ci;jfD=S&ZQk9irpC3$crtI&zEUfI%BIduWnEA6`$^wd6b9SYy4?Y5})TQze z`vljB9U|yB>;=72R$k18us_RK3Hz3LmYpd<#lB^Km$1%CfK+mLS^HAv$D+zCrL1>+ zG7EjoFg{a7Nidzft|aKvmhx70;l^cWN?8MAL*{y{Xvtg^Hr{Pqgen>hW?^PAefF$N zKDaKPyTV-TKo*CvvuJ4JvY~IXN!Ipa4^Rd=22b(G-4Pp@@Z1h9lVR9*W{G&zLu_GJ zp^05UBsP>&4;GE87)E_B7E6V_8LkDf=}6kkR9GtLzm$AclzdH;j9q-LqTd!-77Onk zY*j2=0*`DW_%6J{r6RaY1j~fCTm)B$bSnjkeSRdi_R&?*z-z+$of&Ym!7zs&6A?!l zX3Y~AA2=_}lYhYc^e4{MN)Gsie~Hr;yW-G(cn{$fK4O?5{?|JH%h}<#0G%0Tg%@@s zeD4%WB{Q*Cieu|jp$r;z3li1US#$`4MPFjD=uifWzPx+P+f2jC$``Y~W%75}gR+Pv z?1ml!=9bp>f^h7yMW1*_c%r z7#OB7&0u`RbeCx<<9?Y~3C5cYXBhS~bTfDXAp-*kgE&JB&^C4k1&$aoF$Ud4Pd_e(#Yml!-->;eE*D7yMW1+n7}t z7#KvDC7809W0_T%?3opqjhOtH{sRFAa}3iXhTlx@8Fn$fW6EM`W17aen2~|0j)8}1 z1LG6M2F7kiA4YpdBgTIWUO>pez`-ESup4L_JA(p8jF=dM(sE}%E{4TRUH$(5=hrU; zF}N6%8H5kYZu}481lPMVFbFURGTaG)Y2pBDWdW0{3~CE4{A3xb*I4*5GsrBl@MB_V z29o>?-1Z=oKt?Ds%wFQ*2eIn^f3}_CukKnhcz8E3ys2hqVD|D43h_|*4^kfD>Ejx# n=fUtFWLJo5aEOzui{4~+!PycZSArFSWI+JJao+q^P=yHqp#EX7 diff --git a/jorth.c b/jorth.c index 1795397..004a0ff 100755 --- a/jorth.c +++ b/jorth.c @@ -88,6 +88,11 @@ BINOP(f_uge, u, >=) BINOP(f_ugt, u, >) BINOP(f_ult, u, <) BINOP(f_ule, u, <=) +BINOP(f_and, u, &&) +BINOP(f_or, u, ||) +BINOP(f_bitand, u, &) +BINOP(f_bitor, u, |) +BINOP(f_bitxor, u, ^) void f_eq0() { TOP().i = (TOP().i == 0); @@ -146,6 +151,15 @@ void f_rot() { // a b c -- b c a ST2() = b; } +void f_rput() { + RPUSH(TOP()); + DROP(1); +} + +void f_rtake() { + PUSHC(*RPOP()); +} + void f_cexecute(); void f_key_string() { @@ -180,8 +194,9 @@ void f_key_file() { void f_key() { cell *keyword = RUNNING + TASK_USER_KEY; cell *echoword = RUNNING + TASK_USER_ECHO; - if (keyword->f) { - keyword->f(); + if (keyword->p) { + PUSHCP(keyword->p); + f_cexecute(); } else { PUSHI(0); } @@ -368,11 +383,15 @@ void f_lit_() { IP.p++; } -void f_number() { // str -- num isnum +void f_number() { // str -- (num 1 | str 0) int num = 0, result; result = sscanf(TOP().s, "%d", &num); - TOP().i = num; - PUSHI(result == 1); + if (result == 1) { + TOP().i = num; + PUSHI(result == 1); + } else { + PUSHI(0); + } } void f_streq() { @@ -381,16 +400,30 @@ void f_streq() { TOP().i = result == 0; } +void f_wordname() { + TOP().p = TOP().p + 2; +} +void f_wordflags() { + TOP().u = TOP().p[1].u; +} +void f_codepointer() { + unsigned int flags = TOP().p[1].u; + TOP().p = CELL_OFFSET(TOP().p + 2, (flags & ~F_IMMEDIATE) + 1); +} + void f_lookup() { // name -- (codepointer flags) | (name 0) cell *entry = LATEST; while (entry) { f_dup(); - PUSHP(entry + 2); + PUSHP(entry); + f_wordname(); f_streq(); if (TOP().i) { - unsigned int flags = entry[1].u; - TOP().u = flags; - ST1().p = CELL_OFFSET(entry + 2, (flags & ~F_IMMEDIATE) + 1); + TOP().p = entry; + f_codepointer(); + f_swap(); + TOP().p = entry; + f_wordflags(); return; } DROP(1); @@ -402,13 +435,15 @@ void f_lookup() { // name -- (codepointer flags) | (name 0) void f_revlookup() { // codepointer -- name cell *entry = LATEST; while (entry) { - unsigned int length = entry[1].u & ~F_IMMEDIATE; - cell *name = entry + 2; - cell *cp = CELL_OFFSET(name, length + 1); - if (cp == TOP().p) { - TOP().p = name; + PUSHCP(entry); + f_codepointer(); + if (TOP().p == ST1().p) { + DROP(1); + TOP().p = entry; + f_wordname(); return; } + DROP(1); entry = entry->p; } TOP().p = NULL; @@ -477,14 +512,12 @@ void f_compileword() { // name -- f_lookup(); if (!TOP().u) { // name 0 DROP(1); // name - f_dup(); // name name - f_number(); // name n isnum + f_number(); // n isnum if (TOP().i) { - f_rot(); // name n isnum -- n isnum name - DROP(2); // n isnum w -- n + DROP(1); f_interpretnumber(); } else { - DROP(2); // name + DROP(1); f_interpretunknown(); } } else { // codepointer flags @@ -512,37 +545,21 @@ void f_open() { } void f_close() { - fclose(TOP().fp); - DROP(1); -} - -void f__loadfile() { - cell *key = RUNNING + TASK_USER_KEY; - cell *keysrc = RUNNING + TASK_USER_KEYSRC; - cell oldKey = *key; - cell oldKeysrc = *keysrc; - key->f = f_key_file; - keysrc->fp = TOP().fp; - DROP(1); - f_interpreter(); - if (key->fp != NULL) { - fclose(key->fp); + if (TOP().fp) { + fclose(TOP().fp); } - *key = oldKey; - *keysrc = oldKeysrc; + DROP(1); } -void f_loadstring() { +void f_swapinput() { cell *key = RUNNING + TASK_USER_KEY; cell *keysrc = RUNNING + TASK_USER_KEYSRC; cell oldKey = *key; cell oldKeysrc = *keysrc; - key->f = f_key_string; - keysrc->s = TOP().s; - DROP(1); - f_interpreter(); - *key = oldKey; - *keysrc = oldKeysrc; + *key = TOP(); + *keysrc = ST1(); + TOP() = oldKey; + ST1() = oldKeysrc; } void f_taskemit() { @@ -650,12 +667,18 @@ void f_quote() { void f_loadfile(char *filename) { PUSHS(filename); f_open(); - f__loadfile(); + PUSHS("loadfile"); + f_lookup(); + DROP(1); + f_cexecute(); } void f_runstring(char *s) { PUSHS(s); - f_loadstring(); + PUSHS("loadstring"); + f_lookup(); + DROP(1); + f_cexecute(); } void f_quiet() { @@ -716,11 +739,13 @@ void f_rstacksize() { void f_taskusersize() { PUSHU(TASK_USER_SIZE); } -#define CDEF(name, def) PUSHP(def); PUSHS(name); f_cdef() + void f_init() { CDEF("[", f_compileoff); f_immediate(); CDEF("]", f_compileon); CDEF("key", f_key); + CDEF("key-string", f_key_string); + CDEF("key-file", f_key_file); CDEF("emit", f_emit); CDEF("word", f_word); CDEF("immediate", f_immediate); @@ -753,6 +778,11 @@ void f_init() { CDEF("u>", f_ugt); CDEF("u<", f_ult); CDEF("u<=", f_ule); + CDEF("and", f_and); + CDEF("or", f_or); + CDEF("&", f_bitand); + CDEF("|", f_bitor); + CDEF("^", f_bitxor); CDEF("@", f_get); CDEF("!", f_set); CDEF("b@", f_bget); @@ -762,9 +792,12 @@ void f_init() { CDEF("drop", f_drop); CDEF("swap", f_swap); CDEF("rot", f_rot); + CDEF("r>", f_rput); + CDEF("r<", f_rtake); CDEF("emit", f_emit); CDEF("task-emit", f_taskemit); CDEF("task-echo", f_taskecho); + CDEF("swap-input", f_swapinput); CDEF("putc", f_putc); CDEF("fputc", f_fputc); CDEF("number", f_number); @@ -784,8 +817,6 @@ void f_init() { CDEF("noop", f_noop); CDEF("open", f_open); CDEF("close", f_close); - CDEF("loadfile", f__loadfile); - CDEF("loadstring", f_loadstring); CDEF("quiet", f_quiet); CDEF("loud", f_loud); CDEF("task", f_task); @@ -796,6 +827,16 @@ void f_init() { CDEF("rstacksize", f_rstacksize); CDEF("task-user-size", f_taskusersize); + PUSHS("boot.jor"); + f_open(); + PUSHS("key-file"); + f_lookup(); + DROP(1); + f_swapinput(); + f_interpreter(); + f_swapinput(); + DROP(2); + f_loadfile("defs.jor"); } @@ -805,17 +846,11 @@ void f_quit() { } void f_repl() { - char inputbuf[256]; - CDEF("quit", f_quit); + char input[256]; + CDEF("quit", f_quit); + f_runstring("stdout"); while (!DIE) { - int len; - gets(inputbuf); - len = strlen(inputbuf); - inputbuf[len] = '\n'; - inputbuf[len + 1] = 0; - PUSHS(inputbuf); - f_runstring("REPL send"); - f_taskloop(); + f_runstring(gets(input)); } -} \ No newline at end of file +} diff --git a/jorth.h b/jorth.h index 256231b..348b18d 100755 --- a/jorth.h +++ b/jorth.h @@ -6,6 +6,7 @@ void f_init(); +void f_cdef(); #define CDEF(name, def) PUSHP(def); PUSHS(name); f_cdef() void f_immediate(); diff --git a/temp.jor b/temp.jor new file mode 100755 index 0000000..35ca569 --- /dev/null +++ b/temp.jor @@ -0,0 +1,13 @@ +: interpretword F_IMMEDIATE & state not or if execute else , then ; +: compileword lookup dup + if interpretword + else drop dup number + if swap drop interpretnumber + else drop interpretunknown + then + then ; +: interpreter + begin word dup b@ while compileword repeat + s" ok\n" type drop ; +: loadstring +: loadfile