Skip to content

Commit 07ee16e

Browse files
author
Jeff Aigner
committed
Adding some documentation in lisp.go, cleaning up some more. version now 1.0.3.0
1 parent 52dfd80 commit 07ee16e

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11

2+
Version 1.0.3.0
3+
===============
4+
* Fixed lambda function environment copying to prevent shared env
5+
* Adding quote built-in. Fixed car/cdr which now function properly. Added tests for car/cdr/quote
6+
* Adding print
7+
* Adding some documentation
8+
29
Version 1.0.2.1
310
===============
411
* Fixing version numbering scheme

lisp.go

+30-5
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ import (
1212
)
1313

1414
const (
15-
VERSION = "golisp v1.0.2.1"
16-
VERBOSE = true
15+
VERSION = "golisp v1.0.3.0"
1716
)
1817

18+
// removeEmpty takes a list of strings
19+
// and removes any elements that are empty strings
20+
// returning a new array of string with no empty elements
1921
func removeEmpty(tokens []string) []string {
2022
var result []string
2123
for _, c := range tokens {
@@ -26,7 +28,10 @@ func removeEmpty(tokens []string) []string {
2628
return result
2729
}
2830

29-
func recover_error() {
31+
// recoverError is used to recover from panics
32+
// that are generated by parse / eval. It will
33+
// print the error and the stack trace
34+
func recoverError() {
3035
if r := recover(); r != nil {
3136
fmt.Println("Parse Error:", r)
3237
buf := make([]byte, 1<<16)
@@ -36,7 +41,7 @@ func recover_error() {
3641
}
3742

3843
func parse(program string) Object {
39-
defer recover_error()
44+
defer recoverError()
4045

4146
tokens := tokenize(program)
4247
return build_ast(&tokens)
@@ -51,13 +56,18 @@ type Object interface{}
5156

5257
type List []Object
5358

59+
// String method for Number types
60+
// tries to print as an int, if not
61+
// then float
5462
func (n Number) String() string {
5563
if float64(n) == float64(int64(n)) {
5664
return fmt.Sprintf("%d", int64(n))
5765
}
5866
return fmt.Sprintf("%f", n)
5967
}
6068

69+
// String method for List type, converts
70+
// into a LISP compatible list format
6171
func (l List) String() string {
6272
var s []string
6373
for _, v := range l {
@@ -76,6 +86,8 @@ type Lambda struct {
7686
body Object
7787
}
7888

89+
// Build the abstract syntax tree from
90+
// a (pointer to a) list of tokens.
7991
func build_ast(tokens *[]string) Object {
8092
token := pop(tokens)
8193

@@ -94,6 +106,8 @@ func build_ast(tokens *[]string) Object {
94106
}
95107
}
96108

109+
// pop removes and return the head of a list of tokens
110+
// make changes in-place via pointer
97111
func pop(tokens *[]string) string {
98112
if len(*tokens) == 0 {
99113
panic("unexpected EOF while reading")
@@ -104,6 +118,8 @@ func pop(tokens *[]string) string {
104118
return token
105119
}
106120

121+
// atom converts a string to a primitive
122+
// either a Number or a Symbol
107123
func atom(token string) Object {
108124
n, err := strconv.ParseFloat(token, 64)
109125
if err == nil {
@@ -112,6 +128,7 @@ func atom(token string) Object {
112128
return Symbol(token)
113129
}
114130

131+
// tokenize turns a string into a list of tokens
115132
func tokenize(chars string) []string {
116133
chars = strings.Replace(chars, "(", " ( ", -1)
117134
chars = strings.Replace(chars, ")", " ) ", -1)
@@ -187,6 +204,8 @@ func print(args []Object) Object {
187204
return args[0]
188205
}
189206

207+
// getStandardEnv instantiates and populates
208+
// the standard environment used for evaluation
190209
func getStandardEnv() Env {
191210
e := Env{
192211
mapping: make(map[Symbol]Object),
@@ -207,8 +226,11 @@ func getStandardEnv() Env {
207226
return e
208227
}
209228

229+
// eval takes an object (from parse) and evaluates
230+
// it inside the environment
231+
// for example eval(parse("(* 2 2)"))
210232
func (e *Env) eval(x Object) Object {
211-
defer recover_error()
233+
defer recoverError()
212234

213235
if val, is_symbol := x.(Symbol); is_symbol {
214236
return e.mapping[val]
@@ -267,6 +289,8 @@ func (e *Env) eval(x Object) Object {
267289
}
268290
}
269291

292+
// repl provides a REPL for the LISP machine
293+
// that the user can interact with
270294
func repl(e Env, profile_code bool) {
271295
for {
272296
reader := bufio.NewReader(os.Stdin)
@@ -287,6 +311,7 @@ func repl(e Env, profile_code bool) {
287311
}
288312
}
289313

314+
// main checks arguments and launches the REPL
290315
func main() {
291316
profile_code := flag.Bool("profile", false, "profile code execution time")
292317
show_version := flag.Bool("version", false, "show program version and exit")

0 commit comments

Comments
 (0)