Blocks directly in template also scope

This commit is contained in:
Laurenz 2021-09-15 13:12:07 +02:00
parent 5de791d9e6
commit ea921aca5d
6 changed files with 12 additions and 22 deletions

View File

@ -269,9 +269,7 @@ impl Eval for BlockExpr {
type Output = Value; type Output = Value;
fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> { fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> {
if self.scoping { ctx.scopes.enter();
ctx.scopes.enter();
}
let mut output = Value::None; let mut output = Value::None;
for expr in &self.exprs { for expr in &self.exprs {
@ -279,9 +277,7 @@ impl Eval for BlockExpr {
output = ops::join(output, value).at(expr.span())?; output = ops::join(output, value).at(expr.span())?;
} }
if self.scoping { ctx.scopes.exit();
ctx.scopes.exit();
}
Ok(output) Ok(output)
} }

View File

@ -125,7 +125,7 @@ fn markup_node(p: &mut Parser, at_start: &mut bool) -> Option<MarkupNode> {
} }
// Block and template. // 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))), Token::LeftBracket => return Some(MarkupNode::Expr(template(p))),
// Comments. // Comments.
@ -316,7 +316,7 @@ fn primary(p: &mut Parser, atomic: bool) -> Option<Expr> {
// Structures. // Structures.
Some(Token::LeftParen) => parenthesized(p), Some(Token::LeftParen) => parenthesized(p),
Some(Token::LeftBracket) => Some(template(p)), Some(Token::LeftBracket) => Some(template(p)),
Some(Token::LeftBrace) => Some(block(p, true)), Some(Token::LeftBrace) => Some(block(p)),
// Keywords. // Keywords.
Some(Token::Let) => let_expr(p), Some(Token::Let) => let_expr(p),
@ -527,7 +527,7 @@ fn template(p: &mut Parser) -> Expr {
} }
/// Parse a code block: `{...}`. /// 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); p.start_group(Group::Brace, TokenMode::Code);
let mut exprs = vec![]; let mut exprs = vec![];
while !p.eof() { while !p.eof() {
@ -544,7 +544,7 @@ fn block(p: &mut Parser, scoping: bool) -> Expr {
p.eat_while(|t| matches!(t, Token::Space(_))); p.eat_while(|t| matches!(t, Token::Space(_)));
} }
let span = p.end_group(); let span = p.end_group();
Expr::Block(Box::new(BlockExpr { span, exprs, scoping })) Expr::Block(Box::new(BlockExpr { span, exprs }))
} }
/// Parse a function call. /// Parse a function call.
@ -789,7 +789,7 @@ fn ident(p: &mut Parser) -> Option<Ident> {
fn body(p: &mut Parser) -> Option<Expr> { fn body(p: &mut Parser) -> Option<Expr> {
match p.peek() { match p.peek() {
Some(Token::LeftBracket) => Some(template(p)), 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"); p.expected_at(p.prev_end(), "body");
None None

View File

@ -190,8 +190,6 @@ pub struct BlockExpr {
pub span: Span, pub span: Span,
/// The list of expressions contained in the block. /// The list of expressions contained in the block.
pub exprs: Vec<Expr>, pub exprs: Vec<Expr>,
/// Whether the block should create a scope.
pub scoping: bool,
} }
/// A unary operation: `-x`. /// A unary operation: `-x`.

View File

@ -158,15 +158,11 @@ impl_visitors! {
} }
visit_block(v, block: BlockExpr) { visit_block(v, block: BlockExpr) {
if block.scoping { v.visit_enter();
v.visit_enter();
}
for expr in r!(block.exprs) { for expr in r!(block.exprs) {
v.visit_expr(expr); v.visit_expr(expr);
} }
if block.scoping { v.visit_exit();
v.visit_exit();
}
} }
visit_binary(v, binary: BinaryExpr) { visit_binary(v, binary: BinaryExpr) {

View File

@ -58,8 +58,10 @@
} }
--- ---
// Block in template does not create a scope. // Block directly in template also creates a scope.
{ let x = 1 } { let x = 1 }
// Error: 7-8 unknown variable
#test(x, 1) #test(x, 1)
--- ---

View File

@ -21,8 +21,6 @@
test(b, 1) test(b, 1)
} }
#test(b, 1)
// A wildcard import. // A wildcard import.
#import * from "target.typ" #import * from "target.typ"