fix: block ends with expr stmt
This commit is contained in:
16
batch_run.py
16
batch_run.py
@@ -2,36 +2,38 @@ import os
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
|
|
||||||
async def check_file(filepath):
|
async def check_file(in_path, out_path):
|
||||||
proc = await asyncio.create_subprocess_exec(
|
proc = await asyncio.create_subprocess_exec(
|
||||||
"moon",
|
"moon",
|
||||||
"run",
|
"run",
|
||||||
"src/bin/main.mbt",
|
"src/bin/main.mbt",
|
||||||
"--",
|
"--",
|
||||||
"--typecheck",
|
in_path,
|
||||||
filepath,
|
"-o",
|
||||||
|
out_path,
|
||||||
stdout=asyncio.subprocess.PIPE,
|
stdout=asyncio.subprocess.PIPE,
|
||||||
stderr=asyncio.subprocess.PIPE,
|
stderr=asyncio.subprocess.PIPE,
|
||||||
)
|
)
|
||||||
stdout, stderr = await proc.communicate()
|
stdout, stderr = await proc.communicate()
|
||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
print(f"""
|
print(f"""
|
||||||
[{proc.returncode}] Error in file {filepath}:
|
[{proc.returncode}] Error in file {in_path}:
|
||||||
======== STDOUT ========
|
======== STDOUT ========
|
||||||
{stdout.decode()}
|
{stdout.decode()}
|
||||||
======== STDERR ========
|
======== STDERR ========
|
||||||
{stderr.decode()}
|
{stderr.decode()}
|
||||||
""")
|
""")
|
||||||
else:
|
else:
|
||||||
print(f"File {filepath} compiled successfully.")
|
print(f"File {in_path} compiled successfully.")
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
tasks = []
|
tasks = []
|
||||||
for file in os.listdir("contest-2025-data/test_cases/mbt"):
|
for file in os.listdir("contest-2025-data/test_cases/mbt"):
|
||||||
if file.endswith(".mbt"):
|
if file.endswith(".mbt"):
|
||||||
filepath = os.path.join("contest-2025-data/test_cases/mbt", file)
|
in_path = os.path.join("contest-2025-data/test_cases/mbt", file)
|
||||||
tasks.append(check_file(filepath))
|
out_path = os.path.join("output/repo", file.replace(".mbt", ".s"))
|
||||||
|
tasks.append(check_file(in_path, out_path))
|
||||||
await asyncio.gather(*tasks)
|
await asyncio.gather(*tasks)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -485,7 +485,12 @@ pub fn parse_block_expr(
|
|||||||
}
|
}
|
||||||
break r
|
break r
|
||||||
} else if r is [RCurlyBracket, .. r] {
|
} else if r is [RCurlyBracket, .. r] {
|
||||||
stmts.push(Expr(Literal(Unit)))
|
// 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
|
break r
|
||||||
}
|
}
|
||||||
continue r
|
continue r
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ test "parse_block_expr" {
|
|||||||
RCurlyBracket,
|
RCurlyBracket,
|
||||||
EOF,
|
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,
|
RCurlyBracket,
|
||||||
EOF,
|
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,
|
LCurlyBracket,
|
||||||
IntLiteral(0),
|
IntLiteral(0),
|
||||||
Semicolon,
|
Semicolon,
|
||||||
|
LParen,
|
||||||
|
RParen,
|
||||||
RCurlyBracket,
|
RCurlyBracket,
|
||||||
EOF,
|
EOF,
|
||||||
]),
|
]),
|
||||||
|
|||||||
@@ -563,7 +563,7 @@ test "Block Expr TypeCheck Test" {
|
|||||||
// TypeCheck first block expr
|
// TypeCheck first block expr
|
||||||
let (block_expr1, tok_view) = @parser.parse_block_expr(tok_view)
|
let (block_expr1, tok_view) = @parser.parse_block_expr(tok_view)
|
||||||
let checked_block1 = ctx.check_block_expr(block_expr1)
|
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)
|
assert_true(checked_block1.ty is Unit)
|
||||||
// TypeCheck second block expr
|
// TypeCheck second block expr
|
||||||
let (block_expr2, tok_view) = @parser.parse_block_expr(tok_view)
|
let (block_expr2, tok_view) = @parser.parse_block_expr(tok_view)
|
||||||
|
|||||||
Reference in New Issue
Block a user