github.com/huandu/go@v0.0.0-20151114150818-04e615e41150/src/cmd/asm/internal/lex/lex_test.go (about)

     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 lex
     6  
     7  import (
     8  	"bytes"
     9  	"strings"
    10  	"testing"
    11  	"text/scanner"
    12  )
    13  
    14  type lexTest struct {
    15  	name   string
    16  	input  string
    17  	output string
    18  }
    19  
    20  var lexTests = []lexTest{
    21  	{
    22  		"empty",
    23  		"",
    24  		"",
    25  	},
    26  	{
    27  		"simple",
    28  		"1 (a)",
    29  		"1.(.a.)",
    30  	},
    31  	{
    32  		"simple define",
    33  		lines(
    34  			"#define A 1234",
    35  			"A",
    36  		),
    37  		"1234.\n",
    38  	},
    39  	{
    40  		"define without value",
    41  		"#define A",
    42  		"",
    43  	},
    44  	{
    45  		"macro without arguments",
    46  		"#define A() 1234\n" + "A()\n",
    47  		"1234.\n",
    48  	},
    49  	{
    50  		"macro with just parens as body",
    51  		"#define A () \n" + "A\n",
    52  		"(.).\n",
    53  	},
    54  	{
    55  		"macro with parens but no arguments",
    56  		"#define A (x) \n" + "A\n",
    57  		"(.x.).\n",
    58  	},
    59  	{
    60  		"macro with arguments",
    61  		"#define A(x, y, z) x+z+y\n" + "A(1, 2, 3)\n",
    62  		"1.+.3.+.2.\n",
    63  	},
    64  	{
    65  		"argumented macro invoked without arguments",
    66  		lines(
    67  			"#define X() foo ",
    68  			"X()",
    69  			"X",
    70  		),
    71  		"foo.\n.X.\n",
    72  	},
    73  	{
    74  		"multiline macro without arguments",
    75  		lines(
    76  			"#define A 1\\",
    77  			"\t2\\",
    78  			"\t3",
    79  			"before",
    80  			"A",
    81  			"after",
    82  		),
    83  		"before.\n.1.\n.2.\n.3.\n.after.\n",
    84  	},
    85  	{
    86  		"multiline macro with arguments",
    87  		lines(
    88  			"#define A(a, b, c) a\\",
    89  			"\tb\\",
    90  			"\tc",
    91  			"before",
    92  			"A(1, 2, 3)",
    93  			"after",
    94  		),
    95  		"before.\n.1.\n.2.\n.3.\n.after.\n",
    96  	},
    97  	{
    98  		"LOAD macro",
    99  		lines(
   100  			"#define LOAD(off, reg) \\",
   101  			"\tMOVBLZX	(off*4)(R12),	reg \\",
   102  			"\tADDB	reg,		DX",
   103  			"",
   104  			"LOAD(8, AX)",
   105  		),
   106  		"\n.\n.MOVBLZX.(.8.*.4.).(.R12.).,.AX.\n.ADDB.AX.,.DX.\n",
   107  	},
   108  	{
   109  		"nested multiline macro",
   110  		lines(
   111  			"#define KEYROUND(xmm, load, off, r1, r2, index) \\",
   112  			"\tMOVBLZX	(BP)(DX*4),	R8 \\",
   113  			"\tload((off+1), r2) \\",
   114  			"\tMOVB	R8,		(off*4)(R12) \\",
   115  			"\tPINSRW	$index, (BP)(R8*4), xmm",
   116  			"#define LOAD(off, reg) \\",
   117  			"\tMOVBLZX	(off*4)(R12),	reg \\",
   118  			"\tADDB	reg,		DX",
   119  			"KEYROUND(X0, LOAD, 8, AX, BX, 0)",
   120  		),
   121  		"\n.MOVBLZX.(.BP.).(.DX.*.4.).,.R8.\n.\n.MOVBLZX.(.(.8.+.1.).*.4.).(.R12.).,.BX.\n.ADDB.BX.,.DX.\n.MOVB.R8.,.(.8.*.4.).(.R12.).\n.PINSRW.$.0.,.(.BP.).(.R8.*.4.).,.X0.\n",
   122  	},
   123  }
   124  
   125  func TestLex(t *testing.T) {
   126  	for _, test := range lexTests {
   127  		input := NewInput(test.name)
   128  		input.Push(NewTokenizer(test.name, strings.NewReader(test.input), nil))
   129  		result := drain(input)
   130  		if result != test.output {
   131  			t.Errorf("%s: got %q expected %q", test.name, result, test.output)
   132  		}
   133  	}
   134  }
   135  
   136  // lines joins the arguments together as complete lines.
   137  func lines(a ...string) string {
   138  	return strings.Join(a, "\n") + "\n"
   139  }
   140  
   141  // drain returns a single string representing the processed input tokens.
   142  func drain(input *Input) string {
   143  	var buf bytes.Buffer
   144  	for {
   145  		tok := input.Next()
   146  		if tok == scanner.EOF {
   147  			return buf.String()
   148  		}
   149  		if buf.Len() > 0 {
   150  			buf.WriteByte('.')
   151  		}
   152  		buf.WriteString(input.Text())
   153  	}
   154  }