Initial commit
[profile/ivi/openjade.git] / style / Expression.h
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   };
33   static bool flagsBoxed(unsigned f) { return (f & boxedFlags) == boxedFlags; }
34   bool boxed() const { return flagsBoxed(flags); }
35   unsigned flags;
36   unsigned reboundCount;
37 };
38
39 class BoundVarList : public Vector<BoundVar> {
40 public:
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 &);
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
367 const Location &Expression::location() const
368 {
369   return loc_;
370 }
371
372 inline
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 */