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
|
/*****
* record.h
* Andy Hammerlindl 2003/07/09
*
* The type for records and modules in the language.
*****/
#ifndef RECORD_H
#define RECORD_H
#include "types.h"
#include "env.h"
#include "frame.h"
#include "access.h"
namespace vm {
struct lambda;
}
using trans::frame;
using trans::protoenv;
using trans::varEntry;
using trans::tyEntry;
namespace types {
class record : public ty {
// The base name of this type.
symbol name;
// The frame. Like a frame for a function, it allocates the accesses
// for fields and specifies the size of the record.
frame *level;
// The runtime representation of the record used by the virtual machine.
vm::lambda *init;
public:
// The name bindings for fields of the record.
protoenv e;
// These are name bindings that should be added to the enclosing environment
// after translation of the record is completed. Constructors implicitly
// defined by "operator init" are stored here.
protoenv postdefenv;
record(symbol name, frame *level);
~record();
symbol getName()
{
return name;
}
symbol getTemplateIndex() {
return getName(); // May change in the future.
}
bool isReference() {
return true;
}
size_t hash() const {
// Use the pointer, as two records are equivalent only if they are the
// same object.
return (size_t)this;
}
// Initialize to null by default.
trans::access *initializer();
frame *getLevel(bool statically = false)
{
if (statically) {
frame *f=level->getParent();
return f ? f : level;
}
else
return level;
}
vm::lambda *getInit()
{
return init;
}
// Allocates a new dynamic field in the record.
trans::access *allocField(bool statically)
{
frame *underlevel = getLevel(statically);
assert(underlevel);
return underlevel->allocLocal();
}
// Create a statically enclosed record from this record.
record *newRecord(symbol id, bool statically);
void print(ostream& out) const
{
out << name;
}
void debug(ostream& out) const
{
out << "struct " << name << endl;
out << "types:" << endl;
out << "re-implement" << endl;
//out << te;
out << "fields: " << endl;
out << "re-implement" << endl;
//out << ve;
}
};
// A record that is being used just for its fields and types, and has no real
// initializer. This is for modules such as settings that are built into the
// language.
class dummyRecord : public record {
public:
dummyRecord(symbol name);
dummyRecord(string s);
// Convenient functions for adding fields.
void add(string name, ty *t, trans::access *a,
trans::permission perm=trans::PUBLIC);
void add(string name, function *t, vm::bltin f,
trans::permission perm=trans::PUBLIC);
};
} //namespace types
#endif
|