READ

Pondering the philosophy behind the language
Locked
plugge
Posts: 11
Joined: Sun May 22, 2005 10:00 pm
Location: Maastricht, The Netherlands

READ

Post by plugge »

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-

eddier
Posts: 289
Joined: Mon Oct 07, 2002 2:48 pm
Location: Blue Mountain College, MS US

Post by eddier »

If you are reading from a file:

Code: Select all

(eval-string (read-file "filename"))
If you just want to evaluate something from the console

Code: Select all

(eval-string (read-line))
Hope this helps.

Eddie

newdep
Posts: 2038
Joined: Mon Feb 23, 2004 7:40 pm
Location: Netherlands

Post by newdep »

Welcome :-) The more Dutch the better ;-)
Enjoy newlisp.. !

Norman.
-- (define? (Cornflakes))

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

I used this read-emulation:

Code: Select all

(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))
		)
	)
	)
Hans-Peter

plugge
Posts: 11
Joined: Sun May 22, 2005 10:00 pm
Location: Maastricht, The Netherlands

READ

Post by plugge »

eddier wrote:If you are reading from a file:

Code: Select all

(eval-string (read-file "filename"))
If you just want to evaluate something from the console

Code: Select all

(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.

plugge
Posts: 11
Joined: Sun May 22, 2005 10:00 pm
Location: Maastricht, The Netherlands

Post by plugge »

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.
HPW wrote:I used this read-emulation:

Code: Select all

(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))
		)
	)
	)

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by 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.
Hans-Peter

plugge
Posts: 11
Joined: Sun May 22, 2005 10:00 pm
Location: Maastricht, The Netherlands

Post by plugge »

HPW wrote: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.

plugge
Posts: 11
Joined: Sun May 22, 2005 10:00 pm
Location: Maastricht, The Netherlands

READ

Post by plugge »

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!

Code: Select all

(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)

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

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.
Hans-Peter

plugge
Posts: 11
Joined: Sun May 22, 2005 10:00 pm
Location: Maastricht, The Netherlands

Post by plugge »

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-

newdep
Posts: 2038
Joined: Mon Feb 23, 2004 7:40 pm
Location: Netherlands

Post by newdep »

Isnt 'load doing that?
-- (define? (Cornflakes))

plugge
Posts: 11
Joined: Sun May 22, 2005 10:00 pm
Location: Maastricht, The Netherlands

Post by plugge »

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-

plugge
Posts: 11
Joined: Sun May 22, 2005 10:00 pm
Location: Maastricht, The Netherlands

Post by plugge »

newdep wrote:Isnt 'load doing that?
Nope.

Quote from the newLisp manual:
Loads 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-

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

I think I get the point now.
Maybe Lutz can tell his point of view or made that function.
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:

Code: Select all

> (set 'a '(+ 1 2 3))
(+ 1 2 3)
> (source 'a)
"(set 'a '(+ 1 2 3))\r\n\r\n"
> (eval-string(source 'a))
(+ 1 2 3)
> 
Hans-Peter

plugge
Posts: 11
Joined: Sun May 22, 2005 10:00 pm
Location: Maastricht, The Netherlands

Post by plugge »

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
Posts: 180
Joined: Sat Dec 06, 2003 6:11 pm
Location: Loveland, Colorado USA

Post by Sammo »

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:

Code: Select all

(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.

Code: Select all

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

Code: Select all

(sexpr-ize (parse "atom (list (sublist magoo))")) 
--> ("atom" "(list (sublist magoo))") 
With the above in place, the READ function can be defined as:

Code: Select all

(define-macro (READ stack) (pop (eval stack)))
and the whole thing used like this:

Code: Select all

(set 'hanoi (sexpr-file "hanoi.lsp"))
(READ hanoi) ; returns first sexpr
(READ hanoi) ; returns second sexpr
(READ hanoi) ; etc.
(READ hanoi) ; eventually returns nil
Last edited by Sammo on Fri Jul 01, 2005 7:40 pm, edited 3 times in total.

plugge
Posts: 11
Joined: Sun May 22, 2005 10:00 pm
Location: Maastricht, The Netherlands

Post by plugge »

Looks good. Thanx!
-Leo-

eddier
Posts: 289
Joined: Mon Oct 07, 2002 2:48 pm
Location: Blue Mountain College, MS US

Post by eddier »

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

Code: Select all

(eval-string (append "(define data '" (read-file "fname") ")"))
Afterwards, data will have the unevaluated S-expression from the file.

Eddie

plugge
Posts: 11
Joined: Sun May 22, 2005 10:00 pm
Location: Maastricht, The Netherlands

READ ... why is it there?

Post by plugge »

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
Posts: 289
Joined: Mon Oct 07, 2002 2:48 pm
Location: Blue Mountain College, MS US

Post by eddier »

I'm sorry I couldn't help.

Eddie

Locked