File: record.h

package info (click to toggle)
asymptote 3.05%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 33,420 kB
  • sloc: cpp: 172,663; ansic: 69,690; python: 14,957; sh: 5,605; javascript: 4,871; lisp: 1,507; perl: 1,417; makefile: 1,026; yacc: 610; lex: 449; xml: 182; asm: 8
file content (132 lines) | stat: -rw-r--r-- 2,818 bytes parent folder | download | duplicates (2)
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