PageRenderTime 72ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/branches/jade_tl/style/Interpreter.cxx

#
C++ | 2520 lines | 2338 code | 139 blank | 43 comment | 503 complexity | 16d4a582b6284d6ca49cb82deb966b7d MD5 | raw file
Possible License(s): LGPL-2.1, LGPL-2.0

Large files files are truncated, but you can click here to view the full file

  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. static size_t sz[] = {
  43. sizeof(UnresolvedQuantityObj),
  44. sizeof(VarStyleObj),
  45. sizeof(OverriddenStyleObj),
  46. sizeof(MergeStyleObj),
  47. sizeof(DeviceRGBColorObj),
  48. sizeof(ColorSpaceObj),
  49. sizeof(PairObj),
  50. sizeof(QuantityObj),
  51. sizeof(GlyphIdObj),
  52. sizeof(NamedNodeListPtrNodeListObj),
  53. sizeof(ProcessNodeSosofoObj),
  54. sizeof(AppendSosofoObj),
  55. sizeof(SetNonInheritedCsSosofoObj),
  56. sizeof(LabelSosofoObj),
  57. sizeof(MacroFlowObj),
  58. sizeof(FlowObj) + sizeof(StringC), // for FormattingInstructionFlowObj
  59. sizeof(LangObj),
  60. #ifdef SP_HAVE_LOCALE
  61. sizeof(RefLangObj),
  62. #endif
  63. sizeof(SubgroveSpecObj),
  64. sizeof(CreateSpecObj),
  65. };
  66. size_t n = sz[0];
  67. for (size_t i = 1; i < SIZEOF(sz); i++)
  68. if (sz[i] > n)
  69. n = sz[i];
  70. return n;
  71. }
  72. Interpreter::Interpreter(GroveManager *groveManager,
  73. Messenger *messenger,
  74. int unitsPerInch,
  75. bool debugMode,
  76. bool dsssl2,
  77. bool style,
  78. bool strictMode,
  79. const FOTBuilder::Description &fotbDescr)
  80. : groveManager_(groveManager),
  81. messenger_(messenger),
  82. fotbDescr_(fotbDescr),
  83. Collector(maxObjSize()),
  84. partIndex_(0), // 0 is for command-line definitions
  85. dPartIndex_(1),
  86. lexCategory_(lexOther),
  87. unitsPerInch_(unitsPerInch),
  88. nInheritedC_(0),
  89. initialProcessingMode_(StringC()),
  90. currentPartFirstInitialValue_(0),
  91. initialStyle_(0),
  92. nextGlyphSubstTableUniqueId_(0),
  93. debugMode_(debugMode),
  94. dsssl2_(dsssl2),
  95. mathClassCPV_(FOTBuilder::symbolOrdinary),
  96. style_(style),
  97. strictMode_(strictMode),
  98. explicitFeatures_(0),
  99. explicitModules_(0)
  100. {
  101. makePermanent(theNilObj_ = new (*this) NilObj);
  102. makePermanent(theFalseObj_ = new (*this) FalseObj);
  103. makePermanent(theTrueObj_ = new (*this) TrueObj);
  104. makePermanent(theErrorObj_ = new (*this) ErrorObj);
  105. makePermanent(theUnspecifiedObj_ = new (*this) UnspecifiedObj);
  106. makePermanent(addressNoneObj_
  107. = new (*this) AddressObj(FOTBuilder::Address::none));
  108. makePermanent(emptyNodeListObj_
  109. = new (*this) NodePtrNodeListObj);
  110. defaultLanguage_ = theFalseObj_;
  111. installSyntacticKeys();
  112. installCValueSymbols();
  113. installPortNames();
  114. installPrimitives();
  115. installUnits();
  116. installFeatures(fotbDescr_.features);
  117. installModules();
  118. installCharNames();
  119. installSdata();
  120. installFlowObjs();
  121. installInheritedCs();
  122. installNodeProperties();
  123. static const char *lexCategories[] = {
  124. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
  125. "!$%&*/<=>?~_^:",
  126. "",
  127. "0123456789",
  128. "-+.",
  129. "",
  130. "();\"",
  131. " \t\r\n\f",
  132. "",
  133. };
  134. lexCategory_.setEe(lexDelimiter);
  135. for (size_t i = 0; i < SIZEOF(lexCategories); i++)
  136. for (const char *s = lexCategories[i]; *s; s++)
  137. lexCategory_.setChar(*s, i);
  138. // #',@[\\]`{|} are ASCII chars not mentioned above,
  139. // but I guess we don't want to allow any of these
  140. // in names (as most of them have special meaning in
  141. // scheme/dsssl).
  142. if (!strictMode_)
  143. for (Char i = 127; i < charMax; i++)
  144. lexCategory_.setChar(i, lexAddNameStart);
  145. initialProcessingMode_.setDefined();
  146. // can't be done before initializing lexCategory_
  147. installBuiltins();
  148. installCharProperties();
  149. }
  150. void Interpreter::compile()
  151. {
  152. // FIXME compile all definitions
  153. compileInitialValues();
  154. initialProcessingMode_.compile(*this);
  155. NamedTableIter<ProcessingMode> iter(processingModeTable_);
  156. for (;;) {
  157. ProcessingMode *mode = iter.next();
  158. if (!mode)
  159. break;
  160. mode->compile(*this);
  161. }
  162. compileCharProperties();
  163. compileDefaultLanguage();
  164. checkGrovePlan();
  165. }
  166. void Interpreter::compileInitialValues()
  167. {
  168. Vector<ConstPtr<InheritedC> > ics;
  169. for (size_t i = 0; i < initialValueNames_.size(); i++) {
  170. const Identifier *ident = initialValueNames_[i];
  171. Owner<Expression> &expr = initialValueValues_[i];
  172. ConstPtr<InheritedC> ic(ident->inheritedC());
  173. expr->optimize(*this, Environment(), expr);
  174. ELObj *val = expr->constantValue();
  175. if (val) {
  176. ConstPtr<InheritedC> tem(ic->make(val, expr->location(), *this));
  177. if (!tem.isNull())
  178. ics.push_back(tem);
  179. }
  180. else
  181. ics.push_back(new VarInheritedC(ic,
  182. expr->compile(*this, Environment(), 0, InsnPtr()),
  183. expr->location()));
  184. }
  185. if (ics.size()) {
  186. Vector<ConstPtr<InheritedC> > forceIcs;
  187. initialStyle_ = new (*this) VarStyleObj(new StyleSpec(forceIcs, ics), 0, 0, NodePtr());
  188. makePermanent(initialStyle_);
  189. }
  190. }
  191. void Interpreter::installInitialValue(Identifier *ident, Owner<Expression> &expr)
  192. {
  193. for (size_t i = 0; i < initialValueNames_.size(); i++) {
  194. if (ident == initialValueNames_[i]) {
  195. if (i >= currentPartFirstInitialValue_) {
  196. setNextLocation(expr->location());
  197. message(InterpreterMessages::duplicateInitialValue,
  198. StringMessageArg(ident->name()),
  199. initialValueValues_[i]->location());
  200. }
  201. return;
  202. }
  203. }
  204. initialValueValues_.resize(initialValueValues_.size() + 1);
  205. expr.swap(initialValueValues_.back());
  206. initialValueNames_.push_back(ident);
  207. }
  208. void Interpreter::installUnits()
  209. {
  210. static struct {
  211. const char *name;
  212. int numer;
  213. int denom;
  214. bool dsssl2;
  215. } units[] = {
  216. { "m", 5000, 127 },
  217. { "cm", 50, 127 },
  218. { "mm", 5, 127 },
  219. { "in", 1, 1 },
  220. { "pt", 1, 72 },
  221. { "pica", 1, 6 },
  222. { "pc", 1, 6 } // a DSSSL2 addition
  223. };
  224. size_t nUnits = dsssl2() ? SIZEOF(units) : SIZEOF(units) - 1;
  225. for (size_t i = 0; i < nUnits; i++) {
  226. Unit *unit = lookupUnit(makeStringC(units[i].name));
  227. long n = unitsPerInch_ * units[i].numer;
  228. if (n % units[i].denom == 0)
  229. unit->setValue(long(n / units[i].denom));
  230. else
  231. unit->setValue(double(n)/units[i].denom);
  232. }
  233. }
  234. void Interpreter::installSyntacticKeys()
  235. {
  236. static struct {
  237. const char *name;
  238. Identifier::SyntacticKey key;
  239. } keys[] = {
  240. { "quote", Identifier::keyQuote },
  241. { "lambda", Identifier::keyLambda },
  242. { "if", Identifier::keyIf },
  243. { "cond", Identifier::keyCond },
  244. { "and", Identifier::keyAnd },
  245. { "or", Identifier::keyOr },
  246. { "case", Identifier::keyCase },
  247. { "let", Identifier::keyLet },
  248. { "let*", Identifier::keyLetStar },
  249. { "letrec", Identifier::keyLetrec },
  250. { "quasiquote", Identifier::keyQuasiquote },
  251. { "unquote", Identifier::keyUnquote },
  252. { "unquote-splicing", Identifier::keyUnquoteSplicing },
  253. { "define", Identifier::keyDefine },
  254. { "else", Identifier::keyElse },
  255. { "=>", Identifier::keyArrow },
  256. { "there-exists?", Identifier::keyThereExists },
  257. { "for-all?", Identifier::keyForAll },
  258. { "select-each", Identifier::keySelectEach },
  259. { "union-for-each", Identifier::keyUnionForEach },
  260. { "define-unit", Identifier::keyDefineUnit },
  261. { "declare-default-language", Identifier::keyDeclareDefaultLanguage },
  262. { "declare-char-property", Identifier::keyDeclareCharProperty },
  263. { "define-language", Identifier::keyDefineLanguage },
  264. { "collate", Identifier::keyCollate },
  265. { "toupper", Identifier::keyToupper },
  266. { "tolower", Identifier::keyTolower },
  267. { "symbol", Identifier::keySymbol },
  268. { "order", Identifier::keyOrder },
  269. { "forward", Identifier::keyForward },
  270. { "backward", Identifier::keyBackward },
  271. { "add-char-properties", Identifier::keyAddCharProperties },
  272. { "architecture", Identifier::keyArchitecture },
  273. { "default", Identifier::keyDefault },
  274. { "null", Identifier::keyNull },
  275. { "rcs?", Identifier::keyIsRcs },
  276. { "parent", Identifier::keyParent },
  277. { "active", Identifier::keyActive },
  278. { "label", Identifier::keyLabel },
  279. { "children", Identifier::keyChildren },
  280. { "class", Identifier::keyClass },
  281. }, styleKeys[] = {
  282. { "make", Identifier::keyMake },
  283. { "style", Identifier::keyStyle },
  284. { "with-mode", Identifier::keyWithMode },
  285. { "query", Identifier::keyQuery },
  286. { "element", Identifier::keyElement },
  287. { "root", Identifier::keyRoot },
  288. { "id", Identifier::keyId },
  289. { "mode", Identifier::keyMode },
  290. { "declare-initial-value", Identifier::keyDeclareInitialValue },
  291. { "declare-characteristic", Identifier::keyDeclareCharacteristic },
  292. { "declare-flow-object-class", Identifier::keyDeclareFlowObjectClass },
  293. { "declare-char-characteristic+property", Identifier::keyDeclareCharCharacteristicAndProperty },
  294. { "declare-reference-value-type", Identifier::keyDeclareReferenceValueType },
  295. { "define-page-model", Identifier::keyDefinePageModel },
  296. { "define-column-set-model", Identifier::keyDefineColumnSetModel },
  297. { "use", Identifier::keyUse },
  298. { "content-map", Identifier::keyContentMap },
  299. { "keep-with-previous?", Identifier::keyIsKeepWithPrevious },
  300. { "keep-with-next?", Identifier::keyIsKeepWithNext },
  301. { "space-before", Identifier::keySpaceBefore },
  302. { "space-after", Identifier::keySpaceAfter },
  303. { "left-header", Identifier::keyLeftHeader },
  304. { "center-header", Identifier::keyCenterHeader },
  305. { "right-header", Identifier::keyRightHeader },
  306. { "left-footer", Identifier::keyLeftFooter },
  307. { "center-footer", Identifier::keyCenterFooter },
  308. { "right-footer", Identifier::keyRightFooter },
  309. { "destination", Identifier::keyDestination },
  310. { "type", Identifier::keyType },
  311. { "coalesce-id", Identifier::keyCoalesceId },
  312. { "display?", Identifier::keyIsDisplay },
  313. { "scale", Identifier::keyScale },
  314. { "max-width", Identifier::keyMaxWidth },
  315. { "max-height", Identifier::keyMaxHeight },
  316. { "entity-system-id", Identifier::keyEntitySystemId },
  317. { "notation-system-id", Identifier::keyNotationSystemId },
  318. { "position-point-x", Identifier::keyPositionPointX },
  319. { "position-point-y", Identifier::keyPositionPointY },
  320. { "escapement-direction", Identifier::keyEscapementDirection },
  321. { "break-before-priority", Identifier::keyBreakBeforePriority },
  322. { "break-after-priority", Identifier::keyBreakAfterPriority },
  323. { "orientation", Identifier::keyOrientation },
  324. { "length", Identifier::keyLength },
  325. { "char", Identifier::keyChar },
  326. { "glyph-id", Identifier::keyGlyphId },
  327. { "space?", Identifier::keyIsSpace },
  328. { "record-end?", Identifier::keyIsRecordEnd },
  329. { "input-tab?", Identifier::keyIsInputTab },
  330. { "input-whitespace?", Identifier::keyIsInputWhitespace },
  331. { "punct?", Identifier::keyIsPunct },
  332. { "drop-after-line-break?", Identifier::keyIsDropAfterLineBreak },
  333. { "drop-unless-before-line-break?", Identifier::keyIsDropUnlessBeforeLineBreak },
  334. { "math-class", Identifier::keyMathClass },
  335. { "math-font-posture", Identifier::keyMathFontPosture },
  336. { "script", Identifier::keyScript },
  337. { "stretch-factor", Identifier::keyStretchFactor },
  338. { "keep", Identifier::keyKeep },
  339. { "break-before", Identifier::keyBreakBefore },
  340. { "break-after", Identifier::keyBreakAfter },
  341. { "may-violate-keep-before?", Identifier::keyIsMayViolateKeepBefore },
  342. { "may-violate-keep-after?", Identifier::keyIsMayViolateKeepAfter },
  343. { "before-row-border", Identifier::keyBeforeRowBorder },
  344. { "after-row-border", Identifier::keyAfterRowBorder },
  345. { "before-column-border", Identifier::keyBeforeColumnBorder },
  346. { "after-column-border", Identifier::keyAfterColumnBorder },
  347. { "column-number", Identifier::keyColumnNumber },
  348. { "row-number", Identifier::keyRowNumber },
  349. { "n-columns-spanned", Identifier::keyNColumnsSpanned },
  350. { "n-rows-spanned", Identifier::keyNRowsSpanned },
  351. { "width", Identifier::keyWidth },
  352. { "starts-row?", Identifier::keyIsStartsRow },
  353. { "ends-row?", Identifier::keyIsEndsRow },
  354. { "table-width", Identifier::keyTableWidth },
  355. { "multi-modes", Identifier::keyMultiModes },
  356. { "data", Identifier::keyData },
  357. { "min", Identifier::keyMin },
  358. { "max", Identifier::keyMax },
  359. { "conditional?", Identifier::keyIsConditional },
  360. { "priority", Identifier::keyPriority },
  361. { "grid-n-rows", Identifier::keyGridNRows },
  362. { "grid-n-columns", Identifier::keyGridNColumns },
  363. { "radical", Identifier::keyRadical },
  364. { "attributes", Identifier::keyAttributes },
  365. { "repeat", Identifier::keyRepeat },
  366. { "position", Identifier::keyPosition },
  367. { "only", Identifier::keyOnly },
  368. { "importance", Identifier::keyImportance },
  369. { "position-preference", Identifier::keyPositionPreference },
  370. { "white-point", Identifier::keyWhitePoint },
  371. { "black-point", Identifier::keyBlackPoint },
  372. { "range", Identifier::keyRange },
  373. { "range-abc", Identifier::keyRangeAbc },
  374. { "range-lmn", Identifier::keyRangeLmn },
  375. { "range-a", Identifier::keyRangeA },
  376. { "decode-abc", Identifier::keyDecodeAbc },
  377. { "decode-lmn", Identifier::keyDecodeLmn },
  378. { "decode-a", Identifier::keyDecodeA },
  379. { "matrix-abc", Identifier::keyMatrixAbc },
  380. { "matrix-lmn", Identifier::keyMatrixLmn },
  381. { "matrix-a", Identifier::keyMatrixA },
  382. }, transformKeys[] = {
  383. { "define-transliteration-map", Identifier::keyDefineTransliterationMap },
  384. { "node", Identifier::keyNode },
  385. { "subgrove", Identifier::keySubgrove },
  386. { "add", Identifier::keyAdd },
  387. { "remove", Identifier::keyRemove },
  388. { "sub", Identifier::keySub },
  389. { "sort-children", Identifier::keySortChildren },
  390. { "optional", Identifier::keyOptional },
  391. { "unique", Identifier::keyUnique },
  392. { "result-path", Identifier::keyResultPath },
  393. { "property", Identifier::keyProperty },
  394. }, keys2[] = {
  395. { "declare-class-attribute", Identifier::keyDeclareClassAttribute },
  396. { "declare-id-attribute", Identifier::keyDeclareIdAttribute },
  397. { "declare-flow-object-macro", Identifier::keyDeclareFlowObjectMacro },
  398. { "or-element", Identifier::keyOrElement },
  399. { "set!", Identifier::keySet },
  400. { "begin", Identifier::keyBegin },
  401. };
  402. for (size_t i = 0; i < SIZEOF(keys); i++) {
  403. StringC tem(makeStringC(keys[i].name));
  404. lookup(tem)->setSyntacticKey(keys[i].key);
  405. if (dsssl2() && tem[tem.size() - 1] == '?') {
  406. tem.resize(tem.size() - 1);
  407. lookup(tem)->setSyntacticKey(keys[i].key);
  408. }
  409. }
  410. if (style())
  411. for (size_t i = 0; i < SIZEOF(styleKeys); i++) {
  412. StringC tem(makeStringC(styleKeys[i].name));
  413. lookup(tem)->setSyntacticKey(styleKeys[i].key);
  414. if (dsssl2() && tem[tem.size() - 1] == '?') {
  415. tem.resize(tem.size() - 1);
  416. lookup(tem)->setSyntacticKey(styleKeys[i].key);
  417. }
  418. }
  419. else
  420. for (size_t i = 0; i < SIZEOF(transformKeys); i++) {
  421. StringC tem(makeStringC(transformKeys[i].name));
  422. lookup(tem)->setSyntacticKey(transformKeys[i].key);
  423. }
  424. if (dsssl2()) {
  425. for (size_t i = 0; i < SIZEOF(keys2); i++)
  426. lookup(makeStringC(keys2[i].name))->setSyntacticKey(keys2[i].key);
  427. }
  428. }
  429. void Interpreter::installCValueSymbols()
  430. {
  431. cValueSymbols_[0] = makeFalse();
  432. cValueSymbols_[1] = makeTrue();
  433. for (size_t i = 2; i < FOTBuilder::nSymbols; i++) {
  434. SymbolObj *sym = makeSymbol(makeStringC(FOTBuilder::symbolName(FOTBuilder::Symbol(i))));
  435. sym->setCValue(FOTBuilder::Symbol(i));
  436. cValueSymbols_[i] = sym;
  437. }
  438. }
  439. void Interpreter::installPortNames()
  440. {
  441. // These must match the order in SymbolObj.
  442. static const char *names[] = {
  443. "numerator",
  444. "denominator",
  445. "pre-sup",
  446. "pre-sub",
  447. "post-sup",
  448. "post-sub",
  449. "mid-sup",
  450. "mid-sub",
  451. "over-mark",
  452. "under-mark",
  453. "open",
  454. "close",
  455. "degree",
  456. "operator",
  457. "lower-limit",
  458. "upper-limit",
  459. "header",
  460. "footer"
  461. };
  462. ASSERT(SIZEOF(names) == nPortNames);
  463. for (size_t i = 0; i < SIZEOF(names); i++)
  464. portNames_[i] = makeSymbol(makeStringC(names[i]));
  465. }
  466. void Interpreter::installCharNames()
  467. {
  468. if (!strictMode()) {
  469. static struct {
  470. Char c;
  471. const char *name;
  472. } chars[] = {
  473. #include "charNames.h"
  474. };
  475. for (size_t i = 0; i < SIZEOF(chars); i++) {
  476. CharPart ch;
  477. ch.c = chars[i].c;
  478. ch.defPart = unsigned(-1);
  479. namedCharTable_.insert(makeStringC(chars[i].name), ch, 1);
  480. }
  481. }
  482. }
  483. void Interpreter::installSdata()
  484. {
  485. if (!strictMode()) {
  486. // This comes from uni2sgml.txt on ftp://unicode.org.
  487. // It is marked there as obsolete, so it probably ought to be checked.
  488. // The definitions of apos and quot have been fixed for consistency with XML.
  489. static struct {
  490. Char c;
  491. const char *name;
  492. } entities[] = {
  493. #include "sdata.h"
  494. };
  495. for (size_t i = 0; i < SIZEOF(entities); i++) {
  496. CharPart ch;
  497. ch.c = entities[i].c;
  498. ch.defPart = unsigned(-1);
  499. sdataEntityNameTable_.insert(makeStringC(entities[i].name), ch, 1);
  500. }
  501. }
  502. }
  503. void Interpreter::installNodeProperties()
  504. {
  505. for (int i = 0; i < ComponentName::nIds; i++) {
  506. ComponentName::Id id = ComponentName::Id(i);
  507. nodePropertyTable_.insert(makeStringC(ComponentName::rcsName(id)), i);
  508. nodePropertyTable_.insert(makeStringC(ComponentName::sdqlName(id)), i);
  509. }
  510. }
  511. void Interpreter::setCharRepertoire(const StringC &pubid)
  512. {
  513. if (pubid == "UNREGISTERED::OpenJade//Character Repertoire::OpenJade") {
  514. if (strictMode_) {
  515. installCharNames();
  516. installSdata();
  517. // This assumes that we process char-repertoire
  518. // declaration before any declarations which change
  519. // lexical categories.
  520. for (Char i = 127; i < charMax; i++)
  521. lexCategory_.setChar(i, lexAddNameStart);
  522. strictMode_ = 0;
  523. }
  524. } else
  525. message(InterpreterMessages::unsupportedCharRepertoire,
  526. StringMessageArg(pubid));
  527. }
  528. void Interpreter::addStandardChar(const StringC &name, const StringC &num)
  529. {
  530. int n;
  531. size_t i = 0;
  532. if (!scanSignDigits(num, i, n)) {
  533. message(InterpreterMessages::invalidCharNumber, StringMessageArg(num));
  534. return;
  535. }
  536. const CharPart *def = namedCharTable_.lookup(name);
  537. CharPart ch;
  538. ch.c = n;
  539. ch.defPart = dPartIndex_;
  540. if (def) {
  541. if (dPartIndex_ < def->defPart)
  542. namedCharTable_.insert(name, ch, 1);
  543. else if (def->defPart == dPartIndex_ && def->c != ch.c)
  544. message(InterpreterMessages::duplicateCharName,
  545. StringMessageArg(name));
  546. }
  547. else
  548. namedCharTable_.insert(name, ch, 1);
  549. }
  550. void Interpreter::addNameChar(const StringC &name)
  551. {
  552. const CharPart *cp = namedCharTable_.lookup(name);
  553. if (!cp)
  554. message(InterpreterMessages::badCharName,
  555. StringMessageArg(name));
  556. else if (lexCategory_[cp->c] != lexOther)
  557. // FIXME give a more specific error
  558. message(InterpreterMessages::badDeclaration);
  559. else
  560. lexCategory_.setChar(cp->c, lexAddNameStart);
  561. }
  562. void Interpreter::addSeparatorChar(const StringC &name)
  563. {
  564. const CharPart *cp = namedCharTable_.lookup(name);
  565. if (!cp)
  566. message(InterpreterMessages::badCharName,
  567. StringMessageArg(name));
  568. else if (lexCategory_[cp->c] != lexOther)
  569. // FIXME give a more specific error
  570. message(InterpreterMessages::badDeclaration);
  571. else
  572. lexCategory_.setChar(cp->c, lexAddWhiteSpace);
  573. }
  574. void Interpreter::addSdataEntity(const StringC &ename, const StringC &etext, const StringC &name)
  575. {
  576. const CharPart *cp = namedCharTable_.lookup(name);
  577. if (!cp) {
  578. message(InterpreterMessages::badCharName,
  579. StringMessageArg(name));
  580. return;
  581. }
  582. CharPart ch;
  583. ch.c = cp->c;
  584. ch.defPart = dPartIndex_;
  585. if (ename.size() > 0) {
  586. const CharPart *def = sdataEntityNameTable_.lookup(ename);
  587. if (def) {
  588. if (dPartIndex_ < def->defPart)
  589. sdataEntityNameTable_.insert(ename, ch);
  590. else if (def->defPart == dPartIndex_ && def->c != cp->c)
  591. message(InterpreterMessages::duplicateSdataEntityName,
  592. StringMessageArg(ename));
  593. }
  594. else
  595. sdataEntityNameTable_.insert(ename, ch);
  596. }
  597. if (etext.size() > 0) {
  598. const CharPart *def = sdataEntityTextTable_.lookup(etext);
  599. if (def) {
  600. if (dPartIndex_ < def->defPart)
  601. sdataEntityTextTable_.insert(etext, ch);
  602. else if (def->defPart == dPartIndex_ && def->c != cp->c)
  603. message(InterpreterMessages::duplicateSdataEntityText,
  604. StringMessageArg(etext));
  605. }
  606. else
  607. sdataEntityTextTable_.insert(etext, ch);
  608. }
  609. }
  610. bool Interpreter::sdataMap(GroveString name, GroveString text, GroveChar &c) const
  611. {
  612. StringC tem(name.data(), name.size());
  613. StringC tem2(text.data(), text.size());
  614. const CharPart *cp = sdataEntityNameTable_.lookup(tem);
  615. if (cp) {
  616. c = cp->c;
  617. return 1;
  618. }
  619. cp = sdataEntityTextTable_.lookup(tem2);
  620. if (cp) {
  621. c = cp->c;
  622. return 1;
  623. }
  624. if (convertUnicodeCharName(tem, c))
  625. return 1;
  626. // I think this is the best thing to do.
  627. // At least it makes preserve-sdata work with unknown SDATA entities.
  628. c = defaultChar;
  629. return 1;
  630. }
  631. ELObj *Interpreter::convertGlyphId(const Char *str, size_t len, const Location &loc)
  632. {
  633. unsigned long n = 0;
  634. const char *publicId = 0;
  635. for (size_t i = len; i > 1; --i) {
  636. if (str[i - 1] == ':' && str[i - 2] == ':' && i < len && str[i] != '0') {
  637. for (size_t j = i; j < len; j++)
  638. n = n*10 + (str[j] - '0');
  639. publicId = storePublicId(str, i - 2, loc);
  640. break;
  641. }
  642. if (str[i - 1] < '0' || str[i - 1] > '9')
  643. break;
  644. }
  645. if (!publicId)
  646. publicId = storePublicId(str, len, loc);
  647. return new (*this) GlyphIdObj(FOTBuilder::GlyphId(publicId, n));
  648. }
  649. bool Interpreter::convertCharName(const StringC &str, Char &c) const
  650. {
  651. const CharPart *cp = namedCharTable_.lookup(str);
  652. if (cp) {
  653. c = cp->c;
  654. return 1;
  655. }
  656. return convertUnicodeCharName(str, c);
  657. }
  658. bool Interpreter::convertUnicodeCharName(const StringC &str, Char &c)
  659. {
  660. if (str.size() != 6 || str[0] != 'U' || str[1] != '-')
  661. return 0;
  662. Char value = 0;
  663. for (int i = 2; i < 6; i++) {
  664. value <<= 4;
  665. switch (str[i]) {
  666. case '0':
  667. case '1':
  668. case '2':
  669. case '3':
  670. case '4':
  671. case '5':
  672. case '6':
  673. case '7':
  674. case '8':
  675. case '9':
  676. value |= str[i] - '0';
  677. break;
  678. case 'A':
  679. case 'B':
  680. case 'C':
  681. case 'D':
  682. case 'E':
  683. case 'F':
  684. value |= 10 + (str[i] - 'A');
  685. break;
  686. default:
  687. return 0;
  688. }
  689. }
  690. c = value;
  691. return 1;
  692. }
  693. SymbolObj *Interpreter::makeSymbol(const StringC &str)
  694. {
  695. SymbolObj *sym = symbolTable_.lookup(str);
  696. if (!sym) {
  697. StringObj *strObj = new (*this) StringObj(str);
  698. makePermanent(strObj);
  699. sym = new (*this) SymbolObj(strObj);
  700. makePermanent(sym);
  701. symbolTable_.insert(sym);
  702. }
  703. return sym;
  704. }
  705. Identifier *Interpreter::lookup(const StringC &str)
  706. {
  707. Identifier *ident = identTable_.lookup(str);
  708. if (!ident) {
  709. ident = new Identifier(str);
  710. identTable_.insert(ident);
  711. }
  712. return ident;
  713. }
  714. bool Interpreter::lookupNodeProperty(const StringC &str, ComponentName::Id &id)
  715. {
  716. const int *val = nodePropertyTable_.lookup(str);
  717. if (!val) {
  718. StringC tem(str);
  719. for (size_t i = 0; i < tem.size(); i++) {
  720. if (tem[i] >= 'A' && tem[i] <= 'Z')
  721. tem[i] = 'a' + (tem[i] - 'A');
  722. }
  723. val = nodePropertyTable_.lookup(tem);
  724. if (!val)
  725. return 0;
  726. }
  727. id = ComponentName::Id(*val);
  728. return 1;
  729. }
  730. Unit *Interpreter::lookupUnit(const StringC &str)
  731. {
  732. Unit *unit = unitTable_.lookup(str);
  733. if (!unit) {
  734. unit = new Unit(str);
  735. unitTable_.insert(unit);
  736. }
  737. return unit;
  738. }
  739. CharProp *Interpreter::lookupCharProperty(const StringC &n)
  740. {
  741. CharProp *p = charPropTable_.lookup(n);
  742. if (!p) {
  743. p = new CharProp(n);
  744. charPropTable_.insert(p);
  745. }
  746. return p;
  747. }
  748. ProcessingMode *Interpreter::lookupProcessingMode(const StringC &str)
  749. {
  750. ProcessingMode *mode = processingModeTable_.lookup(str);
  751. if (!mode) {
  752. mode = new ProcessingMode(str, &initialProcessingMode_);
  753. processingModeTable_.insert(mode);
  754. }
  755. return mode;
  756. }
  757. StringC Interpreter::makeStringC(const char *s)
  758. {
  759. StringC tem;
  760. if (s)
  761. while (*s)
  762. tem += (unsigned char)*s++;
  763. return tem;
  764. }
  765. void Interpreter::endPart()
  766. {
  767. currentPartFirstInitialValue_ = initialValueNames_.size();
  768. partIndex_++;
  769. }
  770. void Interpreter::dEndPart()
  771. {
  772. dPartIndex_++;
  773. }
  774. void Interpreter::normalizeGeneralName(const NodePtr &nd, StringC &str)
  775. {
  776. NamedNodeListPtr nnl;
  777. NodePtr root;
  778. if (nd->getGroveRoot(root) == accessOK
  779. && root->getElements(nnl) == accessOK)
  780. str.resize(nnl->normalize(str.begin(), str.size()));
  781. }
  782. ELObj *Interpreter::makeLengthSpec(const FOTBuilder::LengthSpec &ls)
  783. {
  784. if (ls.displaySizeFactor != 0.0) {
  785. LengthSpec result(LengthSpec::displaySize, ls.displaySizeFactor);
  786. result += double(ls.length);
  787. return new (*this) LengthSpecObj(result);
  788. }
  789. else
  790. return new (*this) LengthObj(ls.length);
  791. }
  792. bool Interpreter::convertBooleanC(ELObj *obj, const Identifier *ident, const Location &loc,
  793. bool &result)
  794. {
  795. obj = convertFromString(obj, convertAllowBoolean, loc);
  796. if (obj == makeFalse()) {
  797. result = 0;
  798. return 1;
  799. }
  800. if (obj == makeTrue()) {
  801. result = 1;
  802. return 1;
  803. }
  804. invalidCharacteristicValue(ident, loc);
  805. return 0;
  806. }
  807. bool Interpreter::convertPublicIdC(ELObj *obj, const Identifier *ident,
  808. const Location &loc,
  809. FOTBuilder::PublicId &pubid)
  810. {
  811. if (obj == makeFalse()) {
  812. pubid = 0;
  813. return 1;
  814. }
  815. const Char *s;
  816. size_t n;
  817. if (obj->stringData(s, n)) {
  818. if (n == 0)
  819. pubid = 0;
  820. else
  821. pubid = storePublicId(s, n, loc);
  822. return 1;
  823. }
  824. invalidCharacteristicValue(ident, loc);
  825. return 0;
  826. }
  827. const char *Interpreter::storePublicId(const Char *s, size_t n, const Location &loc)
  828. {
  829. String<char> buf;
  830. for (; n > 0; s++, n--) {
  831. if (*s >= 128) {
  832. setNextLocation(loc);
  833. message(InterpreterMessages::invalidPublicIdChar,
  834. StringMessageArg(StringC(s, 1)));
  835. }
  836. else
  837. buf += char(*s);
  838. }
  839. buf += '\0';
  840. return publicIds_.store(buf);
  841. }
  842. bool Interpreter::convertStringC(ELObj *obj, const Identifier *ident, const Location &loc,
  843. StringC &result)
  844. {
  845. const Char *s;
  846. size_t n;
  847. if (obj->stringData(s, n)) {
  848. result.assign(s, n);
  849. return 1;
  850. }
  851. invalidCharacteristicValue(ident, loc);
  852. return 0;
  853. }
  854. bool Interpreter::convertLengthSpec(ELObj *obj,
  855. FOTBuilder::LengthSpec &result)
  856. {
  857. int dim;
  858. double d;
  859. switch (obj->quantityValue(result.length, d, dim)) {
  860. case ELObj::longQuantity:
  861. if (dim == 1)
  862. return 1;
  863. break;
  864. case ELObj::doubleQuantity:
  865. if (dim == 1) {
  866. // FIXME catch overflow
  867. result.length = d < 0.0 ? long(d - .5) : long(d + .5);
  868. return 1;
  869. }
  870. break;
  871. default:
  872. {
  873. const LengthSpec *ls = obj->lengthSpec();
  874. if (ls)
  875. return ls->convert(result);
  876. }
  877. break;
  878. }
  879. return 0;
  880. }
  881. bool Interpreter::convertLengthC(ELObj *obj, const Identifier *ident,
  882. const Location &loc,
  883. FOTBuilder::Length &n)
  884. {
  885. obj = convertFromString(obj, convertAllowNumber, loc);
  886. int dim;
  887. double d;
  888. switch (obj->quantityValue(n, d, dim)) {
  889. case ELObj::longQuantity:
  890. if (dim == 1)
  891. return 1;
  892. break;
  893. case ELObj::doubleQuantity:
  894. if (dim == 1) {
  895. // FIXME catch overflow
  896. n = long(d);
  897. return 1;
  898. }
  899. break;
  900. default:
  901. break;
  902. }
  903. invalidCharacteristicValue(ident, loc);
  904. return 0;
  905. }
  906. bool Interpreter::convertLengthSpecC(ELObj *obj, const Identifier *ident,
  907. const Location &loc,
  908. FOTBuilder::LengthSpec &result)
  909. {
  910. obj = convertFromString(obj, convertAllowNumber, loc);
  911. if (convertLengthSpec(obj, result))
  912. return 1;
  913. invalidCharacteristicValue(ident, loc);
  914. return 0;
  915. }
  916. bool Interpreter::convertOptLengthSpecC(ELObj *obj, const Identifier *ident,
  917. const Location &loc,
  918. FOTBuilder::OptLengthSpec &result)
  919. {
  920. obj = convertFromString(obj, convertAllowBoolean|convertAllowNumber, loc);
  921. if (obj == makeFalse()) {
  922. result.hasLength = 0;
  923. return 1;
  924. }
  925. if (convertLengthSpecC(obj, ident, loc, result.length)) {
  926. result.hasLength = 1;
  927. return 1;
  928. }
  929. return 0;
  930. }
  931. bool Interpreter::convertOptPositiveIntegerC(ELObj *obj, const Identifier *ident, const Location &loc,
  932. long &result)
  933. {
  934. obj = convertFromString(obj, convertAllowNumber|convertAllowBoolean, loc);
  935. if (obj == makeFalse()) {
  936. result = 0;
  937. return 1;
  938. }
  939. if (obj->exactIntegerValue(result) && result > 0)
  940. return 1;
  941. // FIXME allow inexact value
  942. invalidCharacteristicValue(ident, loc);
  943. return 0;
  944. }
  945. bool Interpreter::convertIntegerC(ELObj *obj, const Identifier *ident, const Location &loc,
  946. long &result)
  947. {
  948. obj = convertFromString(obj, convertAllowNumber, loc);
  949. if (obj->exactIntegerValue(result))
  950. return 1;
  951. // FIXME allow inexact value
  952. invalidCharacteristicValue(ident, loc);
  953. return 0;
  954. }
  955. bool Interpreter::convertLetter2C(ELObj *obj, const Identifier *ident, const Location &loc,
  956. FOTBuilder::Letter2 &code)
  957. {
  958. StringObj *strObj = obj->convertToString();
  959. if (strObj) {
  960. const StringC &str = *strObj;
  961. if (str.size() == 2
  962. && str[0] >= 'A' && str[0] <= 'Z'
  963. && str[1] >= 'A' && str[1] <= 'Z') {
  964. code = SP_LETTER2(str[0], str[1]);
  965. return 1;
  966. }
  967. if (str.size() == 0) {
  968. code = 0;
  969. return 1;
  970. }
  971. }
  972. else if (obj == makeFalse()) {
  973. code = 0;
  974. return 1;
  975. }
  976. invalidCharacteristicValue(ident, loc);
  977. return 0;
  978. }
  979. bool Interpreter::convertCharC(ELObj *obj, const Identifier *ident, const Location &loc,
  980. Char &result)
  981. {
  982. if (obj->charValue(result))
  983. return 1;
  984. const Char *s;
  985. size_t n;
  986. if (obj->stringData(s, n) && n == 1) {
  987. result = s[0];
  988. return 1;
  989. }
  990. invalidCharacteristicValue(ident, loc);
  991. return 0;
  992. }
  993. bool Interpreter::convertColorC(ELObj *obj, const Identifier *ident, const Location &loc, ColorObj *&color)
  994. {
  995. color = obj->asColor();
  996. if (color)
  997. return 1;
  998. invalidCharacteristicValue(ident, loc);
  999. return 0;
  1000. }
  1001. bool Interpreter::convertOptColorC(ELObj *obj, const Identifier *ident, const Location &loc, ColorObj *&color)
  1002. {
  1003. color = obj->asColor();
  1004. if (color)
  1005. return 1;
  1006. if (obj == makeFalse())
  1007. return 1;
  1008. invalidCharacteristicValue(ident, loc);
  1009. return 0;
  1010. }
  1011. bool Interpreter::convertRealC(ELObj *obj, const Identifier *ident, const Location &loc,
  1012. double &result)
  1013. {
  1014. obj = convertFromString(obj, convertAllowNumber, loc);
  1015. if (obj->realValue(result))
  1016. return 1;
  1017. invalidCharacteristicValue(ident, loc);
  1018. return 0;
  1019. }
  1020. bool Interpreter::convertEnumC(ELObj *obj, const Identifier *ident, const Location &loc,
  1021. FOTBuilder::Symbol &sym)
  1022. {
  1023. obj = convertFromString(obj, convertAllowSymbol|convertAllowBoolean, loc);
  1024. if (obj == makeFalse()) {
  1025. sym = FOTBuilder::symbolFalse;
  1026. return 1;
  1027. }
  1028. SymbolObj *symObj = obj->asSymbol();
  1029. if (symObj) {
  1030. sym = symObj->cValue();
  1031. if (sym != FOTBuilder::symbolFalse)
  1032. return 1;
  1033. }
  1034. if (obj == makeTrue()) {
  1035. sym = FOTBuilder::symbolTrue;
  1036. return 1;
  1037. }
  1038. invalidCharacteristicValue(ident, loc);
  1039. return 0;
  1040. }
  1041. bool Interpreter::convertEnumC(const FOTBuilder::Symbol *syms, size_t nSyms,
  1042. ELObj *obj, const Identifier *ident, const Location &loc,
  1043. FOTBuilder::Symbol &result)
  1044. {
  1045. obj = convertFromString(obj, convertAllowSymbol|convertAllowBoolean, loc);
  1046. SymbolObj *symObj = obj->asSymbol();
  1047. FOTBuilder::Symbol val;
  1048. if (symObj) {
  1049. val = symObj->cValue();
  1050. if (val == FOTBuilder::symbolFalse) {
  1051. invalidCharacteristicValue(ident, loc);
  1052. return 0;
  1053. }
  1054. }
  1055. else if (obj == makeFalse())
  1056. val = FOTBuilder::symbolFalse;
  1057. else if (obj == makeTrue())
  1058. val = FOTBuilder::symbolTrue;
  1059. else {
  1060. invalidCharacteristicValue(ident, loc);
  1061. return 0;
  1062. }
  1063. for (size_t i = 0; i < nSyms; i++)
  1064. if (val == syms[i]) {
  1065. result = val;
  1066. return 1;
  1067. }
  1068. invalidCharacteristicValue(ident, loc);
  1069. return 0;
  1070. }
  1071. void Interpreter::invalidCharacteristicValue(const Identifier *ident, const Location &loc)
  1072. {
  1073. setNextLocation(loc);
  1074. message(InterpreterMessages::invalidCharacteristicValue,
  1075. StringMessageArg(ident->name()));
  1076. }
  1077. static
  1078. bool equal(const Char *s1, const char *s2, size_t n)
  1079. {
  1080. while (n > 0) {
  1081. if (*s1++ != (unsigned char)*s2++)
  1082. return 0;
  1083. --n;
  1084. }
  1085. return 1;
  1086. }
  1087. ELObj *Interpreter::convertFromString(ELObj *obj, unsigned hints, const Location &loc)
  1088. {
  1089. // FIXME fold to lower case
  1090. const Char *s;
  1091. size_t n;
  1092. if (!dsssl2() || !obj->stringData(s, n))
  1093. return obj;
  1094. if (hints & convertAllowNumber) {
  1095. ELObj *tem = convertNumber(StringC(s, n));
  1096. if (tem)
  1097. return tem->resolveQuantities(1, *this, loc);
  1098. }
  1099. if (hints & convertAllowSymbol) {
  1100. StringC tem(s, n);
  1101. SymbolObj *sym = symbolTable_.lookup(tem);
  1102. if (sym && sym->cValue() != FOTBuilder::symbolFalse)
  1103. return sym;
  1104. }
  1105. if (hints & convertAllowBoolean) {
  1106. switch (n) {
  1107. case 2:
  1108. if (equal(s, "no", n))
  1109. return makeFalse();
  1110. break;
  1111. case 3:
  1112. if (equal(s, "yes", n))
  1113. return makeTrue();
  1114. break;
  1115. case 4:
  1116. if (equal(s, "true", n))
  1117. return makeTrue();
  1118. break;
  1119. case 5:
  1120. if (equal(s, "false", n))
  1121. return makeFalse();
  1122. break;
  1123. }
  1124. }
  1125. return obj;
  1126. }
  1127. ELObj *Interpreter::convertNumber(const StringC &str, int radix)
  1128. {
  1129. {
  1130. if (str.size() == 0)
  1131. return 0;
  1132. size_t i = 0;
  1133. if (str[0] == '#') {
  1134. if (str.size() < 2)
  1135. return 0;
  1136. switch (str[1]) {
  1137. case 'd':
  1138. radix = 10;
  1139. break;
  1140. case 'x':
  1141. radix = 16;
  1142. break;
  1143. case 'o':
  1144. radix = 8;
  1145. break;
  1146. case 'b':
  1147. radix = 2;
  1148. break;
  1149. default:
  1150. return 0;
  1151. }
  1152. i += 2;
  1153. }
  1154. if (i >= str.size())
  1155. return 0;
  1156. bool negative;
  1157. if (str[i] == '-') {
  1158. negative = 1;
  1159. i++;
  1160. }
  1161. else {
  1162. negative = 0;
  1163. if (str[i] == '+')
  1164. i++;
  1165. }
  1166. bool hadDecimalPoint = 0;
  1167. bool hadDigit = 0;
  1168. long n = 0;
  1169. int exp = 0;
  1170. for (; i < str.size(); i++) {
  1171. Char c = str[i];
  1172. int weight;
  1173. switch (c) {
  1174. case '0':
  1175. weight = 0;
  1176. break;
  1177. case '1':
  1178. weight = 1;
  1179. break;
  1180. case '2':
  1181. weight = 2;
  1182. break;
  1183. case '3':
  1184. weight = 3;
  1185. break;
  1186. case '4':
  1187. weight = 4;
  1188. break;
  1189. case '5':
  1190. weight = 5;
  1191. break;
  1192. case '6':
  1193. weight = 6;
  1194. break;
  1195. case '7':
  1196. weight = 7;
  1197. break;
  1198. case '8':
  1199. weight = 8;
  1200. break;
  1201. case '9':
  1202. weight = 9;
  1203. break;
  1204. case 'a':
  1205. weight = 10;
  1206. break;
  1207. case 'b':
  1208. weight = 11;
  1209. break;
  1210. case 'c':
  1211. weight = 12;
  1212. break;
  1213. case 'd':
  1214. weight = 13;
  1215. break;
  1216. case 'e':
  1217. weight = 14;
  1218. break;
  1219. case 'f':
  1220. weight = 15;
  1221. break;
  1222. default:
  1223. weight = -1;
  1224. break;
  1225. }
  1226. if (weight >= 0 && weight < radix) {
  1227. hadDigit = 1;
  1228. if (negative) {
  1229. if (-(unsigned long)n > (-(unsigned long)LONG_MIN - weight)/radix) {
  1230. if (radix != 10)
  1231. return 0;
  1232. return convertNumberFloat(str);
  1233. }
  1234. else
  1235. n = n*radix - weight;
  1236. }
  1237. else {
  1238. if (n > (LONG_MAX - weight)/radix) {
  1239. if (radix != 10)
  1240. return 0;
  1241. return convertNumberFloat(str);
  1242. }
  1243. else
  1244. n = n*radix + weight;
  1245. }
  1246. if (hadDecimalPoint)
  1247. exp--;
  1248. }
  1249. else if (c == '.' && radix == 10) {
  1250. if (hadDecimalPoint)
  1251. return 0;
  1252. hadDecimalPoint = 1;
  1253. }
  1254. else
  1255. break;
  1256. }
  1257. if (!hadDigit || (radix != 10 && i < str.size()))
  1258. return 0;
  1259. if (i + 1 < str.size() && str[i] == 'e'
  1260. && lexCategory(str[i + 1]) != lexLetter) {
  1261. hadDecimalPoint = 1;
  1262. i++;
  1263. int e;
  1264. if (!scanSignDigits(str, i, e))
  1265. return 0;
  1266. exp += e;
  1267. }
  1268. if (i < str.size()) {
  1269. int unitExp;
  1270. Unit *unit = scanUnit(str, i, unitExp);
  1271. if (!unit)
  1272. return 0;
  1273. if (unitExp == 1)
  1274. return new (*this) UnresolvedLengthObj(n, exp, unit);
  1275. else
  1276. return convertNumberFloat(str);
  1277. }
  1278. if (hadDecimalPoint)
  1279. return convertNumberFloat(str);
  1280. return makeInteger(n);
  1281. }
  1282. }
  1283. bool Interpreter::scanSignDigits(const StringC &str, size_t &i, int &n)
  1284. {
  1285. bool negative = 0;
  1286. if (i < str.size()) {
  1287. if (str[i] == '-') {
  1288. i++;
  1289. negative = 1;
  1290. } else if (str[i] == '+')
  1291. i++;
  1292. }
  1293. size_t j = i;
  1294. n = 0;
  1295. while (i < str.size()
  1296. && ('0' <= str[i] && str[i] <= '9')) {
  1297. if (negative)
  1298. n = n*10 - (str[i] - '0');
  1299. else
  1300. n = n*10 + (str[i] - '0');
  1301. i++;
  1302. }
  1303. if (i == j)
  1304. return 0;
  1305. return 1;
  1306. }
  1307. ELObj *Interpreter::convertNumberFloat(const StringC &str)
  1308. {
  1309. String<char> buf;
  1310. // omit an optional radix prefix
  1311. size_t i0 = 0;
  1312. if (str.size() > 1 && str[0] == '#' && str[1] == 'd')
  1313. i0 = 2;
  1314. for (size_t i = i0; i < str.size(); i++) {
  1315. if (str[i] > CHAR_MAX || str[i] == '\0')
  1316. return 0;
  1317. // 'E' is a valid exponent marker for C but not us
  1318. if (str[i] == 'E')
  1319. break;
  1320. buf += char(str[i]);
  1321. }
  1322. buf += '\0';
  1323. const char *endPtr;
  1324. double val = strtod((char *)buf.data(), (char **)&endPtr);
  1325. if (endPtr - buf.data() == str.size() - i0)
  1326. return new (*this) RealObj(val);
  1327. if (endPtr == buf.data())
  1328. return 0;
  1329. int unitExp;
  1330. Unit *unit = scanUnit(str, endPtr - buf.data() + i0, unitExp);
  1331. if (!unit)
  1332. return 0;
  1333. return new (*this) UnresolvedQuantityObj(val, unit, unitExp);
  1334. }
  1335. // Return 0 for error.
  1336. Unit *Interpreter::scanUnit(const StringC &str, size_t i, int &unitExp)
  1337. {
  1338. StringC unitName;
  1339. while (i < str.size()) {
  1340. if (str[i] == '-' || str[i] == '+' || ('0' <= str[i] && str[i] <= '9'))
  1341. break;
  1342. unitName += str[i++];
  1343. }
  1344. if (i >= str.size())
  1345. unitExp = 1;
  1346. else {
  1347. unitExp = 0;
  1348. bool neg = 0;
  1349. if (str[i] == '-' || str[i] == '+') {
  1350. if (str[i] == '-')
  1351. neg = 1;
  1352. i++;
  1353. if (i >= str.size())
  1354. return 0;
  1355. }
  1356. while (i < str.size()) {
  1357. if (str[i] < '0' || str[i] > '9')
  1358. return 0;
  1359. unitExp *= 10;
  1360. if (neg)
  1361. unitExp -= (str[i] - '0');
  1362. else
  1363. unitExp += (str[i] - '0');
  1364. i++;
  1365. }
  1366. }
  1367. return lookupUnit(unitName);
  1368. }
  1369. void Interpreter::setNodeLocation(const NodePtr &nd)
  1370. {
  1371. const LocNode *lnp;
  1372. Location nodeLoc;
  1373. if ((lnp = LocNode::convert(nd)) != 0
  1374. && lnp->getLocation(nodeLoc) == accessOK)
  1375. setNextLocation(nodeLoc);
  1376. }
  1377. bool Interpreter::convertToPattern(ELObj *obj, const Location &loc, Pattern &pattern)
  1378. {
  1379. IList<Pattern::Element> list;
  1380. if (!convertToPattern(obj, loc, 0, list))
  1381. return 0;
  1382. Pattern tem(list);
  1383. tem.swap(pattern);
  1384. return 1;
  1385. }
  1386. bool Interpreter::convertToPattern(ELObj *obj, const Location &loc,
  1387. bool isChild,
  1388. IList<Pattern::Element> &list)
  1389. {
  1390. StringObj *str = obj->convertToString();
  1391. if (str) {
  1392. const Char *s;
  1393. size_t n;
  1394. str->stringData(s, n);
  1395. if (!n) {
  1396. setNextLocation(loc);
  1397. message(InterpreterMessages::patternEmptyGi);
  1398. return 0;
  1399. }
  1400. list.insert(new Pattern::Element(StringC(s, n)));
  1401. return 1;
  1402. }
  1403. if (obj == makeTrue()) {
  1404. list.insert(new Pattern::Element(StringC()));
  1405. return 1;
  1406. }
  1407. Pattern::Element *curElement = 0;
  1408. while (!obj->isNil()) {
  1409. PairObj *pair = obj->asPair();
  1410. if (!pair) {
  1411. setNextLocation(loc);
  1412. message(InterpreterMessages::patternNotList);
  1413. return 0;
  1414. }
  1415. ELObj *head = pair->car();
  1416. obj = pair->cdr();
  1417. if (head == makeTrue() && dsssl2()) {
  1418. list.insert(curElement = new Pattern::Element(StringC()));
  1419. continue;
  1420. }
  1421. str = head->convertToString();
  1422. if (str) {
  1423. const Char *s;
  1424. size_t n;
  1425. str->stringData(s, n);
  1426. if (!n) {
  1427. setNextLocation(loc);
  1428. message(InterpreterMessages::patternEmptyGi);
  1429. return 0;
  1430. }
  1431. list.insert(curElement = new Pattern::Element(StringC(s, n)));
  1432. continue;
  1433. }
  1434. if (!curElement) {
  1435. setNextLocation(loc);
  1436. message(InterpreterMessages::patternBadGi,
  1437. ELObjMessageArg(head, *this));
  1438. return 0;
  1439. }
  1440. if (head->isNil())
  1441. continue; // empty attribute list
  1442. if (head->asPair()) {
  1443. if (!patternAddAttributeQualifiers(head, loc, *curElement)) {
  1444. setNextLocation(loc);
  1445. message(InterpreterMessages::patternBadAttributeQualifier);
  1446. return 0;
  1447. }
  1448. continue;
  1449. }
  1450. KeywordObj *key = dsssl2() ? head->asKeyword() : 0;
  1451. if (!key) {
  1452. setNextLocation(loc);
  1453. message(InterpreterMessages::patternBadMember,
  1454. ELObjMessageArg(head, *this));
  1455. return 0;
  1456. }
  1457. pair = obj->asPair();
  1458. if (!pair) {
  1459. setNextLocation(loc);
  1460. message(obj->isNil()
  1461. ? InterpreterMessages::patternMissingQualifierValue
  1462. : InterpreterMessages::patternNotList);
  1463. return 0;
  1464. }
  1465. ELObj *value = pair->car();
  1466. obj = pair->cdr();
  1467. Identifier::SyntacticKey k;
  1468. if (!key->identifier()->syntacticKey(k)) {
  1469. setNextLocation(loc);
  1470. message(InterpreterMessages::patternUnknownQualifier,
  1471. StringMessageArg(key->identifier()->name()));
  1472. return 0;
  1473. }
  1474. switch (k) {
  1475. case Identifier::keyAttributes:
  1476. if (!patternAddAttributeQualifiers(value, loc, *curElement)) {
  1477. setNextLocation(loc);
  1478. message(InterpreterMessages::patternBadAttributeQualifier);
  1479. return 0;
  1480. }
  1481. break;
  1482. case Identifier::keyChildren:
  1483. {
  1484. IList<Pattern::Element> children;
  1485. if (!convertToPattern(value, loc, 1, children))
  1486. return 0;
  1487. if (!children.empty())
  1488. curElement->addQualifier(new Pattern::ChildrenQualifier(children));
  1489. }
  1490. break;
  1491. case Identifier::keyRepeat:
  1492. {
  1493. if (isChild) {
  1494. setNextLocation(loc);
  1495. message(InterpreterMessages::patternChildRepeat);
  1496. return 0;
  1497. }
  1498. SymbolObj *sym = value->asSymbol();
  1499. if (sym) {
  1500. const StringC &str = *sym->name();
  1501. if (str.size() == 1) {
  1502. switch (str[0]) {
  1503. case '*':
  1504. curElement->setRepeat(0, Pattern::Repeat(-1));
  1505. value = 0;
  1506. break;
  1507. case '?':
  1508. curElement->setRepeat(0, 1);
  1509. value = 0;
  1510. break;
  1511. case '+':
  1512. curElement->setRepeat(1, Pattern::Repeat(-1));
  1513. value = 0;
  1514. break;
  1515. default:
  1516. break;
  1517. }
  1518. }
  1519. }
  1520. if (value) {
  1521. setNextLocation(loc);
  1522. message(InterpreterMessages::patternBadQualifierValue,
  1523. ELObjMessageArg(value, *this),
  1524. StringMessageArg(key->identifier()->name()));
  1525. return 0;
  1526. }
  1527. }
  1528. break;
  1529. case Identifier::keyPosition:
  1530. {
  1531. SymbolObj *sym = value->asSymbol();
  1532. if (sym) {
  1533. Pattern::Qualifier *qual = 0;
  1534. const StringC &str = *sym->name();
  1535. if (str == "first-of-type")
  1536. qual = new Pattern::FirstOfTypeQualifier;
  1537. else if (str == "last-of-type")
  1538. qual = new Pattern::LastOfTypeQualifier;
  1539. else if (str == "first-of-any")
  1540. qual = new Pattern::FirstOfAnyQualifier;
  1541. else if (str == "last-of-any")
  1542. qual = new Pattern::LastOfAnyQualifier;
  1543. if (qual) {
  1544. curElement->addQualifier(qual);
  1545. break;
  1546. }
  1547. }
  1548. setNextLocation(loc);
  1549. message(InterpreterMessages::patternBadQualifierValue,
  1550. ELObjMessageArg(value, *this),
  1551. StringMessageArg(key->identifier()->name()));
  1552. return 0;
  1553. }
  1554. case Identifier::keyOnly:
  1555. {
  1556. SymbolObj *sym = value->asSymbol();
  1557. if (sym) {
  1558. Pattern::Qualifier *qual = 0;
  1559. const StringC &str = *sym->name();
  1560. if (str == "of-type")
  1561. qual = new Pattern::OnlyOfTypeQualifier;
  1562. else if (str == "of-any")
  1563. qual = new Pattern::OnlyOfAnyQualifier;
  1564. if (qual) {
  1565. curElement->addQualifier(qual);
  1566. break;
  1567. }
  1568. }
  1569. setNextLocation(loc);
  1570. message(InterpreterMessages::patternBadQualifierValue,
  1571. ELObjMessageArg(value, *this),
  1572. StringMessageArg(key->identifier()->name()));
  1573. return 0;
  1574. }
  1575. break;
  1576. case Identifier::keyId:
  1577. {
  1578. StringObj *str = value->convertToString();
  1579. if (!str) {
  1580. setNextLocation(loc);
  1581. message(InterpreterMessages::patternBadQualifierValue,
  1582. ELObjMessageArg(value, *this),
  1583. StringMessageArg(key->identifier()->name()));
  1584. return 0;
  1585. }
  1586. const Char *s;
  1587. size_t n;
  1588. str->stringData(s, n);
  1589. curElement->addQualifier(new Pattern::IdQualifier(StringC(s, n)));
  1590. }
  1591. break;
  1592. case Identifier::keyClass:
  1593. {
  1594. StringObj *str = value->convertToString();
  1595. if (!str) {
  1596. setNextLocation(loc);
  1597. message(InterpreterMessages::patternBadQualifierValue,
  1598. ELObjMessageArg(value, *this),
  1599. StringMessageArg(key->identifier()->name()));
  1600. return 0;
  1601. }
  1602. const Char *s;
  1603. size_t n;
  1604. str->stringData(s, n);
  1605. curElement->addQualifier(new Pattern::ClassQualifier(StringC(s, n)));
  1606. }
  1607. break;
  1608. case Identifier::keyImportance:
  1609. {
  1610. long n;
  1611. if (!value->exactIntegerValue(n)) {
  1612. setNextLocation(loc);
  1613. message(InterpreterMessages::patternBadQualifierValue,
  1614. ELObjMessageArg(value, *this),
  1615. StringMessageArg(key->identifier()->name()));
  1616. return 0;
  1617. }
  1618. curElement->addQualifier(new Pattern::ImportanceQualifier(n));
  1619. }
  1620. break;
  1621. case Identifier::keyPriority:
  1622. {
  1623. long n;
  1624. if (!value->exactIntegerValue(n)) {
  1625. setNextLocation(loc);
  1626. message(InterpreterMessages::patternBadQualifierValue,
  1627. ELObjMessageArg(value, *this),
  1628. StringMessageArg(key->identifier()->name()));
  1629. return 0;
  1630. }
  1631. curElement->addQualifier(new Pattern::PriorityQualifier(n));
  1632. }
  1633. break;
  1634. default:
  1635. setNextLocation(loc);
  1636. message(InterpreterMessages::patternUnknownQualifier,
  1637. StringMessageArg(key->identifier()->name()));
  1638. return 0;
  1639. }
  1640. }
  1641. return 1;
  1642. }
  1643. bool Interpreter::patternAddAttributeQualifiers(ELObj *obj,
  1644. const Location &loc,
  1645. Pattern::Element &elem)
  1646. {
  1647. while (!obj->isNil()) {
  1648. PairObj *pair = obj->asPair();
  1649. if (!pair)
  1650. return 0;
  1651. StringObj *tem = pair->car()->convertToString();
  1652. if (!tem)
  1653. return 0;
  1654. const Char *s;
  1655. size_t n;
  1656. tem->stringData(s, n);
  1657. if (n == 0)
  1658. return 0;
  1659. StringC name(s, n);
  1660. obj = pair->cdr();
  1661. pair = obj->asPair();
  1662. if (!pair)
  1663. return 0;
  1664. obj = pair->cdr();
  1665. if (pair->car() == makeFalse() && dsssl2())
  1666. elem.addQualifier(new Pattern::AttributeMissingValueQualifier(name));
  1667. else if (pair->car() == makeTrue() && dsssl2())
  1668. elem.addQualifier(new Pattern::AttributeHasValueQualifier(name));
  1669. else {
  1670. tem = pair->car()->convertToString();
  1671. if (!tem)
  1672. return 0;
  1673. tem->stringData(s, n);
  1674. elem.addQualifier(new Pattern::AttributeQualifier(name, StringC(s, n)));
  1675. }
  1676. }
  1677. return 1;
  1678. }
  1679. void Interpreter::dispatchMessage(Message &msg)
  1680. {
  1681. messenger_->dispatchMessage(msg);
  1682. }
  1683. void Interpreter::dispatchMessage(const Message &msg)
  1684. {
  1685. messenger_->dispatchMessage(msg);
  1686. }
  1687. Interpreter::StringSet::StringSet()
  1688. {
  1689. }
  1690. const char *Interpreter::StringSet::store(String<char> &str)
  1691. {
  1692. str += '\0';
  1693. const String<char> *p = table_.lookup(str);
  1694. if (!p) {
  1695. String<char> *tem = new String<char>;
  1696. str.swap(*tem);
  1697. table_.insert(tem);
  1698. p = tem;
  1699. }
  1700. return p->data();
  1701. }
  1702. unsigned long Interpreter::StringSet::hash(const String<char> &str)
  1703. {
  1704. const char *p = str.data();
  1705. unsigned long h = 0;
  1706. for (size_t n = str.size(); n > 0; n--)
  1707. h = (h << 5) + h + (unsigned char)*p++; // from Chris Torek
  1708. return h;
  1709. }
  1710. bool Identifier::preferBuiltin_ = 0;
  1711. Identifier::Identifier(const StringC &name)
  1712. : Named(name), value_(0), syntacticKey_(notKey), beingComputed_(0),
  1713. flowObj_(0), builtin_(0), defPart_(0), charNIC_(0),
  1714. feature_(Interpreter::noFeature)
  1715. {
  1716. }
  1717. void Identifier::maybeSaveBuiltin()
  1718. {
  1719. if (defPart_ == unsigned(-1) && !builtin_) {
  1720. builtin_ = new Identifier(name());
  1721. if (value_)
  1722. builtin_->setValue(value_, defPart_);
  1723. else
  1724. builtin_->setDefinition(def_, defPart_, defLoc_);
  1725. }
  1726. }
  1727. void Identifier::setDefinition(Owner<Expression> &expr,
  1728. unsigned part,
  1729. const Location &loc)
  1730. {
  1731. maybeSaveBuiltin();
  1732. def_.swap(expr);
  1733. defPart_ = part;
  1734. defLoc_ = loc;
  1735. value_ = 0;
  1736. }
  1737. void Identifier::setBuiltinDefinition(Owner<Expression> &expr,
  1738. unsigned part,
  1739. const Location &loc)
  1740. {
  1741. if (!builtin_) {
  1742. builtin_ = new Identifier(name());
  1743. builtin_->setDefinition(expr, part, loc);
  1744. }
  1745. }
  1746. void Identifier::setValue(ELObj *value, unsigned partIndex)
  1747. {
  1748. maybeSaveBuiltin();
  1749. value_ = value;
  1750. // Built in functions have lowest priority.
  1751. defPart_ = partIndex;
  1752. }
  1753. bool Identifier::defined(unsigned &part, Location &loc) const
  1754. {
  1755. if (builtin_ && preferBuiltin_)
  1756. return builtin_->defined(part, loc);
  1757. if (!def_ && !value_)
  1758. return 0;
  1759. part = defPart_;
  1760. loc = defLoc_;
  1761. return 1;
  1762. }
  1763. ELObj *Identifier::computeValue(bool force, Interpreter &interp) const
  1764. {
  1765. if (builtin_ && preferBuiltin_)
  1766. return builtin_->computeValue(force, interp);
  1767. if (value_)
  1768. return value_;
  1769. bool preferred = 0;
  1770. if (defPart_ == unsigned(-1) && !preferBuiltin_) {
  1771. preferBuiltin_ = 1;
  1772. preferred = 1;
  1773. }
  1774. ASSERT(def_);
  1775. if (beingComputed_) {
  1776. if (force) {
  1777. interp.setNextLocation(defLoc_);
  1778. interp.message(InterpreterMessages::identifierLoop,
  1779. StringMessageArg(name()));
  1780. ((Identifier *)this)->value_ = interp.makeError();
  1781. }
  1782. }
  1783. else {
  1784. ((Identifier *)this)->beingComputed_ = 1;
  1785. if (insn_.isNull())
  1786. ((Identifier *)this)->insn_
  1787. = Expression::optimizeCompile(((Identifier *)this)->def_, interp,
  1788. Environment(), 0, InsnPtr());
  1789. if (force || def_->canEval(0)) {
  1790. VM vm(interp);
  1791. ELObj *v = vm.eval(insn_.pointer());
  1792. interp.makePermanent(v);

Large files files are truncated, but you can click here to view the full file