aboutsummaryrefslogtreecommitdiff
path: root/go/src/reader
diff options
context:
space:
mode:
authorJoel Martin <github@martintribe.org>2014-10-04 22:16:57 -0500
committerJoel Martin <github@martintribe.org>2014-10-04 22:16:57 -0500
commitfcbda8d58a22c734c1c9020287cbe1df795d76c0 (patch)
tree85af580f006bdd705500f21110121ebd725a8476 /go/src/reader
parent70ea599b6e0787102f12cd543dcd65a2eb3751d5 (diff)
downloadmal-fcbda8d58a22c734c1c9020287cbe1df795d76c0.tar.gz
mal-fcbda8d58a22c734c1c9020287cbe1df795d76c0.zip
go: step1_read_print vectors and hash-maps
Diffstat (limited to 'go/src/reader')
-rw-r--r--go/src/reader/reader.go46
1 files changed, 40 insertions, 6 deletions
diff --git a/go/src/reader/reader.go b/go/src/reader/reader.go
index 6a08840..55cea59 100644
--- a/go/src/reader/reader.go
+++ b/go/src/reader/reader.go
@@ -70,18 +70,18 @@ func read_atom(rdr Reader) (types.MalType, error) {
return token, nil
}
-func read_list(rdr Reader) (types.MalType, error) {
+func read_list(rdr Reader, start string, end string) (types.MalType, error) {
token := rdr.next()
if token == nil { return nil, errors.New("read_list underflow") }
ast_list := []types.MalType{}
- if *token != "(" {
- return nil, errors.New("expected '('")
+ if *token != start {
+ return nil, errors.New("expected '" + start + "'")
}
token = rdr.peek()
for ; true ; token = rdr.peek() {
- if token == nil { return nil, errors.New("exepected ')', got EOF") }
- if *token == ")" { break }
+ if token == nil { return nil, errors.New("exepected '" + end + "', got EOF") }
+ if *token == end { break }
f, e := read_form(rdr)
if e != nil { return nil, e }
ast_list = append(ast_list, f)
@@ -90,12 +90,46 @@ func read_list(rdr Reader) (types.MalType, error) {
return types.List{ast_list}, nil
}
+func read_vector(rdr Reader) (types.MalType, error) {
+ lst, e := read_list(rdr, "[", "]")
+ if e != nil { return nil, e }
+ vec := types.Vector{lst.(types.List).Val}
+ return vec, nil
+}
+
+func read_hash_map(rdr Reader) (types.MalType, error) {
+ mal_lst, e := read_list(rdr, "{", "}")
+ lst := mal_lst.(types.List).Val
+ if e != nil { return nil, e }
+ if len(lst) % 2 == 1 {
+ return nil, errors.New("Odd number of hash map arguments")
+ }
+ m := map[string]types.MalType{}
+ for i := 0; i < len(lst); i+=2 {
+ str, ok := lst[i].(string)
+ if !ok {
+ return nil, errors.New("expected hash-map key string")
+ }
+ m[str] = lst[i+1]
+ }
+ return m, nil
+}
+
func read_form(rdr Reader) (types.MalType, error) {
token := rdr.peek()
if token == nil { return nil, errors.New("read_form underflow") }
switch (*token) {
+ // list
case ")": return nil, errors.New("unexpected ')'")
- case "(": return read_list(rdr)
+ case "(": return read_list(rdr, "(", ")")
+
+ // vector
+ case "]": return nil, errors.New("unexpected ']'")
+ case "[": return read_vector(rdr)
+
+ // hash-map
+ case "}": return nil, errors.New("unexpected '}'")
+ case "{": return read_hash_map(rdr)
default: return read_atom(rdr)
}
return read_atom(rdr)