1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package asm 6 7 import ( 8 "cmd/asm/internal/lex" 9 "strings" 10 "testing" 11 "text/scanner" 12 ) 13 14 type exprTest struct { 15 input string 16 output int64 17 atEOF bool 18 } 19 20 var exprTests = []exprTest{ 21 // Simple 22 {"0", 0, true}, 23 {"3", 3, true}, 24 {"070", 8 * 7, true}, 25 {"0x0f", 15, true}, 26 {"0xFF", 255, true}, 27 {"9223372036854775807", 9223372036854775807, true}, // max int64 28 // Unary 29 {"-0", 0, true}, 30 {"~0", -1, true}, 31 {"~0*0", 0, true}, 32 {"+3", 3, true}, 33 {"-3", -3, true}, 34 {"-9223372036854775808", -9223372036854775808, true}, // min int64 35 // Binary 36 {"3+4", 3 + 4, true}, 37 {"3-4", 3 - 4, true}, 38 {"2|5", 2 | 5, true}, 39 {"3^4", 3 ^ 4, true}, 40 {"3*4", 3 * 4, true}, 41 {"14/4", 14 / 4, true}, 42 {"3<<4", 3 << 4, true}, 43 {"48>>3", 48 >> 3, true}, 44 {"3&9", 3 & 9, true}, 45 // General 46 {"3*2+3", 3*2 + 3, true}, 47 {"3+2*3", 3 + 2*3, true}, 48 {"3*(2+3)", 3 * (2 + 3), true}, 49 {"3*-(2+3)", 3 * -(2 + 3), true}, 50 {"3<<2+4", 3<<2 + 4, true}, 51 {"3<<2+4", 3<<2 + 4, true}, 52 {"3<<(2+4)", 3 << (2 + 4), true}, 53 // Junk at EOF. 54 {"3 x", 3, false}, 55 // Big number 56 {"4611686018427387904", 4611686018427387904, true}, 57 } 58 59 func TestExpr(t *testing.T) { 60 p := NewParser(nil, nil, nil) // Expression evaluation uses none of these fields of the parser. 61 for i, test := range exprTests { 62 p.start(lex.Tokenize(test.input)) 63 result := int64(p.expr()) 64 if result != test.output { 65 t.Errorf("%d: %q evaluated to %d; expected %d", i, test.input, result, test.output) 66 } 67 tok := p.next() 68 if test.atEOF && tok.ScanToken != scanner.EOF { 69 t.Errorf("%d: %q: at EOF got %s", i, test.input, tok) 70 } else if !test.atEOF && tok.ScanToken == scanner.EOF { 71 t.Errorf("%d: %q: expected not EOF but at EOF", i, test.input) 72 } 73 } 74 } 75 76 type badExprTest struct { 77 input string 78 error string // Empty means no error. 79 } 80 81 var badExprTests = []badExprTest{ 82 {"0/0", "division by zero"}, 83 {"3/0", "division by zero"}, 84 {"(1<<63)/0", "divide of value with high bit set"}, 85 {"3%0", "modulo by zero"}, 86 {"(1<<63)%0", "modulo of value with high bit set"}, 87 {"3<<-4", "negative left shift count"}, 88 {"3<<(1<<63)", "negative left shift count"}, 89 {"3>>-4", "negative right shift count"}, 90 {"3>>(1<<63)", "negative right shift count"}, 91 {"(1<<63)>>2", "right shift of value with high bit set"}, 92 {"(1<<62)>>2", ""}, 93 {`'\x80'`, "illegal UTF-8 encoding for character constant"}, 94 {"(23*4", "missing closing paren"}, 95 {")23*4", "unexpected ) evaluating expression"}, 96 {"18446744073709551616", "value out of range"}, 97 } 98 99 func TestBadExpr(t *testing.T) { 100 panicOnError = true 101 defer func() { 102 panicOnError = false 103 }() 104 for i, test := range badExprTests { 105 err := runBadTest(i, test, t) 106 if err == nil { 107 if test.error != "" { 108 t.Errorf("#%d: %q: expected error %q; got none", i, test.input, test.error) 109 } 110 continue 111 } 112 if !strings.Contains(err.Error(), test.error) { 113 t.Errorf("#%d: expected error %q; got %q", i, test.error, err) 114 continue 115 } 116 } 117 } 118 119 func runBadTest(i int, test badExprTest, t *testing.T) (err error) { 120 p := NewParser(nil, nil, nil) // Expression evaluation uses none of these fields of the parser. 121 p.start(lex.Tokenize(test.input)) 122 defer func() { 123 e := recover() 124 var ok bool 125 if err, ok = e.(error); e != nil && !ok { 126 t.Fatal(e) 127 } 128 }() 129 p.expr() 130 return nil 131 } 132