aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-07-26 17:21:14 +0000
committer_ov4 <ov4@ov4.org>2026-07-26 17:21:14 +0000
commit3366a2e0fae05d9e792169e74471c7282bf18681 (patch)
tree0cc4cacdac7d32ee7671d6799c52f74953c2007e /lib/CodeGen
parent0fef2986daa2945c9e3d050c0f750d56792b30bd (diff)
feat: TYPE-system front end — tokens, designators, ParamDecl grammar
- Reserve TYPE/ENDTYPE/SET/DEFINE (-600 token block); SET/DEFINE parse to dedicated not-implemented errors (RANDOM precedent). - New TypeAST.h: enum/pointer/record decl nodes, designator chain (DesignatorExprAST + Index/Field/Deref accessors), AddrOfExprAST, DesignatorAssignStmtAST. Bare-name and single-index shapes degrade to their legacy nodes, so existing programs produce identical ASTs. - ParserType.cc: TYPE declarations (top-level only, enforced via a ParseBlock depth counter), DECLARE-only record bodies with local field-level error recovery. - Postfix [ ] . ^ chain in ParseIdentifierExpr; prefix ^ (address-of, designator operand only) in ParseUnary; assignment targets rebuilt on the same suffix parser. - Parameters: ParamDecl{name, type, mode, array rank/bounds} replaces the (name, type, byref) tuple. Pass mode is sticky across parameters and BYREF is rejected in FUNCTIONs, both per guide §8.3 (the old per-param reset made the guide's own SWAP example pass Y by value). ARRAY OF T / ARRAY[l:u,...] OF T parameter syntax parses; codegen rejects it until the parameter-passing phase lands. - CodeGen stubs report clear not-implemented errors for the new nodes so nothing is silently ignored. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CodeGen.cc18
-rw-r--r--lib/CodeGen/FunctionGen.cc41
2 files changed, 40 insertions, 19 deletions
diff --git a/lib/CodeGen/CodeGen.cc b/lib/CodeGen/CodeGen.cc
index 4b9ebfb..8940e63 100644
--- a/lib/CodeGen/CodeGen.cc
+++ b/lib/CodeGen/CodeGen.cc
@@ -3,6 +3,7 @@
#include "cps/FileAST.h"
#include "cps/FileHandler.h"
#include "cps/Lexer.h"
+#include "cps/TypeAST.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Verifier.h"
#include <cstdarg>
@@ -619,6 +620,12 @@ Value *CodeGen::emitExpr(ExprAST *Expr) {
return FuncGen->emitCallExpr(Call, Args);
}
+ // TYPE-system stubs: parsed but not yet wired (phases C/D/E of the TYPE work).
+ if (dynamic_cast<DesignatorExprAST*>(Expr) || dynamic_cast<AddrOfExprAST*>(Expr)) {
+ reportError("Record field / pointer expressions are not implemented yet");
+ return nullptr;
+ }
+
return nullptr;
}
@@ -1039,4 +1046,15 @@ void CodeGen::emitStmt(StmtAST *Stmt) {
emitForStmt(ForStmt);
return;
}
+
+ // TYPE-system stubs: parsed but not yet wired (phases C/D of the TYPE work).
+ if (dynamic_cast<EnumTypeDeclAST*>(Stmt) || dynamic_cast<PointerTypeDeclAST*>(Stmt) ||
+ dynamic_cast<RecordTypeDeclAST*>(Stmt)) {
+ reportError("TYPE declarations are not implemented yet");
+ return;
+ }
+ if (dynamic_cast<DesignatorAssignStmtAST*>(Stmt)) {
+ reportError("Assignment to record fields / pointer targets is not implemented yet");
+ return;
+ }
}
diff --git a/lib/CodeGen/FunctionGen.cc b/lib/CodeGen/FunctionGen.cc
index df0a8b6..dc238b5 100644
--- a/lib/CodeGen/FunctionGen.cc
+++ b/lib/CodeGen/FunctionGen.cc
@@ -31,27 +31,24 @@ Type *FunctionGen::getLLVMType(const std::string &TypeName) {
return Resolved;
}
-void FunctionGen::createArgumentAllocas(Function *F, const std::vector<std::tuple<std::string, std::string, bool>> &Args) {
+void FunctionGen::createArgumentAllocas(Function *F, const std::vector<ParamDecl> &Params) {
Function::arg_iterator AI = F->arg_begin();
- for (unsigned Idx = 0, E = Args.size(); Idx != E; ++Idx, ++AI) {
- std::string ArgName = std::get<0>(Args[Idx]);
- std::string ArgTypeStr = std::get<1>(Args[Idx]);
- bool IsRef = std::get<2>(Args[Idx]);
-
+ for (const ParamDecl &P : Params) {
Value *ArgVal = &(*AI);
- ArgVal->setName(ArgName);
+ ++AI;
+ ArgVal->setName(P.Name);
- if (IsRef) {
- Symbols[ArgName] = {ArgVal, ArgTypeStr, false};
+ if (P.Mode == PassMode::ByRef) {
+ Symbols[P.Name] = {ArgVal, P.TypeName, false};
continue;
}
- Type *ArgType = getLLVMType(ArgTypeStr);
+ Type *ArgType = getLLVMType(P.TypeName);
IRBuilder<> TmpB(&F->getEntryBlock(), F->getEntryBlock().begin());
- AllocaInst *Alloca = TmpB.CreateAlloca(ArgType, nullptr, ArgName);
+ AllocaInst *Alloca = TmpB.CreateAlloca(ArgType, nullptr, P.Name);
Builder.CreateStore(ArgVal, Alloca);
- Symbols[ArgName] = {Alloca, ArgTypeStr, false};
+ Symbols[P.Name] = {Alloca, P.TypeName, false};
}
}
@@ -78,13 +75,19 @@ Function *FunctionGen::emitPrototype(PrototypeAST *Proto) {
Sig.ReturnTypeName = Proto->getReturnType();
std::vector<Type*> ArgTypes;
- for (const auto &Arg : Proto->getArgs()) {
- Type *T = getLLVMType(std::get<1>(Arg));
- if (std::get<2>(Arg)) {
+ for (const ParamDecl &P : Proto->getParams()) {
+ if (P.IsArray) {
+ fprintf(stderr, "Error: Array parameters are not implemented yet (parameter '%s' of %s)\n",
+ P.Name.c_str(), Proto->getName().c_str());
+ HadError = true;
+ return nullptr;
+ }
+ Type *T = getLLVMType(P.TypeName);
+ if (P.Mode == PassMode::ByRef) {
T = T->getPointerTo();
}
ArgTypes.push_back(T);
- Sig.Params.emplace_back(std::get<1>(Arg), std::get<2>(Arg));
+ Sig.Params.emplace_back(P.TypeName, P.Mode == PassMode::ByRef);
}
Type *RetType = getLLVMType(Proto->getReturnType());
@@ -106,8 +109,8 @@ Function *FunctionGen::emitPrototype(PrototypeAST *Proto) {
unsigned Idx = 0;
for (auto &Arg : F->args()) {
- if (Idx < Proto->getArgs().size()) {
- Arg.setName(std::get<0>(Proto->getArgs()[Idx++]));
+ if (Idx < Proto->getParams().size()) {
+ Arg.setName(Proto->getParams()[Idx++].Name);
}
}
return F;
@@ -131,7 +134,7 @@ Function *FunctionGen::emitFunctionDef(FunctionDefAST *FuncAST,
std::map<std::string, SymbolInfo> OldSymbols = Symbols;
Symbols.clear();
- createArgumentAllocas(TheFunction, Proto->getArgs());
+ createArgumentAllocas(TheFunction, Proto->getParams());
for (const auto &Stmt : FuncAST->getBody()) {
StmtEmitter(Stmt.get());