diff --git a/docs/codox/beowulf.reader.generate.html b/docs/codox/beowulf.reader.generate.html index 3788098..3241c93 100644 --- a/docs/codox/beowulf.reader.generate.html +++ b/docs/codox/beowulf.reader.generate.html @@ -1,3 +1,24 @@ -beowulf.reader.generate documentation

beowulf.reader.generate

TODO: write docs

gen-cond

(gen-cond p)

Generate a cond statement from this simplified parse tree fragment p; returns nil if p does not represent a (MEXPR) cond statement.

gen-cond-clause

(gen-cond-clause p)

Generate a cond clause from this simplified parse tree fragment p; returns nil if p does not represent a cond clause.

gen-dot-terminated-list

(gen-dot-terminated-list p)

Generate a list, which may be dot-terminated, from this partial parse tree ‘p’. Note that the function acts recursively and progressively decapitates its argument, so that the argument will not always be a valid parse tree.

gen-fn-call

(gen-fn-call p)

Generate a function call from this simplified parse tree fragment p; returns nil if p does not represent a (MEXPR) function call.

gen-iexpr

(gen-iexpr tree)

TODO: write docs

generate

(generate p)

Generate lisp structure from this parse tree p. It is assumed that p has been simplified.

generate-assign

(generate-assign tree)

Generate an assignment statement based on this tree. If the thing being assigned to is a function signature, then we have to do something different to if it’s an atom.

generate-defn

(generate-defn tree)

TODO: write docs

generate-set

(generate-set tree)

Actually not sure what the mexpr representation of set looks like

strip-leading-zeros

(strip-leading-zeros s)(strip-leading-zeros s prefix)

