Skip to content
This repository has been archived by the owner on Jun 3, 2021. It is now read-only.

Commit

Permalink
WIP Token::concat manually
Browse files Browse the repository at this point in the history
  • Loading branch information
hdamron17 committed Aug 17, 2020
1 parent 28aaca8 commit 6866968
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 5 deletions.
4 changes: 4 additions & 0 deletions src/data/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,10 @@ pub enum CppError {
/// '##' missing arguments
#[error("'##' cannot appear at {} of macro expansion", if *(.0) { "start" } else { "end"})]
HashHashMissingParameter(bool),

/// The result of '##' is not a valid token
#[error("pasting formed '{0}{1}', an invalid preprocessing token")]
HashHashInvalid(Token, Token),
}

/// Lex errors are non-exhaustive and may have new variants added at any time
Expand Down
48 changes: 48 additions & 0 deletions src/data/lex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,54 @@ impl<T> Locatable<T> {

impl Token {
pub const EQUAL: Token = Token::Assignment(AssignmentToken::Equal);

pub fn concat(x: &Token, y: &Token) -> Option<Token> {
use Token::*;
use AssignmentToken::*;
use ComparisonToken::*;
let tok = match (x, y) {
(Whitespace(wx), Whitespace(wy)) => Whitespace(format!("{}{}", wx, wy)),
(Whitespace(_), tok) => tok.clone(),
(tok, Whitespace(_)) => tok.clone(),

(Plus, Assignment(Equal)) => Assignment(AddEqual),
(Minus, Assignment(Equal)) => Assignment(SubEqual),
(Star, Assignment(Equal)) => Assignment(MulEqual),
(Divide, Assignment(Equal)) => Assignment(DivEqual),
(Mod, Assignment(Equal)) => Assignment(ModEqual),
(ShiftLeft, Assignment(Equal)) => Assignment(ShlEqual),
(ShiftRight, Assignment(Equal)) => Assignment(ShrEqual),
(Ampersand, Assignment(Equal)) => Assignment(AndEqual),
(BitwiseOr, Assignment(Equal)) => Assignment(OrEqual),
(Xor, Assignment(Equal)) => Assignment(XorEqual),

(Assignment(Equal), Assignment(Equal)) => Comparison(EqualEqual),
(LogicalNot, Assignment(Equal)) => Comparison(NotEqual),
(Comparison(Less), Assignment(Equal)) => Comparison(LessEqual),
(Comparison(Greater), Assignment(Equal)) => Comparison(GreaterEqual),

(Ampersand, Ampersand) => LogicalAnd,
(BitwiseOr, BitwiseOr) => LogicalOr,

(Comparison(Less), Comparison(Less)) => ShiftLeft,
(Comparison(Greater), Comparison(Greater)) => ShiftRight,

(Minus, Comparison(Greater)) => StructDeref,
(Hash, Hash) => HashHash,

(Keyword(kx), Keyword(ky)) => Id(InternedStr::get_or_intern(format!("{}{}", kx, ky))),
(Keyword(kx), Id(idy)) => Id(InternedStr::get_or_intern(format!("{}{}", kx, idy))),
(Id(idx), Keyword(ky)) => Id(InternedStr::get_or_intern(format!("{}{}", idx, ky))),
(Id(idx), Id(idy)) => Id(InternedStr::get_or_intern(format!("{}{}", idx, idy))),

// Chars and Strings cannot be concatenated with token pasting
// TODO implement Literals

// TODO what about Keyword::UserTypedef as differentiated from Id?
_ => return None,
};
Some(tok)
}
}

impl AssignmentToken {
Expand Down
16 changes: 11 additions & 5 deletions src/lex/replace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,17 @@ pub fn replace(
continue;
}
let pending_hashhash = pending_hashhash.take().unwrap(); // We just checked that it's some
let concat_token = concat(pending_hashhash, succeeding_tok.clone(), &location);
let concat_token = Token::concat(&pending_hashhash, succeeding_tok)
.map(|tok| location.with(tok))
.ok_or_else(|| {
location.with(
CppError::HashHashInvalid(
pending_hashhash.clone(),
succeeding_tok.clone(),
)
.into(),
)
});
replacements.push(concat_token); // TODO don't bypass pending
continue;
}
Expand Down Expand Up @@ -480,10 +490,6 @@ fn stringify(args: Vec<Token>) -> Token {
))]))
}

fn concat(x: Token, b: Token, location: &Location) -> CompileResult<Locatable<Token>> {
todo!();
}

fn wrap_error(location: &Location, err: CppError) -> Vec<CppResult<Token>> {
vec![Err(location.with(err.into()))]
}

0 comments on commit 6866968

Please sign in to comment.