aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-17 06:02:21 +0000
committer_ov4 <ov4@ov4.org>2026-10-17 06:02:21 +0000
commit3425b95cb654f8e1adc98365a4b370aa1fff8b4d (patch)
tree4d81b91d0bd807cd6f7ced037533d6e60f5c307f /include
parent4e22f464387725a5a282f3d72e11cfb694a31a5a (diff)
feat(classes): support ordinary member methods and this references
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat (limited to 'include')
-rw-r--r--include/cps/CodeGen.h4
-rw-r--r--include/cps/FunctionAST.h32
-rw-r--r--include/cps/FunctionGen.h2
-rw-r--r--include/cps/Parser.h9
-rw-r--r--include/cps/TypeAST.h10
5 files changed, 48 insertions, 9 deletions
diff --git a/include/cps/CodeGen.h b/include/cps/CodeGen.h
index 94aacb7..1c80434 100644
--- a/include/cps/CodeGen.h
+++ b/include/cps/CodeGen.h
@@ -32,6 +32,10 @@ class CodeGen {
std::unique_ptr<llvm::IRBuilder<>> Builder;
int DiagnosticLine = 0;
IdentifierMap<SymbolInfo> Symbols;
+ IdentifierMap<IdentifierMap<FunctionDefAST*>> ClassMethods;
+ std::string CurrentClass;
+ const PrototypeAST *findMethod(const std::string &Class, const std::string &Name) const;
+ llvm::Value *emitMemberCall(MemberCallExprAST *Call);
struct ConstantScope {
unsigned ID;
IdentifierMap<std::optional<SymbolInfo>> Saved;
diff --git a/include/cps/FunctionAST.h b/include/cps/FunctionAST.h
index 0c2d0b5..16057e5 100644
--- a/include/cps/FunctionAST.h
+++ b/include/cps/FunctionAST.h
@@ -28,18 +28,24 @@ class PrototypeAST {
std::vector<ParamDecl> Params;
std::string ReturnType;
bool IsExternal;
+ std::string OwnerClass;
+ bool IsPublic;
public:
PrototypeAST(const std::string &Name,
std::vector<ParamDecl> Params,
const std::string &ReturnType,
- bool IsExternal = false)
- : Name(Name), Params(std::move(Params)), ReturnType(ReturnType), IsExternal(IsExternal) {}
+ bool IsExternal = false, std::string OwnerClass = {}, bool IsPublic = true)
+ : Name(Name), Params(std::move(Params)), ReturnType(ReturnType), IsExternal(IsExternal),
+ OwnerClass(std::move(OwnerClass)), IsPublic(IsPublic) {}
const std::string &getName() const { return Name; }
const std::vector<ParamDecl> &getParams() const { return Params; }
const std::string &getReturnType() const { return ReturnType; }
bool isExternal() const { return IsExternal; }
+ const std::string &getOwnerClass() const { return OwnerClass; }
+ bool isPublic() const { return IsPublic; }
+ std::string getLinkName() const { return OwnerClass.empty() ? Name : OwnerClass + "." + Name; }
};
class FunctionDefAST : public StmtAST {
@@ -80,6 +86,28 @@ public:
};
+// A member call keeps the receiver separate from explicit arguments.
+class MemberCallExprAST : public ExprAST {
+ std::unique_ptr<ExprAST> Receiver;
+ std::string Method;
+ std::vector<std::unique_ptr<ExprAST>> Args;
+public:
+ MemberCallExprAST(std::unique_ptr<ExprAST> Receiver, std::string Method,
+ std::vector<std::unique_ptr<ExprAST>> Args, int Line)
+ : ExprAST(Line), Receiver(std::move(Receiver)), Method(std::move(Method)), Args(std::move(Args)) {}
+ ExprAST *getReceiver() const { return Receiver.get(); }
+ const std::string &getMethod() const { return Method; }
+ const std::vector<std::unique_ptr<ExprAST>> &getArgs() const { return Args; }
+};
+
+class MemberCallStmtAST : public StmtAST {
+ std::unique_ptr<MemberCallExprAST> Call;
+public:
+ explicit MemberCallStmtAST(std::unique_ptr<MemberCallExprAST> Call)
+ : StmtAST(Call->getLine()), Call(std::move(Call)) {}
+ MemberCallExprAST *getCall() const { return Call.get(); }
+};
+
class ReturnStmtAST : public StmtAST {
std::unique_ptr<ExprAST> RetVal;
diff --git a/include/cps/FunctionGen.h b/include/cps/FunctionGen.h
index fd874d2..5ff746d 100644
--- a/include/cps/FunctionGen.h
+++ b/include/cps/FunctionGen.h
@@ -65,7 +65,7 @@ private:
IdentifierMap<FuncSig> Signatures;
ArrayParamBinder BindArrayParam;
- void createArgumentAllocas(llvm::Function *F, const std::vector<ParamDecl> &Params);
+ void createArgumentAllocas(llvm::Function *F, const std::vector<ParamDecl> &Params, bool IsMethod);
public:
FunctionGen(llvm::LLVMContext &C,
diff --git a/include/cps/Parser.h b/include/cps/Parser.h
index fdbb99a..4874d7a 100644
--- a/include/cps/Parser.h
+++ b/include/cps/Parser.h
@@ -43,6 +43,8 @@ class Parser {
std::unique_ptr<ExprAST> ParseNumberExpr();
std::unique_ptr<ExprAST> ParseIdentifierExpr();
std::unique_ptr<ExprAST> ParseParenExpr();
+ std::unique_ptr<MemberCallExprAST> ParseMemberCall(
+ const std::string &Name, std::vector<DesignatorAccess> Accesses, int Line);
std::string ParseTypeName(bool AllowVoid = false);
std::unique_ptr<StmtAST> ParseStatement();
@@ -66,11 +68,12 @@ class Parser {
std::unique_ptr<StmtAST> ParseTypeDecl();
std::optional<std::vector<RecordFieldDecl>> ParseRecordBody(
- const std::string &Name, int Line, int EndToken);
+ const std::string &Name, int Line, int EndToken,
+ std::vector<std::unique_ptr<FunctionDefAST>> *Methods = nullptr);
bool ParseRecordField(std::vector<RecordFieldDecl> &Out, bool IsPublic);
- std::unique_ptr<StmtAST> ParseFunction();
- std::unique_ptr<StmtAST> ParseProcedure();
+ std::unique_ptr<FunctionDefAST> ParseFunction(const std::string &OwnerClass = {}, bool IsPublic = true);
+ std::unique_ptr<FunctionDefAST> ParseProcedure(const std::string &OwnerClass = {}, bool IsPublic = true);
std::unique_ptr<StmtAST> ParseCallStmt();
std::unique_ptr<StmtAST> ParseReturnStmt();
std::optional<std::vector<ParamDecl>> ParsePrototypeArgs(bool AllowByRef);
diff --git a/include/cps/TypeAST.h b/include/cps/TypeAST.h
index edf2ee5..de5d12c 100644
--- a/include/cps/TypeAST.h
+++ b/include/cps/TypeAST.h
@@ -1,5 +1,6 @@
#pragma once
#include "cps/AST.h"
+#include "cps/FunctionAST.h"
#include <cstdint>
#include <memory>
#include <string>
@@ -81,12 +82,15 @@ public:
const std::vector<RecordFieldDecl> &getFields() const { return Fields; }
};
-// CLASS <name> with default-public or explicit PUBLIC/PRIVATE fields, ending in ENDCLASS.
+// CLASS <name> with default-public or explicit PUBLIC/PRIVATE members, ending in ENDCLASS.
// Storage and value semantics are inherited from record declarations.
class ClassTypeDeclAST : public RecordTypeDeclAST {
+ std::vector<std::unique_ptr<FunctionDefAST>> Methods;
public:
- ClassTypeDeclAST(const std::string &Name, std::vector<RecordFieldDecl> Fields)
- : RecordTypeDeclAST(Name, std::move(Fields)) {}
+ ClassTypeDeclAST(const std::string &Name, std::vector<RecordFieldDecl> Fields,
+ std::vector<std::unique_ptr<FunctionDefAST>> Methods)
+ : RecordTypeDeclAST(Name, std::move(Fields)), Methods(std::move(Methods)) {}
+ const auto &getMethods() const { return Methods; }
};
// ---- Designators: chained accesses usable as lvalue or rvalue (ยง4.2) ----