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 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
/*****
* 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 << "<base name>";
}
virtual symbol getName() = 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);
// As a variable:
void varTrans(action act, coenv &e, types::ty *target);
types::ty *varGetType(coenv &);
trans::varEntry *getCallee(coenv &e, types::signature *sig);
// As a type:
types::ty *typeTrans(coenv &e, bool tacit = false);
virtual trans::tyEntry *tyEntryTrans(coenv &e);
trans::frame *tyFrameTrans(coenv &e);
void prettyprint(ostream &out, Int indent);
void print(ostream& out) const {
out << id;
}
symbol getName() {
return id;
}
};
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);
// As a variable:
void varTrans(action act, coenv &, types::ty *target);
types::ty *varGetType(coenv &);
trans::varEntry *getCallee(coenv &e, types::signature *sig);
// As a type:
types::ty *typeTrans(coenv &e, bool tacit = false);
trans::tyEntry *tyEntryTrans(coenv &e);
trans::frame *tyFrameTrans(coenv &e);
void prettyprint(ostream &out, Int indent);
void print(ostream& out) const {
out << *qualifier << "." << id;
}
symbol getName() {
return id;
}
};
} // namespace absyntax
#endif
|