1 // Copyright (c) 1996 James Clark
2 // See the file copying.txt for copying permission.
5 #define ELObj_INCLUDED 1
9 #include "OutputCharStream.h"
13 #include "FOTBuilder.h"
16 #ifdef DSSSL_NAMESPACE
17 namespace DSSSL_NAMESPACE {
31 class AppendSosofoObj;
37 class NamedNodeListObj;
40 class DisplaySpaceObj;
42 class GlyphSubstTableObj;
46 class ELObj : public Collector::Object {
49 void *operator new(size_t, Collector &c) {
50 return c.allocateObject(0);
52 #ifdef SP_HAVE_PLACEMENT_OPERATOR_DELETE
54 void operator delete(void *p) { }
56 void operator delete(void *p, Collector &c) {
57 c.unallocateObject(p);
60 virtual bool isNil() const;
61 virtual bool isList() const;
62 virtual bool isTrue() const;
63 virtual PairObj *asPair();
64 virtual SymbolObj *asSymbol();
65 virtual KeywordObj *asKeyword();
66 virtual FunctionObj *asFunction();
67 virtual SosofoObj *asSosofo();
68 virtual AppendSosofoObj *asAppendSosofo();
69 virtual ColorObj *asColor();
70 virtual ColorSpaceObj *asColorSpace();
71 virtual StyleObj *asStyle();
72 virtual AddressObj *asAddress();
73 virtual DisplaySpaceObj *asDisplaySpace();
74 virtual InlineSpaceObj *asInlineSpace();
75 virtual GlyphSubstTableObj *asGlyphSubstTable();
76 virtual NodeListObj *asNodeList();
77 virtual NamedNodeListObj *asNamedNodeList();
78 virtual StringObj *convertToString(); // either symbol or string
79 virtual BoxObj *asBox();
80 virtual VectorObj *asVector();
81 virtual LanguageObj *asLanguage();
82 virtual bool charValue(Char &);
83 virtual bool stringData(const Char *&, size_t &);
84 virtual void print(Interpreter &, OutputCharStream &);
85 virtual void print(Interpreter &, OutputCharStream &, unsigned);
86 virtual bool exactIntegerValue(long &);
87 virtual bool realValue(double &);
88 virtual bool inexactRealValue(double &);
89 virtual bool lengthValue(long &);
90 virtual const FOTBuilder::GlyphId *glyphId() const;
91 virtual const LengthSpec *lengthSpec() const;
97 virtual QuantityType quantityValue(long &, double &, int &);
98 virtual ELObj *resolveQuantities(bool force, Interpreter &,
100 virtual bool optSingletonNodeList(EvalContext &, Interpreter &, NodePtr &);
101 static bool equal(ELObj &, ELObj &);
102 // Note that in DSSSL2 unlike Scheme eqv? for lists and strings is the same
103 // as equal?. Only for vectors do they differ.
104 static bool eqv(ELObj &, ELObj &);
106 // This checks for equality of *distinct* objects.
107 virtual bool isEqual(ELObj &);
108 // This checks for equivalence of *distinct* objects.
109 virtual bool isEquiv(ELObj &);
112 class ErrorObj : public ELObj {
114 void print(Interpreter &, OutputCharStream &);
117 friend class Interpreter;
120 class UnspecifiedObj : public ELObj {
122 void print(Interpreter &, OutputCharStream &);
125 friend class Interpreter;
128 class NilObj : public ELObj {
132 void print(Interpreter &, OutputCharStream &);
135 friend class Interpreter;
138 class TrueObj : public ELObj {
140 void print(Interpreter &, OutputCharStream &);
143 friend class Interpreter;
146 class FalseObj : public ELObj {
148 void print(Interpreter &, OutputCharStream &);
152 friend class Interpreter;
158 class SymbolObj : public ELObj {
160 void print(Interpreter &, OutputCharStream &);
161 SymbolObj *asSymbol();
162 StringObj *convertToString();
163 StringObj *name() const;
164 void traceSubObjects(Collector &) const;
165 FOTBuilder::Symbol cValue() const;
166 void setCValue(FOTBuilder::Symbol);
167 static const StringC &key(const SymbolObj &);
169 SymbolObj(StringObj *);
171 FOTBuilder::Symbol cValue_;
172 friend class Interpreter;
177 class KeywordObj : public ELObj {
179 void print(Interpreter &, OutputCharStream &);
180 KeywordObj *asKeyword();
181 const Identifier *identifier() const;
182 bool isEqual(ELObj &);
184 KeywordObj(const Identifier *);
185 const Identifier *ident_;
186 friend class Interpreter;
189 class PairObj : public ELObj {
191 PairObj(ELObj *car, ELObj *cdr);
194 void setCar(ELObj *);
195 void setCdr(ELObj *);
198 void print(Interpreter &, OutputCharStream &);
199 void traceSubObjects(Collector &) const;
200 ELObj *resolveQuantities(bool force, Interpreter &, const Location &);
201 bool isEqual(ELObj &);
202 bool isEquiv(ELObj &);
208 class VectorObj : public ELObj, public Vector<ELObj *> {
210 void *operator new(size_t, Collector &c) {
211 return c.allocateObject(1);
214 VectorObj(Vector<ELObj *> &v);
215 void traceSubObjects(Collector &) const;
216 VectorObj *asVector();
217 bool isEqual(ELObj &);
218 bool isEquiv(ELObj &);
219 void print(Interpreter &, OutputCharStream &);
220 ELObj *resolveQuantities(bool force, Interpreter &, const Location &);
223 class CharObj : public ELObj {
226 void print(Interpreter &, OutputCharStream &);
227 void display(Interpreter &, OutputCharStream &) const;
228 bool isEqual(ELObj &);
229 bool charValue(Char &);
233 friend class Interpreter;
236 class StringObj : public ELObj, public StringC {
238 void *operator new(size_t, Collector &c) {
239 return c.allocateObject(1);
242 StringObj(const StringC &str);
243 StringObj(const Char *, size_t);
244 void print(Interpreter &, OutputCharStream &);
245 StringObj *convertToString();
246 bool stringData(const Char *&, size_t &);
247 bool isEqual(ELObj &);
250 class IntegerObj : public ELObj {
252 void print(Interpreter &, OutputCharStream &);
253 void print(Interpreter &, OutputCharStream &, unsigned);
254 bool exactIntegerValue(long &);
255 bool realValue(double &);
256 QuantityType quantityValue(long &, double &, int &);
257 bool isEqual(ELObj &);
259 friend class Interpreter;
265 class RealObj : public ELObj {
268 bool realValue(double &);
269 bool inexactRealValue(double &);
270 QuantityType quantityValue(long &, double &, int &);
271 bool isEqual(ELObj &);
272 void print(Interpreter &, OutputCharStream &);
277 class LengthObj : public ELObj {
279 LengthObj(long units);
280 bool lengthValue(long &);
281 QuantityType quantityValue(long &, double &, int &);
282 void print(Interpreter &, OutputCharStream &);
283 bool isEqual(ELObj &);
288 class QuantityObj : public ELObj {
290 QuantityObj(double, int);
291 QuantityType quantityValue(long &, double &, int &);
292 void print(Interpreter &, OutputCharStream &);
293 bool isEqual(ELObj &);
294 bool realValue(double &);
295 bool inexactRealValue(double &);
297 // This is in units per inch.
304 enum Unknown { displaySize = 1, tableUnit };
307 LengthSpec(Unknown, double);
308 void operator+=(const LengthSpec &);
309 void operator+=(double d) { val_[0] += d; }
310 void operator-=(const LengthSpec &);
311 void operator-=(double d) { val_[0] -= d; }
312 void operator*=(double);
313 void operator/=(double);
314 bool convert(FOTBuilder::LengthSpec &) const;
315 bool convert(FOTBuilder::TableLengthSpec &) const;
321 class LengthSpecObj : public ELObj {
323 void *operator new(size_t, Collector &c) {
324 return c.allocateObject(1);
326 LengthSpecObj(const LengthSpec &);
327 const LengthSpec *lengthSpec() const;
329 Owner<LengthSpec> lengthSpec_;
332 class DisplaySpaceObj : public ELObj {
334 void *operator new(size_t, Collector &c) {
335 return c.allocateObject(1);
337 DisplaySpaceObj(const FOTBuilder::DisplaySpace &);
338 const FOTBuilder::DisplaySpace &displaySpace() const;
339 DisplaySpaceObj *asDisplaySpace();
341 Owner<FOTBuilder::DisplaySpace> displaySpace_;
344 class InlineSpaceObj : public ELObj {
346 void *operator new(size_t, Collector &c) {
347 return c.allocateObject(1);
349 InlineSpaceObj(const FOTBuilder::InlineSpace &);
350 const FOTBuilder::InlineSpace &inlineSpace() const;
351 InlineSpaceObj *asInlineSpace();
353 Owner<FOTBuilder::InlineSpace> inlineSpace_;
356 class UnresolvedQuantityObj : public ELObj {
358 UnresolvedQuantityObj(double, Unit *, int);
359 ELObj *resolveQuantities(bool force, Interpreter &, const Location &);
366 class UnresolvedLengthObj : public ELObj {
368 UnresolvedLengthObj(long val, int valExp, Unit *);
369 ELObj *resolveQuantities(bool force, Interpreter &, const Location &);
376 class GlyphIdObj : public ELObj {
378 GlyphIdObj(const FOTBuilder::GlyphId &);
379 const FOTBuilder::GlyphId *glyphId() const;
380 bool isEqual(ELObj &);
382 FOTBuilder::GlyphId glyphId_;
385 class GlyphSubstTableObj : public ELObj {
387 void *operator new(size_t, Collector &c) {
388 return c.allocateObject(1);
390 GlyphSubstTableObj(const ConstPtr<FOTBuilder::GlyphSubstTable> &);
391 GlyphSubstTableObj *asGlyphSubstTable();
392 const ConstPtr<FOTBuilder::GlyphSubstTable> &glyphSubstTable() const;
394 ConstPtr<FOTBuilder::GlyphSubstTable> table_;
397 class AddressObj : public ELObj {
399 void *operator new(size_t, Collector &c) {
400 return c.allocateObject(1);
402 AddressObj(FOTBuilder::Address::Type,
403 const NodePtr & = NodePtr(),
404 const StringC & = StringC(),
405 const StringC & = StringC(),
406 const StringC & = StringC());
407 AddressObj *asAddress();
408 const FOTBuilder::Address &address() const;
410 Owner<FOTBuilder::Address> address_;
413 class NodeListObj : public ELObj {
415 NodeListObj *asNodeList();
416 bool optSingletonNodeList(EvalContext &, Interpreter &, NodePtr &);
417 virtual NodePtr nodeListFirst(EvalContext &, Interpreter &) = 0;
418 virtual NodeListObj *nodeListRest(EvalContext &, Interpreter &) = 0;
419 virtual NodeListObj *nodeListNoOrder(Collector &);
420 // If this node contains all the node in the chunk of the first node, then
421 // this *may* return the node list containing the nodes following the chunk;
422 // If so chunk, will be set to 1. Otherwise return nodeListRest() and set
423 // chunk to 0. If charChunk() returns a string of length n, then
424 // the chunk of the node is the node together with the n - 1 following siblings;
425 // otherwise the chunk of the node is the node itself.
426 virtual NodeListObj *nodeListChunkRest(EvalContext &, Interpreter &, bool &chunk);
427 virtual NodePtr nodeListRef(long, EvalContext &, Interpreter &);
428 virtual NodeListObj *nodeListReverse(EvalContext &, Interpreter &);
429 virtual long nodeListLength(EvalContext &, Interpreter &);
430 virtual bool suppressError();
433 class NamedNodeListObj : public NodeListObj {
435 NamedNodeListObj *asNamedNodeList();
436 virtual NodePtr namedNode(const Char *, size_t) = 0;
437 virtual bool nodeName(const NodePtr &, GroveString &) = 0;
438 virtual size_t normalize(Char *, size_t) = 0;
441 class NodePtrNodeListObj : public NodeListObj {
443 void *operator new(size_t, Collector &c) {
444 return c.allocateObject(1);
446 NodePtrNodeListObj();
447 NodePtrNodeListObj(const NodePtr &);
448 NodePtr nodeListFirst(EvalContext &, Interpreter &);
449 NodeListObj *nodeListRest(EvalContext &, Interpreter &);
450 bool optSingletonNodeList(EvalContext &, Interpreter &, NodePtr &);
451 bool chunkComplete();
457 class NodeListPtrNodeListObj : public NodeListObj {
459 void *operator new(size_t, Collector &c) {
460 return c.allocateObject(1);
462 NodeListPtrNodeListObj(const NodeListPtr &);
463 NodePtr nodeListFirst(EvalContext &, Interpreter &);
464 NodeListObj *nodeListRest(EvalContext &, Interpreter &);
465 NodeListObj *nodeListChunkRest(EvalContext &, Interpreter &, bool &);
466 NodePtr nodeListRef(long, EvalContext &, Interpreter &);
469 NodeListPtr nodeList_;
472 class NamedNodeListPtrNodeListObj : public NamedNodeListObj {
474 void *operator new(size_t, Collector &c) {
475 return c.allocateObject(1);
477 NamedNodeListPtrNodeListObj(const NamedNodeListPtr &);
478 NodePtr nodeListFirst(EvalContext &, Interpreter &);
479 NodeListObj *nodeListRest(EvalContext &, Interpreter &);
480 NodePtr namedNode(const Char *, size_t);
481 bool nodeName(const NodePtr &, GroveString &);
482 size_t normalize(Char *, size_t);
483 NodeListObj *nodeListNoOrder(Collector &);
485 NamedNodeListPtr namedNodeList_;
486 // cached node list, null if not yet computed
487 NodeListPtr nodeList_;
490 class PairNodeListObj : public NodeListObj {
492 PairNodeListObj(NodeListObj *, NodeListObj *);
493 NodePtr nodeListFirst(EvalContext &, Interpreter &);
494 NodeListObj *nodeListRest(EvalContext &, Interpreter &);
495 NodeListObj *nodeListChunkRest(EvalContext &, Interpreter &, bool &);
496 void traceSubObjects(Collector &) const;
498 NodeListObj *head_; // may be null
503 bool ELObj::equal(ELObj &obj1, ELObj &obj2)
505 return &obj1 == &obj2 || obj1.isEqual(obj2);
509 bool ELObj::eqv(ELObj &obj1, ELObj &obj2)
511 return &obj1 == &obj2 || obj1.isEquiv(obj2);
515 ELObj *PairObj::car()
521 ELObj *PairObj::cdr()
527 void PairObj::setCar(ELObj *car)
533 void PairObj::setCdr(ELObj *cdr)
539 StringObj *SymbolObj::name() const
545 FOTBuilder::Symbol SymbolObj::cValue() const
551 void SymbolObj::setCValue(FOTBuilder::Symbol sym)
563 const StringC &SymbolObj::key(const SymbolObj &sym)
569 const Identifier *KeywordObj::identifier() const
575 const FOTBuilder::Address &AddressObj::address() const
581 const ConstPtr<FOTBuilder::GlyphSubstTable> &
582 GlyphSubstTableObj::glyphSubstTable() const
587 #ifdef DSSSL_NAMESPACE
591 #endif /* not ELObj_INCLUDED */