Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Ongoing Development: Logo in Common Lisp

19 views
Skip to first unread message

Karl Winterling

unread,
Jan 14, 2009, 1:31:59 AM1/14/09
to

If this is difficult to read, there is an HTML 1.0 Strict version at
my Web site: http://www.ocf.berkeley.edu/~kwinterl/logocl.html


Author: Karl Winterling <kwin...@ocf.berkeley.edu>
Date: 2009-01-13 22:11:51 PST


Table of Contents
=================
1 Introduction
2 Issues Surrounding Implementing Logo in Common Lisp
3 Implementation
4 License


1 Introduction
~~~~~~~~~~~~~~

After looking at several options, it seems like a good idea to
implement Logo in Common Lisp. I've hacked together a reader that
transforms a subset of Logo expressions into Common Lisp data
structures that may be fed to an evaluator function. I haven't
consulted any references except Berkeley dialect expressions and the
Common Lisp HyperSpec (i.e. the ANSI standard). There are probably
easier and more elegant ways to do this, but this is only
experimental. As an example, consider the Logo procedure for mapping
onto an arbitrarily deep list:

to dmap :fn :list
if emptyp :list [op []]
if listp (first :list) [op fput (dmap :fn (first :list)) (dmap :fn
(bf :list))]
op fput (invoke :fn (first :list)) (dmap :fn (bf :list))
end

The reader, as it works now, outputs the following:

((TO DMAP *THING* FN *THING* LIST)
(IF EMPTYP *THING* LIST *BEGIN-LIST* OP *BEGIN-LIST* *END-LIST*
*END-LIST*)
(IF LISTP *BEGIN-PAREN* FIRST *THING* LIST *END-PAREN* *BEGIN-LIST*
OP FPUT
*BEGIN-PAREN* DMAP *THING* FN *BEGIN-PAREN* FIRST *THING* LIST
*END-PAREN*
*END-PAREN* *BEGIN-PAREN* DMAP *THING* FN *BEGIN-PAREN* BF
*THING* LIST
*END-PAREN* *END-PAREN* *END-LIST*)
(OP FPUT *BEGIN-PAREN* INVOKE *THING* FN *BEGIN-PAREN* FIRST
*THING* LIST
*END-PAREN* *END-PAREN* *BEGIN-PAREN* DMAP *THING* FN *BEGIN-
PAREN* BF
*THING* LIST *END-PAREN* *END-PAREN*)
(END))

I haven't found a way to translate numeral characters into number
objects yet (more HyperSpec browsing, I suppose).


2 Issues Surrounding Implementing Logo in Common Lisp
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Implementing Logo in Common Lisp has several advantages. Perhaps most
significantly, Logo and Common Lisp are relatively similar
languages. Therefore, it should be possible to write a relatively
elegant implementation. The evaluator could even mechanically
translate Logo into a subset of Common Lisp and incrementally load it
into the Lisp image. Additionally, advanced Logo users should be able
to learn Common Lisp and hack the interpreter to suit their
needs. This opens up possibilities like embedding Logo into Common
Lisp applications and writing Logo bindings to CL libraries (like if
SWIG supported UCBLogo).

