/***** * name.h * Andy Hammerlindl 2002/07/14 * * Qualified names (such as x, f, builtin.sin, a.b.c.d, etc.) can be used * either as variables or a type names. This class stores qualified * names used in nameExp and nameTy in the abstract syntax, and * implements the exp and type functions. *****/ #ifndef NAME_H #define NAME_H #include "absyn.h" #include "types.h" #include "frame.h" #include "access.h" namespace trans { class coenv; class varEntry; class tyEntry; } namespace types { class record; } namespace absyntax { using trans::coenv; using trans::action; using types::record; using std::ostream; class name : public absyn { public: name(position pos) : absyn(pos) {} // Helper function - ensures target and source match up, using casting in the // case of a read. Issues errors on failure. void forceEquivalency(action act, coenv &e, types::ty *target, types::ty *source); // Used for determining the type when the context does not establish // the name as a variable or a type. First, the function looks for a // non-function variable fitting the description. If one fits, the // type of the variable is returned. Failing that, the function looks // for a fitting type and returns that. If nothing is found, an // appropriate error is reported and ty_error is returned. // Because this is used only on qualifiers (ie. names to the left of a // dot), it does not look at function variables. // Tacit means that no error messages will be reported to the user. virtual types::ty *getType(coenv &e, bool tacit = false); // Pushes the highest level frame possible onto the stack. Returning // the frame pushed. If no frame can be pushed, returns 0. // NOTE: This duplicates some functionality with getVarEntry. virtual trans::frame *frameTrans(coenv &e); // Helper function for the case where the name is known to be a type. virtual trans::frame *tyFrameTrans(coenv &e) = 0; // Constructs the varEntry part of the tyEntry for the name. Like // getType, this is called on the qualifier, instead of the full name. // This reports no errors, and returns 0 if there is no varEntry to // use. virtual trans::varEntry *getVarEntry(coenv &e) = 0; // As a variable: // Translates the name (much like an expression). virtual void varTrans(action act, coenv &e, types::ty *target) = 0; // Returns the possible variable types. Unlike exp, returns 0 if none // match. virtual types::ty *varGetType(coenv &e) = 0; virtual trans::varEntry *getCallee(coenv &e, types::signature *sig) = 0; // As a type: // Determines the type, as used in a variable declaration. virtual types::ty *typeTrans(coenv &e, bool tacit = false) = 0; // Constructs the tyEntry of the name, needed so that we know the // parent frame for allocating new objects of that type. Reports // errors as typeTrans() does with tacit=false. virtual trans::tyEntry *tyEntryTrans(coenv &e) = 0; virtual void prettyprint(ostream &out, Int indent) = 0; virtual void print(ostream& out) const { out << ""; } [[nodiscard]] virtual symbol getName() const = 0; [[nodiscard]] virtual AsymptoteLsp::SymbolLit getLit() const = 0; }; inline ostream& operator<< (ostream& out, const name& n) { n.print(out); return out; } class simpleName : public name { symbol id; public: simpleName(position pos, symbol id) : name(pos), id(id) {} trans::varEntry *getVarEntry(coenv &e) override; // As a variable: void varTrans(action act, coenv &e, types::ty *target) override; types::ty *varGetType(coenv &) override; trans::varEntry *getCallee(coenv &e, types::signature *sig) override; // As a type: types::ty *typeTrans(coenv &e, bool tacit = false) override; virtual trans::tyEntry *tyEntryTrans(coenv &e) override; trans::frame *tyFrameTrans(coenv &e) override; void prettyprint(ostream &out, Int indent) override; void print(ostream& out) const override { out << id; } [[nodiscard]] symbol getName() const override { return id; } [[nodiscard]] AsymptoteLsp::SymbolLit getLit() const override; }; class qualifiedName : public name { name *qualifier; symbol id; // Gets the record type associated with the qualifier. Reports an // error and returns null if the type is not a record. record *castToRecord(types::ty *t, bool tacit = false); // Translates as a virtual field, if possible. qt is the type of the // qualifier. Return true if there was a matching virtual field. bool varTransVirtual(action act, coenv &e, types::ty *target, types::ty *qt); // Translates as an ordinary (non-virtual) field of a record, r. void varTransField(action act, coenv &e, types::ty *target, record *r); public: qualifiedName(position pos, name *qualifier, symbol id) : name(pos), qualifier(qualifier), id(id) {} trans::varEntry *getVarEntry(coenv &e) override; // As a variable: void varTrans(action act, coenv &, types::ty *target) override; types::ty *varGetType(coenv &) override; trans::varEntry *getCallee(coenv &e, types::signature *sig) override; // As a type: types::ty *typeTrans(coenv &e, bool tacit = false) override; trans::tyEntry *tyEntryTrans(coenv &e) override; trans::frame *tyFrameTrans(coenv &e) override; void prettyprint(ostream &out, Int indent) override; void print(ostream& out) const override { out << *qualifier << "." << id; } [[nodiscard]] symbol getName() const override { return id; } [[nodiscard]] AsymptoteLsp::SymbolLit getLit() const override; }; } // namespace absyntax #endif