READ

Started by plugge, June 23, 2005, 12:39:52 PM

Previous topic - Next topic

plugge

#15
Maybe this makes it more clear.  Think of a file that I want to read in with the following:



[bof]

some-atom (and then a list with information) (and another list (with yet another list running into a newline) and some more) (this maybe formatted in 80-column text) some-other atom (and again a list with a number 1.85 and a "string") 2.50 "another string"

[eof]



How would you read this file, controlled, without evaluating, one experession after the other? Note: the contents does not have to be Lisp, it could be anything.



READ does this. How is this done in newLisp?



TIA

-Leo-

Sammo

#16
You might want to investigate newLisp's parse function which, if you don't specify the str-break parameter, uses newLisp's internal tokenizer. parse without str-break automatically discards comments and line breaks.



For example:(parse "atom (list (sublist magoo))")
--> ("atom" "(" "list" "(" "sublist" "magoo" ")" ")")

The trick is in putting the tokens together. Here is a simple-minded and not exhaustively tested solution based on parse.
;; example
;; (set 'hanoi (sexpr-file "hanoi.lsp"))
;; now hanoi is a list of the sexprs found in "hanoi.lsp"

(define (sexpr-file filename)
  (if (file? filename)
    (sexpr-ize (parse (read-file filename))) ))

(define (sexpr-ize token-list)
  (let
    ( sexpr-list nil )
  ;body of let
    (while (not (empty? token-list))
      (let
        ( token (pop token-list) )
      ;body of let
        (case token
          ("'"  (push (make-quote (pop token-list)) sexpr-list -1))
          ("("  (push (make-list) sexpr-list -1))
          (true (push token sexpr-list -1)) )))
    sexpr-list ))
 
(define (make-quote token)
  (string "'" (if (= token "(") (make-list) token)) )

(define (make-list)
  (let
    ( the-list (list "(")
      looking-for-right-paren true
    )
  ;body of let
    (while (and looking-for-right-paren (not (empty? token-list)))
      (let
        ( token (pop token-list) )
      ;body of let
        (case token
          ("'"  (push (make-quote (pop token-list)) the-list -1))
          ("("  (push (make-list) the-list -1))
          (")"  (push token the-list -1)
                (setq looking-for-right-paren nil))
          (true (push token the-list -1)) )))
    (replace " )" (replace "( " (join the-list " ") "(") ")") ))

For example:
(sexpr-ize (parse "atom (list (sublist magoo))"))
--> ("atom" "(list (sublist magoo))")

With the above in place, the READ function can be defined as:
(define-macro (READ stack) (pop (eval stack)))
and the whole thing used like this:
(set 'hanoi (sexpr-file "hanoi.lsp"))
(READ hanoi) ; returns first sexpr
(READ hanoi) ; returns second sexpr
(READ hanoi) ; etc.
(READ hanoi) ; eventually returns nil

plugge

#17
Looks good. Thanx!

-Leo-

eddier

#18
Maybe I still don't get it, but what about.



(eval-string (append "(define data '" (read-file "fname") ")"))


Afterwards, data will have the unevaluated S-expression from the file.



Eddie

plugge

#19
I give up.



Why do thousands (maybe less?) of programmers use READ in Lisp?



Why did they come up with READ in the first place?



I dunno... I just use it now and then, and it's handy.



Let's close this thread. At least from my side, I don't have that much time to spend on this.



Have fun.

-Leo-

eddier

#20
I'm sorry I couldn't help.



Eddie