Skip to content

Commit 4a9ac01

Browse files
committed
Move macro expression functions to expr module
1 parent 666a8da commit 4a9ac01

File tree

3 files changed

+228
-228
lines changed

3 files changed

+228
-228
lines changed

src/context.rs

Lines changed: 0 additions & 227 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,233 +1106,6 @@ impl TypleContext {
11061106
Ok(())
11071107
}
11081108

1109-
fn replace_typle_fold_expr(
1110-
&self,
1111-
mac: &mut Macro,
1112-
attrs: Vec<Attribute>,
1113-
state: &mut BlockState,
1114-
default_span: Span,
1115-
) -> syn::Result<Expr> {
1116-
let mut inner_state = BlockState::default();
1117-
let token_stream = std::mem::take(&mut mac.tokens);
1118-
let mut tokens = token_stream.into_iter();
1119-
let mut init_expr =
1120-
syn::parse2::<Expr>(Self::extract_to_semicolon(&mut tokens, default_span)?)?;
1121-
self.replace_expr(&mut init_expr, &mut inner_state)?;
1122-
let (pattern, range) = self.parse_pattern_range(&mut tokens)?;
1123-
if range.is_empty() {
1124-
return Ok(Expr::Paren(syn::ExprParen {
1125-
attrs,
1126-
paren_token: token::Paren::default(),
1127-
expr: Box::new(init_expr),
1128-
}));
1129-
}
1130-
let fold_ident = Self::parse_fold_ident(&mut tokens, default_span)?;
1131-
let fold_pat = Pat::Ident(syn::PatIdent {
1132-
attrs: Vec::new(),
1133-
by_ref: None,
1134-
mutability: None,
1135-
ident: fold_ident.clone(),
1136-
subpat: None,
1137-
});
1138-
let expr = syn::parse2::<Expr>(tokens.collect())?;
1139-
let mut stmts = Vec::with_capacity(range.len() + 2);
1140-
stmts.push(Stmt::Local(syn::Local {
1141-
attrs: Vec::new(),
1142-
let_token: token::Let::default(),
1143-
pat: fold_pat.clone(),
1144-
init: Some(syn::LocalInit {
1145-
eq_token: token::Eq::default(),
1146-
expr: Box::new(init_expr),
1147-
diverge: None,
1148-
}),
1149-
semi_token: token::Semi::default(),
1150-
}));
1151-
if !range.is_empty() {
1152-
let mut ctx = pattern.as_ref().map(|ident| {
1153-
let mut context = self.clone();
1154-
context.constants.insert(ident.clone(), 0);
1155-
(context, ident)
1156-
});
1157-
for (index, mut expr) in range.zip_clone(expr) {
1158-
if let Some((ref mut context, ident)) = ctx {
1159-
*context.constants.get_mut(ident).unwrap() = index;
1160-
}
1161-
let context = ctx.as_ref().map_or(self, |c| &c.0);
1162-
context.replace_expr(&mut expr, &mut inner_state)?;
1163-
stmts.push(Stmt::Local(syn::Local {
1164-
attrs: Vec::new(),
1165-
let_token: token::Let::default(),
1166-
pat: fold_pat.clone(),
1167-
init: Some(syn::LocalInit {
1168-
eq_token: token::Eq::default(),
1169-
expr: Box::new(expr),
1170-
diverge: None,
1171-
}),
1172-
semi_token: token::Semi::default(),
1173-
}));
1174-
}
1175-
}
1176-
if let Some(span) = inner_state.unlabelled_continue {
1177-
abort!(
1178-
span,
1179-
"unlabelled `continue` not supported in `typle_fold!` macro"
1180-
);
1181-
}
1182-
state.propagate(inner_state, None);
1183-
stmts.push(Stmt::Expr(
1184-
Expr::Break(syn::ExprBreak {
1185-
attrs: Vec::new(),
1186-
break_token: token::Break::default(),
1187-
label: None,
1188-
expr: Some(Box::new(Expr::Path(syn::PatPath {
1189-
attrs: Vec::new(),
1190-
qself: None,
1191-
path: ident_to_path(fold_ident),
1192-
}))),
1193-
}),
1194-
Some(token::Semi::default()),
1195-
));
1196-
// The fold may be used in an expression `typle_fold!() + ...`, in which
1197-
// case the loop needs to be in parentheses.
1198-
Ok(Expr::Paren(syn::ExprParen {
1199-
attrs,
1200-
paren_token: token::Paren::default(),
1201-
expr: Box::new(Expr::Loop(syn::ExprLoop {
1202-
attrs: Vec::new(),
1203-
label: None,
1204-
loop_token: token::Loop::default(),
1205-
body: Block {
1206-
brace_token: token::Brace::default(),
1207-
stmts,
1208-
},
1209-
})),
1210-
}))
1211-
}
1212-
1213-
fn replace_macro_expr(
1214-
&self,
1215-
mac: &mut Macro,
1216-
attrs: &mut Vec<Attribute>,
1217-
state: &mut BlockState,
1218-
) -> syn::Result<Option<Expr>> {
1219-
self.replace_attrs(attrs)?;
1220-
if let Some(macro_name) = mac.path.get_ident() {
1221-
let default_span = macro_name.span();
1222-
if macro_name == "typle" {
1223-
// This is outside a comma-separated sequence so only no-range form is accepted
1224-
// typle!(=> if T::LEN == 0 {} else {})
1225-
let token_stream = std::mem::take(&mut mac.tokens);
1226-
return self.expand_typle_macro_singleton(token_stream, |context, token_stream| {
1227-
let mut expr = syn::parse2::<Expr>(token_stream)?;
1228-
let mut state = BlockState::default();
1229-
context.replace_expr(&mut expr, &mut state)?;
1230-
Ok(Some(expr))
1231-
});
1232-
} else if macro_name == "typle_fold" {
1233-
let expr =
1234-
self.replace_typle_fold_expr(mac, std::mem::take(attrs), state, default_span)?;
1235-
return Ok(Some(expr));
1236-
} else if macro_name == "typle_all" {
1237-
let token_stream = std::mem::take(&mut mac.tokens);
1238-
let expr = self.anyall(
1239-
token_stream,
1240-
state,
1241-
BinOp::And(token::AndAnd::default()),
1242-
true,
1243-
)?;
1244-
return Ok(Some(expr));
1245-
} else if macro_name == "typle_any" {
1246-
let token_stream = std::mem::take(&mut mac.tokens);
1247-
let expr = self.anyall(
1248-
token_stream,
1249-
state,
1250-
BinOp::Or(token::OrOr::default()),
1251-
false,
1252-
)?;
1253-
return Ok(Some(expr));
1254-
}
1255-
}
1256-
mac.tokens = self.replace_macro_token_stream(std::mem::take(&mut mac.tokens))?;
1257-
Ok(None)
1258-
}
1259-
1260-
fn anyall(
1261-
&self,
1262-
token_stream: TokenStream,
1263-
state: &mut BlockState,
1264-
op: BinOp,
1265-
default: bool,
1266-
) -> syn::Result<Expr> {
1267-
let mut tokens = token_stream.into_iter();
1268-
let (pattern, mut range) = self.parse_pattern_range(&mut tokens)?;
1269-
let expr = syn::parse2::<Expr>(tokens.collect())?;
1270-
let all = match range.next() {
1271-
Some(index) => {
1272-
// Parenthesize low precedence expressions.
1273-
let expr = match expr {
1274-
expr @ Expr::Lit(syn::PatLit {
1275-
lit: Lit::Bool(_), ..
1276-
}) => expr,
1277-
expr @ Expr::Block(_) => expr,
1278-
expr @ Expr::Paren(_) => expr,
1279-
expr @ Expr::Path(_) => expr,
1280-
expr @ Expr::MethodCall(_) => expr,
1281-
expr @ Expr::Field(_) => expr,
1282-
expr @ Expr::Call(_) => expr,
1283-
expr @ Expr::Index(_) => expr,
1284-
expr @ Expr::Unary(_) => expr,
1285-
expr @ Expr::Cast(_) => expr,
1286-
expr => Expr::Paren(syn::ExprParen {
1287-
attrs: Vec::new(),
1288-
paren_token: token::Paren::default(),
1289-
expr: Box::new(expr),
1290-
}),
1291-
};
1292-
1293-
let mut context = self.clone();
1294-
if let Some(ident) = &pattern {
1295-
context.constants.insert(ident.clone(), index);
1296-
}
1297-
let mut all = expr.clone();
1298-
context.replace_expr(&mut all, state)?;
1299-
for (index, mut expr) in range.zip_clone(expr) {
1300-
if let Some(ident) = &pattern {
1301-
*context.constants.get_mut(ident).unwrap() = index;
1302-
}
1303-
context.replace_expr(&mut expr, state)?;
1304-
all = Expr::Binary(syn::ExprBinary {
1305-
attrs: Vec::new(),
1306-
left: Box::new(all),
1307-
op,
1308-
right: Box::new(expr),
1309-
});
1310-
}
1311-
if let Expr::Binary(expr) = all {
1312-
// Wrap entire expression in parentheses to:
1313-
// 1. ensure that it is a single expression in a larger expression.
1314-
// 2. handle ambiguity: `{ true } || { true }` is not a boolean expression.
1315-
// It is a block followed by a closure that returns a boolean. Adding
1316-
// parentheses `({ true } || { true })` makes it a boolean expression.
1317-
all = Expr::Paren(syn::ExprParen {
1318-
attrs: Vec::new(),
1319-
paren_token: token::Paren::default(),
1320-
expr: Box::new(Expr::Binary(expr)),
1321-
});
1322-
}
1323-
all
1324-
}
1325-
None => Expr::Lit(syn::PatLit {
1326-
attrs: Vec::new(),
1327-
lit: Lit::Bool(syn::LitBool {
1328-
value: default,
1329-
span: expr.span(),
1330-
}),
1331-
}),
1332-
};
1333-
Ok(all)
1334-
}
1335-
13361109
// Look for `typle_ty!(...)` or `typle_expr!(...)` and evaluate body.
13371110
fn replace_macro_token_stream(&self, input: TokenStream) -> syn::Result<TokenStream> {
13381111
enum TTState {

0 commit comments

Comments
 (0)