diff options
| author | Miki Tebeka <miki.tebeka@gmail.com> | 2015-03-01 05:57:02 +0200 |
|---|---|---|
| committer | Miki Tebeka <miki.tebeka@gmail.com> | 2015-03-01 05:57:02 +0200 |
| commit | 978af8a768be2ed4b0be249a2e87744d0ba8307d (patch) | |
| tree | f10a81f4e874716898af755d9c5b21b85fc606c6 /go/src/reader | |
| parent | 1218ce98a40ef243824fed0efce7160a10fe5f36 (diff) | |
| download | mal-978af8a768be2ed4b0be249a2e87744d0ba8307d.tar.gz mal-978af8a768be2ed4b0be249a2e87744d0ba8307d.zip | |
running "gofmt" on the code
Diffstat (limited to 'go/src/reader')
| -rw-r--r-- | go/src/reader/reader.go | 298 |
1 files changed, 176 insertions, 122 deletions
diff --git a/go/src/reader/reader.go b/go/src/reader/reader.go index 9cacb8b..ee64f56 100644 --- a/go/src/reader/reader.go +++ b/go/src/reader/reader.go @@ -1,162 +1,216 @@ package reader import ( - "errors" - "regexp" - "strconv" - "strings" - //"fmt" + "errors" + "regexp" + "strconv" + "strings" + //"fmt" ) import ( - . "types" + . "types" ) type Reader interface { - next() *string - peek() *string + next() *string + peek() *string } type TokenReader struct { - tokens []string - position int + tokens []string + position int } func (tr *TokenReader) next() *string { - if tr.position >= len(tr.tokens) { return nil } - token := tr.tokens[tr.position] - tr.position = tr.position + 1 - return &token + if tr.position >= len(tr.tokens) { + return nil + } + token := tr.tokens[tr.position] + tr.position = tr.position + 1 + return &token } func (tr *TokenReader) peek() *string { - if tr.position >= len(tr.tokens) { return nil } - return &tr.tokens[tr.position] + if tr.position >= len(tr.tokens) { + return nil + } + return &tr.tokens[tr.position] } - - -func tokenize (str string) []string { - results := make([]string, 0, 1) - // Work around lack of quoting in backtick - re := regexp.MustCompile(`[\s,]*(~@|[\[\]{}()'` + "`" + - `~^@]|"(?:\\.|[^\\"])*"|;.*|[^\s\[\]{}('"` + "`" + - `,;)]*)`) - for _, group := range re.FindAllStringSubmatch(str, -1) { - if (group[1] == "") || (group[1][0] == ';') { continue } - results = append(results, group[1]) - } - return results +func tokenize(str string) []string { + results := make([]string, 0, 1) + // Work around lack of quoting in backtick + re := regexp.MustCompile(`[\s,]*(~@|[\[\]{}()'` + "`" + + `~^@]|"(?:\\.|[^\\"])*"|;.*|[^\s\[\]{}('"` + "`" + + `,;)]*)`) + for _, group := range re.FindAllStringSubmatch(str, -1) { + if (group[1] == "") || (group[1][0] == ';') { + continue + } + results = append(results, group[1]) + } + return results } func read_atom(rdr Reader) (MalType, error) { - token := rdr.next() - if token == nil { return nil, errors.New("read_atom underflow") } - if match, _ := regexp.MatchString(`^-?[0-9]+$`, *token); match { - var i int - var e error - if i, e = strconv.Atoi(*token); e != nil { - return nil, errors.New("number parse error") - } - return i, nil - } else if (*token)[0] == '"' { - str := (*token)[1:len(*token)-1] - return strings.Replace( - strings.Replace(str, `\"`, `"`, -1), - `\n`, "\n", -1), nil - } else if (*token)[0] == ':' { - return NewKeyword((*token)[1:len(*token)]) - } else if *token == "nil" { - return nil, nil - } else if *token == "true" { - return true, nil - } else if *token == "false" { - return false, nil - } else { - return Symbol{*token}, nil - } - return token, nil + token := rdr.next() + if token == nil { + return nil, errors.New("read_atom underflow") + } + if match, _ := regexp.MatchString(`^-?[0-9]+$`, *token); match { + var i int + var e error + if i, e = strconv.Atoi(*token); e != nil { + return nil, errors.New("number parse error") + } + return i, nil + } else if (*token)[0] == '"' { + str := (*token)[1 : len(*token)-1] + return strings.Replace( + strings.Replace(str, `\"`, `"`, -1), + `\n`, "\n", -1), nil + } else if (*token)[0] == ':' { + return NewKeyword((*token)[1:len(*token)]) + } else if *token == "nil" { + return nil, nil + } else if *token == "true" { + return true, nil + } else if *token == "false" { + return false, nil + } else { + return Symbol{*token}, nil + } + return token, nil } func read_list(rdr Reader, start string, end string) (MalType, error) { - token := rdr.next() - if token == nil { return nil, errors.New("read_list underflow") } - if *token != start { - return nil, errors.New("expected '" + start + "'") - } - - ast_list := []MalType{} - token = rdr.peek() - for ; true ; token = rdr.peek() { - 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) - } - rdr.next() - return List{ast_list,nil}, nil + token := rdr.next() + if token == nil { + return nil, errors.New("read_list underflow") + } + if *token != start { + return nil, errors.New("expected '" + start + "'") + } + + ast_list := []MalType{} + token = rdr.peek() + for ; true; token = rdr.peek() { + 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) + } + rdr.next() + return List{ast_list, nil}, nil } func read_vector(rdr Reader) (MalType, error) { - lst, e := read_list(rdr, "[", "]") - if e != nil { return nil, e } - vec := Vector{lst.(List).Val,nil} - return vec, nil + lst, e := read_list(rdr, "[", "]") + if e != nil { + return nil, e + } + vec := Vector{lst.(List).Val, nil} + return vec, nil } func read_hash_map(rdr Reader) (MalType, error) { - mal_lst, e := read_list(rdr, "{", "}") - if e != nil { return nil, e } - return NewHashMap(mal_lst) + mal_lst, e := read_list(rdr, "{", "}") + if e != nil { + return nil, e + } + return NewHashMap(mal_lst) } func read_form(rdr Reader) (MalType, error) { - token := rdr.peek() - if token == nil { return nil, errors.New("read_form underflow") } - switch (*token) { - - case `'`: rdr.next(); - form, e := read_form(rdr); if e != nil { return nil, e } - return List{[]MalType{Symbol{"quote"}, form},nil}, nil - case "`": rdr.next(); - form, e := read_form(rdr); if e != nil { return nil, e } - return List{[]MalType{Symbol{"quasiquote"}, form},nil}, nil - case `~`: rdr.next(); - form, e := read_form(rdr); if e != nil { return nil, e } - return List{[]MalType{Symbol{"unquote"}, form},nil}, nil - case `~@`: rdr.next(); - form, e := read_form(rdr); if e != nil { return nil, e } - return List{[]MalType{Symbol{"splice-unquote"}, form},nil}, nil - case `^`: rdr.next(); - meta, e := read_form(rdr); if e != nil { return nil, e } - form, e := read_form(rdr); if e != nil { return nil, e } - return List{[]MalType{Symbol{"with-meta"}, form,meta},nil}, nil - case `@`: rdr.next(); - form, e := read_form(rdr); if e != nil { return nil, e } - return List{[]MalType{Symbol{"deref"}, form},nil}, nil - - // list - case ")": return nil, errors.New("unexpected ')'") - 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) + token := rdr.peek() + if token == nil { + return nil, errors.New("read_form underflow") + } + switch *token { + + case `'`: + rdr.next() + form, e := read_form(rdr) + if e != nil { + return nil, e + } + return List{[]MalType{Symbol{"quote"}, form}, nil}, nil + case "`": + rdr.next() + form, e := read_form(rdr) + if e != nil { + return nil, e + } + return List{[]MalType{Symbol{"quasiquote"}, form}, nil}, nil + case `~`: + rdr.next() + form, e := read_form(rdr) + if e != nil { + return nil, e + } + return List{[]MalType{Symbol{"unquote"}, form}, nil}, nil + case `~@`: + rdr.next() + form, e := read_form(rdr) + if e != nil { + return nil, e + } + return List{[]MalType{Symbol{"splice-unquote"}, form}, nil}, nil + case `^`: + rdr.next() + meta, e := read_form(rdr) + if e != nil { + return nil, e + } + form, e := read_form(rdr) + if e != nil { + return nil, e + } + return List{[]MalType{Symbol{"with-meta"}, form, meta}, nil}, nil + case `@`: + rdr.next() + form, e := read_form(rdr) + if e != nil { + return nil, e + } + return List{[]MalType{Symbol{"deref"}, form}, nil}, nil + + // list + case ")": + return nil, errors.New("unexpected ')'") + 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) } func Read_str(str string) (MalType, error) { - var tokens = tokenize(str); - if len(tokens) == 0 { - return nil, errors.New("<empty line>") - } + var tokens = tokenize(str) + if len(tokens) == 0 { + return nil, errors.New("<empty line>") + } - return read_form(&TokenReader{tokens: tokens, position: 0}) + return read_form(&TokenReader{tokens: tokens, position: 0}) } |
