mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Blocks directly in template also scope
This commit is contained in:
parent
5de791d9e6
commit
ea921aca5d
@ -269,9 +269,7 @@ impl Eval for BlockExpr {
|
||||
type Output = Value;
|
||||
|
||||
fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> {
|
||||
if self.scoping {
|
||||
ctx.scopes.enter();
|
||||
}
|
||||
|
||||
let mut output = Value::None;
|
||||
for expr in &self.exprs {
|
||||
@ -279,9 +277,7 @@ impl Eval for BlockExpr {
|
||||
output = ops::join(output, value).at(expr.span())?;
|
||||
}
|
||||
|
||||
if self.scoping {
|
||||
ctx.scopes.exit();
|
||||
}
|
||||
|
||||
Ok(output)
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ fn markup_node(p: &mut Parser, at_start: &mut bool) -> Option<MarkupNode> {
|
||||
}
|
||||
|
||||
// Block and template.
|
||||
Token::LeftBrace => return Some(MarkupNode::Expr(block(p, false))),
|
||||
Token::LeftBrace => return Some(MarkupNode::Expr(block(p))),
|
||||
Token::LeftBracket => return Some(MarkupNode::Expr(template(p))),
|
||||
|
||||
// Comments.
|
||||
@ -316,7 +316,7 @@ fn primary(p: &mut Parser, atomic: bool) -> Option<Expr> {
|
||||
// Structures.
|
||||
Some(Token::LeftParen) => parenthesized(p),
|
||||
Some(Token::LeftBracket) => Some(template(p)),
|
||||
Some(Token::LeftBrace) => Some(block(p, true)),
|
||||
Some(Token::LeftBrace) => Some(block(p)),
|
||||
|
||||
// Keywords.
|
||||
Some(Token::Let) => let_expr(p),
|
||||
@ -527,7 +527,7 @@ fn template(p: &mut Parser) -> Expr {
|
||||
}
|
||||
|
||||
/// Parse a code block: `{...}`.
|
||||
fn block(p: &mut Parser, scoping: bool) -> Expr {
|
||||
fn block(p: &mut Parser) -> Expr {
|
||||
p.start_group(Group::Brace, TokenMode::Code);
|
||||
let mut exprs = vec![];
|
||||
while !p.eof() {
|
||||
@ -544,7 +544,7 @@ fn block(p: &mut Parser, scoping: bool) -> Expr {
|
||||
p.eat_while(|t| matches!(t, Token::Space(_)));
|
||||
}
|
||||
let span = p.end_group();
|
||||
Expr::Block(Box::new(BlockExpr { span, exprs, scoping }))
|
||||
Expr::Block(Box::new(BlockExpr { span, exprs }))
|
||||
}
|
||||
|
||||
/// Parse a function call.
|
||||
@ -789,7 +789,7 @@ fn ident(p: &mut Parser) -> Option<Ident> {
|
||||
fn body(p: &mut Parser) -> Option<Expr> {
|
||||
match p.peek() {
|
||||
Some(Token::LeftBracket) => Some(template(p)),
|
||||
Some(Token::LeftBrace) => Some(block(p, true)),
|
||||
Some(Token::LeftBrace) => Some(block(p)),
|
||||
_ => {
|
||||
p.expected_at(p.prev_end(), "body");
|
||||
None
|
||||
|
@ -190,8 +190,6 @@ pub struct BlockExpr {
|
||||
pub span: Span,
|
||||
/// The list of expressions contained in the block.
|
||||
pub exprs: Vec<Expr>,
|
||||
/// Whether the block should create a scope.
|
||||
pub scoping: bool,
|
||||
}
|
||||
|
||||
/// A unary operation: `-x`.
|
||||
|
@ -158,16 +158,12 @@ impl_visitors! {
|
||||
}
|
||||
|
||||
visit_block(v, block: BlockExpr) {
|
||||
if block.scoping {
|
||||
v.visit_enter();
|
||||
}
|
||||
for expr in r!(block.exprs) {
|
||||
v.visit_expr(expr);
|
||||
}
|
||||
if block.scoping {
|
||||
v.visit_exit();
|
||||
}
|
||||
}
|
||||
|
||||
visit_binary(v, binary: BinaryExpr) {
|
||||
v.visit_expr(r!(binary.lhs));
|
||||
|
@ -58,8 +58,10 @@
|
||||
}
|
||||
|
||||
---
|
||||
// Block in template does not create a scope.
|
||||
// Block directly in template also creates a scope.
|
||||
{ let x = 1 }
|
||||
|
||||
// Error: 7-8 unknown variable
|
||||
#test(x, 1)
|
||||
|
||||
---
|
||||
|
@ -21,8 +21,6 @@
|
||||
test(b, 1)
|
||||
}
|
||||
|
||||
#test(b, 1)
|
||||
|
||||
// A wildcard import.
|
||||
#import * from "target.typ"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user