mirror of
https://github.com/golang/go
synced 2024-11-19 09:04:41 -07:00
[dev.cc] cmd/asm: fix macro definition bug in the lexer
Because text/scanner hides the spaces, the lexer treated #define A(x) and #define A (x) the same, but they are not: the first is an argument with macros, the second is a simple one-word macro whose definition contains parentheses. Fix this by noticing the relative column number as we move from A to (. Hacky but simple. Also add a helper to recognize the peculiar ARM shifted register operators. Change-Id: I2cad22f5f1e11d8dad40ad13955793d178afb3ae Reviewed-on: https://go-review.googlesource.com/4872 Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
7fbfbca2c4
commit
ae2b145da2
@ -203,12 +203,21 @@ func (in *Input) defineMacro(name string, args []string, tokens []Token) {
|
||||
// The argument list is nil for no parens on the definition; otherwise a list of
|
||||
// formal argument names.
|
||||
func (in *Input) macroDefinition(name string) ([]string, []Token) {
|
||||
prevCol := in.Stack.Col()
|
||||
tok := in.Stack.Next()
|
||||
if tok == '\n' || tok == scanner.EOF {
|
||||
in.Error("no definition for macro:", name)
|
||||
}
|
||||
var args []string
|
||||
if tok == '(' {
|
||||
// The C preprocessor treats
|
||||
// #define A(x)
|
||||
// and
|
||||
// #define A (x)
|
||||
// distinctly: the first is a macro with arguments, the second without.
|
||||
// Distinguish these cases using the column number, since we don't
|
||||
// see the space itself. Note that text/scanner reports the position at the
|
||||
// end of the token. It's where you are now, and you just read this token.
|
||||
if tok == '(' && in.Stack.Col() == prevCol+1 {
|
||||
// Macro has arguments. Scan list of formals.
|
||||
acceptArg := true
|
||||
args = []string{} // Zero length but not nil.
|
||||
|
@ -29,6 +29,11 @@ const (
|
||||
macroName // name of macro that should not be expanded
|
||||
)
|
||||
|
||||
// IsRegisterShift reports whether the token is one of the ARM register shift operators.
|
||||
func IsRegisterShift(r ScanToken) bool {
|
||||
return ROT <= r && r <= LSH // Order looks backwards because these are negative.
|
||||
}
|
||||
|
||||
func (t ScanToken) String() string {
|
||||
switch t {
|
||||
case scanner.EOF:
|
||||
@ -94,6 +99,8 @@ type TokenReader interface {
|
||||
File() string
|
||||
// Line reports the source line number of the token.
|
||||
Line() int
|
||||
// Col reports the source column number of the token.
|
||||
Col() int
|
||||
// SetPos sets the file and line number.
|
||||
SetPos(line int, file string)
|
||||
// Close does any teardown required.
|
||||
|
@ -41,6 +41,16 @@ var lexTests = []lexTest{
|
||||
"#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",
|
||||
|
@ -43,6 +43,11 @@ func (s *Slice) Line() int {
|
||||
return s.line
|
||||
}
|
||||
|
||||
func (s *Slice) Col() int {
|
||||
// Col is only called when defining a macro, which can't reach here.
|
||||
panic("cannot happen: slice col")
|
||||
}
|
||||
|
||||
func (s *Slice) SetPos(line int, file string) {
|
||||
// Cannot happen because we only have slices of already-scanned
|
||||
// text, but be prepared.
|
||||
|
@ -41,6 +41,10 @@ func (s *Stack) Line() int {
|
||||
return s.tr[len(s.tr)-1].Line()
|
||||
}
|
||||
|
||||
func (s *Stack) Col() int {
|
||||
return s.tr[len(s.tr)-1].Col()
|
||||
}
|
||||
|
||||
func (s *Stack) SetPos(line int, file string) {
|
||||
s.tr[len(s.tr)-1].SetPos(line, file)
|
||||
}
|
||||
|
@ -89,6 +89,10 @@ func (t *Tokenizer) Line() int {
|
||||
return t.line
|
||||
}
|
||||
|
||||
func (t *Tokenizer) Col() int {
|
||||
return t.s.Pos().Column
|
||||
}
|
||||
|
||||
func (t *Tokenizer) SetPos(line int, file string) {
|
||||
t.line = line
|
||||
t.fileName = file
|
||||
|
Loading…
Reference in New Issue
Block a user