// 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.
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:
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.
"#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",
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.
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)
}
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