fix: block ends with expr stmt

This commit is contained in:
2025-11-05 22:12:40 +08:00
parent b312898187
commit cc34f59a4d
4 changed files with 20 additions and 11 deletions

View File

@@ -2,36 +2,38 @@ import os
import asyncio
async def check_file(filepath):
async def check_file(in_path, out_path):
proc = await asyncio.create_subprocess_exec(
"moon",
"run",
"src/bin/main.mbt",
"--",
"--typecheck",
filepath,
in_path,
"-o",
out_path,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await proc.communicate()
if proc.returncode != 0:
print(f"""
[{proc.returncode}] Error in file {filepath}:
[{proc.returncode}] Error in file {in_path}:
======== STDOUT ========
{stdout.decode()}
======== STDERR ========
{stderr.decode()}
""")
else:
print(f"File {filepath} compiled successfully.")
print(f"File {in_path} compiled successfully.")
async def main():
tasks = []
for file in os.listdir("contest-2025-data/test_cases/mbt"):
if file.endswith(".mbt"):
filepath = os.path.join("contest-2025-data/test_cases/mbt", file)
tasks.append(check_file(filepath))
in_path = os.path.join("contest-2025-data/test_cases/mbt", file)
out_path = os.path.join("output/repo", file.replace(".mbt", ".s"))
tasks.append(check_file(in_path, out_path))
await asyncio.gather(*tasks)

View File

@@ -485,7 +485,12 @@ pub fn parse_block_expr(
}
break r
} else if r is [RCurlyBracket, .. r] {
// Ref: syntax.typ:123-125
// - 一个Block 块可以有返回值块内的最后一条语句可以是一个expr也可以是一个`stmt`,如果块的最后一个语句是一个`expr`,则该块的值就是这个 `expr` 的值。如果块的最后一个语句是一个 `stmt`,且这个块是一个`expr_stmt`,则该块的值就是这个 `stmt` 的值。
// 例如, ```rust let a = 1; { let b = 2; a + b }``` 的值是 `3````rust let a = 1; { let b = 2; a + b; }``` 的值是 `3`,而```rust let a = 1; { let b = 2; let _ = a + b; }``` 的值是 `()`。
if !(stmts is [.., Expr(_)]) {
stmts.push(Expr(Literal(Unit)))
}
break r
}
continue r

View File

@@ -154,7 +154,7 @@ test "parse_block_expr" {
RCurlyBracket,
EOF,
]),
content="(Block([Expr(Literal(Int(1))), Expr(Literal(Unit))]), [EOF])",
content="(Block([Expr(Literal(Int(1)))]), [EOF])",
)
}
@@ -226,7 +226,7 @@ test "parse_if_level_expr" {
RCurlyBracket,
EOF,
]),
content="(If(Literal(Int(0)), Block([Expr(Literal(Int(1))), Expr(Literal(Unit))]), None), [EOF])",
content="(If(Literal(Int(0)), Block([Expr(Literal(Int(1)))]), None), [EOF])",
)
}
@@ -333,6 +333,8 @@ test "parse_program" {
LCurlyBracket,
IntLiteral(0),
Semicolon,
LParen,
RParen,
RCurlyBracket,
EOF,
]),

View File

@@ -563,7 +563,7 @@ test "Block Expr TypeCheck Test" {
// TypeCheck first block expr
let (block_expr1, tok_view) = @parser.parse_block_expr(tok_view)
let checked_block1 = ctx.check_block_expr(block_expr1)
assert_true(checked_block1.stmts.length() is 5) // Lilunar adds an implicit Expr(Unit) at the end
assert_true(checked_block1.stmts.length() is 4)
assert_true(checked_block1.ty is Unit)
// TypeCheck second block expr
let (block_expr2, tok_view) = @parser.parse_block_expr(tok_view)