Ron Aaron wrote: >On Tue, March 22, 2005 7:52, Ton Ât Lam said: > > > >>Hi Ron, >> >> > >Hi, Ton - > > > > >>Next is smaller: >> >> > >Yes, but 'cmovxxx' is PentiumPro and above. So I would need to make min/max a >vectored word and fixup at runtime (Reva requires only Pentium or above). >This would make Reva larger overall, but maybe faster on the faster machines. > > > >>I have a slurp that read in one line at the time. >>slurp ( xt a # -- ) >> >>: loadf ['] eval ; >>" file" loadf >> >>: cat ['] type 10 parse slurp ; >>cat filename >> >> > >Hmmm. This isn't a slurp, but a 'spitout' :-) "slurp" in Reva reads an >entire file into a string. What your word appears to do is take that string >and eval it line-by-line. Sort of a 'foreach'. Am I correct? Is there an >advantage to doing that rather than eval the entire string at one go? > >I am looking for a convenient way to halt an eval. For example, when a file >is "include"d I want to be able to stop the include of *that* file (while >continuing on with ongoing includes. One reason would be to have a >'comment-to-end-of-file' where I could have something like "POD" (Perl Plain >Old Documentaiton) where the end of the file contains docs for the file. > >I suppose that adding 'catch' and 'throw' could work for this. Defining say, >-100 throw to mean "stop this eval" and -101 throw to mean what "abort" does >in ANS .... something like that, anyway. So comment to end of file could be >something like: > >: -eof- -100 throw ; > >Ideas? > > > > Actually it was meant to read in lines from a file, and then I realize I could eval as well. The only advantage is little memory usage. The disadvantage is that one line needs to contain a complete word. (Or use [ and ]) If you want to halt an eval, you need to do a look ahead parse. Rather then the real eval you may want to create a feval (file eval), that does constantly a '-text' (strcmp), on invoke. feval on its turn invokes eval. feval needs to work recursive. And each time you read in the parts in seperate memory. In slurp (spitout ;-) ) I eval the string and then moves the remainder to the beginning of the buffer. Below my words. You can use them at your own insight, or ignore. Cheers, Ton ; -text ; dash-text ; Author: Ton 't Lam ; compare two strings code '-text',_text ; ( a1 # a2 -- ? ) push ecx,edx upop edx ; a2 upop ecx ; # ; eax = a1 mov esi,eax mov edi,edx xor eax,eax ; eax = 0 repe cmpsb ; if strings equal then Z=1 jz .a ; not eax ; eax = -1 .a: pop ecx,edx next ; ---------------------------------------------------------------------- ; slurp ( xt a # -- ) ; Author: Ton 't Lam ; Sat Mar 12 20:03:45 CET 2005 ; slurp reads in lines from a file, line by line. ; if xt = 0 the lines are evaluated, otherwise specify the address of a word ; For 'word' next stack rules applies: ( a # -- ) ; ; in retroforth.rf ; b0 rb 1024 ; Load buffer --- TtL ; ; slurp is completely independent from other words. ; this means it can be used as bootstrap. In retroforth.f have ; forth ; : " '" parse ; ; 0 " filename" slurp ; NOTE: unlike retroforth.f you must have the complete word in one line. code 'slurp',slurp ; ( xt a # -- ) .init: ; local variables push ebp mov ebp,esp sub esp,16 virtual at esp cnt dd ? doer dd ? fd dd ? filled dd ? end virtual mov [filled],0 ; set filled explicitely ; OPEN file .open: upop ecx ; # push esi mov edi,b0 ; d mov esi,eax ; s .a: mov dl, byte [esi] ; mov byte [edi], dl ; inc edi ; inc esi ; loop .a mov byte [edi],0 ; append zero char pop esi mov ebx,b0 ; 'a' points to a zero terminated string mov eax,5 ; open(2) int 80h ; eax contains fd mov [fd],eax cmp eax,0 ; check for open() errors jnle .xt ; OK upsh openerror upsh openerror.size call type call print ; eax upsh 10 ; lf call emit jmp .done .xt: upop eax ; eax = xt mov [doer],eax cmp eax,0 jne .loop mov eax,eval ; eval is default mov [doer],eax .loop: cmp dword [filled],200h jge .flf ; READ 512 bytes .read: mov ebx,[fd] ; fd mov ecx,b0 ; a add ecx,[filled] ; a offset + mov edx,200h ; # = 512 mov eax,3 ; read(2) int 80h ; eax contains n add [filled],eax ; filled n + cmp eax,0 ; check for read() errors jge .flf ; OK upsh readerror upsh readerror.size call type call print ; eax upsh 10 ; lf call emit jmp .close ; FIND lf .flf: mov ebx,b0 ; xor ecx,ecx ; count=0 .b: cmp byte [ebx],10 ; je .c inc ebx ; next char inc ecx ; count++ jmp .b .c: inc ecx mov [cnt],ecx ; mov eax,b0 ; prepare stack upsh ecx .eval: mov edi,[doer] call edi ; execute dup ; DUP .admin: mov eax,[filled] ; filled cnt - sub eax,[cnt] mov [filled],eax cmp eax,0 ; filled 0 =if je .close ; then ; CMOVE .cmove: mov ecx,[filled] ; # push esi mov edi,b0 ; d mov esi,edi add esi,[cnt] ; .d: mov dl, byte [esi] ; mov byte [edi], dl ; inc edi ; inc esi ; loop .d pop esi jmp .loop ; again .close: mov ebx,[fd] ; fd mov eax,6 ; close(2) int 80h drop .done: mov esp,ebp pop ebp next openerror: db "open(2) error: " openerror.size = $ - openerror readerror: db "read(2) error: " readerror.size = $ - readerror ; ----------------------------------------------------------------------