Source file src/cmd/asm/internal/asm/expr_test.go

     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  	for i, test := range badExprTests {
   101  		err := runBadTest(i, test, t)
   102  		if err == nil {
   103  			if test.error != "" {
   104  				t.Errorf("#%d: %q: expected error %q; got none", i, test.input, test.error)
   105  			}
   106  			continue
   107  		}
   108  		if !strings.Contains(err.Error(), test.error) {
   109  			t.Errorf("#%d: expected error %q; got %q", i, test.error, err)
   110  			continue
   111  		}
   112  	}
   113  }
   114  
   115  func runBadTest(i int, test badExprTest, t *testing.T) (err error) {
   116  	p := NewParser(nil, nil, nil) // Expression evaluation uses none of these fields of the parser.
   117  	p.start(lex.Tokenize(test.input))
   118  	return tryParse(t, func() {
   119  		p.expr()
   120  	})
   121  }
   122  

View as plain text