newLISP Fan Club

Forum => Whither newLISP? => Topic started by: plugge on June 23, 2005, 12:39:52 PM

Title: READ
Post by: plugge on June 23, 2005, 12:39:52 PM
Hi, I'm new to newLisp, but not to lisp.

In the lisp I used most often muLISP (a looong time ago) there was a READ function, to read a normal LISP expression.

Why is that not present in newLISP? Does anyone have ready made READ function?



TIA

-Leo-
Title:
Post by: eddier on June 23, 2005, 01:02:47 PM
If you are reading from a file:

(eval-string (read-file "filename"))

If you just want to evaluate something from the console

(eval-string (read-line))

Hope this helps.



Eddie
Title:
Post by: newdep on June 23, 2005, 01:08:19 PM
Welcome :-) The more Dutch the better ;-)

Enjoy newlisp.. !



Norman.
Title:
Post by: HPW on June 23, 2005, 01:22:22 PM
I used this read-emulation:

(define (read readstr   readret)
(cond
((float readstr)
(if (find "." readstr)
(setq readret (float readstr))
(setq readret (integer readstr))
)
)
((=(slice readstr 0 1)"(") ;)
(setq readret(eval-string(append "'" readstr)))
)
(true
(setq readret (symbol readstr))
)
)
)
Title: READ
Post by: plugge on June 24, 2005, 08:43:18 AM
Quote from: "eddier"If you are reading from a file:

(eval-string (read-file "filename"))

If you just want to evaluate something from the console

(eval-string (read-line))

Hope this helps.



Eddie


No, this is not what READ does. READ reads one atom or a list at a time, but does not evaluate. Quoted text is read in as strings, number as numers etc.

and there is no cr-lf.
Title:
Post by: plugge on June 24, 2005, 08:47:22 AM
Thanx, but this is also not what I'm looking for.

It should not evaluate and read an atom or a list at the time.


Quote from: "HPW"I used this read-emulation:

(define (read readstr   readret)
(cond
((float readstr)
(if (find "." readstr)
(setq readret (float readstr))
(setq readret (integer readstr))
)
)
((=(slice readstr 0 1)"(") ;)
(setq readret(eval-string(append "'" readstr)))
)
(true
(setq readret (symbol readstr))
)
)
)
Title:
Post by: HPW on June 24, 2005, 08:52:54 AM
Maybe it is not like muLISP-read, but I use it in code ported from autolisp.



So it should be possible to code the wanted behaviour.



You can list all test-cases of input and wanted output and then it should be possible.
Title:
Post by: plugge on June 25, 2005, 07:50:46 AM
Quote from: "HPW"Maybe it is not like muLISP-read, but I use it in code ported from autolisp.



So it should be possible to code the wanted behaviour.



You can list all test-cases of input and wanted output and then it should be possible.


Yes, I could. Thanx for helping.

I'm a little suprised that such a basic function is not available. Lisp is a read-eval loop. There's a read-char, read-line,  read-key etc, but not the basic READ.
Title: READ
Post by: plugge on June 25, 2005, 12:34:47 PM
Hi, here's my version of READ:



It is used to read a text file one atom or list at a time.

I'm out of practise since I haven't programmed in Lisp since 1993, and I'm new to newLisp

If someone likes to make an elegant version, be my guest!


(define (read fHandle, i result)
(setq result "")
(do-while (not (= i nil))
 (setq i (read-char fHandle))
 (cond ((= i nil) (setq result "EOF"))
((not (member i '(32 13 10 40))) ;legal character
;; not a list
                     (setq result (append (char i) (read-atom fHandle)))
                     (setq i nil))
                    ((= i 40)
;; opening parethesis - read in the list
                     (setq result (append (char i) (read-list fHandle)))
(setq i nil))
 )
)
   (if (= result "EOF") nil (sym result))
)

(define (read-atom fHandle, x y)
(setq y "")
(do-while (not (= x nil))
 (setq x (read-char fHandle))
     (cond ((not (member x '(32 13 10 40)))
                     (setq y (append y (char x))))
                    ((member x '(32 13 10 40)) (setq x nil))
              )
    )
y)

(define (read-list fHandle, x y flag)
(setq flag 1)
(setq y "")
(do-while (not (= x nil))
 (setq x (read-char fHandle))
 (if (= x 40) (inc 'flag 1))
 (if (= x 41) (dec 'flag 1))
     (cond ((and (= x 41) (= flag 0))
                     (setq y (append y (char x)))
    (setq x nil))
              ((not (member x '(13 10)))
                     (setq y (append y (char x))))
              )
    )
y)
Title:
Post by: HPW on June 25, 2005, 01:32:44 PM
I do not get the point what you want to reach.

Can you give an example file which you want to read

and a explanation what you want to have in memory after read.
Title:
Post by: plugge on June 25, 2005, 01:56:54 PM
Simple:

(from xLisp)

read an expression

(read [<stream> [<eofp> [<eof> [<rflag>]]]])

<stream>   the input stream (default, or NIL, is *standard-input*, T is *terminal-io*)

<eofp>   When T, signal an error on end of file, when NIL return <eof> (default is T)

<eof>   the value to return on end of file (default is NIL)

<rflag>   recursive read flag. The value is ignored

returns   the expression read



Actually the basic READ doesn't need any parameter, it uses the *standard-input*



READ is for getting a syntactically valid S-expresseion. Only that value is returned. The S-expression is not evaluated.



Its practical for reading in S-expression from a file, without evaluation.



HTH

-Leo-
Title:
Post by: newdep on June 25, 2005, 02:01:03 PM
Isnt 'load doing that?
Title:
Post by: plugge on June 25, 2005, 02:01:14 PM
BTW



An S-expression in a file may run over a line

read-line only reads until a cr-lf



Do you guys think READ is obsolete?? How do you then perform this type of READing?



-Leo-
Title:
Post by: plugge on June 25, 2005, 02:03:59 PM
Quote from: "newdep"Isnt 'load doing that?


Nope.



Quote from the newLisp manual:
QuoteLoads and translates newLISP from a source file specified in one or more str-file-name and evaluates the expressions contained in the file(s).


It should not evaluate and READ doesn't



Besides: I want a controlled one by one READ of S-expressions, for example to operate on values sequentially.



-Leo-
Title:
Post by: HPW on June 26, 2005, 12:04:45 AM
I think I get the point now.

Maybe Lutz can tell his point of view or made that function.


Quote
Do you guys think READ is obsolete?? How do you then perform this type of READing?


My S-expressions are bound to symbols.

I store them with:



(save "stuff.lsp" 'aContext 'myFunc 'otherVar 'Acontext)



Then I easily load them with:



(load "stuff.lsp")



Also source and eval-string can be used:

> (set 'a '(+ 1 2 3))
(+ 1 2 3)
> (source 'a)
"(set 'a '(+ 1 2 3))rnrn"
> (eval-string(source 'a))
(+ 1 2 3)
>
Title:
Post by: plugge on June 26, 2005, 05:19:25 AM
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-
Title:
Post by: Sammo on June 26, 2005, 11:18:15 AM
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
Title:
Post by: plugge on June 26, 2005, 11:22:16 AM
Looks good. Thanx!

-Leo-
Title:
Post by: eddier on June 27, 2005, 05:29:55 AM
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
Title: READ ... why is it there?
Post by: plugge on June 27, 2005, 05:57:46 AM
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-
Title:
Post by: eddier on June 27, 2005, 07:26:46 AM
I'm sorry I couldn't help.



Eddie