#pragma once #include "cps/AST.h" #include #include #include #include #include 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> DeclaredBounds; int Line = 0; }; class PrototypeAST { std::string Name; std::vector Params; std::string ReturnType; bool IsExternal; std::string OwnerClass; bool IsPublic; public: PrototypeAST(const std::string &Name, std::vector 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 &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 { std::unique_ptr Proto; std::vector> Body; public: FunctionDefAST(std::unique_ptr Proto, std::vector> Body) : Proto(std::move(Proto)), Body(std::move(Body)) {} PrototypeAST *getProto() const { return Proto.get(); } const std::vector> &getBody() const { return Body; } }; class CallExprAST : public ExprAST { std::string Callee; std::vector> Args; public: CallExprAST(const std::string &Callee, std::vector> Args, int Line) : ExprAST(Line), Callee(Callee), Args(std::move(Args)) {} const std::string &getCallee() const { return Callee; } const std::vector> &getArgs() const { return Args; } }; class CallStmtAST : public StmtAST { std::string Callee; std::vector> Args; public: CallStmtAST(const std::string &Callee, std::vector> Args, int Line) : StmtAST(Line), Callee(Callee), Args(std::move(Args)) {} const std::string &getCallee() const { return Callee; } const std::vector> &getArgs() const { return Args; } }; // A member call keeps the receiver separate from explicit arguments. class MemberCallExprAST : public ExprAST { std::unique_ptr Receiver; std::string Method; std::vector> Args; public: MemberCallExprAST(std::unique_ptr Receiver, std::string Method, std::vector> 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> &getArgs() const { return Args; } }; class MemberCallStmtAST : public StmtAST { std::unique_ptr Call; public: explicit MemberCallStmtAST(std::unique_ptr Call) : StmtAST(Call->getLine()), Call(std::move(Call)) {} MemberCallExprAST *getCall() const { return Call.get(); } }; class ReturnStmtAST : public StmtAST { std::unique_ptr RetVal; public: ReturnStmtAST(std::unique_ptr RetVal = nullptr) : RetVal(std::move(RetVal)) {} ExprAST *getRetVal() const { return RetVal.get(); } }; } // namespace cps