Speed probably won't be a huge issue since many Common Lisps are about
as fast as (or faster than), say, Java for most purposes. Logo users
probably won't focus too much on solving the traveling salesman
problem (though one always gets the sinister urge to evaluate
`ackermann tree 3' for example).

Another benefit would be portability if as much of the interpreter as
possible is written in pure ANSI Common Lisp. The major problem with
this is that Logo needs turtle graphics features, a friendly GUI
interface, and an easy-to-use installer for Windows and Mac OS X. The
latter may be solved by making an image dump of the Lisp system,
writing an appropriate initialization file, and creating a `.msi' or
`.dmg' installer. The GUI and graphics raise bigger issues since it
may take some time to decide on graphics and GUI bindings for Common
Lisp (and find graphics and UI design people who are also Lisp
programmers). The main bindings I'm interested in are gtk2 and cairo,
which are cross-platform. It may prove difficult to get everything to
work without modification on each platform, though (without having to
``cheat'' and use XQuartz or Cygwin).

There are several good Common Lisp implementations for Windows and Mac
OSX. Among them are [GNU Clisp] and [Clozure CL] (an evolution of
OpenMCL
and Macintosh Common Lisp).

The main disadvantage is that it's hard to find volunteers to develop
software written in Lisp. However, I'm under the (possibly false)
impression that most Logo people like Lisp. Anyway, the most pressing
issues seem to be graphics and UI.

3 Implementation
~~~~~~~~~~~~~~~~

(defun read-list ()
"Read standard input to a list of characters"
(let ((next-char (read-char *standard-input* t nil)))
(if (equalp next-char #\Newline)
nil
(cons next-char
(read-list)))))

(defun read-file-list (port)
"Read in port and return a character list"
(let ((next-char (read-char port nil nil)))
(if (not next-char)
nil
(cons next-char
(read-file-list port)))))

;; (defun driver-loop ()
;; (print "? ")
;; (print (logo-eval (logo-read)))
;; (driver-loop))

;;;

(defun chars->symbol (char-list)
(intern (string-upcase (coerce char-list 'string))))

(defun parse-word (list)
"Parse for the first word and return it as a token"
(defun helper (list)
(if (or (null list)
(special-char-p (car list)))
'()
(cons (car list)
(helper (cdr list)))))
(chars->symbol (helper list)))

(defvar *special-char-list* (list #\: #\; #\space #\[ #\] #\{ #\} #\
( #\)
#\Newline #\+ #\- #\* #\/ #\"))

(defvar *special-token-table* (make-hash-table))

(defmacro puthash (key value ht)
`(setf (gethash ,key ,ht) ,value))

(defun get-special-token (char)
(gethash char *special-token-table*))

