summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/access.h
blob: 08e0a48e3a907ea83a413303f5d7e37a7d585a30 (plain)
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
/*****
 * access.h
 * Andy Hammerlindl 2003/12/03
 *
 * Describes an "access," a representation of where a variable will be
 * stored at runtime, so that read, write, and call instructions can be
 * made.
 *****/

#ifndef ACCESS_H
#define ACCESS_H

#include <cassert>

#include "errormsg.h"
#include "item.h"
#include "vm.h"

namespace vm {
  struct callable;
}

namespace trans {
  
class frame;
class coder;

enum action {
  READ,
  WRITE,
  CALL
};

// These serves as the base class for the accesses.
class access : public gc { 
protected:
  // Generic compiler access error - if the compiler functions properly,
  // none of these should be reachable by the user.
  void error(position pos)
  {
    em.compiler(pos);
    em << "invalid use of access";
  }

public:
  virtual ~access() = 0;
  
  // Encode a read/write/call of the access when nothing is on the stack.
  virtual void encode(action, position pos, coder &)
  {
    error(pos);
  }
  // Encode a read/write/call of the access when the frame "top" is on top
  // of the stack.
  virtual void encode(action, position pos, coder &, frame *)
  {
    error(pos);
  }
};

// This class represents identity conversions in casting.
class identAccess : public access 
{
  virtual void encode(action act, position, coder&);
};

// Represents a function that is implemented by a built-in C++ function.
class bltinAccess : public access {
  vm::bltin f;

public:
  bltinAccess(vm::bltin f)
    : f(f) {}

  void encode(action act, position pos, coder &e);
  void encode(action act, position pos, coder &e, frame *);
};

// Similar to bltinAccess, but works for any callable.
class callableAccess : public access {
  vm::callable *f;

public:
  callableAccess(vm::callable *f)
    : f(f) {}

  void encode(action act, position pos, coder &e);
  void encode(action act, position pos, coder &e, frame *);
};

// An access that puts a frame on the top of the stack.
class frameAccess : public access {
  frame *f;

public:
  frameAccess(frame *f)
    : f(f) {}
  
  void encode(action act, position pos, coder &e);
  void encode(action act, position pos, coder &e, frame *top);
};

// Represents the access of a local variable.
class localAccess : public access {
  Int offset;
  frame *level;

public:
  localAccess(Int offset, frame *level)
    : offset(offset), level(level) {}

  void encode(action act, position pos, coder &e);
  void encode(action act, position pos, coder &e, frame *top);
};

class qualifiedAccess : public access {
  // The location and frame of the record.
  access *qualifier;
  frame *qualifierLevel;  

  // The location of the field relative to the record.
  access *field;

public:
  qualifiedAccess(access *qualifier, frame *qualifierLevel, access *field)
    : qualifier(qualifier), qualifierLevel(qualifierLevel), field(field) {}

  void encode(action act, position pos, coder &e);
  void encode(action act, position pos, coder &e, frame *top);
};

} // namespace trans

#endif // ACCESS_H