master
Jordan Orelli 12 years ago
parent a3791fcc0e
commit b6a88a15fb

@ -1,9 +1,9 @@
package main package main
import ( import (
"io" "fmt"
"fmt" "io"
"strings" "strings"
) )
type typ3 int type typ3 int

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

Loading…
Cancel
Save