阶段3-4:新类型运算验证 + 修复(011 前缀位、func 大小写、位串 AND/OR)
新类型运算验证(综合用例全部正确): - REAL 算术 ADD.F32、LREAL 算术 ADD.F64 - TIME+ ADD.I64、TIME 比较 CMP_GT.I64 - DATE/TOD/DT 比较 CMP_GT.U32/U32/U64 - DINT 算术 ADD.I32、UDINT 字面量装载+截断 - WORD 位串 AND(短路 JF+MOVE) - 负例:UINT 溢出拦截 修复的 bug: 1. set_byte0 '011' 分支 0x40→0x60(RRR 指令被误判为 010 区, ADD 等显示错乱)——阶段 2 遗留 2. Codegen func_of_name 大小写不敏感(符号表小写/type 表大写, 否则 REAL 等返回 func 0) 3. Typecheck AND/OR 支持位串(BOOL 逻辑或 bit 按宽度逐位) 已知缺陷(记录):LREAL 字面量装载按 REAL(LOADK.F32), ADD.F64 运算位模式错位——需 compile_expr 携带目标 func(TODO)。
This commit is contained in:
@@ -209,7 +209,7 @@ void set_byte0(uint8_t* out, const std::string& prefix, uint32_t op) {
|
||||
} else if (prefix == "10") {
|
||||
out[0] = static_cast<uint8_t>(0x80 | (op & 0x3F)); // bit7..6 = 10
|
||||
} else if (prefix == "011") {
|
||||
out[0] = static_cast<uint8_t>(0x40 | (op & 0x1F));
|
||||
out[0] = static_cast<uint8_t>(0x60 | (op & 0x1F)); // bit7..5 = 011
|
||||
} else if (prefix.size() == 6 && prefix.compare(0, 3, "010") == 0) {
|
||||
const uint32_t shape = static_cast<uint32_t>(prefix[3] - '0') * 4 +
|
||||
static_cast<uint32_t>(prefix[4] - '0') * 2 +
|
||||
|
||||
@@ -211,9 +211,13 @@ namespace {
|
||||
return s;
|
||||
}
|
||||
|
||||
/// 语言类型名 → func 位段值(MachineConfig 强校验保证存在)。
|
||||
/// 语言类型名 → func 位段值(大小写不敏感:符号表存小写,type 表存大写)。
|
||||
uint8_t func_of_name(const std::string& type_name) const {
|
||||
const ConfigType* t = cfg_.find_type(type_name);
|
||||
std::string key = type_name;
|
||||
for (char& ch : key) {
|
||||
ch = static_cast<char>(std::toupper(static_cast<unsigned char>(ch)));
|
||||
}
|
||||
const ConfigType* t = cfg_.find_type(key);
|
||||
return t ? static_cast<uint8_t>(t->func) : 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -540,12 +540,27 @@ namespace {
|
||||
if (!check_expr(file, sc, *e.lhs, &l) || !check_expr(file, sc, *e.rhs, &r)) {
|
||||
return false;
|
||||
}
|
||||
if (!resolve_to(file, *e.lhs, l, TType::Bool) ||
|
||||
!resolve_to(file, *e.rhs, r, TType::Bool)) {
|
||||
const char* op = (e.kind == ExprKind::And) ? "AND" : "OR";
|
||||
return fail(file, std::string(op) + " operands must be BOOL");
|
||||
const char* op = (e.kind == ExprKind::And) ? "AND" : "OR";
|
||||
// 两侧都是未定型字面量 → BOOL 逻辑(TRUE/FALSE 或 0/1)
|
||||
if (l == TType::Unresolved && r == TType::Unresolved) {
|
||||
if (!resolve_to(file, *e.lhs, l, TType::Bool) ||
|
||||
!resolve_to(file, *e.rhs, r, TType::Bool)) {
|
||||
return fail(file, std::string(op) + " operands must be BOOL");
|
||||
}
|
||||
*out = TType::Bool;
|
||||
return true;
|
||||
}
|
||||
*out = TType::Bool;
|
||||
// 同型定型;允许 BOOL(逻辑)或位串(按宽度逐位)
|
||||
const TType want = (l == TType::Unresolved) ? r : l;
|
||||
if (!resolve_to(file, *e.lhs, l, want) ||
|
||||
!resolve_to(file, *e.rhs, r, want)) {
|
||||
return fail(file, std::string(op) + " operands must have same type");
|
||||
}
|
||||
const TypeMeta tm = type_meta(cfg_, tname_lower(want));
|
||||
if (want != TType::Bool && (!tm || tm.kind() != "bit")) {
|
||||
return fail(file, std::string(op) + " operands must be BOOL or bit-string");
|
||||
}
|
||||
*out = want;
|
||||
return true;
|
||||
}
|
||||
case ExprKind::Cmp: {
|
||||
|
||||
Reference in New Issue
Block a user