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