From dd5bbae055fd34ce2e12ef63f8a261c6b15dc83e Mon Sep 17 00:00:00 2001 From: _ov4 Date: Wed, 21 Oct 2026 05:43:35 +0000 Subject: feat(parser): parse TEMPLATE declarations, template ids and parameter packs Co-Authored-By: Claude Opus 5.5 --- include/cps/CodeGen.h | 3 +++ include/cps/FunctionAST.h | 15 +++++++++++---- include/cps/Lexer.h | 1 + include/cps/Parser.h | 7 +++++++ include/cps/TemplateAST.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 include/cps/TemplateAST.h (limited to 'include/cps') 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 TheContext; @@ -35,6 +36,8 @@ class CodeGen { size_t CurrentUnit = 0; size_t MainUnit = 0; IdentifierMap TypeOwners; + struct TemplateDefinition { TemplateDeclAST *Decl; size_t OwnerUnit; }; + IdentifierMap> Templates; std::vector> 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> DeclaredBounds; int Line = 0; + bool IsPack = false; }; class PrototypeAST { @@ -87,25 +88,31 @@ public: class CallExprAST : public ExprAST { std::string Callee; std::vector> Args; + std::vector TemplateArgs; public: - CallExprAST(const std::string &Callee, std::vector> Args, int Line) - : ExprAST(Line), Callee(Callee), Args(std::move(Args)) {} + CallExprAST(const std::string &Callee, std::vector> Args, int Line, + std::vector TemplateArgs = {}) + : ExprAST(Line), Callee(Callee), Args(std::move(Args)), TemplateArgs(std::move(TemplateArgs)) {} const std::string &getCallee() const { return Callee; } const std::vector> &getArgs() const { return Args; } + const std::vector &getTemplateArgs() const { return TemplateArgs; } }; class CallStmtAST : public StmtAST { std::string Callee; std::vector> Args; + std::vector TemplateArgs; public: - CallStmtAST(const std::string &Callee, std::vector> Args, int Line) - : StmtAST(Line), Callee(Callee), Args(std::move(Args)) {} + CallStmtAST(const std::string &Callee, std::vector> Args, int Line, + std::vector TemplateArgs = {}) + : StmtAST(Line), Callee(Callee), Args(std::move(Args)), TemplateArgs(std::move(TemplateArgs)) {} const std::string &getCallee() const { return Callee; } const std::vector> &getArgs() const { return Args; } + const std::vector &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 #include #include @@ -23,6 +24,8 @@ class Parser { std::vector CaseBodyDepths; unsigned NumErrors = 0; unsigned BlockDepth = 0; // ParseBlock nesting; 1 = top level + std::vector CurrentTemplate; + IdentifierSet PackNames; std::map BinopPrecedence; IdentifierSet TypeNames = { @@ -49,6 +52,9 @@ class Parser { std::unique_ptr ParseMemberCall( const std::string &Name, std::vector Accesses, int Line); std::string ParseTypeName(bool AllowVoid = false); + std::optional> ParseTemplateArgs(); + bool isTemplateCall(); + bool isTemplatePack(const std::string &Name) const; std::unique_ptr ParseStatement(); std::unique_ptr ParseStatementImpl(); @@ -70,6 +76,7 @@ class Parser { bool ParseDesignatorSuffix(std::vector &Out); std::unique_ptr ParseTypeDecl(); + std::unique_ptr ParseTemplateDecl(); std::optional> ParseRecordBody( const std::string &Name, int Line, int EndToken, std::vector> *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 +#include +#include +#include + +namespace cps { + +struct TemplateParam { + std::string Name; + bool IsPack = false; + int Line = 0; +}; + +class TemplateDeclAST : public StmtAST { + std::vector Params; + std::unique_ptr Function; + std::unique_ptr Class; +public: + TemplateDeclAST(std::vector Params, std::unique_ptr Function) + : Params(std::move(Params)), Function(std::move(Function)) {} + TemplateDeclAST(std::vector Params, std::unique_ptr 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 -- cgit v1.3.1-4-g156e