diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-14 03:29:04 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-14 03:29:04 +0000 |
| commit | 699e18b65b07af73ccd14b28f83572b1843c7d37 (patch) | |
| tree | 98b98269e02eb9052b2af698383a858d63b120a7 /lib/CodeGen/CodeGen.cc | |
| parent | 3ef7f8b778dce23af25965b379126b9dd95d1c27 (diff) | |
feat(types): add native C scalar types and imported aliases
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen/CodeGen.cc')
| -rw-r--r-- | lib/CodeGen/CodeGen.cc | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/lib/CodeGen/CodeGen.cc b/lib/CodeGen/CodeGen.cc index f69fc03..8c01972 100644 --- a/lib/CodeGen/CodeGen.cc +++ b/lib/CodeGen/CodeGen.cc @@ -262,6 +262,7 @@ const TypeInfo *CodeGen::getExprTypeInfo(ExprAST *Expr) const { const TypeInfo *L = getExprTypeInfo(Bin->getLHS()); const TypeInfo *R = getExprTypeInfo(Bin->getRHS()); + if ((L && L->isC()) || (R && R->isC())) return nullptr; // Enum arithmetic: E +/- INTEGER (enum on the left) yields the enum; // every other user-kind combination has no type (emission rejects it). if ((L && L->isUserKind()) || (R && R->isUserKind())) { @@ -387,6 +388,8 @@ Value *CodeGen::coerceValueToType(Value *Val, const TypeInfo *TargetInfo) { case TypeKind::Enum: case TypeKind::Record: case TypeKind::Pointer: + case TypeKind::CScalar: + case TypeKind::CPointer: reportError("Internal: a %s value reached representation coercion without a name-level check", TargetInfo->Name.c_str()); return nullptr; @@ -507,6 +510,11 @@ void CodeGen::emitOutputValue(Value *Val, const TypeInfo *Info, bool AppendNewli reportError("Cannot OUTPUT a value of pointer type %s", Info->Name.c_str()); return; + case TypeKind::CScalar: + case TypeKind::CPointer: + reportError("OUTPUT is not supported for type %s", Info->Name.c_str()); + return; + case TypeKind::Void: reportError("Cannot OUTPUT a VOID value"); return; @@ -644,6 +652,10 @@ Value *CodeGen::emitExpr(ExprAST *Expr) { // '&' path: their admissible operations are decided by name here. const TypeInfo *LT = getExprTypeInfo(Bin->getLHS()); const TypeInfo *RT = getExprTypeInfo(Bin->getRHS()); + if ((LT && LT->isC()) || (RT && RT->isC())) { + reportError("C operators require explicit support for their operand types"); + return nullptr; + } if ((LT && LT->isUserKind()) || (RT && RT->isUserKind())) { return emitUserKindBinaryOp(Bin, LT, RT); } @@ -719,7 +731,7 @@ Value *CodeGen::emitExpr(ExprAST *Expr) { } if (Name == "ASC") { const TypeInfo *ArgType = getExprTypeInfo(Call->getArgs()[0].get()); - if (ArgType && ArgType->isUserKind()) { + if (ArgType && (ArgType->isUserKind() || ArgType->isC())) { reportError("ASC expects a CHAR or STRING (got %s)", ArgType->Name.c_str()); return nullptr; } @@ -747,7 +759,7 @@ Value *CodeGen::emitExpr(ExprAST *Expr) { } if (Name == "NUM_TO_STR") { const TypeInfo *ArgType = getExprTypeInfo(Call->getArgs()[0].get()); - if (ArgType && ArgType->isUserKind()) { + if (ArgType && (ArgType->isUserKind() || ArgType->isC())) { reportError("NUM_TO_STR expects a number (got %s)", ArgType->Name.c_str()); return nullptr; } @@ -850,7 +862,7 @@ bool CodeGen::marshalCallArgs(const std::string &Callee, return false; } // BYREF aliases the storage, so the types must match exactly. - if (Info->TypeName != TypeName) { + if (!Types->sameType(Info->TypeName, TypeName)) { reportError("BYREF argument %s to %s must be of type %s (got %s)", Var->getName().c_str(), Callee.c_str(), TypeName.c_str(), Info->TypeName.c_str()); @@ -1093,11 +1105,11 @@ void CodeGen::emitStmt(StmtAST *Stmt) { reportError("RETURN is only allowed inside a FUNCTION or PROCEDURE"); return; } - if (Sig->ReturnTypeName == "VOID" && Ret->getRetVal()) { + if (F->getReturnType()->isVoidTy() && Ret->getRetVal()) { reportError("RETURN with a value is only allowed in a FUNCTION"); return; } - if (Sig->ReturnTypeName != "VOID" && !Ret->getRetVal()) { + if (!F->getReturnType()->isVoidTy() && !Ret->getRetVal()) { reportError("RETURN in a FUNCTION requires a value"); return; } @@ -1293,7 +1305,7 @@ void CodeGen::emitStmt(StmtAST *Stmt) { // TYPE declarations are registered by compile()'s pre-pass (the parser // guarantees they are top-level); nothing is emitted here. if (dynamic_cast<EnumTypeDeclAST*>(Stmt) || dynamic_cast<PointerTypeDeclAST*>(Stmt) || - dynamic_cast<RecordTypeDeclAST*>(Stmt)) { + dynamic_cast<RecordTypeDeclAST*>(Stmt) || dynamic_cast<CTypeDeclAST*>(Stmt)) { return; } if (auto *DA = dynamic_cast<DesignatorAssignStmtAST*>(Stmt)) { |
