From b19a61aabf9dadd243b3d5b7087fba717c5c1e62 Mon Sep 17 00:00:00 2001 From: chentianya Date: Wed, 26 Aug 2026 09:40:12 +0800 Subject: [PATCH] =?UTF-8?q?=E9=98=B6=E6=AE=B53-4=EF=BC=9A=E6=96=B0?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E8=BF=90=E7=AE=97=E9=AA=8C=E8=AF=81=20+=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=88011=20=E5=89=8D=E7=BC=80=E4=BD=8D?= =?UTF-8?q?=E3=80=81func=20=E5=A4=A7=E5=B0=8F=E5=86=99=E3=80=81=E4=BD=8D?= =?UTF-8?q?=E4=B8=B2=20AND/OR=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新类型运算验证(综合用例全部正确): - 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)。 --- compiler/src/Codec.cpp | 2 +- compiler/src/Codegen.cpp | 8 ++++++-- compiler/src/Typecheck.cpp | 25 ++++++++++++++++++++----- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/compiler/src/Codec.cpp b/compiler/src/Codec.cpp index 342fa13..d0ef983 100644 --- a/compiler/src/Codec.cpp +++ b/compiler/src/Codec.cpp @@ -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(0x80 | (op & 0x3F)); // bit7..6 = 10 } else if (prefix == "011") { - out[0] = static_cast(0x40 | (op & 0x1F)); + out[0] = static_cast(0x60 | (op & 0x1F)); // bit7..5 = 011 } else if (prefix.size() == 6 && prefix.compare(0, 3, "010") == 0) { const uint32_t shape = static_cast(prefix[3] - '0') * 4 + static_cast(prefix[4] - '0') * 2 + diff --git a/compiler/src/Codegen.cpp b/compiler/src/Codegen.cpp index f4a824c..adf92a6 100644 --- a/compiler/src/Codegen.cpp +++ b/compiler/src/Codegen.cpp @@ -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(std::toupper(static_cast(ch))); + } + const ConfigType* t = cfg_.find_type(key); return t ? static_cast(t->func) : 0; } diff --git a/compiler/src/Typecheck.cpp b/compiler/src/Typecheck.cpp index 50f652f..beae691 100644 --- a/compiler/src/Typecheck.cpp +++ b/compiler/src/Typecheck.cpp @@ -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: {