diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-18 06:05:53 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-18 06:05:53 +0000 |
| commit | 16231050058131860f710073c17d3bca7c6637eb (patch) | |
| tree | 1da2ca606f1d513822ccd04b3053d5eee69ac19d /lib/CodeGen/FunctionGen.cc | |
| parent | 1b0b287629e6e3b6d8eb6182db72b28fd0510574 (diff) | |
feat(operators): support global binary operator overloads
Resolve exact operand types and preserve declared operator return types.
Reject implicit STRING to BOOLEAN conversion at typed expression boundaries.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen/FunctionGen.cc')
| -rw-r--r-- | lib/CodeGen/FunctionGen.cc | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/lib/CodeGen/FunctionGen.cc b/lib/CodeGen/FunctionGen.cc index 9559717..bccf397 100644 --- a/lib/CodeGen/FunctionGen.cc +++ b/lib/CodeGen/FunctionGen.cc @@ -2,6 +2,7 @@ #include "cps/FunctionGen.h" #include "cps/CodeGen.h" #include "cps/ExceptionHandler.h" +#include "cps/Operator.h" #include <cstdio> #include <cstdarg> @@ -122,6 +123,28 @@ const FuncSig *FunctionGen::getSignatureByLink(const std::string &Name) const { Function *FunctionGen::emitPrototype(PrototypeAST *Proto) { auto Registered = PrototypeLinks.find(Proto); if (Registered != PrototypeLinks.end()) return Module.getFunction(Registered->second); + if (int Op = Proto->getOperator()) { + size_t Count = Proto->getParams().size() + !Proto->getOwnerClass().empty(); + bool ValidCount = Op == '-' ? Count == 1 || Count == 2 + : Op == tok_not ? Count == 1 : Count == 2; + if (!ValidCount) { + reportError("Invalid operand count for %s", Proto->getName().c_str()); + return nullptr; + } + bool HasUserOperand = !Proto->getOwnerClass().empty(); + for (const auto &P : Proto->getParams()) { + if (P.IsArray) { + reportError("An operator parameter cannot be a whole array"); + return nullptr; + } + const TypeInfo *T = Types.resolve(P.TypeName); + HasUserOperand |= T && (T->isRecord() || T->isEnum()); + } + if (!HasUserOperand) { + reportError("%s requires a record, class or enum operand", Proto->getName().c_str()); + return nullptr; + } + } if (Proto->isOverload() && Proto->getOwnerClass().empty() && sameIdentifier(Proto->getName(), "MAIN")) { reportError("MAIN cannot be declared OVERLOAD"); return nullptr; |
