aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-21 05:43:35 +0000
committer_ov4 <ov4@ov4.org>2026-10-21 05:43:35 +0000
commitdd5bbae055fd34ce2e12ef63f8a261c6b15dc83e (patch)
tree757e367daacf92c50148eb42d7bda97ba33ed3fb /include
parentc682f983b0dce3acba76d1f08719a26b9c52c5ec (diff)
feat(parser): parse TEMPLATE declarations, template ids and parameter packs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'include')
-rw-r--r--include/cps/CodeGen.h3
-rw-r--r--include/cps/FunctionAST.h15
-rw-r--r--include/cps/Lexer.h1
-rw-r--r--include/cps/Parser.h7
-rw-r--r--include/cps/TemplateAST.h43
5 files changed, 65 insertions, 4 deletions
diff --git a/include/cps/CodeGen.h b/include/cps/CodeGen.h
index e6281c5..283c4b1 100644
--- a/include/cps/CodeGen.h
+++ b/include/cps/CodeGen.h
@@ -25,6 +25,7 @@ class MemoryHandler;
class ExceptionHandler;
class CastExprAST;
class NewExprAST;
+class TemplateDeclAST;
class CodeGen {
std::unique_ptr<llvm::LLVMContext> TheContext;
@@ -35,6 +36,8 @@ class CodeGen {
size_t CurrentUnit = 0;
size_t MainUnit = 0;
IdentifierMap<size_t> TypeOwners;
+ struct TemplateDefinition { TemplateDeclAST *Decl; size_t OwnerUnit; };
+ IdentifierMap<std::vector<TemplateDefinition>> Templates;
std::vector<IdentifierMap<SymbolInfo>> Exports;
bool isVisible(size_t Owner) const;
void selectUnit(size_t Unit);
diff --git a/include/cps/FunctionAST.h b/include/cps/FunctionAST.h
index 90ef5c4..9188015 100644
--- a/include/cps/FunctionAST.h
+++ b/include/cps/FunctionAST.h
@@ -23,6 +23,7 @@ struct ParamDecl {
int Rank = 0; // 0 = scalar
std::vector<std::pair<int64_t, int64_t>> DeclaredBounds;
int Line = 0;
+ bool IsPack = false;
};
class PrototypeAST {
@@ -87,25 +88,31 @@ public:
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
+ std::vector<std::string> TemplateArgs;
public:
- CallExprAST(const std::string &Callee, std::vector<std::unique_ptr<ExprAST>> Args, int Line)
- : ExprAST(Line), Callee(Callee), Args(std::move(Args)) {}
+ CallExprAST(const std::string &Callee, std::vector<std::unique_ptr<ExprAST>> Args, int Line,
+ std::vector<std::string> TemplateArgs = {})
+ : ExprAST(Line), Callee(Callee), Args(std::move(Args)), TemplateArgs(std::move(TemplateArgs)) {}
const std::string &getCallee() const { return Callee; }
const std::vector<std::unique_ptr<ExprAST>> &getArgs() const { return Args; }
+ const std::vector<std::string> &getTemplateArgs() const { return TemplateArgs; }
};
class CallStmtAST : public StmtAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
+ std::vector<std::string> TemplateArgs;
public:
- CallStmtAST(const std::string &Callee, std::vector<std::unique_ptr<ExprAST>> Args, int Line)
- : StmtAST(Line), Callee(Callee), Args(std::move(Args)) {}
+ CallStmtAST(const std::string &Callee, std::vector<std::unique_ptr<ExprAST>> Args, int Line,
+ std::vector<std::string> TemplateArgs = {})
+ : StmtAST(Line), Callee(Callee), Args(std::move(Args)), TemplateArgs(std::move(TemplateArgs)) {}
const std::string &getCallee() const { return Callee; }
const std::vector<std::unique_ptr<ExprAST>> &getArgs() const { return Args; }
+ const std::vector<std::string> &getTemplateArgs() const { return TemplateArgs; }
};
diff --git a/include/cps/Lexer.h b/include/cps/Lexer.h
index b514904..0ac2068 100644
--- a/include/cps/Lexer.h
+++ b/include/cps/Lexer.h
@@ -103,6 +103,7 @@ enum Token {
tok_c_string = -611,
tok_c_double = -612,
tok_new = -613, tok_delete = -614,
+ tok_template = -615,
tok_include = -650, tok_global = -651, tok_endglobal = -652,
tok_include_obj = -653, tok_extern = -654,
diff --git a/include/cps/Parser.h b/include/cps/Parser.h
index eedc3f8..f2c0868 100644
--- a/include/cps/Parser.h
+++ b/include/cps/Parser.h
@@ -4,6 +4,7 @@
#include "cps/AST.h"
#include "cps/TypeAST.h"
#include "cps/FunctionAST.h"
+#include "cps/TemplateAST.h"
#include <cstdint>
#include <vector>
#include <initializer_list>
@@ -23,6 +24,8 @@ class Parser {
std::vector<unsigned> CaseBodyDepths;
unsigned NumErrors = 0;
unsigned BlockDepth = 0; // ParseBlock nesting; 1 = top level
+ std::vector<TemplateParam> CurrentTemplate;
+ IdentifierSet PackNames;
std::map<int, int> BinopPrecedence;
IdentifierSet TypeNames = {
@@ -49,6 +52,9 @@ class Parser {
std::unique_ptr<MemberCallExprAST> ParseMemberCall(
const std::string &Name, std::vector<DesignatorAccess> Accesses, int Line);
std::string ParseTypeName(bool AllowVoid = false);
+ std::optional<std::vector<std::string>> ParseTemplateArgs();
+ bool isTemplateCall();
+ bool isTemplatePack(const std::string &Name) const;
std::unique_ptr<StmtAST> ParseStatement();
std::unique_ptr<StmtAST> ParseStatementImpl();
@@ -70,6 +76,7 @@ class Parser {
bool ParseDesignatorSuffix(std::vector<DesignatorAccess> &Out);
std::unique_ptr<StmtAST> ParseTypeDecl();
+ std::unique_ptr<StmtAST> ParseTemplateDecl();
std::optional<std::vector<RecordFieldDecl>> ParseRecordBody(
const std::string &Name, int Line, int EndToken,
std::vector<std::unique_ptr<FunctionDefAST>> *Methods = nullptr);
diff --git a/include/cps/TemplateAST.h b/include/cps/TemplateAST.h
new file mode 100644
index 0000000..c338b66
--- /dev/null
+++ b/include/cps/TemplateAST.h
@@ -0,0 +1,43 @@
+#pragma once
+#include "cps/FunctionAST.h"
+#include "cps/TypeAST.h"
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace cps {
+
+struct TemplateParam {
+ std::string Name;
+ bool IsPack = false;
+ int Line = 0;
+};
+
+class TemplateDeclAST : public StmtAST {
+ std::vector<TemplateParam> Params;
+ std::unique_ptr<FunctionDefAST> Function;
+ std::unique_ptr<ClassTypeDeclAST> Class;
+public:
+ TemplateDeclAST(std::vector<TemplateParam> Params, std::unique_ptr<FunctionDefAST> Function)
+ : Params(std::move(Params)), Function(std::move(Function)) {}
+ TemplateDeclAST(std::vector<TemplateParam> Params, std::unique_ptr<ClassTypeDeclAST> Class)
+ : Params(std::move(Params)), Class(std::move(Class)) {}
+ const auto &getParams() const { return Params; }
+ const std::string &getName() const {
+ return Function ? Function->getProto()->getName() : Class->getName();
+ }
+ bool isVariadic() const { return !Params.empty() && Params.back().IsPack; }
+ FunctionDefAST *getFunction() const { return Function.get(); }
+ ClassTypeDeclAST *getClass() const { return Class.get(); }
+};
+
+class PackExpansionExprAST : public ExprAST {
+ std::string Name;
+public:
+ PackExpansionExprAST(std::string Name, int Line)
+ : ExprAST(Line), Name(std::move(Name)) {}
+ const std::string &getName() const { return Name; }
+};
+
+} // namespace cps