diff options
| author | Joel Martin <github@martintribe.org> | 2014-10-04 22:16:57 -0500 |
|---|---|---|
| committer | Joel Martin <github@martintribe.org> | 2014-10-04 22:16:57 -0500 |
| commit | fcbda8d58a22c734c1c9020287cbe1df795d76c0 (patch) | |
| tree | 85af580f006bdd705500f21110121ebd725a8476 | |
| parent | 70ea599b6e0787102f12cd543dcd65a2eb3751d5 (diff) | |
| download | mal-fcbda8d58a22c734c1c9020287cbe1df795d76c0.tar.gz mal-fcbda8d58a22c734c1c9020287cbe1df795d76c0.zip | |
go: step1_read_print vectors and hash-maps
| -rw-r--r-- | go/src/printer/printer.go | 22 | ||||
| -rw-r--r-- | go/src/reader/reader.go | 46 | ||||
| -rw-r--r-- | go/src/types/types.go | 4 |
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 +} + |
