refactor(ast2ir): 移除废弃的ABI依赖并优化类型转换处理
移除了对scc_abi包的依赖,将相关头文件从libs/abi移动到libs/ast2ir目录下。 重构了基本类型解析功能,将parse_base_type函数提取为独立的 scc_ast2ir_parse_base_type实现,并支持有符号/无符号类型区分。 feat(ast2ir): 实现整数常量表达式求值器 新增了完整的整数常量表达式求值功能,支持C11标准中的常量表达式规则, 包括字面量、标识符、sizeof/_Alignof、一元/二元运算、条件表达式和 类型转换等操作。该功能用于数组大小和枚举值的编译期计算验证。 refactor(ast2ir): 完善类型提升和算术转换机制 改进了整数提升和寻常算术转换的实现,修复了移位操作的符号处理问题, 添加了无符号比较操作的支持,增强了类型安全检查,统一了错误处理流程。 fix(ast2ir): 修复赋值表达式返回值和数组大小计算问题 修正了赋值表达式的返回值处理,确保返回右侧值而不是存储指令引用。 使用新的常量表达式求值器替代原有的硬编码数组大小计算,提高了 数组声明的正确性。
This commit is contained in:
@@ -7,6 +7,7 @@ executes the resulting binary, and validates the process return code or stdout.
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import difflib
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
@@ -23,7 +24,8 @@ from typing import Sequence
|
||||
# Configuration
|
||||
# ---------------------------------------------------------------------------
|
||||
WORKSPACE = Path(__file__).resolve().parent
|
||||
CC_PATH = WORKSPACE / "../../build/dev/scc"
|
||||
CC_ROOT = WORKSPACE / "../.."
|
||||
CC_PATH = CC_ROOT / "build/dev/scc"
|
||||
CONFIG_PATH = WORKSPACE / "expect.toml"
|
||||
DEFAULT_TIMEOUT = 1 # seconds
|
||||
|
||||
@@ -99,8 +101,15 @@ class Runner:
|
||||
text=True,
|
||||
timeout=self.timeout,
|
||||
)
|
||||
except subprocess.TimeoutExpired:
|
||||
return False, "Compilation timed out"
|
||||
except subprocess.TimeoutExpired as e:
|
||||
# e.stdout, e.stderr 为已捕获的部分输出(字符串)
|
||||
captured_stderr = e.stderr.strip() if e.stderr else ""
|
||||
captured_stdout = e.stdout.strip() if e.stdout else ""
|
||||
err_msg = f"""Compilation timed out.
|
||||
stderr: {captured_stderr or '(no output)'}
|
||||
stdout: {captured_stdout or '(no output)'}
|
||||
cmd: {" ".join(cmd)}"""
|
||||
return False, err_msg
|
||||
except OSError as exc:
|
||||
return False, f"Failed to invoke compiler: {exc}"
|
||||
|
||||
@@ -127,6 +136,26 @@ class Runner:
|
||||
|
||||
return proc.returncode, proc.stdout, proc.stderr.strip()
|
||||
|
||||
def _print_diff(self, expected: str, actual: str) -> None:
|
||||
"""Print unified diff between expected and actual stdout."""
|
||||
expected_lines = expected.splitlines()
|
||||
actual_lines = actual.splitlines()
|
||||
diff = difflib.unified_diff(
|
||||
expected_lines, actual_lines,
|
||||
fromfile='expected', tofile='actual',
|
||||
lineterm=''
|
||||
)
|
||||
# diff = difflib.ndiff(
|
||||
# expected_lines, actual_lines,
|
||||
# )
|
||||
diff_lines = list(diff)
|
||||
if not diff_lines:
|
||||
logger.error(" Strings differ but no diff generated?")
|
||||
return
|
||||
logger.error(" Diff (expected vs actual):")
|
||||
for line in diff_lines:
|
||||
logger.error(" %s", line)
|
||||
|
||||
def run_one(self, test: TestCase) -> bool:
|
||||
"""Run a single test case. Returns True if passed."""
|
||||
logger.info("Testing %s", test.source)
|
||||
@@ -157,9 +186,14 @@ class Runner:
|
||||
if passed:
|
||||
logger.info(" PASSED")
|
||||
else:
|
||||
logger.error(
|
||||
" FAILED: expected %r, got %r", test.expected, actual
|
||||
)
|
||||
if test.test_type == "stdout":
|
||||
logger.error(" FAILED: stdout mismatch")
|
||||
self._print_diff(test.expected, actual)
|
||||
else:
|
||||
logger.error(
|
||||
" FAILED: expected return code %r, got %r",
|
||||
test.expected, actual
|
||||
)
|
||||
|
||||
# 4. Cleanup
|
||||
self._remove(exe_path)
|
||||
@@ -326,12 +360,12 @@ def main() -> None:
|
||||
|
||||
runner = Runner(
|
||||
cc=args.cc,
|
||||
workspace=WORKSPACE,
|
||||
workspace=CC_ROOT,
|
||||
timeout=args.timeout,
|
||||
keep_temps=args.keep_temps,
|
||||
)
|
||||
|
||||
global_timeout = DEFAULT_TIMEOUT * 3
|
||||
global_timeout = args.timeout * 3
|
||||
passed, total = runner.run_all(selected, global_timeout)
|
||||
logger.info("=" * 40)
|
||||
if global_timeout and total < len(selected):
|
||||
|
||||
Reference in New Issue
Block a user