func TestQuoteList(t *testing.T) { r := strings.NewReader("'(1 2)") parser := New(lexer.New(r)) actual := types.NewList(types.Number(1), types.Number(2)) exps, err := parser.Parse() if err != nil { t.Fatalf("parser failed: %s", err) } if !reflect.DeepEqual(exps, actual) { t.Fatalf("expressions is not expected. %v", exps) } }
func TestQuote(t *testing.T) { r := strings.NewReader("'hello") parser := New(lexer.New(r)) actual := types.Symbol("hello") exps, err := parser.Parse() if err != nil { t.Fatalf("parser failed: %s", err) } if !reflect.DeepEqual(exps, actual) { t.Fatalf("expressions is not expected. %v", exps) } }
func TestParseString(t *testing.T) { r := strings.NewReader("(print \"it's test\")") parser := New(lexer.New(r)) actual := []types.Expression{ types.Symbol("print"), "it's test", } exps, err := parser.Parse() if err != nil { t.Fatalf("parser failed: %s", err) } if !reflect.DeepEqual(exps, actual) { t.Fatalf("expressions is not expected. %#v", exps) } }
func TestNewLine(t *testing.T) { r := strings.NewReader("(print 1)\n\n") parser := New(lexer.New(r)) actual := []types.Expression{ types.Symbol("print"), types.Number(1), } exps, err := parser.Parse() if err != nil { t.Fatalf("parser failed: %s", err) } if !reflect.DeepEqual(exps, actual) { t.Fatalf("expressions is not expected. %v", exps) } }
func TestParseDash(t *testing.T) { r := strings.NewReader("(define a-b-c-efg x)") parser := New(lexer.New(r)) actual := []types.Expression{ types.Symbol("define"), types.Symbol("a-b-c-efg"), types.Symbol("x"), } exps, err := parser.Parse() if err != nil { t.Fatalf("parser failed: %s", err) } if !reflect.DeepEqual(exps, actual) { t.Fatalf("expressions is not expected. %#v", exps) } }
// EvalReader evaluate scheme program from io.Reader func EvalReader(r io.Reader, env *Env) (types.Expression, error) { l := lexer.New(r) p := parser.New(l) if _, err := env.Get("#current-load-path"); err != nil { env.Put("#current-load-path", "") } var exps types.Expression for { tokens, err := p.Parse() if err != nil { return nil, err } // TODO should handle unknown token. if tokens == types.Symbol("") { break } exps, err = Eval(tokens, env) if err != nil { return nil, err } } return exps, nil }
func TestParserRecursive(t *testing.T) { r := strings.NewReader("(define (square x) (* x x))") parser := New(lexer.New(r)) expected := []types.Expression{ types.Symbol("define"), []types.Expression{ types.Symbol("square"), types.Symbol("x"), }, []types.Expression{ types.Symbol("*"), types.Symbol("x"), types.Symbol("x"), }, } exps, err := parser.Parse() if err != nil { t.Fatalf("parser failed: %s", err) } if !reflect.DeepEqual(exps, expected) { t.Fatalf("expressions is not expected. %#v", exps) } }
func TestParseLineDelimited(t *testing.T) { r := strings.NewReader(` (define (fib n) (cond ((= n 0) 0) ((= n 1) 1) (else (+ (fib (- n 1)) (fib (- n 2)))))) `) parser := New(lexer.New(r)) actual := []types.Expression{ types.Symbol("define"), []types.Expression{ types.Symbol("fib"), types.Symbol("n"), }, []types.Expression{ types.Symbol("cond"), []types.Expression{ []types.Expression{ types.Symbol("="), types.Symbol("n"), types.Number(0), }, types.Number(0), }, []types.Expression{ []types.Expression{ types.Symbol("="), types.Symbol("n"), types.Number(1), }, types.Number(1), }, []types.Expression{ types.Symbol("else"), []types.Expression{ types.Symbol("+"), []types.Expression{ types.Symbol("fib"), []types.Expression{ types.Symbol("-"), types.Symbol("n"), types.Number(1), }, }, []types.Expression{ types.Symbol("fib"), []types.Expression{ types.Symbol("-"), types.Symbol("n"), types.Number(2), }, }, }, }, }, } exps, err := parser.Parse() if err != nil { t.Fatalf("parser failed: %s", err) } if !reflect.DeepEqual(exps, actual) { t.Fatalf("expressions is not expected. %#v", exps) } }