diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-21 05:43:35 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-21 05:43:35 +0000 |
| commit | dd5bbae055fd34ce2e12ef63f8a261c6b15dc83e (patch) | |
| tree | 757e367daacf92c50148eb42d7bda97ba33ed3fb /include | |
| parent | c682f983b0dce3acba76d1f08719a26b9c52c5ec (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.h | 3 | ||||
| -rw-r--r-- | include/cps/FunctionAST.h | 15 | ||||
| -rw-r--r-- | include/cps/Lexer.h | 1 | ||||
| -rw-r--r-- | include/cps/Parser.h | 7 | ||||
| -rw-r--r-- | include/cps/TemplateAST.h | 43 |
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 |
