1 // Copyright (c) 1996 James Clark
2 // See the file copying.txt for copying permission.
3
4 #ifndef Expression_INCLUDED
5 #define Expression_INCLUDED 1
6
7 #include "ELObj.h"
8 #include "Owner.h"
9 #include "Vector.h"
10 #include "NCVector.h"
11 #include "Resource.h"
12 #include "Ptr.h"
13 #include "Insn.h"
14 #include "Named.h"
15 #include "Location.h"
16
17 #ifdef DSSSL_NAMESPACE
18 namespace DSSSL_NAMESPACE {
19 #endif
20
21 class Interpreter;
22 class Identifier;
23
24 struct BoundVar {
25 const Identifier *ident;
26 enum {
27 usedFlag = 01,
28 assignedFlag = 02,
29 sharedFlag = 04,
30 uninitFlag = 010,
31 boxedFlags = assignedFlag|sharedFlag
32 };
flagsBoxedBoundVar33 static bool flagsBoxed(unsigned f) { return (f & boxedFlags) == boxedFlags; }
boxedBoundVar34 bool boxed() const { return flagsBoxed(flags); }
35 unsigned flags;
36 unsigned reboundCount;
37 };
38
39 class BoundVarList : public Vector<BoundVar> {
40 public:
BoundVarList()41 BoundVarList() { }
42 BoundVarList(const Vector<const Identifier *> &);
43 BoundVarList(const Vector<const Identifier *> &, size_t, unsigned flags = 0);
44 void append(const Identifier *, unsigned flags);
45 void mark(const Identifier *, unsigned flags);
46 void removeUnused();
47 void remove(const Vector<const Identifier *> &);
48 void rebind(const Vector<const Identifier *> &);
49 void unbind(const Vector<const Identifier *> &);
50 BoundVar *find(const Identifier *);
51 };
52
53 class Environment {
54 public:
55 Environment();
56 Environment(const BoundVarList &frameVars,
57 const BoundVarList &closureVars);
58 void boundVars(BoundVarList &) const;
59 bool lookup(const Identifier *var,
60 bool &isFrame, int &index, unsigned &flags) const;
61 void augmentFrame(const BoundVarList &,
62 int stackPos);
63 private:
64 struct FrameVarList : public Resource {
65 int stackPos;
66 const BoundVarList *vars;
67 ConstPtr<FrameVarList> next;
68 };
69 ConstPtr<FrameVarList> frameVarList_;
70 const BoundVarList *closureVars_;
71 };
72
73 class Expression {
74 public:
75 Expression(const Location &);
~Expression()76 virtual ~Expression() { }
77 virtual InsnPtr compile(Interpreter &, const Environment &, int,
78 const InsnPtr &) = 0;
79 static
80 InsnPtr optimizeCompile(Owner<Expression> &, Interpreter &, const Environment &, int,
81 const InsnPtr &);
82 virtual void markBoundVars(BoundVarList &vars, bool);
83 virtual void optimize(Interpreter &, const Environment &, Owner<Expression> &);
84 virtual ELObj *constantValue() const;
85 virtual bool canEval(bool maybeCall) const = 0;
86 virtual const Identifier *keyword() const;
87 const Location &location() const;
88 protected:
89 static
90 InsnPtr compilePushVars(Interpreter &interp,
91 const Environment &env, int stackPos,
92 const BoundVarList &vars, size_t varIndex,
93 const InsnPtr &next);
94 private:
95 Location loc_;
96 };
97
98 class ConstantExpression : public Expression {
99 public:
100 ConstantExpression(ELObj *, const Location &);
101 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
102 void optimize(Interpreter &, const Environment &, Owner<Expression> &);
103 bool canEval(bool maybeCall) const;
104 const Identifier *keyword() const;
105 private:
106 ELObj *obj_; // must be permanent
107 };
108
109 class ResolvedConstantExpression : public Expression {
110 public:
111 ResolvedConstantExpression(ELObj *, const Location &);
112 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
113 bool canEval(bool maybeCall) const;
114 ELObj *constantValue() const;
115 private:
116 ELObj *obj_;
117 };
118
119 class CallExpression : public Expression {
120 public:
121 CallExpression(Owner<Expression> &, NCVector<Owner<Expression> > &,
122 const Location &loc);
123 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
124 void markBoundVars(BoundVarList &vars, bool);
125 int nArgs();
126 bool canEval(bool maybeCall) const;
127 private:
128 Owner<Expression> op_;
129 NCVector<Owner<Expression> > args_;
130 };
131
132 class VariableExpression : public Expression {
133 public:
134 VariableExpression(const Identifier *, const Location &loc);
135 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
136 void optimize(Interpreter &, const Environment &, Owner<Expression> &);
137 void markBoundVars(BoundVarList &vars, bool);
138 bool canEval(bool maybeCall) const;
139 private:
140 const Identifier *ident_;
141 bool isTop_;
142 };
143
144 class IfExpression : public Expression {
145 public:
146 IfExpression(Owner<Expression> &,
147 Owner<Expression> &,
148 Owner<Expression> &,
149 const Location &);
150 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
151 void markBoundVars(BoundVarList &vars, bool);
152 bool canEval(bool maybeCall) const;
153 void optimize(Interpreter &, const Environment &, Owner<Expression> &);
154 private:
155 Owner<Expression> test_;
156 Owner<Expression> consequent_;
157 Owner<Expression> alternate_;
158 };
159
160 class OrExpression : public Expression {
161 public:
162 OrExpression(Owner<Expression> &,
163 Owner<Expression> &,
164 const Location &);
165 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
166 void markBoundVars(BoundVarList &vars, bool);
167 bool canEval(bool maybeCall) const;
168 void optimize(Interpreter &, const Environment &, Owner<Expression> &);
169 private:
170 Owner<Expression> test1_;
171 Owner<Expression> test2_;
172 };
173
174 class CondFailExpression : public Expression {
175 public:
176 CondFailExpression(const Location &);
177 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
178 bool canEval(bool maybeCall) const;
179 };
180
181 class CaseExpression : public Expression {
182 public:
183 struct Case {
184 Vector<ELObj *> datums;
185 Owner<Expression> expr;
186 };
187 CaseExpression(Owner<Expression> &,
188 NCVector<Case> &,
189 Owner<Expression> &,
190 const Location &);
191 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
192 void markBoundVars(BoundVarList &vars, bool);
193 bool canEval(bool maybeCall) const;
194 void optimize(Interpreter &, const Environment &, Owner<Expression> &);
195 private:
196 Owner<Expression> key_;
197 NCVector<Case> cases_;
198 Vector<unsigned> nResolved_;
199 Owner<Expression> else_;
200 };
201
202 class LambdaExpression : public Expression {
203 public:
204 LambdaExpression(Vector<const Identifier *> &vars,
205 NCVector<Owner<Expression> > &inits,
206 int nOptional,
207 bool hasRest,
208 int nKey,
209 Owner<Expression> &body,
210 const Location &);
211 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
212 void markBoundVars(BoundVarList &vars, bool);
213 bool canEval(bool maybeCall) const;
214 private:
215 Vector<const Identifier *> formals_;
216 NCVector<Owner<Expression> > inits_;
217 Signature sig_;
218 Owner<Expression> body_;
219 };
220
221 class LetExpression : public Expression {
222 public:
223 LetExpression(Vector<const Identifier *> &vars,
224 NCVector<Owner<Expression> > &inits,
225 Owner<Expression> &body,
226 const Location &);
227 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
228 void markBoundVars(BoundVarList &vars, bool);
229 bool canEval(bool maybeCall) const;
230 protected:
231 InsnPtr compileInits(Interpreter &interp, const Environment &env,
232 const BoundVarList &initVars,
233 size_t initIndex, int stackPos, const InsnPtr &next);
234 Vector<const Identifier *> vars_;
235 NCVector<Owner<Expression> > inits_;
236 Owner<Expression> body_;
237 };
238
239 class LetStarExpression : public LetExpression {
240 public:
241 LetStarExpression(Vector<const Identifier *> &vars,
242 NCVector<Owner<Expression> > &inits,
243 Owner<Expression> &body,
244 const Location &);
245 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
246 private:
247 InsnPtr compileInits(Interpreter &interp, const Environment &env,
248 const BoundVarList &initVars,
249 size_t initIndex, int stackPos, const InsnPtr &next);
250 };
251
252 class LetrecExpression : public Expression {
253 public:
254 LetrecExpression(Vector<const Identifier *> &vars,
255 NCVector<Owner<Expression> > &inits,
256 Owner<Expression> &body,
257 const Location &);
258 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
259 void markBoundVars(BoundVarList &vars, bool);
260 bool canEval(bool maybeCall) const;
261 private:
262 InsnPtr compileInits(Interpreter &interp, const Environment &env,
263 size_t initIndex, int stackPos, const InsnPtr &next);
264 Vector<const Identifier *> vars_;
265 NCVector<Owner<Expression> > inits_;
266 Owner<Expression> body_;
267 };
268
269 class QuasiquoteExpression : public Expression {
270 public:
271 enum Type {
272 listType,
273 improperType,
274 vectorType
275 };
276 QuasiquoteExpression(NCVector<Owner<Expression> > &,
277 Vector<PackedBoolean> &spliced,
278 Type type,
279 const Location &);
280 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
281 void markBoundVars(BoundVarList &vars, bool);
282 bool canEval(bool maybeCall) const;
283 void optimize(Interpreter &, const Environment &, Owner<Expression> &);
284 private:
285 NCVector<Owner<Expression> > members_;
286 Vector<PackedBoolean> spliced_;
287 Type type_;
288 };
289
290 class SequenceExpression : public Expression {
291 public:
292 SequenceExpression(NCVector<Owner<Expression> > &,
293 const Location &);
294 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
295 void markBoundVars(BoundVarList &vars, bool);
296 bool canEval(bool maybeCall) const;
297 void optimize(Interpreter &, const Environment &, Owner<Expression> &);
298 private:
299 NCVector<Owner<Expression> > sequence_;
300 };
301
302 class AssignmentExpression : public Expression {
303 public:
304 AssignmentExpression(const Identifier *,
305 Owner<Expression> &,
306 const Location &);
307 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
308 void markBoundVars(BoundVarList &vars, bool);
309 bool canEval(bool maybeCall) const;
310 private:
311 const Identifier *var_;
312 Owner<Expression> value_;
313 };
314
315 class ProcessingMode;
316
317 class WithModeExpression : public Expression {
318 public:
319 WithModeExpression(const ProcessingMode *, Owner<Expression> &,
320 const Location &);
321 InsnPtr compile(Interpreter &, const Environment &, int,
322 const InsnPtr &);
323 void markBoundVars(BoundVarList &vars, bool);
324 bool canEval(bool maybeCall) const;
325 private:
326 const ProcessingMode *mode_;
327 Owner<Expression> expr_;
328 };
329
330 class StyleExpression : public Expression {
331 public:
332 StyleExpression(Vector<const Identifier *> &,
333 NCVector<Owner<Expression> > &,
334 const Location &loc);
335 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
336 void markBoundVars(BoundVarList &vars, bool);
337 bool canEval(bool maybeCall) const;
338 protected:
339 virtual void unknownStyleKeyword(const Identifier *ident, Interpreter &interp,
340 const Location &loc) const;
341 virtual bool maybeStyleKeyword(const Identifier *ident) const;
342 Vector<const Identifier *> keys_;
343 NCVector<Owner<Expression> > exprs_;
344 };
345
346 class FlowObj;
347
348 class MakeExpression : public StyleExpression {
349 public:
350 MakeExpression(const Identifier *,
351 Vector<const Identifier *> &,
352 NCVector<Owner<Expression> > &,
353 const Location &loc);
354 InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &);
355 private:
356 InsnPtr compileNonInheritedCs(Interpreter &interp, const Environment &env,
357 int stackPos, const InsnPtr &next);
358 FlowObj *applyConstNonInheritedCs(FlowObj *, Interpreter &, const Environment &);
359 void unknownStyleKeyword(const Identifier *ident, Interpreter &interp,
360 const Location &loc) const;
361 bool maybeStyleKeyword(const Identifier *ident) const;
362
363 const Identifier *foc_;
364 };
365
366 inline
location()367 const Location &Expression::location() const
368 {
369 return loc_;
370 }
371
372 inline
optimizeCompile(Owner<Expression> & expr,Interpreter & interp,const Environment & env,int stackPos,const InsnPtr & next)373 InsnPtr Expression::optimizeCompile(Owner<Expression> &expr, Interpreter &interp,
374 const Environment &env, int stackPos,
375 const InsnPtr &next)
376 {
377 expr->optimize(interp, env, expr);
378 return expr->compile(interp, env, stackPos, next);
379 }
380
381 #ifdef DSSSL_NAMESPACE
382 }
383 #endif
384
385 #endif /* not Expression_INCLUDED */
386