aboutsummaryrefslogtreecommitdiff
path: root/include/cps/FunctionAST.h
blob: 4dfe908572ca0db16595efeeb18ca3f4b9180ff9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

#pragma once
#include "cps/AST.h"
#include "cps/Identifier.h"
#include <cstdint>
#include <vector>
#include <string>
#include <memory>
#include <utility>

namespace cps {

enum class PassMode : uint8_t { ByVal, ByRef };

// One declared FUNCTION/PROCEDURE parameter. For array parameters TypeName
// is the ELEMENT type; DeclaredBounds holds literal per-dimension bounds for
// the bounded form (empty for `ARRAY OF T`, which is rank 1 with the bounds
// travelling alongside the argument).
struct ParamDecl {
    std::string Name;
    std::string TypeName;
    PassMode Mode = PassMode::ByVal;
    bool IsArray = false;
    int Rank = 0; // 0 = scalar
    std::vector<std::pair<int64_t, int64_t>> DeclaredBounds;
    int Line = 0;
};

class PrototypeAST {
    std::string Name;
    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, 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 {
        if (!OwnerClass.empty()) return OwnerClass + "." + Name;
        return sameIdentifier(Name, "MAIN") ? "__cps_main" : Name;
    }
};

class FunctionDefAST : public StmtAST {
    std::unique_ptr<PrototypeAST> Proto;
    std::vector<std::unique_ptr<StmtAST>> Body;

public:
    FunctionDefAST(std::unique_ptr<PrototypeAST> Proto, 
                   std::vector<std::unique_ptr<StmtAST>> Body)
        : Proto(std::move(Proto)), Body(std::move(Body)) {}

    PrototypeAST *getProto() const { return Proto.get(); }
    const std::vector<std::unique_ptr<StmtAST>> &getBody() const { return Body; }
};

class CallExprAST : public ExprAST {
    std::string Callee;
    std::vector<std::unique_ptr<ExprAST>> Args;

public:
    CallExprAST(const std::string &Callee, std::vector<std::unique_ptr<ExprAST>> Args, int Line)
        : ExprAST(Line), Callee(Callee), Args(std::move(Args)) {}

    const std::string &getCallee() const { return Callee; }
    const std::vector<std::unique_ptr<ExprAST>> &getArgs() const { return Args; }
};

class CallStmtAST : public StmtAST {
    std::string Callee;
    std::vector<std::unique_ptr<ExprAST>> Args;

public:
    CallStmtAST(const std::string &Callee, std::vector<std::unique_ptr<ExprAST>> Args, int Line)
        : StmtAST(Line), Callee(Callee), Args(std::move(Args)) {}

    const std::string &getCallee() const { return Callee; }
    const std::vector<std::unique_ptr<ExprAST>> &getArgs() const { return Args; }
};


// 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;

public:
    ReturnStmtAST(std::unique_ptr<ExprAST> RetVal = nullptr) 
        : RetVal(std::move(RetVal)) {}
        
    ExprAST *getRetVal() const { return RetVal.get(); }
};

} // namespace cps