[retroforth] Re: slurp. cmovxxx

  • From: Ton Ât Lam <ton.tlam@xxxxxxxxx>
  • To: retroforth@xxxxxxxxxxxxx
  • Date: Tue, 22 Mar 2005 17:58:06 +0100

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
; ----------------------------------------------------------------------






Other related posts: