func TestLexer_Token(t *testing.T) { l := Lexer{Lexer: util.Lexer{ Reader: util.NewReader(`123 + 456 2 - 78 4569 0 15 == 16 a != 3 3 >= 4 5 <= 6 7 > 8 9 < 10 a = 1 + 2 * (3 / 4 - b) wwhilew iiff`), IsWhitespace: util.IsWhitespaceSTNL, }} for _, expected := range []struct { Token Token Kind int }{ {"123", NUM}, {"+", '+'}, {"456", NUM}, {"2", NUM}, {"-", '-'}, {"78", NUM}, {"4569", NUM}, {"0", NUM}, {"15", NUM}, {"==", EQ}, {"16", NUM}, {"a", VAR}, {"!=", NEQ}, {"3", NUM}, {"3", NUM}, {">=", GTEQ}, {"4", NUM}, {"5", NUM}, {"<=", LTEQ}, {"6", NUM}, {"7", NUM}, {">", '>'}, {"8", NUM}, {"9", NUM}, {"<", '<'}, {"10", NUM}, {"a", VAR}, {"=", '='}, {"1", NUM}, {"+", '+'}, {"2", NUM}, {"*", '*'}, {"(", '('}, {"3", NUM}, {"/", '/'}, {"4", NUM}, {"-", '-'}, {"b", VAR}, {")", ')'}, {"w", VAR}, {"while", WHILE}, {"w", VAR}, {"i", VAR}, {"if", IF}, {"f", VAR}, } { token, kind, err := l.Token() defect.Equal(t, err, nil) defect.Equal(t, kind, expected.Kind) defect.Equal(t, token, expected.Token) } // errors l = Lexer{Lexer: util.Lexer{ Reader: util.NewReader("01\n"), IsWhitespace: util.IsWhitespaceSTNL, }} _, _, err := l.Token() defect.Equal(t, err, IllegalInteger) }
func TestLexer_Token(t *testing.T) { l := Lexer{Lexer: util.Lexer{ Reader: util.NewReader(`123 + 456 2 - 78 4569 a = 1 + 2 * (3 / 4 - b)`), IsWhitespace: util.IsWhitespaceST, }} for _, expected := range []struct { Token Token Kind int }{ {"123", NUM}, {"+", '+'}, {"456", NUM}, {"\n", '\n'}, {"2", NUM}, {"-", '-'}, {"78", NUM}, {"\n", '\n'}, {"4569", NUM}, {"\n", '\n'}, {"a", VAR}, {"=", '='}, {"1", NUM}, {"+", '+'}, {"2", NUM}, {"*", '*'}, {"(", '('}, {"3", NUM}, {"/", '/'}, {"4", NUM}, {"-", '-'}, {"b", VAR}, {")", ')'}, } { token, kind, err := l.Token() defect.Equal(t, err, nil) defect.Equal(t, kind, expected.Kind) defect.Equal(t, token, expected.Token) } }
func TestLexer_Scan(t *testing.T) { l := Lexer{Lexer: util.Lexer{ Reader: util.NewReader("1 + 2"), IsWhitespace: util.IsWhitespaceST, }} for _, expected := range []rune{'1', '+', '2', util.EOF} { r, err := l.Scan() defect.Equal(t, err, nil) defect.Equal(t, r, expected) } }
func TestLexer_Scan(t *testing.T) { l := Lexer{Lexer: util.Lexer{ Reader: util.NewReader("a = 1 + 2 * (3 / 4 - b)"), IsWhitespace: util.IsWhitespaceSTNL, }} for _, expected := range []rune{ 'a', '=', '1', '+', '2', '*', '(', '3', '/', '4', '-', 'b', ')', util.EOF, } { r, err := l.Scan() defect.Equal(t, err, nil) defect.Equal(t, r, expected) } }
func TestLexer(t *testing.T) { l := Lexer{Lexer: util.Lexer{Reader: util.NewReader("12")}} fn := func(get func() (rune, error), expected rune) { r, err := get() defect.Equal(t, err, nil) defect.Equal(t, r, expected) } fn(l.Peek, '1') fn(l.Peek, '1') fn(l.Next, '1') fn(l.Peek, '2') fn(l.Next, '2') fn(l.Peek, util.EOF) fn(l.Next, util.EOF) }
func TestYyParse(t *testing.T) { fn := func(s string, expected []int) { Output.Mtx.Lock() Output.Val = []int{} p := yyParse(&Lexer{Lexer: util.Lexer{ Reader: util.NewReader(s), IsWhitespace: util.IsWhitespaceST, }}) defect.Equal(t, p, util.EOF) defect.DeepEqual(t, Output.Val, expected) Output.Mtx.Unlock() } fn("6\n", []int{6}) fn("67 + 89\n", []int{67 + 89}) fn("2 * 3\n", []int{6}) fn("6 / 2\n", []int{3}) fn("(4)\n", []int{4}) fn("1 + 3 * (4 / 2 - 5)\n", []int{-8}) fn("a = 1\n", []int{}) fn(`a = 1 a `, []int{1}) fn(`123 + 456 2 - 78 4569 `, []int{123 + 456, 2 - 78, 4569}) fn("1 + 3 * (4 / 2 - 5)\n", []int{-8}) fn(`a = 1 + 3 * (4 / 2 - 5) b = a + 10 b `, []int{2}) // examples from the book fn(`3 * (4 + 5) x = 3 * (4 + 5) y = 5 x y x + 2 * y `, []int{27, 27, 5, 37}) }
func TestV1Parse(t *testing.T) { fn := func(s string, expected []int) { Output.Mtx.Lock() Output.Val = []int{} p := yyParse(&Lexer{Lexer: util.Lexer{ Reader: util.NewReader(s), IsWhitespace: util.IsWhitespaceST, }}) defect.Equal(t, p, util.EOF) defect.DeepEqual(t, Output.Val, expected) Output.Mtx.Unlock() } fn("6\n", []int{6}) fn("67 + 89\n", []int{67 + 89}) fn(`123 + 456 2 - 78 4569 `, []int{123 + 456, 2 - 78, 4569}) }
func TestLexer_Token(t *testing.T) { l := Lexer{Lexer: util.Lexer{ Reader: util.NewReader(`123 + 456 2 - 78 4569`), IsWhitespace: util.IsWhitespaceST, }} for _, expected := range []struct { Token Token Kind int }{ {"123", NUM}, {"+", '+'}, {"456", NUM}, {"\n", '\n'}, {"2", NUM}, {"-", '-'}, {"78", NUM}, {"\n", '\n'}, {"4569", NUM}, } { token, kind, err := l.Token() defect.Equal(t, err, nil) defect.Equal(t, kind, expected.Kind) defect.Equal(t, token, expected.Token) } }
func TestYyParse(t *testing.T) { fn := func(s string, expected []interface{}) { Mtx.Lock() Initialize() p := yyParse(&Lexer{Lexer: util.Lexer{ Reader: util.NewReader(s), IsWhitespace: util.IsWhitespaceSTNL, }}) defect.Equal(t, p, util.EOF) defect.DeepEqual(t, vals(Output), expected) Mtx.Unlock() } fn("print 6;", []interface{}{6}) fn("print 67 + 89;", []interface{}{67 + 89}) fn("print 2 * 3;", []interface{}{6}) fn("print 6 / 2;", []interface{}{3}) fn("print (4);", []interface{}{4}) fn("print 1 + 3 * (4 / 2 - 5);", []interface{}{-8}) fn("print -2;", []interface{}{-2}) fn("a = 1;", []interface{}{}) fn(`a = 1; print a; `, []interface{}{1}) fn(`print 123 + 456; print 2 - 78; print 4569; `, []interface{}{123 + 456, 2 - 78, 4569}) fn("print 1 + 3 * (4 / 2 - 5);", []interface{}{-8}) fn(`a = 1 + 3 * (4 / 2 - 5); b = a + 10; print b; `, []interface{}{2}) fn("print 1 == 1;", []interface{}{true}) fn("print (1 == 1) == (2 == 3);", []interface{}{false}) fn("print 2 < 1;", []interface{}{false}) fn("print 2 > 1;", []interface{}{true}) fn("print 3 >= 3;", []interface{}{true}) fn("print 4 <= 3;", []interface{}{false}) fn("print 2 != 2;", []interface{}{false}) fn("print (1 != 1) != (1 != 2);", []interface{}{true}) fn("{print 1; print 2;}", []interface{}{1, 2}) fn("{{{print 1;}}}", []interface{}{1}) fn("a = 1; { a = 2; {{ a = 3; a = 4; } a = 5; }} print a;", []interface{}{5}) fn("{a = 1; print a;}", []interface{}{1}) fn("if (1 == 1) {print 1;}", []interface{}{1}) fn("if (1 == 2) {print 1;}", []interface{}{}) fn("a = 1; if (a == 1) { print 1; }", []interface{}{1}) fn("a = 1 == 1; if (a) { print 1; }", []interface{}{1}) fn("{a = 1; if (a == 1) { print 1; }}", []interface{}{1}) fn("a = 1; while (a < 3) { print a; a = a + 1; }", []interface{}{1, 2}) fn("if (1 == 2) print 1; else print 2;", []interface{}{2}) fn("a = 1; if (a == 2) print 1; else print 2;", []interface{}{2}) fn(`a = 1; if (a == 2) { a = a + 1; print a; } else { a = a + 1; if (a == 2) print a == 2; else print a == 2; }`, []interface{}{true}) fn(`a = 1; while (a < 4) { while (a < 4) { print a; a = a + 1; } }`, []interface{}{1, 2, 3}) // examples from the book fn(`print 3 * (4 + 5); x = 3 * (4 + 5); y = 5; print x; print y; print x + 2 * y; `, []interface{}{27, 27, 5, 37}) }