aboutsummaryrefslogtreecommitdiff
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
parent70ea599b6e0787102f12cd543dcd65a2eb3751d5 (diff)
downloadmal-fcbda8d58a22c734c1c9020287cbe1df795d76c0.tar.gz
mal-fcbda8d58a22c734c1c9020287cbe1df795d76c0.zip
go: step1_read_print vectors and hash-maps
-rw-r--r--go/src/printer/printer.go22
-rw-r--r--go/src/reader/reader.go46
-rw-r--r--go/src/types/types.go4
3 files changed, 61 insertions, 11 deletions
diff --git a/go/src/printer/printer.go b/go/src/printer/printer.go
index 83d4c84..fa1c0fb 100644
--- a/go/src/printer/printer.go
+++ b/go/src/printer/printer.go
@@ -9,14 +9,27 @@ import (
"types"
)
+func _pr_list(lst []types.MalType, pr bool, start string, end string) string {
+ str_list := make([]string, 0, len(lst))
+ for _, e := range lst {
+ str_list = append(str_list, Pr_str(e, pr))
+ }
+ return start + strings.Join(str_list, " ") + end
+}
+
func Pr_str(obj types.MalType, print_readably bool) string {
switch tobj := obj.(type) {
case types.List:
- str_list := make([]string, 0, len(tobj.Val))
- for _, e := range tobj.Val {
- str_list = append(str_list, Pr_str(e, print_readably))
+ return _pr_list(tobj.Val, print_readably, "(", ")")
+ case types.Vector:
+ return _pr_list(tobj.Val, print_readably, "[", "]")
+ case map[string]types.MalType:
+ str_list := make([]string, 0, len(tobj)*2)
+ for k, v := range tobj {
+ str_list = append(str_list, Pr_str(k, print_readably))
+ str_list = append(str_list, Pr_str(v, print_readably))
}
- return "(" + strings.Join(str_list, " ") + ")"
+ return "{" + strings.Join(str_list, " ") + "}"
case string:
if print_readably {
// TODO: quote backslash, quote, and newline
@@ -31,5 +44,4 @@ func Pr_str(obj types.MalType, print_readably bool) string {
default:
return fmt.Sprintf("%v", obj)
}
- return "<printed>"
}
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)
diff --git a/go/src/types/types.go b/go/src/types/types.go
index 3f1c652..a212725 100644
--- a/go/src/types/types.go
+++ b/go/src/types/types.go
@@ -15,3 +15,7 @@ type List struct {
Val []MalType
}
+type Vector struct {
+ Val []MalType
+}
+