read-string interprets strings with leading zeros as octal; strip any from this string s. If what’s left is empty (i.e. there were only zeros, return "0".

\ No newline at end of file +beowulf.reader.generate documentation

beowulf.reader.generate

Generating S-Expressions from parse trees.

+

From Lisp 1.5 Programmers Manual, page 10

+

Note that I’ve retyped much of this, since copy/pasting out of PDF is less than reliable. Any typos are mine.

+

Quote starts:

+

We are now in a position to define the universal LISP function evalquote[fn;args], When evalquote is given a function and a list of arguments for that function, it computes the value of the function applied to the arguments. LISP functions have S-expressions as arguments. In particular, the argument fn of the function evalquote must be an S-expression. Since we have been writing functions as M-expressions, it is necessary to translate them into S-expressions.

+

The following rules define a method of translating functions written in the meta-language into S-expressions. 1. If the function is represented by its name, it is translated by changing all of the letters to upper case, making it an atomic symbol. Thus car is translated to CAR. 2. If the function uses the lambda notation, then the expression λ[[x ..;xn]; ε] is translated into (LAMBDA (X1 ...XN) ε*), where ε* is the translation of ε. 3. If the function begins with label, then the translation of label[α;ε] is (LABEL α* ε*).

+

Forms are translated as follows: 1. A variable, like a function name, is translated by using uppercase letters. Thus the translation of var1 is VAR1. 2. The obvious translation of letting a constant translate into itself will not work. Since the translation of x is X, the translation of X must be something else to avoid ambiguity. The solution is to quote it. Thus X is translated into (QUOTE X). 3. The form fn[argl;. ..;argn] is translated into (fn* argl* ...argn*) 4. The conditional expression [pl-el;...;pn-en] is translated into (COND (p1* e1*)...(pn* en*))

+

Examples

+
  M-expressions                                  S-expressions             
+
+  x                                              X                         
+  car                                            CAR                       
+  car[x]                                         (CAR X)                   
+  T                                              (QUOTE T)                 
+  ff[car [x]]                                    (FF (CAR X))              
+  [atom[x]->x; T->ff[car[x]]]                    (COND ((ATOM X) X) 
+                                                     ((QUOTE T)(FF (CAR X))))
+  label[ff;λ[[x];[atom[x]->x;                    (LABEL FF (LAMBDA (X) 
+       T->ff[car[x]]]]]                              (COND ((ATOM X) X) 
+                                                         ((QUOTE T)(FF (CAR X))))))
+
+

quote ends

gen-cond

(gen-cond p)

Generate a cond statement from this simplified parse tree fragment p; returns nil if p does not represent a (MEXPR) cond statement.

gen-cond-clause

(gen-cond-clause p)

Generate a cond clause from this simplified parse tree fragment p; returns nil if p does not represent a cond clause.

gen-dot-terminated-list

(gen-dot-terminated-list p)

Generate a list, which may be dot-terminated, from this partial parse tree ‘p’. Note that the function acts recursively and progressively decapitates its argument, so that the argument will not always be a valid parse tree.

gen-fn-call

(gen-fn-call p)

Generate a function call from this simplified parse tree fragment p; returns nil if p does not represent a (MEXPR) function call.

gen-iexpr

(gen-iexpr tree)

TODO: write docs

generate

(generate p)

Generate lisp structure from this parse tree p. It is assumed that p has been simplified.

generate-assign

(generate-assign tree)

Generate an assignment statement based on this tree. If the thing being assigned to is a function signature, then we have to do something different to if it’s an atom.

generate-defn

(generate-defn tree)

TODO: write docs

generate-set

(generate-set tree)

Actually not sure what the mexpr representation of set looks like

strip-leading-zeros

(strip-leading-zeros s)(strip-leading-zeros s prefix)

read-string interprets strings with leading zeros as octal; strip any from this string s. If what’s left is empty (i.e. there were only zeros, return "0".

\ No newline at end of file diff --git a/docs/codox/index.html b/docs/codox/index.html index d77bafa..1cfca84 100644 --- a/docs/codox/index.html +++ b/docs/codox/index.html @@ -1,3 +1,3 @@ -Beowulf 0.2.1-SNAPSHOT

Beowulf 0.2.1-SNAPSHOT

Released under the GPL-2.0-or-later

An implementation of LISP 1.5 in Clojure.

Installation

To install, add the following dependency to your project or build file:

[beowulf "0.2.1-SNAPSHOT"]

Topics

Namespaces

beowulf.bootstrap

Lisp as defined in Chapter 1 (pages 1-14) of the Lisp 1.5 Programmer's Manual; that is to say, a very simple Lisp language, which should, I believe, be sufficient in conjunction with the functions provided by beowulf.host, be sufficient to bootstrap the full Lisp 1.5 interpreter..

beowulf.cons-cell

The fundamental cons cell on which all Lisp structures are built. Lisp 1.5 lists do not necessarily have a sequence as their CDR, and must have both CAR and CDR mutable, so cannot be implemented on top of Clojure lists.

beowulf.core

Essentially, the -main function and the bootstrap read-eval-print loop.

Public variables and functions:

beowulf.host

provides Lisp 1.5 functions which can’t be (or can’t efficiently be) implemented in Lisp 1.5, which therefore need to be implemented in the host language, in this case Clojure.

beowulf.read

This provides the reader required for boostrapping. It’s not a bad reader - it provides feedback on errors found in the input - but it isn’t the real Lisp reader.

Public variables and functions:

beowulf.reader.generate

TODO: write docs

beowulf.reader.macros

Can I implement reader macros? let’s see!

Public variables and functions:

beowulf.reader.parser

The actual parser, supporting both S-expression and M-expression syntax.

Public variables and functions:

beowulf.reader.simplify

Simplify parse trees. Be aware that this is very tightly coupled with the parser.

Public variables and functions:

\ No newline at end of file +Beowulf 0.2.1-SNAPSHOT

Beowulf 0.2.1-SNAPSHOT

Released under the GPL-2.0-or-later

An implementation of LISP 1.5 in Clojure.

Installation

To install, add the following dependency to your project or build file:

[beowulf "0.2.1-SNAPSHOT"]

Topics

Namespaces

beowulf.bootstrap

Lisp as defined in Chapter 1 (pages 1-14) of the Lisp 1.5 Programmer's Manual; that is to say, a very simple Lisp language, which should, I believe, be sufficient in conjunction with the functions provided by beowulf.host, be sufficient to bootstrap the full Lisp 1.5 interpreter..

beowulf.cons-cell

The fundamental cons cell on which all Lisp structures are built. Lisp 1.5 lists do not necessarily have a sequence as their CDR, and must have both CAR and CDR mutable, so cannot be implemented on top of Clojure lists.

beowulf.core

Essentially, the -main function and the bootstrap read-eval-print loop.

Public variables and functions:

beowulf.host

provides Lisp 1.5 functions which can’t be (or can’t efficiently be) implemented in Lisp 1.5, which therefore need to be implemented in the host language, in this case Clojure.

beowulf.read

This provides the reader required for boostrapping. It’s not a bad reader - it provides feedback on errors found in the input - but it isn’t the real Lisp reader.

Public variables and functions:

beowulf.reader.generate

Generating S-Expressions from parse trees.

beowulf.reader.macros

Can I implement reader macros? let’s see!

Public variables and functions:

beowulf.reader.parser

The actual parser, supporting both S-expression and M-expression syntax.

Public variables and functions:

beowulf.reader.simplify

Simplify parse trees. Be aware that this is very tightly coupled with the parser.

Public variables and functions:

\ No newline at end of file diff --git a/src/beowulf/reader/generate.clj b/src/beowulf/reader/generate.clj index 81f461e..53f5a56 100644 --- a/src/beowulf/reader/generate.clj +++ b/src/beowulf/reader/generate.clj @@ -1,58 +1,65 @@ (ns beowulf.reader.generate + "Generating S-Expressions from parse trees. + + ## From Lisp 1.5 Programmers Manual, page 10 + *Note that I've retyped much of this, since copy/pasting out of PDF is less + than reliable. Any typos are mine.* + + *Quote starts:* + + We are now in a position to define the universal LISP function + `evalquote[fn;args]`, When evalquote is given a function and a list of arguments + for that function, it computes the value of the function applied to the arguments. + LISP functions have S-expressions as arguments. In particular, the argument `fn` + of the function evalquote must be an S-expression. Since we have been + writing functions as M-expressions, it is necessary to translate them into + S-expressions. + + The following rules define a method of translating functions written in the + meta-language into S-expressions. + 1. If the function is represented by its name, it is translated by changing + all of the letters to upper case, making it an atomic symbol. Thus `car` is + translated to `CAR`. + 2. If the function uses the lambda notation, then the expression + `λ[[x ..;xn]; ε]` is translated into `(LAMBDA (X1 ...XN) ε*)`, where ε* is the translation + of ε. + 3. If the function begins with label, then the translation of + `label[α;ε]` is `(LABEL α* ε*)`. + + Forms are translated as follows: + 1. A variable, like a function name, is translated by using uppercase letters. + Thus the translation of `var1` is `VAR1`. + 2. The obvious translation of letting a constant translate into itself will not + work. Since the translation of `x` is `X`, the translation of `X` must be something + else to avoid ambiguity. The solution is to quote it. Thus `X` is translated + into `(QUOTE X)`. + 3. The form `fn[argl;. ..;argn]` is translated into `(fn* argl* ...argn*)` + 4. The conditional expression `[pl-el;...;pn-en]` is translated into + `(COND (p1* e1*)...(pn* en*))` + + ## Examples + ``` + M-expressions S-expressions + + x X + car CAR + car[x] (CAR X) + T (QUOTE T) + ff[car [x]] (FF (CAR X)) + [atom[x]->x; T->ff[car[x]]] (COND ((ATOM X) X) + ((QUOTE T)(FF (CAR X)))) + label[ff;λ[[x];[atom[x]->x; (LABEL FF (LAMBDA (X) + T->ff[car[x]]]]] (COND ((ATOM X) X) + ((QUOTE T)(FF (CAR X)))))) + ``` + + *quote ends* +" (:require [beowulf.cons-cell :refer [make-beowulf-list make-cons-cell NIL]] [beowulf.reader.macros :refer [expand-macros]] [clojure.math.numeric-tower :refer [expt]] [clojure.string :refer [upper-case]])) -;; # From Lisp 1.5 Programmers Manual, page 10 -;; Note that I've retyped much of this, since copy/pasting out of PDF is less -;; than reliable. Any typos are mine. Quote starts [[ - -;; We are now in a position to define the universal LISP function -;; evalquote[fn;args], When evalquote is given a function and a list of arguments -;; for that function, it computes the value of the function applied to the arguments. -;; LISP functions have S-expressions as arguments. In particular, the argument "fn" -;; of the function evalquote must be an S-expression. Since we have been -;; writing functions as M-expressions, it is necessary to translate them into -;; S-expressions. - -;; The following rules define a method of translating functions written in the -;; meta-language into S-expressions. -;; 1. If the function is represented by its name, it is translated by changing -;; all of the letters to upper case, making it an atomic symbol. Thus is -;; translated to CAR. -;; 2. If the function uses the lambda notation, then the expression -;; λ[[x ..;xn]; ε] is translated into (LAMBDA (X1 ...XN) ε*), where ε* is the translation -;; of ε. -;; 3. If the function begins with label, then the translation of -;; label[α;ε] is (LABEL α* ε*). - -;; Forms are translated as follows: -;; 1. A variable, like a function name, is translated by using uppercase letters. -;; Thus the translation of varl is VAR1. -;; 2. The obvious translation of letting a constant translate into itself will not -;; work. Since the translation of x is X, the translation of X must be something -;; else to avoid ambiguity. The solution is to quote it. Thus X is translated -;; into (QUOTE X). -;; 3. The form fn[argl;. ..;argn] is translated into (fn* argl* ...argn*) -;; 4. The conditional expression [pl-el;...;pn-en] is translated into -;; (COND (p1* e1*)...(pn* en*)) - -;; ## Examples - -;; M-expressions S-expressions -;; x X -;; car CAR -;; car[x] (CAR X) -;; T (QUOTE T) -;; ff[car [x]] (FF (CAR X)) -;; [atom[x]->x; T->ff[car[x]]] (COND ((ATOM X) X) -;; ((QUOTE T)(FF (CAR X)))) -;; label[ff;λ[[x];[atom[x]->x; T->ff[car[x]]]]] (LABEL FF (LAMBDA (X) (COND -;; ((ATOM X) X) -;; ((QUOTE T)(FF (CAR X)))))) - -;; ]] quote ends (declare generate)