/* At this point, we have consumed the first M_PASTE. * @see Macro#addPaste(Token) */ private void paste(Token ptok) { StringBuilder buf = new StringBuilder(); Token err = null; /* We know here that arg is null or expired, * since we cannot paste an expanded arg. */ int count = 2; for (int i = 0; i < count; i++) { if (!tokens.hasNext()) { /* XXX This one really should throw. */ error(ptok.getLine(), ptok.getColumn(), "Paste at end of expansion"); buf.append(' ').append(ptok.getText()); break; } Token tok = tokens.next(); // System.out.println("Paste " + tok); switch (tok.getType()) { case Token.M_PASTE: /* One extra to paste, plus one because the * paste token didn't count. */ count += 2; ptok = tok; break; case Token.M_ARG: int idx = (int)tok.getValue(); concat(buf, args.get(idx)); break; /* XXX Test this. */ case Token.CCOMMENT: case Token.CPPCOMMENT: break; default: buf.append(tok.getText()); break; } } /* Push and re-lex. */ /* * StringBuilder src = new StringBuilder(); * escape(src, buf); * StringLexerSource sl = new StringLexerSource(src.toString()); */ StringLexerSource sl = new StringLexerSource(buf.toString()); /* XXX Check that concatenation produces a valid token. */ arg = new SourceIterator(sl); }
/* Paste tokens are inserted before the first of the two pasted * tokens, so it's a kind of bytecode notation. This method * swaps them around again. We know that there will never be two * sequential paste tokens, so a bool is sufficient. */ public String getText() { StringBuilder buf = new StringBuilder(); bool paste = false; for (int i = 0; i < tokens.Count; i++) { Token tok = tokens[i]; if (tok.getType() == Token.M_PASTE) { System.Diagnostics.Debug.Assert(paste == false, "Two sequential pastes."); paste = true; continue; } else { buf.Append(tok.getText()); } if (paste) { buf.Append(" #" + "# "); paste = false; } // buf.Append(tokens.get(i)); } return(buf.ToString()); }
override public Token token() { for (;;) { /* Deal with lexed tokens first. */ if (arg != null) { if (arg.hasNext()) { Token tok2 = arg.next(); /* XXX PASTE -> INVALID. */ Debug.Assert(tok2.getType() != Token.M_PASTE, "Unexpected paste token"); return(tok2); } arg = null; } if (!tokens.hasNext()) { return(new Token(Token.EOF, -1, -1, "")); /* End of macro. */ } Token tok = tokens.next(); int idx; switch (tok.getType()) { case Token.M_STRING: /* Use the nonexpanded arg. */ idx = (int)tok.getValue(); return(stringify(tok, args.get(idx))); case Token.M_ARG: /* Expand the arg. */ idx = (int)tok.getValue(); // System.out.println("Pushing arg " + args.get(idx)); arg = args.get(idx).expansion(); break; case Token.M_PASTE: paste(tok); break; default: return(tok); } } /* for */ }
private bool isWhite(Token tok) { int type = tok.getType(); return (type == Token.WHITESPACE) || (type == Token.CCOMMENT) || (type == Token.CPPCOMMENT); }
private int expr_priority(Token op) { switch (op.getType()) { case '/': return 11; case '%': return 11; case '*': return 11; case '+': return 10; case '-': return 10; case Token.LSH: return 9; case Token.RSH: return 9; case '<': return 8; case '>': return 8; case Token.LE: return 8; case Token.GE: return 8; case Token.EQ: return 7; case Token.NE: return 7; case '&': return 6; case '^': return 5; case '|': return 4; case Token.LAND: return 3; case Token.LOR: return 2; case '?': return 1; default: // System.out.println("Unrecognised operator " + op); return 0; } }