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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
#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;
bool IsOverload;
std::string OwnerClass;
bool IsPublic;
bool IsVariadic = false;
public:
PrototypeAST(const std::string &Name,
std::vector<ParamDecl> Params,
const std::string &ReturnType,
bool IsExternal = false, std::string OwnerClass = {}, bool IsPublic = true, bool IsOverload = false)
: Name(Name), Params(std::move(Params)), ReturnType(ReturnType), IsExternal(IsExternal), IsOverload(IsOverload),
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 isOverload() const { return IsOverload; }
bool isExternal() const { return IsExternal; }
bool isVariadic() const { return IsVariadic; }
void setVariadic(bool V) { IsVariadic = V; }
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; }
};
// EXTERN "C" EXTERN_FUNCTION/EXTERN_PROCEDURE: a body-less C prototype whose
// name is the exact C symbol.
class ExternDeclAST : public StmtAST {
std::unique_ptr<PrototypeAST> Proto;
public:
explicit ExternDeclAST(std::unique_ptr<PrototypeAST> Proto) : Proto(std::move(Proto)) {}
PrototypeAST *getProto() const { return Proto.get(); }
};
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
|