diff --git a/lex.go b/lex.go index 83ed143..cb90648 100644 --- a/lex.go +++ b/lex.go @@ -1,9 +1,9 @@ package main import ( - "io" - "fmt" - "strings" + "fmt" + "io" + "strings" ) type typ3 int diff --git a/skeam.go b/skeam.go index 6203353..4105a6a 100644 --- a/skeam.go +++ b/skeam.go @@ -2,7 +2,7 @@ package main import ( "bufio" - "errors" + "errors" "fmt" "io" "os" @@ -17,75 +17,89 @@ type symbol string // parses the string lexeme into a value that can be eval'd func atom(t token) (interface{}, error) { - switch t.t { - case integerToken: - val, err := strconv.ParseInt(t.lexeme, 10, 64) - if err != nil { - return nil, err - } - return val, nil - - case floatToken: - val, err := strconv.ParseFloat(t.lexeme, 64) - if err != nil { - return nil, err - } - return val, nil - - case stringToken: - return t.lexeme, nil - - case symbolToken: - return symbol(t.lexeme), nil - } - - return nil, fmt.Errorf("unable to atomize token: %v", t) + switch t.t { + case integerToken: + val, err := strconv.ParseInt(t.lexeme, 10, 64) + if err != nil { + return nil, err + } + return val, nil + + case floatToken: + val, err := strconv.ParseFloat(t.lexeme, 64) + if err != nil { + return nil, err + } + return val, nil + + case stringToken: + return t.lexeme, nil + + case symbolToken: + return symbol(t.lexeme), nil + } + + return nil, fmt.Errorf("unable to atomize token: %v", t) } // reads in tokens on the channel until a matching close paren is found. func (s *sexp) readIn(c chan token) error { - for t := range c { - switch t.t { - case closeParenToken: - return nil - case openParenToken: - child := make(sexp, 0) - if err := child.readIn(c); err != nil { - return err - } - *s = append(*s, child) - default: - v, err := atom(t) - if err != nil { - return err - } - *s = append(*s, v) - } - } - return errors.New("unexpected EOF in sexp.readIn") + for t := range c { + switch t.t { + case closeParenToken: + return nil + case openParenToken: + child := make(sexp, 0) + if err := child.readIn(c); err != nil { + return err + } + *s = append(*s, child) + default: + v, err := atom(t) + if err != nil { + return err + } + *s = append(*s, v) + } + } + return errors.New("unexpected EOF in sexp.readIn") } // parses one value that can be evaled from the channel func parse(c chan token) (interface{}, error) { - for t := range c { - switch t.t { - case closeParenToken: - return nil, errors.New("unexpected EOF in read") - case openParenToken: - s := make(sexp, 0) - if err := s.readIn(c); err != nil { - return nil, err - } - return s, nil - default: - return atom(t) - } - } - return nil, io.EOF + for t := range c { + switch t.t { + case closeParenToken: + return nil, errors.New("unexpected EOF in read") + case openParenToken: + s := make(sexp, 0) + if err := s.readIn(c); err != nil { + return nil, err + } + return s, nil + default: + return atom(t) + } + } + return nil, io.EOF } func eval(v interface{}) { - fmt.Println(v) + fmt.Println(v) +} + +func evalall(c chan token) { + for { + v, err := parse(c) + switch err { + case io.EOF: + return + case nil: + eval(v) + default: + fmt.Println("error in eval: %v", err) + } + } } func args() { @@ -99,18 +113,7 @@ func args() { c := make(chan token, 32) go lex(bufio.NewReader(f), c) - - for { - v, err := parse(c) - switch err { - case io.EOF: - return - case nil: - eval(v) - default: - fmt.Println("error in args(): %v", err) - } - } + evalall(c) } func main() { @@ -139,17 +142,6 @@ func main() { c := make(chan token, 32) go lexs(string(line)+"\n", c) - for { - v, err := parse(c) - switch err { - case io.EOF: - goto OUT - case nil: - eval(v) - default: - fmt.Println("error in repl: %v", err) - } - } - OUT: + evalall(c) } }