func TestParseIf(t *testing.T) { types := []Type{FILE, DECL, IDENT, IDENT, IF, IDENT, IDENT, BASIC} src := "(decl main int (if true int 3))" file := token.NewFile("if.calc", 1, len(src)) f := parse.ParseFile(file, "if.calc", src) if f == nil { t.Fatal("Failed to parse") } ast.Walk(f, nodeTest(types, t)) types = []Type{FILE, DECL, IDENT, IDENT, IF, BINARY, IDENT, IDENT, IDENT, IDENT, LIST, BINARY, IDENT, BASIC, IDENT} src = "(decl main int (if (< a b) int a ((+ b 1) b)))" file = token.NewFile("if2.calc", 1, len(src)) f = parse.ParseFile(file, "if2.calc", src) if f == nil { t.Fatal("Failed to parse") } ast.Walk(f, nodeTest(types, t)) types = []Type{FILE, DECL, IDENT, IDENT, IF, BINARY, IDENT, IDENT, LIST, ASSIGN, IDENT, IDENT} src = "(decl main int (if (< a b) ((= a b))))" file = token.NewFile("if3.calc", 1, len(src)) f = parse.ParseFile(file, "if3.calc", src) if f == nil { t.Fatal("Failed to parse") } ast.Walk(f, nodeTest(types, t)) }
func TestParseVar(t *testing.T) { types := []Type{FILE, DECL, IDENT, IDENT, VAR, IDENT, IDENT} src := "(decl main int (var a int))" file := token.NewFile("var.calc", 1, len(src)) f := parse.ParseFile(file, "var.calc", src) if f == nil { t.Fatal("Failed to parse") } ast.Walk(f, nodeTest(types, t)) types = []Type{FILE, DECL, IDENT, IDENT, VAR, IDENT, IDENT, ASSIGN, IDENT, BASIC} src = "(decl main int (var (= a 5) int))" file = token.NewFile("var2.calc", 1, len(src)) f = parse.ParseFile(file, "var2.calc", src) if f == nil { t.Fatal("Failed to parse") } ast.Walk(f, nodeTest(types, t)) types = []Type{FILE, DECL, IDENT, IDENT, VAR, IDENT, ASSIGN, IDENT, BASIC} src = "(decl main int (var (= a 5)))" file = token.NewFile("var3.calc", 1, len(src)) f = parse.ParseFile(file, "var3.calc", src) if f == nil { t.Fatal("Failed to parse") } ast.Walk(f, nodeTest(types, t)) }
func TestParseDecl(t *testing.T) { types := []Type{FILE, DECL, IDENT, IDENT, IDENT} src := "(decl func int a)" file := token.NewFile("decl1.calc", 1, len(src)) f := parse.ParseFile(file, "decl1.calc", src) if f == nil { t.Fatal("Failed to parse") } ast.Walk(f, nodeTest(types, t)) types = []Type{FILE, DECL, IDENT, IDENT, BINARY, BASIC, BASIC} src = "(decl five int (+ 2 3))" file = token.NewFile("decl2.calc", 1, len(src)) f = parse.ParseFile(file, "decl1.calc", src) if f == nil { t.Fatal("Failed to parse") } ast.Walk(f, nodeTest(types, t)) types = []Type{FILE, DECL, IDENT, IDENT, IDENT, IDENT, BINARY, IDENT, IDENT} src = "(decl add(a b int) int (+ a b))" file = token.NewFile("decl3.calc", 1, len(src)) f = parse.ParseFile(file, "decl2.calc", src) if f == nil { t.Fatal("Failed to parse") } ast.Walk(f, nodeTest(types, t)) }
func TestFilePosition(t *testing.T) { var tests = []struct { col, row int pos token.Pos }{ {1, 1, token.Pos(1)}, {1, 2, token.Pos(8)}, {7, 2, token.Pos(14)}, } f := token.NewFile("", 1, 15) f.AddLine(token.Pos(1)) p := f.Position(token.Pos(1)) if p.String() != "1:1" { t.Fatal("Nameless file: Expected: 1:1, Got:", p.String()) } f = token.NewFile("test.calc", 1, 15) f.AddLine(token.Pos(1)) p = f.Position(token.Pos(1)) if p.String() != "test.calc:1:1" { t.Fatal("Nameless file: Expected: test.calc:1:1, Got:", p.String()) } f = token.NewFile("test", 1, len(test_expr)) f.AddLine(token.Pos(7)) f.AddLine(token.Pos(14)) for _, v := range tests { p := f.Position(v.pos) if p.Col != v.col || p.Row != v.row { t.Fatal("For:", v.pos, "Expected:", v.col, "and", v.row, "Got:", p.Col, "and", p.Row) } } }
func TestExpectFail(t *testing.T) { var tests = []string{ "+ 3 5)", "(- 5)", "(3 5 +)", "(3 + 4)", "(+ 6 2", "(- 4 5)2", "(d", "(% / d)", "(& 3 5)", "((+ 3 5) 5)", "(* (- 2 6) (+ 4 2)())", ";comment", "(var a)", "(decl main () int a)", "(decl main int ())", "(decl main int a)(decl main in b)", "(var a)", "(var (+ a b))", "(var 23)", "(var a int)(var a int)", } for _, src := range tests { file := token.NewFile("expectfail", 1, len(src)) if f := parse.ParseFile(file, "expectfail", src); f != nil { t.Log(src, "- not nil") t.Fail() } } }
func TestParseFileBasic(t *testing.T) { types := []Type{FILE, DECL, IDENT, IDENT, BINARY, BASIC, BASIC} src := "(decl main int (+ 1 2))" file := token.NewFile("basicdec", 1, len(src)) f := parse.ParseFile(file, "basicdec", src) if f == nil { t.Fatal("Failed to parse") } ast.Walk(f, nodeTest(types, t)) }
func TestParseNested(t *testing.T) { var types = []Type{FILE, DECL, IDENT, IDENT, BINARY, BINARY, BASIC, BASIC, BASIC, BINARY, BASIC, BASIC} src := ";comment\n(decl main int (+ (/ 9 3) 5 (- 3 1)))" file := token.NewFile("nested.calc", 1, len(src)) f := parse.ParseFile(file, "nested.calc", src) if f == nil { t.Fatal("Failed to parse") } ast.Walk(f, nodeTest(types, t)) }
func TestParseCall(t *testing.T) { types := []Type{FILE, DECL, IDENT, IDENT, CALL, IDENT, BASIC, BASIC, BASIC, BASIC} src := "(decl main int (add 1 2 3 4))" file := token.NewFile("call1", 1, len(src)) f := parse.ParseFile(file, "call1", "(decl main int (add 1 2 3 4))") if f == nil { t.Fatal("Failed to parse") } ast.Walk(f, nodeTest(types, t)) types = []Type{FILE, DECL, IDENT, IDENT, CALL, IDENT} src = "(decl main int (nothing))" file = token.NewFile("call1", 1, len(src)) f = parse.ParseFile(file, "call1", src) if f == nil { t.Fatal("Failed to parse") } ast.Walk(f, nodeTest(types, t)) }
func test_handler(t *testing.T, src string, expected []token.Token) { var s scan.Scanner s.Init(token.NewFile("", 1, len(src)), src) lit, tok, pos := s.Scan() for i := 0; tok != token.EOF; i++ { if tok != expected[i] { t.Fatal(pos, "Expected:", expected[i], "Got:", tok, lit) } lit, tok, pos = s.Scan() } }