mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
Was rejected but should be legal. Change-Id: I0189e3bef6b67c6ba390c75a48a8d9d8f39b7636 Reviewed-on: https://go-review.googlesource.com/5286 Reviewed-by: Russ Cox <rsc@golang.org>
154 lines
2.8 KiB
Go
154 lines
2.8 KiB
Go
// Copyright 2015 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package lex
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
"testing"
|
|
"text/scanner"
|
|
)
|
|
|
|
type lexTest struct {
|
|
name string
|
|
input string
|
|
output string
|
|
}
|
|
|
|
var lexTests = []lexTest{
|
|
{
|
|
"empty",
|
|
"",
|
|
"",
|
|
},
|
|
{
|
|
"simple",
|
|
"1 (a)",
|
|
"1.(.a.)",
|
|
},
|
|
{
|
|
"simple define",
|
|
lines(
|
|
"#define A 1234",
|
|
"A",
|
|
),
|
|
"1234.\n",
|
|
},
|
|
{
|
|
"define without value",
|
|
"#define A",
|
|
"",
|
|
},
|
|
{
|
|
"macro without arguments",
|
|
"#define A() 1234\n" + "A()\n",
|
|
"1234.\n",
|
|
},
|
|
{
|
|
"macro with just parens as body",
|
|
"#define A () \n" + "A\n",
|
|
"(.).\n",
|
|
},
|
|
{
|
|
"macro with parens but no arguments",
|
|
"#define A (x) \n" + "A\n",
|
|
"(.x.).\n",
|
|
},
|
|
{
|
|
"macro with arguments",
|
|
"#define A(x, y, z) x+z+y\n" + "A(1, 2, 3)\n",
|
|
"1.+.3.+.2.\n",
|
|
},
|
|
{
|
|
"argumented macro invoked without arguments",
|
|
lines(
|
|
"#define X() foo ",
|
|
"X()",
|
|
"X",
|
|
),
|
|
"foo.\n.X.\n",
|
|
},
|
|
{
|
|
"multiline macro without arguments",
|
|
lines(
|
|
"#define A 1\\",
|
|
"\t2\\",
|
|
"\t3",
|
|
"before",
|
|
"A",
|
|
"after",
|
|
),
|
|
"before.\n.1.\n.2.\n.3.\n.after.\n",
|
|
},
|
|
{
|
|
"multiline macro with arguments",
|
|
lines(
|
|
"#define A(a, b, c) a\\",
|
|
"\tb\\",
|
|
"\tc",
|
|
"before",
|
|
"A(1, 2, 3)",
|
|
"after",
|
|
),
|
|
"before.\n.1.\n.2.\n.3.\n.after.\n",
|
|
},
|
|
{
|
|
"LOAD macro",
|
|
lines(
|
|
"#define LOAD(off, reg) \\",
|
|
"\tMOVBLZX (off*4)(R12), reg \\",
|
|
"\tADDB reg, DX",
|
|
"",
|
|
"LOAD(8, AX)",
|
|
),
|
|
"\n.\n.MOVBLZX.(.8.*.4.).(.R12.).,.AX.\n.ADDB.AX.,.DX.\n",
|
|
},
|
|
{
|
|
"nested multiline macro",
|
|
lines(
|
|
"#define KEYROUND(xmm, load, off, r1, r2, index) \\",
|
|
"\tMOVBLZX (BP)(DX*4), R8 \\",
|
|
"\tload((off+1), r2) \\",
|
|
"\tMOVB R8, (off*4)(R12) \\",
|
|
"\tPINSRW $index, (BP)(R8*4), xmm",
|
|
"#define LOAD(off, reg) \\",
|
|
"\tMOVBLZX (off*4)(R12), reg \\",
|
|
"\tADDB reg, DX",
|
|
"KEYROUND(X0, LOAD, 8, AX, BX, 0)",
|
|
),
|
|
"\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",
|
|
},
|
|
}
|
|
|
|
func TestLex(t *testing.T) {
|
|
for _, test := range lexTests {
|
|
input := NewInput(test.name)
|
|
input.Push(NewTokenizer(test.name, strings.NewReader(test.input), nil))
|
|
result := drain(input)
|
|
if result != test.output {
|
|
t.Errorf("%s: got %q expected %q", test.name, result, test.output)
|
|
}
|
|
}
|
|
}
|
|
|
|
// lines joins the arguments together as complete lines.
|
|
func lines(a ...string) string {
|
|
return strings.Join(a, "\n") + "\n"
|
|
}
|
|
|
|
// drain returns a single string representing the processed input tokens.
|
|
func drain(input *Input) string {
|
|
var buf bytes.Buffer
|
|
for {
|
|
tok := input.Next()
|
|
if tok == scanner.EOF {
|
|
return buf.String()
|
|
}
|
|
if buf.Len() > 0 {
|
|
buf.WriteByte('.')
|
|
}
|
|
buf.WriteString(input.Text())
|
|
}
|
|
}
|