(puthash #\: '*thing* *special-token-table*)
(puthash #\; '*comment* *special-token-table*)
(puthash #\space '*space* *special-token-table*)
(puthash #\Newline '*newline* *special-token-table*)
(puthash #\[ '*begin-list* *special-token-table*)
(puthash #\] '*end-list* *special-token-table*)
(puthash #\{ '*begin-array* *special-token-table*)
(puthash #\} '*end-array* *special-token-table*)
(puthash #\( '*begin-paren* *special-token-table*)
(puthash #\) '*end-paren* *special-token-table*)
(puthash #\+ '*math-plus* *special-token-table*)
(puthash #\- '*math-minus* *special-token-table*)
(puthash #\* '*math-times* *special-token-table*)
(puthash #\/ '*math-divide* *special-token-table*)
(puthash #\" '*quote* *special-token-table*)

(defun special-char-p (char)
"Tests whether char is special."
(member char *special-char-list*))

(defun cchar (char)
"Test function"
(if (equalp char #\")
'*quote*
char))


(defun strip-word (list)
"Cdr up to the next special character"
(cond ((null list) '())
((special-char-p (car list)) list)
(t (strip-word (cdr list)))))

(defun tokenize-words (char-list)
(cond ((null char-list) '())
((equalp (car char-list) #\Newline)
(cons '*newline*
(tokenize-words (cdr char-list))))
((special-char-p (car char-list))
(cons (get-special-token (car char-list))
(tokenize-words (cdr char-list))))
(t (cons (parse-word char-list)
(tokenize-words (strip-word char-list))))))

(defun line-tokenize (token-list)
(cond ((null token-list) '())
((equalp (car token-list) '*newline*)
(line-tokenize (cdr token-list)))
(t (cons (read-logo-line token-list)
(line-tokenize (skip-line token-list))))))

(defun read-logo-line (logo-line)
"Return the line as a list terminating at newline or eof (i.e.
nil)"
(if (or (null logo-line)
(equalp (car logo-line) '*newline*))
'()
(cons (car logo-line)
(read-logo-line (cdr logo-line)))))

(defun skip-line (token-list)
(if (or (null token-list)
(equalp (car token-list) '*newline*))
token-list
(skip-line (cdr token-list))))

(defun deep-filter (pred list)
"Takes a list of arbitrary depth and a predicate and returns
another
list of the same depth containing only the atoms satisfying pred
on
each level of depth. Consp is used for efficiency."
(cond ((null list) '())
((consp (car list))
(cons (deep-filter pred (car list))
(deep-filter pred (cdr list))))
((funcall pred (car list))
(cons (car list)
(deep-filter pred (cdr list))))
(t (deep-filter pred (cdr list)))))

(defun tokenize (char-list)
(deep-filter #'(lambda (token) (not (equalp token '*space*)))
(line-tokenize (tokenize-words char-list))))

4 License
~~~~~~~~~

Copyright (c) 2009 Karl Winterling

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.


Brad

unread,
Jan 16, 2009, 1:20:27 PM1/16/09
to
On Jan 13, 11:31 pm, Karl Winterling <kwinterl...@gmail.com> wrote:

> After looking at several options, it seems like a good idea to
> implement Logo in Common Lisp.

Yes, I'd like to do a similar project using scheme just for fun and
learning. I wouldn't worry about GUI and graphics to start with. First
I'd build a simple interpreter that handles words, sentences and
simple arithmetic. From there, I'd experiment with my language--play
with dynamic vs lexical scoping, alternate syntax, or maybe some kind
of OO. When I like the way it works, I'd try to make my interpreter
more efficient. After I have a good core interpreter I'd add more
built-in functions (trig, advanced string manipulation, etc). Then I'd
start looking for libraries to start implementing turtle graphics.
After I've got a single turtle version working, maybe I'd try working
with more than one. Finally, I'd think about GUI and building an IDE.
By then I might have something that someone else might want to use and
I could package for whatever platform it would run on. On the other
hand it might end up as just an interesting program that I had a lot
of fun working on and learning from.

I believe Brian Harvey's SICP lectures cover implementation of a small
logo interpreter. I haven't looked at them, but I've read most of the
book and I think its an excellent place to start with this kind of
thing. I imagine it would be possible to work through the exercises
using Common Lisp. Mr Harvey's lectures are available on Itunes.

Good luck with your project!

Brad

Karl Winterling

unread,
Jan 17, 2009, 1:24:30 AM1/17/09
to
Adding primitive procedures shouldn't be a big deal since you can
inherit most of them from Scheme or CL. You just use a hash with the
Logo primitive procedure names as keys that map to Lisp procedures.

John St. Clair

unread,
Jan 19, 2009, 12:36:14 AM1/19/09
to
The message below is being cross-posted from the LogoForum. Please
reply here at comp.lang.logo and it will be crossposted back to the
LogoForum. The original author of this message is
pave...@elica.nospam.net.


> to dmap :fn :list


>
> The reader, as it works now, outputs the following:
>
> ((TO DMAP *THING* FN *THING* LIST)

Karl, just be careful, that :A translates into:

:A when it is in list-constant
A when it is in header (like the example above)
THING "A when it is to be evaluated.

So, IMO, in your case :FN should not be thing-ized. Also, are you sure
that using these *BEGIN-PAREN* *END-PAREN* makes things easier? I mean
would it be simpler to make a more straightforward compiler from Logo
source to Lisp source, and then let the Lisp interpreter/compiler do the
execution?

Pavel

In article
<378e46af-6d46-4aa1...@t26g2000prh.googlegroups.com>,

Karl Winterling

unread,
Jan 19, 2009, 8:23:43 AM1/19/09
to
On Jan 18, 9:36 pm, "John St. Clair" <john.stcl...@verizon.net> wrote

> Karl, just be careful, that :A translates into:
>
> :A when it is in list-constant
> A when it is in header (like the example above)
> THING "A when it is to be evaluated.
>
> So, IMO, in your case :FN should not be thing-ized. Also, are you sure
> that using these *BEGIN-PAREN* *END-PAREN* makes things easier? I mean
> would it be simpler to make a more straightforward compiler from Logo
> source to Lisp source, and then let the Lisp interpreter/compiler do the
> execution?

Yeah, my ``lexer,'' strictly speaking, doesn't properly handle : but
I'll have a parsing
procedure infer the context. The lexer is kind of lazy (pun intended).
I probably should
brainstorm about good code generation strategies that'll preserve tail
recursion with dynamic scope.

Karl

Brian Harvey

unread,
Jan 19, 2009, 1:33:24 PM1/19/09
to
>pave...@elica.nospam.net says:
>Karl, just be careful, that :A translates into:
>
>:A when it is in list-constant
>A when it is in header (like the example above)
>THING "A when it is to be evaluated.

UCBLogo's parser translates :A to a string block containing A, with a special
type-tag of COLON type. Then the three different contexts you describe
recognize this node type and do the appropriate thing -- including putting
the colon back when the node is to be used as text, e.g., taking its FIRST
or printing it. This is because the parser doesn't really know how that
text will be used; if it's inside a list, the list might later be RUN, for
example. The word after the colon is interned by the parser, so later
stages don't have to do string processing on it.

Brad

unread,
Jan 24, 2009, 5:16:39 PM1/24/09
to
On Jan 19, 11:33 am, b...@cs.berkeley.edu (Brian Harvey) wrote:

I've started on my attempt at "logo in scheme". I have a similar but
related question.

Typically the first step in a compiler or interpreter is to tokenize
the input before parsing. I can't figure out how to do this for logo.
Should the lexer tokenize the string "a+b" as one word or three? From
the example below it seems as though this depends on context. It also
implies that "dots" isn't an abbreviation "thing quote" all of the
time.

Welcome to Berkeley Logo version 5.5
? make "a+b 42
? print :a+b
a has no value
? print thing "a+b
42


Brian Harvey

unread,
Jan 24, 2009, 8:20:35 PM1/24/09
to
Brad <bowes...@gmail.com> writes:
>? make "a+b 42
>? print :a+b
>a has no value
>? print thing "a+b
>42

Indeed, UCBLogo tokenization is complicated. It tries to "do the right thing"
for most common cases, and that entails slightly different rules for, I think,
five cases:
1. in square brackets or braces
2. after quote
3. after colon
4. none of the above, starts with digit
5. none of the above

Of course, using backslash or vertical bars overrides the rules.

Numbers are the most complicated case, because 3+2 is two numbers added,
but 3e+2 is one number.

LCSI versions of Logo have very simple tokenization rules. Old ones (before
LogoWriter) always treat operator characters as separate tokens; new ones
never do (so you have to say 2 + 3 rather than 2+3). Terrapin has "do the
right thing" tokenization but I think the rules aren't quite the same as in
UCBLogo. Most of the free Logos follow UCBLogo more or less.

Karl Winterling

unread,
Jan 25, 2009, 4:10:32 AM1/25/09
to
On Jan 24, 2:16 pm, Brad <bowes.b...@gmail.com> wrote:
> Typically the first step in a compiler or interpreter is to tokenize
> the input before parsing. I can't figure out how to do this for logo.
> Should the lexer tokenize the string "a+b" as one word or three? From
> the example below it seems as though this depends on context. It also
> implies that "dots" isn't an abbreviation "thing quote" all of the
> time.
>
> Welcome to Berkeley Logo version 5.5
> ? make "a+b 42
> ? print :a+b
> a has no value
> ? print thing "a+b
> 42

You could try tokenizing into a DYADIC-FIELD-OP box and having the
parser take care of it
after it infers the context (I'm biased, I never really liked infix
operations with, assuming (Q, +, *), a totally ordered precedence
relation, (< + *) :-) ). Good luck. Unfortunately, I need to suspend
my concentration until I teach Logo to
do.karls.algebra.homework :problem.set, which I don't expect happening
any time soon :P. You may, by the way, enjoy reading
http://www.eecs.berkeley.edu/~bh/v3ch6/ai.html

Brad

unread,
Jan 25, 2009, 12:56:59 PM1/25/09
to
On Jan 24, 6:20 pm, b...@cs.berkeley.edu (Brian Harvey) wrote:
> Indeed, UCBLogo tokenization is complicated.  It tries to "do the right thing"
> for most common cases, and that entails slightly different rules for, I think,
> five cases:
>         1. in square brackets or braces
>         2. after quote
>         3. after colon
>         4. none of the above, starts with digit
>         5. none of the above

Thanks Brian,

Would this pseudocode be approximately correct?

cond
whitespace?
if newline?
return token: eol
else
skip
char = [
scan to closing ] keeping internal [] pairs balanced
(may need to parse again if used as a list or invoked
as code block)
return token: list value: string
char one of {}()]
return token: special token for each char
char = "
scan until whitespace or one of ()[]{}:"
return token: quote value: string
char = :
scan until whitespace or one of ()[]{}:"+-*/<>=
return token: colon value: string
digit?
do procedure for numbers.
return token: number value: number
else
scan until whitespace or one of ()[]{}:"
return token: invocation value: string

I'm not sure how to do unary minus, but can probably figure it out.

For my first version, I'd like to stick with simple rules and modify
it to "do the right thing" later. How did you have your students
handle this for the SICP assignment? (So far I've only seen the logo 1
and logo 2 videos). Is the assignment online anywhere? Thanks

Brad

Brian Harvey

unread,
Jan 25, 2009, 2:47:28 PM1/25/09
to
Brad <bowes...@gmail.com> writes:
>cond
> whitespace?
> if newline?
> return token: eol
> else
> skip
> char = [
> scan to closing ] keeping internal [] pairs balanced
> (may need to parse again if used as a list or invoked
> as code block)
> return token: list value: string

This doesn't say how to parse within the list. It's not right that the
list is tokenized as one long string; the tokenizer turns it into linked
list form, and within the list, whitespace separates tokens. Only
whitespace, brackets, and braces are special. Yes, I confess that this
much processing is more than what people usually mean by "tokenization."
If you want to separate this into a tokenization phase and a grouping phase,
then [ and ] should just be tokens by themselves

> char one of {}()]
> return token: special token for each char

Parentheses are tokens, but braces are like brackets; arrays are parsed
as lists and then turned into arrays at the last moment (because we can't
allocate the array until we know how many elements it should have).

> char = "
> scan until whitespace or one of ()[]{}:"
> return token: quote value: string

Quotes and colons don't end a quoted word, just ()[]{} do.

> char = :
> scan until whitespace or one of ()[]{}:"+-*/<>=
> return token: colon value: string
> digit?
> do procedure for numbers.
> return token: number value: number
> else
> scan until whitespace or one of ()[]{}:"
> return token: invocation value: string

Unpunctuated words are ended by infix operators, too, like colon ones.

Not included in the above: line continuation, comments, backslash,
vertical bar.

>I'm not sure how to do unary minus, but can probably figure it out.

For the most part, monadic minus isn't a tokenization issue; it's handled
later in the evaluation process. The only exception is that a minus sign
that has a space before it but no space after it gets turned into the two
tokens 0 and -- (that's not an ascii dash, it's the token minus minus);
the latter is a dyadic minus that binds tighter than all other dyadic
operators.

The reason for this roundabout approach is that the monadic/dyadic
decision is made at a point where the whitespace has been stripped away,
so it can't distinguish this special case. Apart from this, the rule is
simple: If an operator is expected, it's dyadic; if an operand is
expected, it's monadic.

>For my first version, I'd like to stick with simple rules and modify
>it to "do the right thing" later. How did you have your students
>handle this for the SICP assignment? (So far I've only seen the logo 1
>and logo 2 videos). Is the assignment online anywhere? Thanks

Yes, I have recently bowed to repeated requests from the internet
audience for the class and have put the reader online. Look in
http://inst.eecs.berkeley.edu/~cs61a/reader/vol1.html
In the Logo interpreter assignment, they are given the tokenization code
(which is indeed simpler than the UCBLogo version) and they don't implement
multiplication-before-addition ordering of infix operators; they just do
them left to right.

But in
http://www.cs.berkeley.edu/~bh/v3ch5/langi.html
you'll find an algorithm for handling infix precedence correctly.

John St. Clair

unread,
Jan 25, 2009, 3:43:43 PM1/25/09
to
The message below is being cross-posted from the LogoForum. Please
reply here at comp.lang.logo and it will be crossposted back to the
LogoForum. The original author of this message is
pave...@elica.nospam.net.

In article
<d1f48bcc-b6f7-4faa...@t39g2000prh.googlegroups.com>,
Brad <bowes...@gmail.com> wrote:

In Lhogho there are two parsing modes - parsing data and parsing
commands. When a+b is parsed as data it is a single word. If it is
parsed as commands it is 3 words. Initially all the program is parsed as
data and only when a specific list is executed, then it is parsed as
commands.

This solves the problem when the same list is used both as data and as
commands.

-Pavel

Brad

unread,
Jan 25, 2009, 4:39:36 PM1/25/09
to
On Jan 25, 12:47 pm, b...@cs.berkeley.edu (Brian Harvey) wrote:

Thanks again, your reply is very illuminating.

> Brad <bowes.b...@gmail.com> writes:
...


> >  char = [
> >    scan to closing ] keeping internal [] pairs balanced
> >    (may need to parse again if used as a list or invoked
> >    as code block)
> >    return token: list value: string
>
> This doesn't say how to parse within the list.  It's not right that the
> list is tokenized as one long string;

...

I mistakenly thought that

print [This is a list]

would print the string verbatim with whitespace intact. If it was used
any way other than as a string, it would be parsed again at "runtime".
I see that's not necessary now.

> Yes, I have recently bowed to repeated requests from the internet
> audience for the class and have put the reader online.  Look in
>        http://inst.eecs.berkeley.edu/~cs61a/reader/vol1.html

I don't mean to plagiarize anyone's code, just wondering if there was
a requirements spec for the assignment. I'll take a look at the reader
after I've written my own.

>
> But in
>        http://www.cs.berkeley.edu/~bh/v3ch5/langi.html
> you'll find an algorithm for handling infix precedence correctly.

This is covered in most compiler textbooks and I've implemented
recursive descent precedence for a toy language before, so I don't
think I'll have any problem there. I'll look at the link anyway
though, it's always interesting to see how other people do things and
get new ideas.

Brad

Brad

unread,
Jan 25, 2009, 4:54:42 PM1/25/09
to
> In Lhogho there are two parsing modes - parsing data and parsing
> commands. When a+b is parsed as data it is a single word. If it is
> parsed as commands it is 3 words. Initially all the program is parsed as
> data and only when a specific list is executed, then it is parsed as
> commands.
>
> This solves the problem when the same list is used both as data and as
> commands.
>
> -Pavel

OK, would the distinction be that data is a list or an argument to
"quote" and commands are either toplevel or lists evaluated by "run",
"ifelse" etc? How does the colon interpret its argument? Thanks

BTW, does lhogho compile and run on OSX?

Brad

Brian Harvey

unread,
Jan 25, 2009, 5:12:26 PM1/25/09
to
Brad <bowes...@gmail.com> writes:
>I mistakenly thought that
>
>print [This is a list]
>
>would print the string verbatim with whitespace intact. If it was used
>any way other than as a string, it would be parsed again at "runtime".
>I see that's not necessary now.

A list /is/ parsed again, but only if used as an instruction list,
e.g., RUN [...] or IF ... [...].

>I don't mean to plagiarize anyone's code, just wondering if there was
>a requirements spec for the assignment. I'll take a look at the reader
>after I've written my own.

The reader /does/ have the spec. But the assignment involves modifying
existing code, which is in turn a modified version of the SICP metacircular
evaluator (making the point that every language is really Lisp once you get
rid of the syntax :-).


Brad

unread,
Jan 25, 2009, 6:50:43 PM1/25/09
to
On Jan 25, 3:12 pm, b...@cs.berkeley.edu (Brian Harvey) wrote:

> Brad <bowes.b...@gmail.com> writes:
> >I mistakenly thought that
>
> >print [This            is a list]
>
> >would print the string verbatim with whitespace intact. If it was used
> >any way other than as a string, it would be parsed again at "runtime".
> >I see that's not necessary now.
>
> A list /is/ parsed again, but only if used as an instruction list,
> e.g., RUN [...] or IF ... [...].

That seems to fit with what Pavel says about data vs commands. It's
starting to make sense to me now.

> >I don't mean to plagiarize anyone's code, just wondering if there was
> >a requirements spec for the assignment. I'll take a look at the reader
> >after I've written my own.
>
> The reader /does/ have the spec.  But the assignment involves modifying
> existing code, which is in turn a modified version of the SICP metacircular
> evaluator (making the point that every language is really Lisp once you get
> rid of the syntax :-).

Another way to say that is Lisp is every language's AST.

Brad

John St. Clair

unread,
Jan 27, 2009, 8:09:10 AM1/27/09
to
The message below is being cross-posted from the LogoForum. Please
reply here at comp.lang.logo and it will be crossposted back to the
LogoForum. The original author of this message is
pave...@elica.nospam.net.


Brad wrote:
> OK, would the distinction be that data is a list or an argument to
> "quote" and commands are either toplevel or lists evaluated by "run",
> "ifelse" etc?

Brad, I'm not sure I understand your question, but everything in a Logo
program is data (including the program itself). It just happens that
some parts of it are also commands.

> How does the colon interpret its argument? Thanks

In Lhogho the colon is a part of the syntax, so it is not a function
with arguments. In Elica, the colon is both syntax and functions and you
can say :(:a) instead of thing thing "a.

> BTW, does lhogho compile and run on OSX?

I have no idea. I don't have OSX here. My last attempt was to try to run
a x86-based version under virtual machine, but there were serious
problems and I gave up.

Have you consulted the Great Logo Atlas (the PDF, not the site) - there
are some syntax descriptions with test cases for few Logo dialects
(uncluding UCBLogo). Parsing of Logo is also covered.

Pavel

Brian Harvey

unread,
Jan 27, 2009, 10:33:10 AM1/27/09
to
pave...@elica.nospam.net says:
>Brad wrote:
>> OK, would the distinction be that data is a list or an argument to
>> "quote" and commands are either toplevel or lists evaluated by "run",
>> "ifelse" etc?
>
>Brad, I'm not sure I understand your question, but everything in a Logo
>program is data (including the program itself). It just happens that
>some parts of it are also commands.

Reinforcing that point, the very same list could be used both ways:

to foo :list
print run :list
print first :list
end

? foo [2+3]
5
2+3

The point is that running the list doesn't change its tokenization for
non-running use. Its FIRST is still 2+3. not 2.

We maintain the list internally in two forms, as originally tokenized
and as parsed (not just tokenized) for running, so the latter form is
actually [+ 2 3] -- basically the Logo is translated into Lisp.

Brad

unread,
Jan 29, 2009, 10:13:03 PM1/29/09
to
On Jan 27, 6:09 am, "John St. Clair" <john.stcl...@verizon.net> wrote:
> Brad, I'm not sure I understand your question, but everything in a Logo
> program is data (including the program itself). It just happens that
> some parts of it are also commands.

After thinking out this a bit it's clear to me now.

> > BTW, does lhogho compile and run on OSX?
>
> I have no idea. I don't have OSX here. My last attempt was to try to run
> a x86-based version under virtual machine, but there were serious
> problems and I gave up.

Fyi, I got it to compile by adding -fnested-functions to the CFLAGS
for OSX,
but "./lhogho primes.lgo" failed with "Bus error".

> Have you consulted the Great Logo Atlas (the PDF, not the site) - there
> are some syntax descriptions with test cases for few Logo dialects
> (uncluding UCBLogo). Parsing of Logo is also covered.

I can't find the PDF with Google, where can I get it?

Thanks,
Brad

John St. Clair

unread,
Feb 1, 2009, 10:16:48 AM2/1/09
to
In article
<7aa8e174-b37c-4581...@z27g2000prd.googlegroups.com>,
Brad <bowes...@gmail.com> wrote:

Brad, the GLA document is not complete and is not available online. I
will send you the latest version.

Pavel
pave...@elica.nospam.net

0 new messages