PageRenderTime 27ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/branches/jade_annexk/style/Interpreter.cxx

#
C++ | 2524 lines | 2341 code | 139 blank | 44 comment | 503 complexity | a453bc2c30eb80917f829004d212ebc4 MD5 | raw file
Possible License(s): LGPL-2.1, LGPL-2.0
  1. // Copyright (c) 1996 James Clark
  2. // See the file copying.txt for copying permission.
  3. #include "stylelib.h"
  4. #include "Interpreter.h"
  5. #include "Insn.h"
  6. #include "InterpreterMessages.h"
  7. #include "LocNode.h"
  8. #include "Pattern.h"
  9. #include "MacroFlowObj.h"
  10. #include "ELObjMessageArg.h"
  11. #include "VM.h"
  12. #include "Owner.h"
  13. #include "SchemeParser.h"
  14. #include "macros.h"
  15. #include "InternalInputSource.h"
  16. #include <stdlib.h>
  17. #include "LangObj.h"
  18. #ifdef DSSSL_NAMESPACE
  19. namespace DSSSL_NAMESPACE {
  20. #endif
  21. class ELObjCharPropValues : public CharPropValues {
  22. public:
  23. ELObjCharPropValues()
  24. : def_(0), map_(0) {}
  25. private:
  26. ELObjCharPropValues(const ELObjCharPropValues &); // Undefined.
  27. ELObjCharPropValues &operator=(const ELObjCharPropValues &); // Undefined.
  28. // 0 means no value.
  29. ELObj *def_;
  30. CharMap<ELObj *> map_;
  31. bool setDefault(const StringC &, const Location &,
  32. ELObj *, Interpreter &);
  33. bool setValue(const StringC &, const StringC &, const Location &,
  34. ELObj *,Interpreter &);
  35. ELObj *value(Char, Interpreter &) const;
  36. ELObj *defaultValue(Interpreter &) const;
  37. };
  38. const Char defaultChar = 0xfffd;
  39. static
  40. size_t maxObjSize()
  41. {
  42. // FlowObj classes are declared in FlowObj.cxx.
  43. class Dummy : public CompoundFlowObj {
  44. private:
  45. Owner<Location> locp_;
  46. };
  47. static size_t sz[] = {
  48. sizeof(UnresolvedQuantityObj),
  49. sizeof(VarStyleObj),
  50. sizeof(OverriddenStyleObj),
  51. sizeof(MergeStyleObj),
  52. sizeof(DeviceRGBColorObj),
  53. sizeof(ColorSpaceObj),
  54. sizeof(PairObj),
  55. sizeof(QuantityObj),
  56. sizeof(GlyphIdObj),
  57. sizeof(NamedNodeListPtrNodeListObj),
  58. sizeof(ProcessNodeSosofoObj),
  59. sizeof(AppendSosofoObj),
  60. sizeof(LiteralSosofoObj),
  61. sizeof(SetNonInheritedCsSosofoObj),
  62. sizeof(LabelSosofoObj),
  63. sizeof(MacroFlowObj),
  64. sizeof(Dummy),
  65. sizeof(LangObj),
  66. #ifdef SP_HAVE_LOCALE
  67. sizeof(RefLangObj),
  68. #endif
  69. sizeof(SubgroveSpecObj),
  70. sizeof(CreateSpecObj),
  71. };
  72. size_t n = sz[0];
  73. for (size_t i = 1; i < SIZEOF(sz); i++)
  74. if (sz[i] > n)
  75. n = sz[i];
  76. return n;
  77. }
  78. Interpreter::Interpreter(GroveManager *groveManager,
  79. Messenger *messenger,
  80. int unitsPerInch,
  81. bool debugMode,
  82. bool dsssl2,
  83. bool style,
  84. bool strictMode,
  85. const FOTBuilder::Description &fotbDescr)
  86. : groveManager_(groveManager),
  87. messenger_(messenger),
  88. fotbDescr_(fotbDescr),
  89. Collector(maxObjSize()),
  90. partIndex_(0), // 0 is for command-line definitions
  91. dPartIndex_(1),
  92. lexCategory_(lexOther),
  93. unitsPerInch_(unitsPerInch),
  94. nInheritedC_(0),
  95. initialProcessingMode_(StringC()),
  96. currentPartFirstInitialValue_(0),
  97. initialStyle_(0),
  98. nextGlyphSubstTableUniqueId_(0),
  99. debugMode_(debugMode),
  100. dsssl2_(dsssl2),
  101. mathClassCPV_(FOTBuilder::symbolOrdinary),
  102. style_(style),
  103. strictMode_(strictMode),
  104. explicitFeatures_(0),
  105. explicitModules_(0)
  106. {
  107. makePermanent(theNilObj_ = new (*this) NilObj);
  108. makePermanent(theFalseObj_ = new (*this) FalseObj);
  109. makePermanent(theTrueObj_ = new (*this) TrueObj);
  110. makePermanent(theErrorObj_ = new (*this) ErrorObj);
  111. makePermanent(theUnspecifiedObj_ = new (*this) UnspecifiedObj);
  112. makePermanent(addressNoneObj_
  113. = new (*this) AddressObj(FOTBuilder::Address::none));
  114. makePermanent(emptyNodeListObj_
  115. = new (*this) NodePtrNodeListObj);
  116. defaultLanguage_ = theFalseObj_;
  117. installSyntacticKeys();
  118. installCValueSymbols();
  119. installPortNames();
  120. installPrimitives();
  121. installUnits();
  122. installFeatures(fotbDescr_.features);
  123. installModules();
  124. installCharNames();
  125. installSdata();
  126. installFlowObjs();
  127. installInheritedCs();
  128. installNodeProperties();
  129. static const char *lexCategories[] = {
  130. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
  131. "!$%&*/<=>?~_^:",
  132. "",
  133. "0123456789",
  134. "-+.",
  135. "",
  136. "();\"",
  137. " \t\r\n\f",
  138. "",
  139. };
  140. lexCategory_.setEe(lexDelimiter);
  141. for (size_t i = 0; i < SIZEOF(lexCategories); i++)
  142. for (const char *s = lexCategories[i]; *s; s++)
  143. lexCategory_.setChar(*s, i);
  144. // #',@[\\]`{|} are ASCII chars not mentioned above,
  145. // but I guess we don't want to allow any of these
  146. // in names (as most of them have special meaning in
  147. // scheme/dsssl).
  148. if (!strictMode_)
  149. for (Char i = 127; i < charMax; i++)
  150. lexCategory_.setChar(i, lexAddNameStart);
  151. initialProcessingMode_.setDefined();
  152. // can't be done before initializing lexCategory_
  153. installBuiltins();
  154. installCharProperties();
  155. }
  156. void Interpreter::compile()
  157. {
  158. // FIXME compile all definitions
  159. compileInitialValues();
  160. initialProcessingMode_.compile(*this);
  161. NamedTableIter<ProcessingMode> iter(processingModeTable_);
  162. for (;;) {
  163. ProcessingMode *mode = iter.next();
  164. if (!mode)
  165. break;
  166. mode->compile(*this);
  167. }
  168. compileCharProperties();
  169. compileDefaultLanguage();
  170. checkGrovePlan();
  171. }
  172. void Interpreter::compileInitialValues()
  173. {
  174. Vector<ConstPtr<InheritedC> > ics;
  175. for (size_t i = 0; i < initialValueNames_.size(); i++) {
  176. const Identifier *ident = initialValueNames_[i];
  177. Owner<Expression> &expr = initialValueValues_[i];
  178. ConstPtr<InheritedC> ic(ident->inheritedC());
  179. expr->optimize(*this, Environment(), expr);
  180. ELObj *val = expr->constantValue();
  181. if (val) {
  182. ConstPtr<InheritedC> tem(ic->make(val, expr->location(), *this));
  183. if (!tem.isNull())
  184. ics.push_back(tem);
  185. }
  186. else
  187. ics.push_back(new VarInheritedC(ic,
  188. expr->compile(*this, Environment(), 0, InsnPtr()),
  189. expr->location()));
  190. }
  191. if (ics.size()) {
  192. Vector<ConstPtr<InheritedC> > forceIcs;
  193. initialStyle_ = new (*this) VarStyleObj(new StyleSpec(forceIcs, ics), 0, 0, NodePtr());
  194. makePermanent(initialStyle_);
  195. }
  196. }
  197. void Interpreter::installInitialValue(Identifier *ident, Owner<Expression> &expr)
  198. {
  199. for (size_t i = 0; i < initialValueNames_.size(); i++) {
  200. if (ident == initialValueNames_[i]) {
  201. if (i >= currentPartFirstInitialValue_) {
  202. setNextLocation(expr->location());
  203. message(InterpreterMessages::duplicateInitialValue,
  204. StringMessageArg(ident->name()),
  205. initialValueValues_[i]->location());
  206. }
  207. return;
  208. }
  209. }
  210. initialValueValues_.resize(initialValueValues_.size() + 1);
  211. expr.swap(initialValueValues_.back());
  212. initialValueNames_.push_back(ident);
  213. }
  214. void Interpreter::installUnits()
  215. {
  216. static struct {
  217. const char *name;
  218. int numer;
  219. int denom;
  220. bool dsssl2;
  221. } units[] = {
  222. { "m", 5000, 127 },
  223. { "cm", 50, 127 },
  224. { "mm", 5, 127 },
  225. { "in", 1, 1 },
  226. { "pt", 1, 72 },
  227. { "pica", 1, 6 },
  228. { "pc", 1, 6 } // a DSSSL2 addition
  229. };
  230. size_t nUnits = dsssl2() ? SIZEOF(units) : SIZEOF(units) - 1;
  231. for (size_t i = 0; i < nUnits; i++) {
  232. Unit *unit = lookupUnit(makeStringC(units[i].name));
  233. long n = unitsPerInch_ * units[i].numer;
  234. if (n % units[i].denom == 0)
  235. unit->setValue(long(n / units[i].denom));
  236. else
  237. unit->setValue(double(n)/units[i].denom);
  238. }
  239. }
  240. void Interpreter::installSyntacticKeys()
  241. {
  242. static struct {
  243. const char *name;
  244. Identifier::SyntacticKey key;
  245. } keys[] = {
  246. { "quote", Identifier::keyQuote },
  247. { "lambda", Identifier::keyLambda },
  248. { "if", Identifier::keyIf },
  249. { "cond", Identifier::keyCond },
  250. { "and", Identifier::keyAnd },
  251. { "or", Identifier::keyOr },
  252. { "case", Identifier::keyCase },
  253. { "let", Identifier::keyLet },
  254. { "let*", Identifier::keyLetStar },
  255. { "letrec", Identifier::keyLetrec },
  256. { "quasiquote", Identifier::keyQuasiquote },
  257. { "unquote", Identifier::keyUnquote },
  258. { "unquote-splicing", Identifier::keyUnquoteSplicing },
  259. { "define", Identifier::keyDefine },
  260. { "else", Identifier::keyElse },
  261. { "=>", Identifier::keyArrow },
  262. { "there-exists?", Identifier::keyThereExists },
  263. { "for-all?", Identifier::keyForAll },
  264. { "select-each", Identifier::keySelectEach },
  265. { "union-for-each", Identifier::keyUnionForEach },
  266. { "define-unit", Identifier::keyDefineUnit },
  267. { "declare-default-language", Identifier::keyDeclareDefaultLanguage },
  268. { "declare-char-property", Identifier::keyDeclareCharProperty },
  269. { "define-language", Identifier::keyDefineLanguage },
  270. { "collate", Identifier::keyCollate },
  271. { "toupper", Identifier::keyToupper },
  272. { "tolower", Identifier::keyTolower },
  273. { "symbol", Identifier::keySymbol },
  274. { "order", Identifier::keyOrder },
  275. { "forward", Identifier::keyForward },
  276. { "backward", Identifier::keyBackward },
  277. { "add-char-properties", Identifier::keyAddCharProperties },
  278. { "architecture", Identifier::keyArchitecture },
  279. { "default", Identifier::keyDefault },
  280. { "null", Identifier::keyNull },
  281. { "rcs?", Identifier::keyIsRcs },
  282. { "parent", Identifier::keyParent },
  283. { "active", Identifier::keyActive },
  284. { "label", Identifier::keyLabel },
  285. { "children", Identifier::keyChildren },
  286. { "class", Identifier::keyClass },
  287. }, styleKeys[] = {
  288. { "make", Identifier::keyMake },
  289. { "style", Identifier::keyStyle },
  290. { "with-mode", Identifier::keyWithMode },
  291. { "query", Identifier::keyQuery },
  292. { "element", Identifier::keyElement },
  293. { "root", Identifier::keyRoot },
  294. { "id", Identifier::keyId },
  295. { "mode", Identifier::keyMode },
  296. { "declare-initial-value", Identifier::keyDeclareInitialValue },
  297. { "declare-characteristic", Identifier::keyDeclareCharacteristic },
  298. { "declare-flow-object-class", Identifier::keyDeclareFlowObjectClass },
  299. { "declare-char-characteristic+property", Identifier::keyDeclareCharCharacteristicAndProperty },
  300. { "declare-reference-value-type", Identifier::keyDeclareReferenceValueType },
  301. { "define-page-model", Identifier::keyDefinePageModel },
  302. { "define-column-set-model", Identifier::keyDefineColumnSetModel },
  303. { "use", Identifier::keyUse },
  304. { "content-map", Identifier::keyContentMap },
  305. { "keep-with-previous?", Identifier::keyIsKeepWithPrevious },
  306. { "keep-with-next?", Identifier::keyIsKeepWithNext },
  307. { "space-before", Identifier::keySpaceBefore },
  308. { "space-after", Identifier::keySpaceAfter },
  309. { "left-header", Identifier::keyLeftHeader },
  310. { "center-header", Identifier::keyCenterHeader },
  311. { "right-header", Identifier::keyRightHeader },
  312. { "left-footer", Identifier::keyLeftFooter },
  313. { "center-footer", Identifier::keyCenterFooter },
  314. { "right-footer", Identifier::keyRightFooter },
  315. { "destination", Identifier::keyDestination },
  316. { "type", Identifier::keyType },
  317. { "coalesce-id", Identifier::keyCoalesceId },
  318. { "display?", Identifier::keyIsDisplay },
  319. { "scale", Identifier::keyScale },
  320. { "max-width", Identifier::keyMaxWidth },
  321. { "max-height", Identifier::keyMaxHeight },
  322. { "entity-system-id", Identifier::keyEntitySystemId },
  323. { "notation-system-id", Identifier::keyNotationSystemId },
  324. { "position-point-x", Identifier::keyPositionPointX },
  325. { "position-point-y", Identifier::keyPositionPointY },
  326. { "escapement-direction", Identifier::keyEscapementDirection },
  327. { "break-before-priority", Identifier::keyBreakBeforePriority },
  328. { "break-after-priority", Identifier::keyBreakAfterPriority },
  329. { "orientation", Identifier::keyOrientation },
  330. { "length", Identifier::keyLength },
  331. { "char", Identifier::keyChar },
  332. { "glyph-id", Identifier::keyGlyphId },
  333. { "space?", Identifier::keyIsSpace },
  334. { "record-end?", Identifier::keyIsRecordEnd },
  335. { "input-tab?", Identifier::keyIsInputTab },
  336. { "input-whitespace?", Identifier::keyIsInputWhitespace },
  337. { "punct?", Identifier::keyIsPunct },
  338. { "drop-after-line-break?", Identifier::keyIsDropAfterLineBreak },
  339. { "drop-unless-before-line-break?", Identifier::keyIsDropUnlessBeforeLineBreak },
  340. { "math-class", Identifier::keyMathClass },
  341. { "math-font-posture", Identifier::keyMathFontPosture },
  342. { "script", Identifier::keyScript },
  343. { "stretch-factor", Identifier::keyStretchFactor },
  344. { "keep", Identifier::keyKeep },
  345. { "break-before", Identifier::keyBreakBefore },
  346. { "break-after", Identifier::keyBreakAfter },
  347. { "may-violate-keep-before?", Identifier::keyIsMayViolateKeepBefore },
  348. { "may-violate-keep-after?", Identifier::keyIsMayViolateKeepAfter },
  349. { "before-row-border", Identifier::keyBeforeRowBorder },
  350. { "after-row-border", Identifier::keyAfterRowBorder },
  351. { "before-column-border", Identifier::keyBeforeColumnBorder },
  352. { "after-column-border", Identifier::keyAfterColumnBorder },
  353. { "column-number", Identifier::keyColumnNumber },
  354. { "row-number", Identifier::keyRowNumber },
  355. { "n-columns-spanned", Identifier::keyNColumnsSpanned },
  356. { "n-rows-spanned", Identifier::keyNRowsSpanned },
  357. { "width", Identifier::keyWidth },
  358. { "starts-row?", Identifier::keyIsStartsRow },
  359. { "ends-row?", Identifier::keyIsEndsRow },
  360. { "table-width", Identifier::keyTableWidth },
  361. { "multi-modes", Identifier::keyMultiModes },
  362. { "data", Identifier::keyData },
  363. { "min", Identifier::keyMin },
  364. { "max", Identifier::keyMax },
  365. { "conditional?", Identifier::keyIsConditional },
  366. { "priority", Identifier::keyPriority },
  367. { "grid-n-rows", Identifier::keyGridNRows },
  368. { "grid-n-columns", Identifier::keyGridNColumns },
  369. { "radical", Identifier::keyRadical },
  370. { "attributes", Identifier::keyAttributes },
  371. { "repeat", Identifier::keyRepeat },
  372. { "position", Identifier::keyPosition },
  373. { "only", Identifier::keyOnly },
  374. { "importance", Identifier::keyImportance },
  375. { "position-preference", Identifier::keyPositionPreference },
  376. { "white-point", Identifier::keyWhitePoint },
  377. { "black-point", Identifier::keyBlackPoint },
  378. { "range", Identifier::keyRange },
  379. { "range-abc", Identifier::keyRangeAbc },
  380. { "range-lmn", Identifier::keyRangeLmn },
  381. { "range-a", Identifier::keyRangeA },
  382. { "decode-abc", Identifier::keyDecodeAbc },
  383. { "decode-lmn", Identifier::keyDecodeLmn },
  384. { "decode-a", Identifier::keyDecodeA },
  385. { "matrix-abc", Identifier::keyMatrixAbc },
  386. { "matrix-lmn", Identifier::keyMatrixLmn },
  387. { "matrix-a", Identifier::keyMatrixA },
  388. }, transformKeys[] = {
  389. { "define-transliteration-map", Identifier::keyDefineTransliterationMap },
  390. { "node", Identifier::keyNode },
  391. { "subgrove", Identifier::keySubgrove },
  392. { "add", Identifier::keyAdd },
  393. { "remove", Identifier::keyRemove },
  394. { "sub", Identifier::keySub },
  395. { "sort-children", Identifier::keySortChildren },
  396. { "optional", Identifier::keyOptional },
  397. { "unique", Identifier::keyUnique },
  398. { "result-path", Identifier::keyResultPath },
  399. { "property", Identifier::keyProperty },
  400. }, keys2[] = {
  401. { "declare-class-attribute", Identifier::keyDeclareClassAttribute },
  402. { "declare-id-attribute", Identifier::keyDeclareIdAttribute },
  403. { "declare-flow-object-macro", Identifier::keyDeclareFlowObjectMacro },
  404. { "or-element", Identifier::keyOrElement },
  405. { "set!", Identifier::keySet },
  406. { "begin", Identifier::keyBegin },
  407. };
  408. for (size_t i = 0; i < SIZEOF(keys); i++) {
  409. StringC tem(makeStringC(keys[i].name));
  410. lookup(tem)->setSyntacticKey(keys[i].key);
  411. if (dsssl2() && tem[tem.size() - 1] == '?') {
  412. tem.resize(tem.size() - 1);
  413. lookup(tem)->setSyntacticKey(keys[i].key);
  414. }
  415. }
  416. if (style())
  417. for (size_t i = 0; i < SIZEOF(styleKeys); i++) {
  418. StringC tem(makeStringC(styleKeys[i].name));
  419. lookup(tem)->setSyntacticKey(styleKeys[i].key);
  420. if (dsssl2() && tem[tem.size() - 1] == '?') {
  421. tem.resize(tem.size() - 1);
  422. lookup(tem)->setSyntacticKey(styleKeys[i].key);
  423. }
  424. }
  425. else
  426. for (size_t i = 0; i < SIZEOF(transformKeys); i++) {
  427. StringC tem(makeStringC(transformKeys[i].name));
  428. lookup(tem)->setSyntacticKey(transformKeys[i].key);
  429. }
  430. if (dsssl2()) {
  431. for (size_t i = 0; i < SIZEOF(keys2); i++)
  432. lookup(makeStringC(keys2[i].name))->setSyntacticKey(keys2[i].key);
  433. }
  434. }
  435. void Interpreter::installCValueSymbols()
  436. {
  437. cValueSymbols_[0] = makeFalse();
  438. cValueSymbols_[1] = makeTrue();
  439. for (size_t i = 2; i < FOTBuilder::nSymbols; i++) {
  440. SymbolObj *sym = makeSymbol(makeStringC(FOTBuilder::symbolName(FOTBuilder::Symbol(i))));
  441. sym->setCValue(FOTBuilder::Symbol(i));
  442. cValueSymbols_[i] = sym;
  443. }
  444. }
  445. void Interpreter::installPortNames()
  446. {
  447. // These must match the order in SymbolObj.
  448. static const char *names[] = {
  449. "numerator",
  450. "denominator",
  451. "pre-sup",
  452. "pre-sub",
  453. "post-sup",
  454. "post-sub",
  455. "mid-sup",
  456. "mid-sub",
  457. "over-mark",
  458. "under-mark",
  459. "open",
  460. "close",
  461. "degree",
  462. "operator",
  463. "lower-limit",
  464. "upper-limit",
  465. "header",
  466. "footer"
  467. };
  468. ASSERT(SIZEOF(names) == nPortNames);
  469. for (size_t i = 0; i < SIZEOF(names); i++)
  470. portNames_[i] = makeSymbol(makeStringC(names[i]));
  471. }
  472. void Interpreter::installCharNames()
  473. {
  474. if (!strictMode()) {
  475. static struct {
  476. Char c;
  477. const char *name;
  478. } chars[] = {
  479. #include "charNames.h"
  480. };
  481. for (size_t i = 0; i < SIZEOF(chars); i++) {
  482. CharPart ch;
  483. ch.c = chars[i].c;
  484. ch.defPart = unsigned(-1);
  485. namedCharTable_.insert(makeStringC(chars[i].name), ch, 1);
  486. }
  487. }
  488. }
  489. void Interpreter::installSdata()
  490. {
  491. if (!strictMode()) {
  492. // This comes from uni2sgml.txt on ftp://unicode.org.
  493. // It is marked there as obsolete, so it probably ought to be checked.
  494. // The definitions of apos and quot have been fixed for consistency with XML.
  495. static struct {
  496. Char c;
  497. const char *name;
  498. } entities[] = {
  499. #include "sdata.h"
  500. };
  501. for (size_t i = 0; i < SIZEOF(entities); i++) {
  502. CharPart ch;
  503. ch.c = entities[i].c;
  504. ch.defPart = unsigned(-1);
  505. sdataEntityNameTable_.insert(makeStringC(entities[i].name), ch, 1);
  506. }
  507. }
  508. }
  509. void Interpreter::installNodeProperties()
  510. {
  511. for (int i = 0; i < ComponentName::nIds; i++) {
  512. ComponentName::Id id = ComponentName::Id(i);
  513. nodePropertyTable_.insert(makeStringC(ComponentName::rcsName(id)), i);
  514. nodePropertyTable_.insert(makeStringC(ComponentName::sdqlName(id)), i);
  515. }
  516. }
  517. void Interpreter::setCharRepertoire(const StringC &pubid)
  518. {
  519. if (pubid == "UNREGISTERED::OpenJade//Character Repertoire::OpenJade") {
  520. if (strictMode_) {
  521. installCharNames();
  522. installSdata();
  523. // This assumes that we process char-repertoire
  524. // declaration before any declarations which change
  525. // lexical categories.
  526. for (Char i = 127; i < charMax; i++)
  527. lexCategory_.setChar(i, lexAddNameStart);
  528. strictMode_ = 0;
  529. }
  530. } else
  531. message(InterpreterMessages::unsupportedCharRepertoire,
  532. StringMessageArg(pubid));
  533. }
  534. void Interpreter::addStandardChar(const StringC &name, const StringC &num)
  535. {
  536. int n;
  537. size_t i = 0;
  538. if (!scanSignDigits(num, i, n)) {
  539. message(InterpreterMessages::invalidCharNumber, StringMessageArg(num));
  540. return;
  541. }
  542. const CharPart *def = namedCharTable_.lookup(name);
  543. CharPart ch;
  544. ch.c = n;
  545. ch.defPart = dPartIndex_;
  546. if (def) {
  547. if (dPartIndex_ < def->defPart)
  548. namedCharTable_.insert(name, ch, 1);
  549. else if (def->defPart == dPartIndex_ && def->c != ch.c)
  550. message(InterpreterMessages::duplicateCharName,
  551. StringMessageArg(name));
  552. }
  553. else
  554. namedCharTable_.insert(name, ch, 1);
  555. }
  556. void Interpreter::addNameChar(const StringC &name)
  557. {
  558. const CharPart *cp = namedCharTable_.lookup(name);
  559. if (!cp)
  560. message(InterpreterMessages::badCharName,
  561. StringMessageArg(name));
  562. else if (lexCategory_[cp->c] != lexOther)
  563. // FIXME give a more specific error
  564. message(InterpreterMessages::badDeclaration);
  565. else
  566. lexCategory_.setChar(cp->c, lexAddNameStart);
  567. }
  568. void Interpreter::addSeparatorChar(const StringC &name)
  569. {
  570. const CharPart *cp = namedCharTable_.lookup(name);
  571. if (!cp)
  572. message(InterpreterMessages::badCharName,
  573. StringMessageArg(name));
  574. else if (lexCategory_[cp->c] != lexOther)
  575. // FIXME give a more specific error
  576. message(InterpreterMessages::badDeclaration);
  577. else
  578. lexCategory_.setChar(cp->c, lexAddWhiteSpace);
  579. }
  580. void Interpreter::addSdataEntity(const StringC &ename, const StringC &etext, const StringC &name)
  581. {
  582. const CharPart *cp = namedCharTable_.lookup(name);
  583. if (!cp) {
  584. message(InterpreterMessages::badCharName,
  585. StringMessageArg(name));
  586. return;
  587. }
  588. CharPart ch;
  589. ch.c = cp->c;
  590. ch.defPart = dPartIndex_;
  591. if (ename.size() > 0) {
  592. const CharPart *def = sdataEntityNameTable_.lookup(ename);
  593. if (def) {
  594. if (dPartIndex_ < def->defPart)
  595. sdataEntityNameTable_.insert(ename, ch);
  596. else if (def->defPart == dPartIndex_ && def->c != cp->c)
  597. message(InterpreterMessages::duplicateSdataEntityName,
  598. StringMessageArg(ename));
  599. }
  600. else
  601. sdataEntityNameTable_.insert(ename, ch);
  602. }
  603. if (etext.size() > 0) {
  604. const CharPart *def = sdataEntityTextTable_.lookup(etext);
  605. if (def) {
  606. if (dPartIndex_ < def->defPart)
  607. sdataEntityTextTable_.insert(etext, ch);
  608. else if (def->defPart == dPartIndex_ && def->c != cp->c)
  609. message(InterpreterMessages::duplicateSdataEntityText,
  610. StringMessageArg(etext));
  611. }
  612. else
  613. sdataEntityTextTable_.insert(etext, ch);
  614. }
  615. }
  616. bool Interpreter::sdataMap(GroveString name, GroveString text, GroveChar &c) const
  617. {
  618. StringC tem(name.data(), name.size());
  619. StringC tem2(text.data(), text.size());
  620. const CharPart *cp = sdataEntityNameTable_.lookup(tem);
  621. if (cp) {
  622. c = cp->c;
  623. return 1;
  624. }
  625. cp = sdataEntityTextTable_.lookup(tem2);
  626. if (cp) {
  627. c = cp->c;
  628. return 1;
  629. }
  630. if (convertUnicodeCharName(tem, c))
  631. return 1;
  632. // I think this is the best thing to do.
  633. // At least it makes preserve-sdata work with unknown SDATA entities.
  634. c = defaultChar;
  635. return 1;
  636. }
  637. ELObj *Interpreter::convertGlyphId(const Char *str, size_t len, const Location &loc)
  638. {
  639. unsigned long n = 0;
  640. const char *publicId = 0;
  641. for (size_t i = len; i > 1; --i) {
  642. if (str[i - 1] == ':' && str[i - 2] == ':' && i < len && str[i] != '0') {
  643. for (size_t j = i; j < len; j++)
  644. n = n*10 + (str[j] - '0');
  645. publicId = storePublicId(str, i - 2, loc);
  646. break;
  647. }
  648. if (str[i - 1] < '0' || str[i - 1] > '9')
  649. break;
  650. }
  651. if (!publicId)
  652. publicId = storePublicId(str, len, loc);
  653. return new (*this) GlyphIdObj(FOTBuilder::GlyphId(publicId, n));
  654. }
  655. bool Interpreter::convertCharName(const StringC &str, Char &c) const
  656. {
  657. const CharPart *cp = namedCharTable_.lookup(str);
  658. if (cp) {
  659. c = cp->c;
  660. return 1;
  661. }
  662. return convertUnicodeCharName(str, c);
  663. }
  664. bool Interpreter::convertUnicodeCharName(const StringC &str, Char &c)
  665. {
  666. if (str.size() != 6 || str[0] != 'U' || str[1] != '-')
  667. return 0;
  668. Char value = 0;
  669. for (int i = 2; i < 6; i++) {
  670. value <<= 4;
  671. switch (str[i]) {
  672. case '0':
  673. case '1':
  674. case '2':
  675. case '3':
  676. case '4':
  677. case '5':
  678. case '6':
  679. case '7':
  680. case '8':
  681. case '9':
  682. value |= str[i] - '0';
  683. break;
  684. case 'A':
  685. case 'B':
  686. case 'C':
  687. case 'D':
  688. case 'E':
  689. case 'F':
  690. value |= 10 + (str[i] - 'A');
  691. break;
  692. default:
  693. return 0;
  694. }
  695. }
  696. c = value;
  697. return 1;
  698. }
  699. SymbolObj *Interpreter::makeSymbol(const StringC &str)
  700. {
  701. SymbolObj *sym = symbolTable_.lookup(str);
  702. if (!sym) {
  703. StringObj *strObj = new (*this) StringObj(str);
  704. makePermanent(strObj);
  705. sym = new (*this) SymbolObj(strObj);
  706. makePermanent(sym);
  707. symbolTable_.insert(sym);
  708. }
  709. return sym;
  710. }
  711. Identifier *Interpreter::lookup(const StringC &str)
  712. {
  713. Identifier *ident = identTable_.lookup(str);
  714. if (!ident) {
  715. ident = new Identifier(str);
  716. identTable_.insert(ident);
  717. }
  718. return ident;
  719. }
  720. bool Interpreter::lookupNodeProperty(const StringC &str, ComponentName::Id &id)
  721. {
  722. const int *val = nodePropertyTable_.lookup(str);
  723. if (!val) {
  724. StringC tem(str);
  725. for (size_t i = 0; i < tem.size(); i++) {
  726. if (tem[i] >= 'A' && tem[i] <= 'Z')
  727. tem[i] = 'a' + (tem[i] - 'A');
  728. }
  729. val = nodePropertyTable_.lookup(tem);
  730. if (!val)
  731. return 0;
  732. }
  733. id = ComponentName::Id(*val);
  734. return 1;
  735. }
  736. Unit *Interpreter::lookupUnit(const StringC &str)
  737. {
  738. Unit *unit = unitTable_.lookup(str);
  739. if (!unit) {
  740. unit = new Unit(str);
  741. unitTable_.insert(unit);
  742. }
  743. return unit;
  744. }
  745. CharProp *Interpreter::lookupCharProperty(const StringC &n)
  746. {
  747. CharProp *p = charPropTable_.lookup(n);
  748. if (!p) {
  749. p = new CharProp(n);
  750. charPropTable_.insert(p);
  751. }
  752. return p;
  753. }
  754. ProcessingMode *Interpreter::lookupProcessingMode(const StringC &str)
  755. {
  756. ProcessingMode *mode = processingModeTable_.lookup(str);
  757. if (!mode) {
  758. mode = new ProcessingMode(str, &initialProcessingMode_);
  759. processingModeTable_.insert(mode);
  760. }
  761. return mode;
  762. }
  763. StringC Interpreter::makeStringC(const char *s)
  764. {
  765. StringC tem;
  766. if (s)
  767. while (*s)
  768. tem += (unsigned char)*s++;
  769. return tem;
  770. }
  771. void Interpreter::endPart()
  772. {
  773. currentPartFirstInitialValue_ = initialValueNames_.size();
  774. partIndex_++;
  775. }
  776. void Interpreter::dEndPart()
  777. {
  778. dPartIndex_++;
  779. }
  780. void Interpreter::normalizeGeneralName(const NodePtr &nd, StringC &str)
  781. {
  782. NamedNodeListPtr nnl;
  783. NodePtr root;
  784. if (nd->getGroveRoot(root) == accessOK
  785. && root->getElements(nnl) == accessOK)
  786. str.resize(nnl->normalize(str.begin(), str.size()));
  787. }
  788. ELObj *Interpreter::makeLengthSpec(const FOTBuilder::LengthSpec &ls)
  789. {
  790. if (ls.displaySizeFactor != 0.0) {
  791. LengthSpec result(LengthSpec::displaySize, ls.displaySizeFactor);
  792. result += double(ls.length);
  793. return new (*this) LengthSpecObj(result);
  794. }
  795. else
  796. return new (*this) LengthObj(ls.length);
  797. }
  798. bool Interpreter::convertBooleanC(ELObj *obj, const Identifier *ident, const Location &loc,
  799. bool &result)
  800. {
  801. obj = convertFromString(obj, convertAllowBoolean, loc);
  802. if (obj == makeFalse()) {
  803. result = 0;
  804. return 1;
  805. }
  806. if (obj == makeTrue()) {
  807. result = 1;
  808. return 1;
  809. }
  810. invalidCharacteristicValue(ident, loc);
  811. return 0;
  812. }
  813. bool Interpreter::convertPublicIdC(ELObj *obj, const Identifier *ident,
  814. const Location &loc,
  815. FOTBuilder::PublicId &pubid)
  816. {
  817. if (obj == makeFalse()) {
  818. pubid = 0;
  819. return 1;
  820. }
  821. const Char *s;
  822. size_t n;
  823. if (obj->stringData(s, n)) {
  824. if (n == 0)
  825. pubid = 0;
  826. else
  827. pubid = storePublicId(s, n, loc);
  828. return 1;
  829. }
  830. invalidCharacteristicValue(ident, loc);
  831. return 0;
  832. }
  833. const char *Interpreter::storePublicId(const Char *s, size_t n, const Location &loc)
  834. {
  835. String<char> buf;
  836. for (; n > 0; s++, n--) {
  837. if (*s >= 128) {
  838. setNextLocation(loc);
  839. message(InterpreterMessages::invalidPublicIdChar,
  840. StringMessageArg(StringC(s, 1)));
  841. }
  842. else
  843. buf += char(*s);
  844. }
  845. buf += '\0';
  846. return publicIds_.store(buf);
  847. }
  848. bool Interpreter::convertStringC(ELObj *obj, const Identifier *ident, const Location &loc,
  849. StringC &result)
  850. {
  851. const Char *s;
  852. size_t n;
  853. if (obj->stringData(s, n)) {
  854. result.assign(s, n);
  855. return 1;
  856. }
  857. invalidCharacteristicValue(ident, loc);
  858. return 0;
  859. }
  860. bool Interpreter::convertLengthSpec(ELObj *obj,
  861. FOTBuilder::LengthSpec &result)
  862. {
  863. int dim;
  864. double d;
  865. switch (obj->quantityValue(result.length, d, dim)) {
  866. case ELObj::longQuantity:
  867. if (dim == 1)
  868. return 1;
  869. break;
  870. case ELObj::doubleQuantity:
  871. if (dim == 1) {
  872. // FIXME catch overflow
  873. result.length = d < 0.0 ? long(d - .5) : long(d + .5);
  874. return 1;
  875. }
  876. break;
  877. default:
  878. {
  879. const LengthSpec *ls = obj->lengthSpec();
  880. if (ls)
  881. return ls->convert(result);
  882. }
  883. break;
  884. }
  885. return 0;
  886. }
  887. bool Interpreter::convertLengthC(ELObj *obj, const Identifier *ident,
  888. const Location &loc,
  889. FOTBuilder::Length &n)
  890. {
  891. obj = convertFromString(obj, convertAllowNumber, loc);
  892. int dim;
  893. double d;
  894. switch (obj->quantityValue(n, d, dim)) {
  895. case ELObj::longQuantity:
  896. if (dim == 1)
  897. return 1;
  898. break;
  899. case ELObj::doubleQuantity:
  900. if (dim == 1) {
  901. // FIXME catch overflow
  902. n = long(d);
  903. return 1;
  904. }
  905. break;
  906. default:
  907. break;
  908. }
  909. invalidCharacteristicValue(ident, loc);
  910. return 0;
  911. }
  912. bool Interpreter::convertLengthSpecC(ELObj *obj, const Identifier *ident,
  913. const Location &loc,
  914. FOTBuilder::LengthSpec &result)
  915. {
  916. obj = convertFromString(obj, convertAllowNumber, loc);
  917. if (convertLengthSpec(obj, result))
  918. return 1;
  919. invalidCharacteristicValue(ident, loc);
  920. return 0;
  921. }
  922. bool Interpreter::convertOptLengthSpecC(ELObj *obj, const Identifier *ident,
  923. const Location &loc,
  924. FOTBuilder::OptLengthSpec &result)
  925. {
  926. obj = convertFromString(obj, convertAllowBoolean|convertAllowNumber, loc);
  927. if (obj == makeFalse()) {
  928. result.hasLength = 0;
  929. return 1;
  930. }
  931. if (convertLengthSpecC(obj, ident, loc, result.length)) {
  932. result.hasLength = 1;
  933. return 1;
  934. }
  935. return 0;
  936. }
  937. bool Interpreter::convertOptPositiveIntegerC(ELObj *obj, const Identifier *ident, const Location &loc,
  938. long &result)
  939. {
  940. obj = convertFromString(obj, convertAllowNumber|convertAllowBoolean, loc);
  941. if (obj == makeFalse()) {
  942. result = 0;
  943. return 1;
  944. }
  945. if (obj->exactIntegerValue(result) && result > 0)
  946. return 1;
  947. // FIXME allow inexact value
  948. invalidCharacteristicValue(ident, loc);
  949. return 0;
  950. }
  951. bool Interpreter::convertIntegerC(ELObj *obj, const Identifier *ident, const Location &loc,
  952. long &result)
  953. {
  954. obj = convertFromString(obj, convertAllowNumber, loc);
  955. if (obj->exactIntegerValue(result))
  956. return 1;
  957. // FIXME allow inexact value
  958. invalidCharacteristicValue(ident, loc);
  959. return 0;
  960. }
  961. bool Interpreter::convertLetter2C(ELObj *obj, const Identifier *ident, const Location &loc,
  962. FOTBuilder::Letter2 &code)
  963. {
  964. StringObj *strObj = obj->convertToString();
  965. if (strObj) {
  966. const StringC &str = *strObj;
  967. if (str.size() == 2
  968. && str[0] >= 'A' && str[0] <= 'Z'
  969. && str[1] >= 'A' && str[1] <= 'Z') {
  970. code = SP_LETTER2(str[0], str[1]);
  971. return 1;
  972. }
  973. if (str.size() == 0) {
  974. code = 0;
  975. return 1;
  976. }
  977. }
  978. else if (obj == makeFalse()) {
  979. code = 0;
  980. return 1;
  981. }
  982. invalidCharacteristicValue(ident, loc);
  983. return 0;
  984. }
  985. bool Interpreter::convertCharC(ELObj *obj, const Identifier *ident, const Location &loc,
  986. Char &result)
  987. {
  988. if (obj->charValue(result))
  989. return 1;
  990. const Char *s;
  991. size_t n;
  992. if (obj->stringData(s, n) && n == 1) {
  993. result = s[0];
  994. return 1;
  995. }
  996. invalidCharacteristicValue(ident, loc);
  997. return 0;
  998. }
  999. bool Interpreter::convertColorC(ELObj *obj, const Identifier *ident, const Location &loc, ColorObj *&color)
  1000. {
  1001. color = obj->asColor();
  1002. if (color)
  1003. return 1;
  1004. invalidCharacteristicValue(ident, loc);
  1005. return 0;
  1006. }
  1007. bool Interpreter::convertOptColorC(ELObj *obj, const Identifier *ident, const Location &loc, ColorObj *&color)
  1008. {
  1009. color = obj->asColor();
  1010. if (color)
  1011. return 1;
  1012. if (obj == makeFalse())
  1013. return 1;
  1014. invalidCharacteristicValue(ident, loc);
  1015. return 0;
  1016. }
  1017. bool Interpreter::convertRealC(ELObj *obj, const Identifier *ident, const Location &loc,
  1018. double &result)
  1019. {
  1020. obj = convertFromString(obj, convertAllowNumber, loc);
  1021. if (obj->realValue(result))
  1022. return 1;
  1023. invalidCharacteristicValue(ident, loc);
  1024. return 0;
  1025. }
  1026. bool Interpreter::convertEnumC(ELObj *obj, const Identifier *ident, const Location &loc,
  1027. FOTBuilder::Symbol &sym)
  1028. {
  1029. obj = convertFromString(obj, convertAllowSymbol|convertAllowBoolean, loc);
  1030. if (obj == makeFalse()) {
  1031. sym = FOTBuilder::symbolFalse;
  1032. return 1;
  1033. }
  1034. SymbolObj *symObj = obj->asSymbol();
  1035. if (symObj) {
  1036. sym = symObj->cValue();
  1037. if (sym != FOTBuilder::symbolFalse)
  1038. return 1;
  1039. }
  1040. if (obj == makeTrue()) {
  1041. sym = FOTBuilder::symbolTrue;
  1042. return 1;
  1043. }
  1044. invalidCharacteristicValue(ident, loc);
  1045. return 0;
  1046. }
  1047. bool Interpreter::convertEnumC(const FOTBuilder::Symbol *syms, size_t nSyms,
  1048. ELObj *obj, const Identifier *ident, const Location &loc,
  1049. FOTBuilder::Symbol &result)
  1050. {
  1051. obj = convertFromString(obj, convertAllowSymbol|convertAllowBoolean, loc);
  1052. SymbolObj *symObj = obj->asSymbol();
  1053. FOTBuilder::Symbol val;
  1054. if (symObj) {
  1055. val = symObj->cValue();
  1056. if (val == FOTBuilder::symbolFalse) {
  1057. invalidCharacteristicValue(ident, loc);
  1058. return 0;
  1059. }
  1060. }
  1061. else if (obj == makeFalse())
  1062. val = FOTBuilder::symbolFalse;
  1063. else if (obj == makeTrue())
  1064. val = FOTBuilder::symbolTrue;
  1065. else {
  1066. invalidCharacteristicValue(ident, loc);
  1067. return 0;
  1068. }
  1069. for (size_t i = 0; i < nSyms; i++)
  1070. if (val == syms[i]) {
  1071. result = val;
  1072. return 1;
  1073. }
  1074. invalidCharacteristicValue(ident, loc);
  1075. return 0;
  1076. }
  1077. void Interpreter::invalidCharacteristicValue(const Identifier *ident, const Location &loc)
  1078. {
  1079. setNextLocation(loc);
  1080. message(InterpreterMessages::invalidCharacteristicValue,
  1081. StringMessageArg(ident->name()));
  1082. }
  1083. static
  1084. bool equal(const Char *s1, const char *s2, size_t n)
  1085. {
  1086. while (n > 0) {
  1087. if (*s1++ != (unsigned char)*s2++)
  1088. return 0;
  1089. --n;
  1090. }
  1091. return 1;
  1092. }
  1093. ELObj *Interpreter::convertFromString(ELObj *obj, unsigned hints, const Location &loc)
  1094. {
  1095. // FIXME fold to lower case
  1096. const Char *s;
  1097. size_t n;
  1098. if (!dsssl2() || !obj->stringData(s, n))
  1099. return obj;
  1100. if (hints & convertAllowNumber) {
  1101. ELObj *tem = convertNumber(StringC(s, n));
  1102. if (tem)
  1103. return tem->resolveQuantities(1, *this, loc);
  1104. }
  1105. if (hints & convertAllowSymbol) {
  1106. StringC tem(s, n);
  1107. SymbolObj *sym = symbolTable_.lookup(tem);
  1108. if (sym && sym->cValue() != FOTBuilder::symbolFalse)
  1109. return sym;
  1110. }
  1111. if (hints & convertAllowBoolean) {
  1112. switch (n) {
  1113. case 2:
  1114. if (equal(s, "no", n))
  1115. return makeFalse();
  1116. break;
  1117. case 3:
  1118. if (equal(s, "yes", n))
  1119. return makeTrue();
  1120. break;
  1121. case 4:
  1122. if (equal(s, "true", n))
  1123. return makeTrue();
  1124. break;
  1125. case 5:
  1126. if (equal(s, "false", n))
  1127. return makeFalse();
  1128. break;
  1129. }
  1130. }
  1131. return obj;
  1132. }
  1133. ELObj *Interpreter::convertNumber(const StringC &str, int radix)
  1134. {
  1135. {
  1136. if (str.size() == 0)
  1137. return 0;
  1138. size_t i = 0;
  1139. if (str[0] == '#') {
  1140. if (str.size() < 2)
  1141. return 0;
  1142. switch (str[1]) {
  1143. case 'd':
  1144. radix = 10;
  1145. break;
  1146. case 'x':
  1147. radix = 16;
  1148. break;
  1149. case 'o':
  1150. radix = 8;
  1151. break;
  1152. case 'b':
  1153. radix = 2;
  1154. break;
  1155. default:
  1156. return 0;
  1157. }
  1158. i += 2;
  1159. }
  1160. if (i >= str.size())
  1161. return 0;
  1162. bool negative;
  1163. if (str[i] == '-') {
  1164. negative = 1;
  1165. i++;
  1166. }
  1167. else {
  1168. negative = 0;
  1169. if (str[i] == '+')
  1170. i++;
  1171. }
  1172. bool hadDecimalPoint = 0;
  1173. bool hadDigit = 0;
  1174. long n = 0;
  1175. int exp = 0;
  1176. for (; i < str.size(); i++) {
  1177. Char c = str[i];
  1178. int weight;
  1179. switch (c) {
  1180. case '0':
  1181. weight = 0;
  1182. break;
  1183. case '1':
  1184. weight = 1;
  1185. break;
  1186. case '2':
  1187. weight = 2;
  1188. break;
  1189. case '3':
  1190. weight = 3;
  1191. break;
  1192. case '4':
  1193. weight = 4;
  1194. break;
  1195. case '5':
  1196. weight = 5;
  1197. break;
  1198. case '6':
  1199. weight = 6;
  1200. break;
  1201. case '7':
  1202. weight = 7;
  1203. break;
  1204. case '8':
  1205. weight = 8;
  1206. break;
  1207. case '9':
  1208. weight = 9;
  1209. break;
  1210. case 'a':
  1211. weight = 10;
  1212. break;
  1213. case 'b':
  1214. weight = 11;
  1215. break;
  1216. case 'c':
  1217. weight = 12;
  1218. break;
  1219. case 'd':
  1220. weight = 13;
  1221. break;
  1222. case 'e':
  1223. weight = 14;
  1224. break;
  1225. case 'f':
  1226. weight = 15;
  1227. break;
  1228. default:
  1229. weight = -1;
  1230. break;
  1231. }
  1232. if (weight >= 0 && weight < radix) {
  1233. hadDigit = 1;
  1234. if (negative) {
  1235. if (-(unsigned long)n > (-(unsigned long)LONG_MIN - weight)/radix) {
  1236. if (radix != 10)
  1237. return 0;
  1238. return convertNumberFloat(str);
  1239. }
  1240. else
  1241. n = n*radix - weight;
  1242. }
  1243. else {
  1244. if (n > (LONG_MAX - weight)/radix) {
  1245. if (radix != 10)
  1246. return 0;
  1247. return convertNumberFloat(str);
  1248. }
  1249. else
  1250. n = n*radix + weight;
  1251. }
  1252. if (hadDecimalPoint)
  1253. exp--;
  1254. }
  1255. else if (c == '.' && radix == 10) {
  1256. if (hadDecimalPoint)
  1257. return 0;
  1258. hadDecimalPoint = 1;
  1259. }
  1260. else
  1261. break;
  1262. }
  1263. if (!hadDigit || (radix != 10 && i < str.size()))
  1264. return 0;
  1265. if (i + 1 < str.size() && str[i] == 'e'
  1266. && lexCategory(str[i + 1]) != lexLetter) {
  1267. hadDecimalPoint = 1;
  1268. i++;
  1269. int e;
  1270. if (!scanSignDigits(str, i, e))
  1271. return 0;
  1272. exp += e;
  1273. }
  1274. if (i < str.size()) {
  1275. int unitExp;
  1276. Unit *unit = scanUnit(str, i, unitExp);
  1277. if (!unit)
  1278. return 0;
  1279. if (unitExp == 1)
  1280. return new (*this) UnresolvedLengthObj(n, exp, unit);
  1281. else
  1282. return convertNumberFloat(str);
  1283. }
  1284. if (hadDecimalPoint)
  1285. return convertNumberFloat(str);
  1286. return makeInteger(n);
  1287. }
  1288. }
  1289. bool Interpreter::scanSignDigits(const StringC &str, size_t &i, int &n)
  1290. {
  1291. bool negative = 0;
  1292. if (i < str.size()) {
  1293. if (str[i] == '-') {
  1294. i++;
  1295. negative = 1;
  1296. } else if (str[i] == '+')
  1297. i++;
  1298. }
  1299. size_t j = i;
  1300. n = 0;
  1301. while (i < str.size()
  1302. && ('0' <= str[i] && str[i] <= '9')) {
  1303. if (negative)
  1304. n = n*10 - (str[i] - '0');
  1305. else
  1306. n = n*10 + (str[i] - '0');
  1307. i++;
  1308. }
  1309. if (i == j)
  1310. return 0;
  1311. return 1;
  1312. }
  1313. ELObj *Interpreter::convertNumberFloat(const StringC &str)
  1314. {
  1315. String<char> buf;
  1316. // omit an optional radix prefix
  1317. size_t i0 = 0;
  1318. if (str.size() > 1 && str[0] == '#' && str[1] == 'd')
  1319. i0 = 2;
  1320. for (size_t i = i0; i < str.size(); i++) {
  1321. if (str[i] > CHAR_MAX || str[i] == '\0')
  1322. return 0;
  1323. // 'E' is a valid exponent marker for C but not us
  1324. if (str[i] == 'E')
  1325. break;
  1326. buf += char(str[i]);
  1327. }
  1328. buf += '\0';
  1329. const char *endPtr;
  1330. double val = strtod((char *)buf.data(), (char **)&endPtr);
  1331. if (endPtr - buf.data() == str.size() - i0)
  1332. return new (*this) RealObj(val);
  1333. if (endPtr == buf.data())
  1334. return 0;
  1335. int unitExp;
  1336. Unit *unit = scanUnit(str, endPtr - buf.data() + i0, unitExp);
  1337. if (!unit)
  1338. return 0;
  1339. return new (*this) UnresolvedQuantityObj(val, unit, unitExp);
  1340. }
  1341. // Return 0 for error.
  1342. Unit *Interpreter::scanUnit(const StringC &str, size_t i, int &unitExp)
  1343. {
  1344. StringC unitName;
  1345. while (i < str.size()) {
  1346. if (str[i] == '-' || str[i] == '+' || ('0' <= str[i] && str[i] <= '9'))
  1347. break;
  1348. unitName += str[i++];
  1349. }
  1350. if (i >= str.size())
  1351. unitExp = 1;
  1352. else {
  1353. unitExp = 0;
  1354. bool neg = 0;
  1355. if (str[i] == '-' || str[i] == '+') {
  1356. if (str[i] == '-')
  1357. neg = 1;
  1358. i++;
  1359. if (i >= str.size())
  1360. return 0;
  1361. }
  1362. while (i < str.size()) {
  1363. if (str[i] < '0' || str[i] > '9')
  1364. return 0;
  1365. unitExp *= 10;
  1366. if (neg)
  1367. unitExp -= (str[i] - '0');
  1368. else
  1369. unitExp += (str[i] - '0');
  1370. i++;
  1371. }
  1372. }
  1373. return lookupUnit(unitName);
  1374. }
  1375. void Interpreter::setNodeLocation(const NodePtr &nd)
  1376. {
  1377. const LocNode *lnp;
  1378. Location nodeLoc;
  1379. if ((lnp = LocNode::convert(nd)) != 0
  1380. && lnp->getLocation(nodeLoc) == accessOK)
  1381. setNextLocation(nodeLoc);
  1382. }
  1383. bool Interpreter::convertToPattern(ELObj *obj, const Location &loc, Pattern &pattern)
  1384. {
  1385. IList<Pattern::Element> list;
  1386. if (!convertToPattern(obj, loc, 0, list))
  1387. return 0;
  1388. Pattern tem(list);
  1389. tem.swap(pattern);
  1390. return 1;
  1391. }
  1392. bool Interpreter::convertToPattern(ELObj *obj, const Location &loc,
  1393. bool isChild,
  1394. IList<Pattern::Element> &list)
  1395. {
  1396. StringObj *str = obj->convertToString();
  1397. if (str) {
  1398. const Char *s;
  1399. size_t n;
  1400. str->stringData(s, n);
  1401. if (!n) {
  1402. setNextLocation(loc);
  1403. message(InterpreterMessages::patternEmptyGi);
  1404. return 0;
  1405. }
  1406. list.insert(new Pattern::Element(StringC(s, n)));
  1407. return 1;
  1408. }
  1409. if (obj == makeTrue()) {
  1410. list.insert(new Pattern::Element(StringC()));
  1411. return 1;
  1412. }
  1413. Pattern::Element *curElement = 0;
  1414. while (!obj->isNil()) {
  1415. PairObj *pair = obj->asPair();
  1416. if (!pair) {
  1417. setNextLocation(loc);
  1418. message(InterpreterMessages::patternNotList);
  1419. return 0;
  1420. }
  1421. ELObj *head = pair->car();
  1422. obj = pair->cdr();
  1423. if (head == makeTrue() && dsssl2()) {
  1424. list.insert(curElement = new Pattern::Element(StringC()));
  1425. continue;
  1426. }
  1427. str = head->convertToString();
  1428. if (str) {
  1429. const Char *s;
  1430. size_t n;
  1431. str->stringData(s, n);
  1432. if (!n) {
  1433. setNextLocation(loc);
  1434. message(InterpreterMessages::patternEmptyGi);
  1435. return 0;
  1436. }
  1437. list.insert(curElement = new Pattern::Element(StringC(s, n)));
  1438. continue;
  1439. }
  1440. if (!curElement) {
  1441. setNextLocation(loc);
  1442. message(InterpreterMessages::patternBadGi,
  1443. ELObjMessageArg(head, *this));
  1444. return 0;
  1445. }
  1446. if (head->isNil())
  1447. continue; // empty attribute list
  1448. if (head->asPair()) {
  1449. if (!patternAddAttributeQualifiers(head, loc, *curElement)) {
  1450. setNextLocation(loc);
  1451. message(InterpreterMessages::patternBadAttributeQualifier);
  1452. return 0;
  1453. }
  1454. continue;
  1455. }
  1456. KeywordObj *key = dsssl2() ? head->asKeyword() : 0;
  1457. if (!key) {
  1458. setNextLocation(loc);
  1459. message(InterpreterMessages::patternBadMember,
  1460. ELObjMessageArg(head, *this));
  1461. return 0;
  1462. }
  1463. pair = obj->asPair();
  1464. if (!pair) {
  1465. setNextLocation(loc);
  1466. message(obj->isNil()
  1467. ? InterpreterMessages::patternMissingQualifierValue
  1468. : InterpreterMessages::patternNotList);
  1469. return 0;
  1470. }
  1471. ELObj *value = pair->car();
  1472. obj = pair->cdr();
  1473. Identifier::SyntacticKey k;
  1474. if (!key->identifier()->syntacticKey(k)) {
  1475. setNextLocation(loc);
  1476. message(InterpreterMessages::patternUnknownQualifier,
  1477. StringMessageArg(key->identifier()->name()));
  1478. return 0;
  1479. }
  1480. switch (k) {
  1481. case Identifier::keyAttributes:
  1482. if (!patternAddAttributeQualifiers(value, loc, *curElement)) {
  1483. setNextLocation(loc);
  1484. message(InterpreterMessages::patternBadAttributeQualifier);
  1485. return 0;
  1486. }
  1487. break;
  1488. case Identifier::keyChildren:
  1489. {
  1490. IList<Pattern::Element> children;
  1491. if (!convertToPattern(value, loc, 1, children))
  1492. return 0;
  1493. if (!children.empty())
  1494. curElement->addQualifier(new Pattern::ChildrenQualifier(children));
  1495. }
  1496. break;
  1497. case Identifier::keyRepeat:
  1498. {
  1499. if (isChild) {
  1500. setNextLocation(loc);
  1501. message(InterpreterMessages::patternChildRepeat);
  1502. return 0;
  1503. }
  1504. SymbolObj *sym = value->asSymbol();
  1505. if (sym) {
  1506. const StringC &str = *sym->name();
  1507. if (str.size() == 1) {
  1508. switch (str[0]) {
  1509. case '*':
  1510. curElement->setRepeat(0, Pattern::Repeat(-1));
  1511. value = 0;
  1512. break;
  1513. case '?':
  1514. curElement->setRepeat(0, 1);
  1515. value = 0;
  1516. break;
  1517. case '+':
  1518. curElement->setRepeat(1, Pattern::Repeat(-1));
  1519. value = 0;
  1520. break;
  1521. default:
  1522. break;
  1523. }
  1524. }
  1525. }
  1526. if (value) {
  1527. setNextLocation(loc);
  1528. message(InterpreterMessages::patternBadQualifierValue,
  1529. ELObjMessageArg(value, *this),
  1530. StringMessageArg(key->identifier()->name()));
  1531. return 0;
  1532. }
  1533. }
  1534. break;
  1535. case Identifier::keyPosition:
  1536. {
  1537. SymbolObj *sym = value->asSymbol();
  1538. if (sym) {
  1539. Pattern::Qualifier *qual = 0;
  1540. const StringC &str = *sym->name();
  1541. if (str == "first-of-type")
  1542. qual = new Pattern::FirstOfTypeQualifier;
  1543. else if (str == "last-of-type")
  1544. qual = new Pattern::LastOfTypeQualifier;
  1545. else if (str == "first-of-any")
  1546. qual = new Pattern::FirstOfAnyQualifier;
  1547. else if (str == "last-of-any")
  1548. qual = new Pattern::LastOfAnyQualifier;
  1549. if (qual) {
  1550. curElement->addQualifier(qual);
  1551. break;
  1552. }
  1553. }
  1554. setNextLocation(loc);
  1555. message(InterpreterMessages::patternBadQualifierValue,
  1556. ELObjMessageArg(value, *this),
  1557. StringMessageArg(key->identifier()->name()));
  1558. return 0;
  1559. }
  1560. case Identifier::keyOnly:
  1561. {
  1562. SymbolObj *sym = value->asSymbol();
  1563. if (sym) {
  1564. Pattern::Qualifier *qual = 0;
  1565. const StringC &str = *sym->name();
  1566. if (str == "of-type")
  1567. qual = new Pattern::OnlyOfTypeQualifier;
  1568. else if (str == "of-any")
  1569. qual = new Pattern::OnlyOfAnyQualifier;
  1570. if (qual) {
  1571. curElement->addQualifier(qual);
  1572. break;
  1573. }
  1574. }
  1575. setNextLocation(loc);
  1576. message(InterpreterMessages::patternBadQualifierValue,
  1577. ELObjMessageArg(value, *this),
  1578. StringMessageArg(key->identifier()->name()));
  1579. return 0;
  1580. }
  1581. break;
  1582. case Identifier::keyId:
  1583. {
  1584. StringObj *str = value->convertToString();
  1585. if (!str) {
  1586. setNextLocation(loc);
  1587. message(InterpreterMessages::patternBadQualifierValue,
  1588. ELObjMessageArg(value, *this),
  1589. StringMessageArg(key->identifier()->name()));
  1590. return 0;
  1591. }
  1592. const Char *s;
  1593. size_t n;
  1594. str->stringData(s, n);
  1595. curElement->addQualifier(new Pattern::IdQualifier(StringC(s, n)));
  1596. }
  1597. break;
  1598. case Identifier::keyClass:
  1599. {
  1600. StringObj *str = value->convertToString();
  1601. if (!str) {
  1602. setNextLocation(loc);
  1603. message(InterpreterMessages::patternBadQualifierValue,
  1604. ELObjMessageArg(value, *this),
  1605. StringMessageArg(key->identifier()->name()));
  1606. return 0;
  1607. }
  1608. const Char *s;
  1609. size_t n;
  1610. str->stringData(s, n);
  1611. curElement->addQualifier(new Pattern::ClassQualifier(StringC(s, n)));
  1612. }
  1613. break;
  1614. case Identifier::keyImportance:
  1615. {
  1616. long n;
  1617. if (!value->exactIntegerValue(n)) {
  1618. setNextLocation(loc);
  1619. message(InterpreterMessages::patternBadQualifierValue,
  1620. ELObjMessageArg(value, *this),
  1621. StringMessageArg(key->identifier()->name()));
  1622. return 0;
  1623. }
  1624. curElement->addQualifier(new Pattern::ImportanceQualifier(n));
  1625. }
  1626. break;
  1627. case Identifier::keyPriority:
  1628. {
  1629. long n;
  1630. if (!value->exactIntegerValue(n)) {
  1631. setNextLocation(loc);
  1632. message(InterpreterMessages::patternBadQualifierValue,
  1633. ELObjMessageArg(value, *this),
  1634. StringMessageArg(key->identifier()->name()));
  1635. return 0;
  1636. }
  1637. curElement->addQualifier(new Pattern::PriorityQualifier(n));
  1638. }
  1639. break;
  1640. default:
  1641. setNextLocation(loc);
  1642. message(InterpreterMessages::patternUnknownQualifier,
  1643. StringMessageArg(key->identifier()->name()));
  1644. return 0;
  1645. }
  1646. }
  1647. return 1;
  1648. }
  1649. bool Interpreter::patternAddAttributeQualifiers(ELObj *obj,
  1650. const Location &loc,
  1651. Pattern::Element &elem)
  1652. {
  1653. while (!obj->isNil()) {
  1654. PairObj *pair = obj->asPair();
  1655. if (!pair)
  1656. return 0;
  1657. StringObj *tem = pair->car()->convertToString();
  1658. if (!tem)
  1659. return 0;
  1660. const Char *s;
  1661. size_t n;
  1662. tem->stringData(s, n);
  1663. if (n == 0)
  1664. return 0;
  1665. StringC name(s, n);
  1666. obj = pair->cdr();
  1667. pair = obj->asPair();
  1668. if (!pair)
  1669. return 0;
  1670. obj = pair->cdr();
  1671. if (pair->car() == makeFalse() && dsssl2())
  1672. elem.addQualifier(new Pattern::AttributeMissingValueQualifier(name));
  1673. else if (pair->car() == makeTrue() && dsssl2())
  1674. elem.addQualifier(new Pattern::AttributeHasValueQualifier(name));
  1675. else {
  1676. tem = pair->car()->convertToString();
  1677. if (!tem)
  1678. return 0;
  1679. tem->stringData(s, n);
  1680. elem.addQualifier(new Pattern::AttributeQualifier(name, StringC(s, n)));
  1681. }
  1682. }
  1683. return 1;
  1684. }
  1685. void Interpreter::dispatchMessage(Message &msg)
  1686. {
  1687. messenger_->dispatchMessage(msg);
  1688. }
  1689. void Interpreter::dispatchMessage(const Message &msg)
  1690. {
  1691. messenger_->dispatchMessage(msg);
  1692. }
  1693. Interpreter::StringSet::StringSet()
  1694. {
  1695. }
  1696. const char *Interpreter::StringSet::store(String<char> &str)
  1697. {
  1698. str += '\0';
  1699. const String<char> *p = table_.lookup(str);
  1700. if (!p) {
  1701. String<char> *tem = new String<char>;
  1702. str.swap(*tem);
  1703. table_.insert(tem);
  1704. p = tem;
  1705. }
  1706. return p->data();
  1707. }
  1708. unsigned long Interpreter::StringSet::hash(const String<char> &str)
  1709. {
  1710. const char *p = str.data();
  1711. unsigned long h = 0;
  1712. for (size_t n = str.size(); n > 0; n--)
  1713. h = (h << 5) + h + (unsigned char)*p++; // from Chris Torek
  1714. return h;
  1715. }
  1716. bool Identifier::preferBuiltin_ = 0;
  1717. Identifier::Identifier(const StringC &name)
  1718. : Named(name), value_(0), syntacticKey_(notKey), beingComputed_(0),
  1719. flowObj_(0), builtin_(0), defPart_(0), charNIC_(0),
  1720. feature_(Interpreter::noFeature)
  1721. {
  1722. }
  1723. void Identifier::maybeSaveBuiltin()
  1724. {
  1725. if (defPart_ == unsigned(-1) && !builtin_) {
  1726. builtin_ = new Identifier(name());
  1727. if (value_)
  1728. builtin_->setValue(value_, defPart_);
  1729. else
  1730. builtin_->setDefinition(def_, defPart_, defLoc_);
  1731. }
  1732. }
  1733. void Identifier::setDefinition(Owner<Expression> &expr,
  1734. unsigned part,
  1735. const Location &loc)
  1736. {
  1737. maybeSaveBuiltin();
  1738. def_.swap(expr);
  1739. defPart_ = part;
  1740. defLoc_ = loc;
  1741. value_ = 0;
  1742. }
  1743. void Identifier::setBuiltinDefinition(Owner<Expression> &expr,
  1744. unsigned part,
  1745. const Location &loc)
  1746. {
  1747. if (!builtin_) {
  1748. builtin_ = new Identifier(name());
  1749. builtin_->setDefinition(expr, part, loc);
  1750. }
  1751. }
  1752. void Identifier::setValue(ELObj *value, unsigned partIndex)
  1753. {
  1754. maybeSaveBuiltin();
  1755. value_ = value;
  1756. // Built in functions have lowest priority.
  1757. defPart_ = partIndex;
  1758. }
  1759. bool Identifier::defined(unsigned &part, Location &loc) const
  1760. {
  1761. if (builtin_ && preferBuiltin_)
  1762. return builtin_->defined(part, loc);
  1763. if (!def_ && !value_)
  1764. return 0;
  1765. part = defPart_;
  1766. loc = defLoc_;
  1767. return 1;
  1768. }
  1769. ELObj *Identifier::computeValue(bool force, Interpreter &interp) const
  1770. {
  1771. if (builtin_ && preferBuiltin_)
  1772. return builtin_->computeValue(force, interp);
  1773. if (value_)
  1774. return value_;
  1775. bool preferred = 0;
  1776. if (defPart_ == unsigned(-1) && !preferBuiltin_) {
  1777. preferBuiltin_ = 1;
  1778. preferred = 1;
  1779. }
  1780. ASSERT(def_);
  1781. if (beingComputed_) {
  1782. if (force) {
  1783. interp.setNextLocation(defLoc_);
  1784. interp.message(InterpreterMessages::identifierLoop,
  1785. StringMessageArg(name()));
  1786. ((Identifier *)this)->value_ = interp.makeError();
  1787. }
  1788. }
  1789. else {
  1790. ((Identifier *)this)->beingComputed_ = 1;
  1791. if (insn_.isNull())
  1792. ((Identifier *)this)->insn_
  1793. = Expression::optimizeCompile(((Identifier *)this)->def_, interp,
  1794. Environment(), 0, InsnPtr());
  1795. if (force || def_->canEval(0)) {
  1796. VM vm(interp);
  1797. ELObj *v = vm.eval(insn_.pointer());
  1798. interp.makePermanent(v);
  1799. ((Identifier *)this)->value_ = v;
  1800. }
  1801. ((Identifier *)this)->beingComputed_ = 0;
  1802. }
  1803. if (preferred)
  1804. preferBuiltin_ = 0;
  1805. return value_;
  1806. }
  1807. ELObj *Identifier::computeBuiltinValue(bool force, Interpreter &interp) const
  1808. {
  1809. preferBuiltin_ = 1;
  1810. ELObj *res = computeValue(force, interp);
  1811. preferBuiltin_ = 0;
  1812. return res;
  1813. }
  1814. Unit::Unit(const StringC &name)
  1815. : Named(name), computed_(notComputed)
  1816. {
  1817. }
  1818. bool Unit::defined(unsigned &part, Location &loc) const
  1819. {
  1820. if (!def_ && computed_ == notComputed)
  1821. return 0;
  1822. part = defPart_;
  1823. loc = defLoc_;
  1824. return 1;
  1825. }
  1826. void Unit::setDefinition(Owner<Expression> &expr,
  1827. unsigned part,
  1828. const Location &loc)
  1829. {
  1830. def_.swap(expr);
  1831. defPart_ = part;
  1832. defLoc_ = loc;
  1833. computed_ = notComputed;
  1834. }
  1835. void Unit::setValue(long n)
  1836. {
  1837. computed_ = computedExact;
  1838. exact_ = n;
  1839. dim_ = 1;
  1840. defPart_ = unsigned(-1);
  1841. }
  1842. void Unit::setValue(double n)
  1843. {
  1844. computed_ = computedInexact;
  1845. inexact_ = n;
  1846. dim_ = 1;
  1847. defPart_ = unsigned(-1);
  1848. }
  1849. void Unit::tryCompute(bool force, Interpreter &interp)
  1850. {
  1851. if (computed_ == notComputed) {
  1852. computed_ = beingComputed;
  1853. if (insn_.isNull())
  1854. insn_ = Expression::optimizeCompile(def_, interp, Environment(), 0, InsnPtr());
  1855. if (force || def_->canEval(0)) {
  1856. VM vm(interp);
  1857. ELObj *v = vm.eval(insn_.pointer());
  1858. switch (v->quantityValue(exact_, inexact_, dim_)) {
  1859. case ELObj::noQuantity:
  1860. if (!interp.isError(v)) {
  1861. interp.setNextLocation(defLoc_);
  1862. interp.message(InterpreterMessages::badUnitDefinition,
  1863. StringMessageArg(name()));
  1864. }
  1865. computed_ = computedError;
  1866. break;
  1867. case ELObj::longQuantity:
  1868. computed_ = computedExact;
  1869. break;
  1870. case ELObj::doubleQuantity:
  1871. computed_ = computedInexact;
  1872. break;
  1873. default:
  1874. CANNOT_HAPPEN();
  1875. }
  1876. }
  1877. if (computed_ == beingComputed)
  1878. computed_ = notComputed;
  1879. }
  1880. else if (computed_ == beingComputed) {
  1881. interp.setNextLocation(defLoc_);
  1882. interp.message(InterpreterMessages::unitLoop,
  1883. StringMessageArg(name()));
  1884. computed_ = computedError;
  1885. }
  1886. }
  1887. // multiply by 10^valExp
  1888. // quantity has exponent of 1
  1889. ELObj *Unit::resolveQuantity(bool force, Interpreter &interp,
  1890. long val, int valExp)
  1891. {
  1892. tryCompute(force, interp);
  1893. long result;
  1894. if (computed_ == computedExact && scale(val, valExp, exact_, result))
  1895. return new (interp) LengthObj(result);
  1896. double x = val;
  1897. while (valExp > 0) {
  1898. x *= 10.0;
  1899. valExp--;
  1900. }
  1901. while (valExp < 0) {
  1902. x /= 10.0;
  1903. valExp++;
  1904. }
  1905. return resolveQuantity(force, interp, x, 1);
  1906. }
  1907. // val * 10^valExp * factor
  1908. // return 0 if it can't be done without overflow
  1909. bool Unit::scale(long val, int valExp, long factor, long &result)
  1910. {
  1911. if (factor <= 0)
  1912. return 0; // feeble
  1913. while (valExp > 0) {
  1914. if (factor > LONG_MAX/10)
  1915. return 0;
  1916. valExp--;
  1917. factor *= 10;
  1918. }
  1919. if (val >= 0) {
  1920. if (val > LONG_MAX/factor)
  1921. return 0;
  1922. }
  1923. else {
  1924. if (-(unsigned long)val > -(unsigned long)LONG_MIN/factor)
  1925. return 0;
  1926. }
  1927. result = val*factor;
  1928. while (valExp < 0) {
  1929. result /= 10;
  1930. valExp++;
  1931. }
  1932. return 1;
  1933. }
  1934. ELObj *Unit::resolveQuantity(bool force, Interpreter &interp,
  1935. double val, int unitExp)
  1936. {
  1937. tryCompute(force, interp);
  1938. double factor;
  1939. switch (computed_) {
  1940. case computedExact:
  1941. factor = exact_;
  1942. break;
  1943. case computedInexact:
  1944. factor = inexact_;
  1945. break;
  1946. case computedError:
  1947. return interp.makeError();
  1948. default:
  1949. return 0;
  1950. }
  1951. int resultDim = 0;
  1952. double resultVal = val;
  1953. while (unitExp > 0) {
  1954. resultDim += dim_;
  1955. resultVal *= factor;
  1956. unitExp--;
  1957. }
  1958. while (unitExp < 0) {
  1959. resultDim -= dim_;
  1960. resultVal /= factor;
  1961. unitExp++;
  1962. }
  1963. if (resultDim == 0)
  1964. return new (interp) RealObj(resultVal);
  1965. return new (interp) QuantityObj(resultVal, resultDim);
  1966. }
  1967. void ELObjDynamicRoot::trace(Collector &c) const
  1968. {
  1969. c.trace(obj_);
  1970. }
  1971. bool operator==(const StringC &s, const char *p)
  1972. {
  1973. for (size_t i = 0; i < s.size(); i++)
  1974. if (p[i] == '\0' || (unsigned char)p[i] != s[i])
  1975. return 0;
  1976. return p[s.size()] == '\0';
  1977. }
  1978. void Interpreter::installBuiltins()
  1979. {
  1980. partIndex_ = unsigned(-1);
  1981. StringC sysid(makeStringC(DEFAULT_SCHEME_BUILTINS));
  1982. StringC src;
  1983. groveManager_->mapSysid(sysid);
  1984. if (groveManager_->readEntity(sysid, src)) {
  1985. Owner<InputSource> in(new InternalInputSource(src,
  1986. InputSourceOrigin::make()));
  1987. SchemeParser scm(*this, in);
  1988. scm.parse();
  1989. }
  1990. endPart();
  1991. partIndex_ = 0;
  1992. }
  1993. void Interpreter::setDefaultLanguage(Owner<Expression> &expr,
  1994. unsigned part,
  1995. const Location &loc)
  1996. {
  1997. defaultLanguageDef_.swap(expr);
  1998. defaultLanguageDefPart_ = part;
  1999. defaultLanguageDefLoc_ = loc;
  2000. }
  2001. ELObj *Interpreter::defaultLanguage() const
  2002. {
  2003. return defaultLanguage_;
  2004. }
  2005. bool Interpreter::defaultLanguageSet(unsigned &part,Location &loc) const
  2006. {
  2007. if(defaultLanguageDef_) {
  2008. part = defaultLanguageDefPart_;
  2009. loc = defaultLanguageDefLoc_;
  2010. return true;
  2011. }
  2012. return false;
  2013. }
  2014. void Interpreter::compileDefaultLanguage()
  2015. {
  2016. if(defaultLanguageDef_) {
  2017. InsnPtr insn = Expression::optimizeCompile(defaultLanguageDef_, *this,
  2018. Environment(), 0, InsnPtr());
  2019. VM vm(*this);
  2020. ELObj *obj = vm.eval(insn.pointer());
  2021. if(!obj->asLanguage()) {
  2022. if(!isError(obj)) {
  2023. setNextLocation(defaultLanguageDefLoc_);
  2024. message(InterpreterMessages::defLangDeclRequiresLanguage,
  2025. ELObjMessageArg(obj, *this));
  2026. }
  2027. return;
  2028. }
  2029. makePermanent(obj);
  2030. defaultLanguage_ = obj;
  2031. }
  2032. }
  2033. void Interpreter::installCharProperties()
  2034. {
  2035. //FIXME convert this to tables
  2036. // NOte that default values are set in the constructors.
  2037. lookupCharProperty(makeStringC("numeric-equiv"))->
  2038. declarePredefined(&numericEquivCPV_);
  2039. if (!strictMode_) {
  2040. for (int i = 0; i < 10; i++)
  2041. numericEquivCPV_.setValue(i+'0', i);
  2042. }
  2043. if (style()) {
  2044. lookupCharProperty(makeStringC("space?"))->
  2045. declarePredefined(&isSpaceCPV_);
  2046. if (!strictMode_) {
  2047. static struct {
  2048. Char c;
  2049. unsigned short num;
  2050. } chars[] = {
  2051. #define SPACE
  2052. #include "charProps.h"
  2053. #undef SPACE
  2054. };
  2055. for (size_t i = 0; i < SIZEOF(chars); i++)
  2056. isSpaceCPV_.setRange(chars[i].c, chars[i].c+chars[i].num-1, true);
  2057. }
  2058. lookupCharProperty(makeStringC("record-end?"))->
  2059. declarePredefined(&isRecordEndCPV_);
  2060. if (!strictMode_) {
  2061. static struct {
  2062. Char c;
  2063. unsigned short num;
  2064. } chars[] = {
  2065. #define RECORD_END
  2066. #include "charProps.h"
  2067. #undef RECORD_END
  2068. };
  2069. for (size_t i = 0; i < SIZEOF(chars); i++)
  2070. isRecordEndCPV_.setRange(chars[i].c, chars[i].c+chars[i].num-1, true);
  2071. }
  2072. lookupCharProperty(makeStringC("blank?"))->
  2073. declarePredefined(&isBlankCPV_);
  2074. if (!strictMode_) {
  2075. static struct {
  2076. Char c;
  2077. unsigned short num;
  2078. } chars[] = {
  2079. #define BLANK
  2080. #include "charProps.h"
  2081. #undef BLANK
  2082. };
  2083. for (size_t i = 0; i < SIZEOF(chars); i++)
  2084. isBlankCPV_.setRange(chars[i].c, chars[i].c+chars[i].num-1, true);
  2085. }
  2086. lookupCharProperty(makeStringC("input-tab?"))->
  2087. declarePredefined(&isInputTabCPV_);
  2088. if (!strictMode_) {
  2089. static struct {
  2090. Char c;
  2091. unsigned short num;
  2092. } chars[] = {
  2093. #define INPUT_TAB
  2094. #include "charProps.h"
  2095. #undef INPUT_TAB
  2096. };
  2097. for (size_t i = 0; i < SIZEOF(chars); i++)
  2098. isInputTabCPV_.setRange(chars[i].c, chars[i].c+chars[i].num-1, true);
  2099. }
  2100. lookupCharProperty(makeStringC("input-whitespace?"))->
  2101. declarePredefined(&isInputWhitespaceCPV_);
  2102. if (!strictMode_) {
  2103. static struct {
  2104. Char c;
  2105. unsigned short num;
  2106. } chars[] = {
  2107. #define INPUT_WHITESPACE
  2108. #include "charProps.h"
  2109. #undef INPUT_WHITESPACE
  2110. };
  2111. for (size_t i = 0; i < SIZEOF(chars); i++)
  2112. isInputWhitespaceCPV_.setRange(chars[i].c,
  2113. chars[i].c+chars[i].num-1, true);
  2114. }
  2115. lookupCharProperty(makeStringC("punct?"))->
  2116. declarePredefined(&isPunctCPV_);
  2117. if (!strictMode_) {
  2118. static struct {
  2119. Char c;
  2120. unsigned short num;
  2121. } chars[] = {
  2122. #define PUNCT
  2123. #include "charProps.h"
  2124. #undef PUNCT
  2125. };
  2126. for (size_t i = 0; i < SIZEOF(chars); i++)
  2127. isPunctCPV_.setRange(chars[i].c, chars[i].c+chars[i].num-1, true);
  2128. }
  2129. lookupCharProperty(makeStringC("script"))->
  2130. declarePredefined(&scriptCPV_);
  2131. if (!strictMode_) {
  2132. static struct {
  2133. Char c1, c2;
  2134. char *suffix;
  2135. } chars[] = {
  2136. #define SCRIPT
  2137. #include "charProps.h"
  2138. #undef SCRIPT
  2139. };
  2140. StringC prefix = makeStringC("ISO/IEC 10179::1996//Script::");
  2141. for (size_t i = 0; i < SIZEOF(chars); i++) {
  2142. StringC tem(prefix);
  2143. tem += makeStringC(chars[i].suffix);
  2144. scriptCPV_.setRange(chars[i].c1, chars[i].c2,
  2145. storePublicId(tem.data(), tem.size(), Location()));
  2146. }
  2147. }
  2148. lookupCharProperty(makeStringC("glyph-id"))->
  2149. declarePredefined(&glyphIdCPV_);
  2150. // FIXME. Default values?
  2151. lookupCharProperty(makeStringC("drop-after-line-break?"))->
  2152. declarePredefined(&isDropAfterLineBreakCPV_);
  2153. // FIXME: Values.
  2154. lookupCharProperty(makeStringC("drop-unless-before-line-break?"))->
  2155. declarePredefined(&isDropUnlessBeforeLineBreakCPV_);
  2156. // FIXME: Values.
  2157. lookupCharProperty(makeStringC("break-before-priority"))->
  2158. declarePredefined(&breakBeforePriorityCPV_);
  2159. lookupCharProperty(makeStringC("break-after-priority"))->
  2160. declarePredefined(&breakAfterPriorityCPV_);
  2161. if(!strictMode_) {
  2162. static struct {
  2163. Char c;
  2164. unsigned short num;
  2165. unsigned short bbp;
  2166. unsigned short bap;
  2167. } chars[] = {
  2168. #define BREAK_PRIORITIES
  2169. #include "charProps.h"
  2170. #undef BREAK_PRIORITIES
  2171. };
  2172. for (size_t i = 0; i < SIZEOF(chars); ++i) {
  2173. breakBeforePriorityCPV_.setRange(chars[i].c, chars[i].c + chars[i].num-1,
  2174. chars[i].bbp);
  2175. breakAfterPriorityCPV_.setRange(chars[i].c, chars[i].c + chars[i].num-1,
  2176. chars[i].bap);
  2177. }
  2178. }
  2179. lookupCharProperty(makeStringC("math-class"))->
  2180. declarePredefined(&mathClassCPV_);
  2181. // FIXME: Values.
  2182. lookupCharProperty(makeStringC("math-font-posture"))->
  2183. declarePredefined(&mathFontPostureCPV_);
  2184. // FIXME: Values.
  2185. }
  2186. }
  2187. void
  2188. Interpreter::compileCharProperties()
  2189. {
  2190. NamedTableIter<CharProp> iter(charPropTable_);
  2191. CharProp *val;
  2192. while ((val = iter.next()))
  2193. val->compile(*this);
  2194. }
  2195. CharPropValues *Interpreter::installExtensionCharNIC(Identifier *ident,
  2196. const StringC &pubid,
  2197. const Location &loc)
  2198. {
  2199. ident->setCharNIC(currentPartIndex(), loc);
  2200. // FIXME! Shouldn't even get into CVS!
  2201. return new ELObjCharPropValues;
  2202. }
  2203. ELObj *CharProp::value(Char ch, ELObj *def,
  2204. const Location &loc, Interpreter &interp)
  2205. {
  2206. addedProp_ *p=(addedProp_ *)added_(ch);
  2207. if (p != 0 && p->computed_ != computedOK) {
  2208. compileAdded_(*p,interp);
  2209. if(p->computed_ == computedError) {
  2210. if (!values_) {
  2211. interp.setNextLocation (loc);
  2212. interp.message (InterpreterMessages::unknownCharProperty,
  2213. StringMessageArg (name()));
  2214. }
  2215. return interp.makeError();
  2216. }
  2217. ASSERT(p->computed_ == computedOK);
  2218. }
  2219. ASSERT(values_);
  2220. ELObj *tem = values_->value(ch, interp);
  2221. if(tem)
  2222. return tem;
  2223. else if (def)
  2224. return def;
  2225. if (defComputed_ != computedOK) {
  2226. compileDef_ (interp);
  2227. if (defComputed_ == computedError)
  2228. return interp.makeError();
  2229. ASSERT(defComputed_ == computedOK);
  2230. }
  2231. tem = values_->defaultValue(interp);
  2232. ASSERT(tem);
  2233. return tem;
  2234. }
  2235. void CharProp::setValue(StringC &chars, Owner<Expression> &expr,
  2236. unsigned part, const Location &loc)
  2237. {
  2238. ASSERT(chars.size()>0);
  2239. addedPropsVec_.resize (addedPropsVec_.size() + 1);
  2240. addedProp_ &p = addedPropsVec_.back();
  2241. p.chars_.swap(chars);
  2242. p.part_ = part;
  2243. p.loc_ = loc;
  2244. p.expr_.swap(expr);
  2245. p.computed_ = notComputed;
  2246. if(!addedProps_)
  2247. addedProps_ = new CharMap<NCVector<addedProp_>::size_type> (noAddedVal_);
  2248. for(size_t i = 0; i < p.chars_.size(); ++i) {
  2249. ASSERT((*addedProps_)[p.chars_[i]] == noAddedVal_);
  2250. addedProps_->setChar(p.chars_[i],addedPropsVec_.size() - 1);
  2251. }
  2252. }
  2253. void CharProp::declare(Owner<Expression> &expr,
  2254. unsigned part,
  2255. const Location &loc,
  2256. CharPropValues *values)
  2257. {
  2258. ASSERT(!defExpr_);
  2259. ASSERT(expr);
  2260. defExpr_.swap(expr);
  2261. defPart_ = part;
  2262. defLoc_ = loc;
  2263. if (values)
  2264. values_ = values;
  2265. else if (!values_) {
  2266. // FIXME! Shall not get into CVS!
  2267. values_ = new ELObjCharPropValues ();
  2268. }
  2269. }
  2270. void CharProp::declarePredefined(CharPropValues *values)
  2271. {
  2272. values_ = values;
  2273. }
  2274. bool CharProp::hasAddedValue(Char ch,unsigned &part,Location &loc) const
  2275. {
  2276. const addedProp_ *p = added_(ch);
  2277. if(p) {
  2278. part = p->part_;
  2279. loc = p->loc_;
  2280. return true;
  2281. }
  2282. return false;
  2283. }
  2284. bool CharProp::declared(unsigned &part, Location &loc) const
  2285. {
  2286. if(defExpr_) {
  2287. part = defPart_;
  2288. loc = defLoc_;
  2289. return true;
  2290. }
  2291. return false;
  2292. }
  2293. void CharProp::compile(Interpreter &interp)
  2294. {
  2295. compileDef_(interp);
  2296. for(NCVector<addedProp_>::size_type i = 0; i < addedPropsVec_.size(); ++i)
  2297. compileAdded_(addedPropsVec_[i],interp);
  2298. if (!hadError_) {
  2299. addedProps_.clear();
  2300. addedPropsVec_.clear();
  2301. }
  2302. }
  2303. void CharProp::compileDef_(Interpreter &interp)
  2304. {
  2305. switch(defComputed_) {
  2306. case notComputed:
  2307. if (defExpr_) {
  2308. defComputed_ = beingComputed;
  2309. InsnPtr insn = Expression::optimizeCompile (defExpr_, interp,
  2310. Environment(), 0, InsnPtr());
  2311. VM vm (interp);
  2312. ELObj *p = vm.eval (insn.pointer());
  2313. if (!interp.isError(p)
  2314. && values_->setDefault(name(), defLoc_, p, interp))
  2315. defComputed_ = computedOK;
  2316. else
  2317. defComputed_ = computedError;
  2318. }
  2319. else if (values_) {
  2320. defComputed_ = computedOK;
  2321. } else
  2322. defComputed_ = computedError;
  2323. break;
  2324. case beingComputed:
  2325. interp.setNextLocation(defLoc_);
  2326. interp.message(InterpreterMessages::charPropertyLoop,
  2327. StringMessageArg(name()));
  2328. defComputed_ = computedError;
  2329. break;
  2330. default:
  2331. ;
  2332. }
  2333. }
  2334. void CharProp::compileAdded_(addedProp_ &added, Interpreter &interp)
  2335. {
  2336. switch(added.computed_) {
  2337. case notComputed: { // Own block since InsnPtr and VM have destructors.
  2338. // Check that property is declared.
  2339. if (!values_) {
  2340. interp.setNextLocation (added.loc_);
  2341. interp.message (InterpreterMessages::unknownCharProperty,
  2342. StringMessageArg (name()));
  2343. added.computed_ = computedError;
  2344. hadError_ = true;
  2345. return;
  2346. }
  2347. ASSERT(added.expr_);
  2348. added.computed_ = beingComputed;
  2349. InsnPtr insn = Expression::optimizeCompile (added.expr_, interp,
  2350. Environment(), 0, InsnPtr());
  2351. VM vm (interp);
  2352. ELObj *p = vm.eval (insn.pointer());
  2353. if (!interp.isError(p) &&
  2354. values_->setValue(name(), added.chars_, added.loc_, p, interp))
  2355. added.computed_ = computedOK;
  2356. else {
  2357. added.computed_ = computedError;
  2358. hadError_ = true;
  2359. }
  2360. break;
  2361. }
  2362. case beingComputed:
  2363. interp.setNextLocation(added.loc_);
  2364. interp.message(InterpreterMessages::charPropertyLoop,
  2365. StringMessageArg(name()));
  2366. added.computed_ = computedError;
  2367. break;
  2368. default:
  2369. ;
  2370. }
  2371. }
  2372. const CharProp::addedProp_ *CharProp::added_(Char ch) const
  2373. {
  2374. if (!addedProps_)
  2375. return 0;
  2376. NCVector<addedProp_>::size_type n((*addedProps_)[ch]);
  2377. if (n == noAddedVal_)
  2378. return 0;
  2379. return &addedPropsVec_[n];
  2380. }
  2381. bool IntegerCharPropValues::setDefault(const StringC &name,
  2382. const Location &loc,
  2383. ELObj *obj, Interpreter &interp)
  2384. {
  2385. if (!obj->