1 // Copyright (c) 1996 James Clark
2 // See the file copying.txt for copying permission.
5 #include "SchemeParser.h"
6 #include "InterpreterMessages.h"
8 #include "MacroFlowObj.h"
13 #include "ELObjMessageArg.h"
14 #include "DssslSpecEventHandler.h"
16 #ifdef DSSSL_NAMESPACE
17 namespace DSSSL_NAMESPACE {
20 const Char defaultChar = 0xfffd;
22 SchemeParser::SchemeParser(Interpreter &interp,
23 Owner<InputSource> &in)
25 defMode_(interp.initialProcessingMode()),
26 dsssl2_(interp.dsssl2()),
31 StringC tem(Interpreter::makeStringC("ISO/IEC 10036/RA//Glyphs"));
32 afiiPublicId_ = interp_->storePublicId(tem.data(), tem.size(), Location());
36 void SchemeParser::parseStandardChars()
40 if (!getToken(allowIdentifier|allowEndOfEntity, tok)
41 || tok == tokenEndOfEntity)
44 StringC name(currentToken_);
46 if (!getToken(allowOtherExpr, tok) || tok != tokenNumber) {
47 message(InterpreterMessages::badDeclaration);
52 for (i = 0; i < name.size(); i++)
53 if (interp_->lexCategory(name[i]) != Interpreter::lexLetter
55 (interp_->lexCategory(name[i]) != Interpreter::lexDigit
56 && name[i] != '-' && name[i] != '.')))
58 if (i < name.size() || name.size() == 1) {
59 message(InterpreterMessages::invalidCharName,
60 StringMessageArg(name));
64 for (i = 0; i < currentToken_.size(); i++)
65 if (interp_->lexCategory(currentToken_[i]) != Interpreter::lexDigit)
68 if (i < currentToken_.size()) {
69 message(InterpreterMessages::invalidCharNumber,
70 StringMessageArg(currentToken_));
74 interp_->addStandardChar(name, currentToken_);
78 void SchemeParser::parseNameChars()
81 // FIXME we do not check that we have valid character names
83 if (!getToken(allowIdentifier|allowEndOfEntity, tok)
84 || tok == tokenEndOfEntity)
86 interp_->addNameChar(currentToken_);
90 void SchemeParser::parseSeparatorChars()
93 // FIXME we do not check that we have valid character names
95 if (!getToken(allowIdentifier|allowEndOfEntity, tok)
96 || tok == tokenEndOfEntity)
98 interp_->addSeparatorChar(currentToken_);
102 void SchemeParser::parseMapSdataEntity(const StringC &ename, const StringC &etext)
105 if (!getToken(allowIdentifier|allowEndOfEntity, tok)
106 || tok == tokenEndOfEntity) {
107 message(InterpreterMessages::badDeclaration);
111 interp_->addSdataEntity(ename, etext, currentToken_);
114 void SchemeParser::parse()
119 if (!getToken(recovering ? ~0 : allowOpenParen|allowEndOfEntity,
123 if (tok == tokenEndOfEntity)
125 if (tok != tokenOpenParen
126 || !getToken(recovering ? ~0 : unsigned(allowIdentifier), tok)
127 || tok != tokenIdentifier)
130 const Identifier *ident = lookup(currentToken_);
131 Identifier::SyntacticKey key;
132 if (!ident->syntacticKey(key)) {
134 message(InterpreterMessages::unknownTopLevelForm,
135 StringMessageArg(currentToken_));
140 case Identifier::keyDefine:
141 recovering = !doDefine();
143 case Identifier::keyDefineUnit:
144 recovering = !doDefineUnit();
146 case Identifier::keyDefault:
147 recovering = !doDefault();
149 case Identifier::keyElement:
150 recovering = !doElement();
152 case Identifier::keyOrElement:
153 recovering = !doOrElement();
155 case Identifier::keyRoot:
156 recovering = !doRoot();
158 case Identifier::keyId:
159 recovering = !doId();
161 case Identifier::keyMode:
162 recovering = !doMode();
164 case Identifier::keyDeclareInitialValue:
165 recovering = !doDeclareInitialValue();
167 case Identifier::keyDeclareCharacteristic:
168 recovering = !doDeclareCharacteristic();
170 case Identifier::keyDeclareFlowObjectClass:
171 recovering = !doDeclareFlowObjectClass();
173 case Identifier::keyDeclareClassAttribute:
174 recovering = !doDeclareClassAttribute();
176 case Identifier::keyDeclareIdAttribute:
177 recovering = !doDeclareIdAttribute();
179 case Identifier::keyDeclareFlowObjectMacro:
180 recovering = !doDeclareFlowObjectMacro();
182 case Identifier::keyDeclareDefaultLanguage:
183 recovering = !doDeclareDefaultLanguage();
185 case Identifier::keyDefineLanguage:
186 recovering = !doDefineLanguage();
188 case Identifier::keyDeclareCharProperty:
189 recovering = !doDeclareCharProperty();
191 case Identifier::keyAddCharProperties:
192 recovering = !doAddCharProperties();
194 case Identifier::keyDeclareCharCharacteristicAndProperty:
195 recovering = !doDeclareCharCharacteristicAndProperty();
197 case Identifier::keyDeclareReferenceValueType:
198 case Identifier::keyDefinePageModel:
199 case Identifier::keyDefineColumnSetModel:
200 recovering = !skipForm();
204 message(InterpreterMessages::unknownTopLevelForm,
205 StringMessageArg(currentToken_));
214 NamedTableIter<Identifier> iter(identTable_);
216 Identifier *ident = iter.next();
221 if (ident->defined(part, loc)) {
222 ELObj *obj = ident->computeValue(1, *this);
224 *os_ << ident->name() << "=";
225 obj->print(*this, *os_);
226 *os_ << OutputCharStream::newline;
234 bool SchemeParser::parseExpression(Owner<Expression> &expr)
236 Identifier::SyntacticKey key;
238 if (!parseExpression(0, expr, key, tok))
240 getToken(allowEndOfEntity, tok);
244 bool SchemeParser::doMode()
247 if (!getToken(allowIdentifier, tok))
249 defMode_ = lookupProcessingMode(currentToken_);
250 defMode_->setDefined();
252 if (!getToken(allowOpenParen|allowCloseParen, tok))
254 if (tok == tokenCloseParen)
256 if (!getToken(allowIdentifier, tok))
258 const Identifier *ident = lookup(currentToken_);
259 Identifier::SyntacticKey key;
260 if (!ident->syntacticKey(key)) {
261 message(InterpreterMessages::badModeForm,
262 StringMessageArg(currentToken_));
267 case Identifier::keyDefault:
271 case Identifier::keyElement:
275 case Identifier::keyOrElement:
279 case Identifier::keyRoot:
283 case Identifier::keyId:
288 message(InterpreterMessages::badModeForm,
289 StringMessageArg(currentToken_));
294 defMode_ = interp_->initialProcessingMode();
298 bool SchemeParser::doElement()
300 Location loc(in_->currentLocation());
303 if (!parseDatum(0, obj, loc, tok))
305 NCVector<Pattern> patterns(1);
306 Owner<Expression> expr;
307 ProcessingMode::RuleType ruleType;
308 if (interp_->convertToPattern(obj, loc, patterns[0])) {
309 if (!parseRuleBody(expr, ruleType))
311 defMode_->addRule(0, patterns, expr, ruleType, loc, *interp_);
313 else if (!parseRuleBody(expr, ruleType))
318 bool SchemeParser::doOrElement()
320 Location loc(in_->currentLocation());
322 if (!getToken(allowOpenParen, tok))
324 NCVector<Pattern> patterns;
325 unsigned allowed = 0;
329 if (!parseDatum(allowed, obj, loc, tok))
333 allowed = allowCloseParen;
335 patterns.resize(patterns.size() + 1);
336 if (!interp_->convertToPattern(obj, loc, patterns.back()))
340 ProcessingMode::RuleType ruleType;
341 Owner<Expression> expr;
342 if (!parseRuleBody(expr, ruleType))
345 defMode_->addRule(0, patterns, expr, ruleType, loc, *interp_);
349 bool SchemeParser::doId()
351 Location loc(in_->currentLocation());
353 if (!getToken(allowString|allowIdentifier, tok))
355 StringC id(currentToken_);
356 Owner<Expression> expr;
357 ProcessingMode::RuleType ruleType;
358 if (!parseRuleBody(expr, ruleType))
360 IList<Pattern::Element> list;
361 Pattern::Element *elem = new Pattern::Element(StringC());
363 elem->addQualifier(new Pattern::IdQualifier(id));
364 Pattern pattern(list);
365 NCVector<Pattern> patterns(1);
366 patterns[0].swap(pattern);
367 defMode_->addRule(0, patterns, expr, ruleType, loc, *interp_);
371 bool SchemeParser::doDefault()
373 Location loc(in_->currentLocation());
374 Owner<Expression> expr;
375 ProcessingMode::RuleType ruleType;
376 if (!parseRuleBody(expr, ruleType))
378 IList<Pattern::Element> list;
379 list.insert(new Pattern::Element(StringC()));
380 Pattern pattern(list);
381 NCVector<Pattern> patterns(1);
382 pattern.swap(patterns[0]);
383 defMode_->addRule(0, patterns, expr, ruleType, loc, *interp_);
387 bool SchemeParser::doRoot()
389 Location loc(in_->currentLocation());
390 Owner<Expression> expr;
391 ProcessingMode::RuleType ruleType;
392 if (!parseRuleBody(expr, ruleType))
394 NCVector<Pattern> patterns;
395 defMode_->addRule(1, patterns, expr, ruleType, loc, *interp_);
399 bool SchemeParser::parseRuleBody(Owner<Expression> &expr, ProcessingMode::RuleType &ruleType)
402 Identifier::SyntacticKey key;
403 if (!parseExpression(0, expr, key, tok))
405 const Identifier *k = dsssl2() ? expr->keyword() : 0;
408 Vector<const Identifier *> keys;
409 NCVector<Owner<Expression> > exprs;
412 exprs.resize(exprs.size() + 1);
413 if (!parseExpression(0, exprs.back(), key, tok))
415 if (!getToken(allowKeyword|allowCloseParen, tok))
417 if (tok == tokenCloseParen)
419 k = lookup(currentToken_);
421 expr = new StyleExpression(keys, exprs, expr->location());
422 ruleType = ProcessingMode::styleRule;
425 ruleType = ProcessingMode::constructionRule;
426 if (!getToken(allowCloseParen, tok))
432 bool SchemeParser::doDeclareInitialValue()
435 if (!getToken(allowIdentifier, tok))
437 Identifier *ident = lookup(currentToken_);
438 if (ident->inheritedC().isNull())
439 message(InterpreterMessages::notABuiltinInheritedC,
440 StringMessageArg(ident->name()));
441 Owner<Expression> expr;
442 Identifier::SyntacticKey key;
443 if (!parseExpression(0, expr, key, tok))
445 if (!getToken(allowCloseParen, tok))
447 if (ident->inheritedC().isNull())
449 interp_->installInitialValue(ident, expr);
453 bool SchemeParser::doDeclareCharCharacteristicAndProperty()
455 Location loc(in_->currentLocation());
457 if (!getToken(allowIdentifier, tok))
459 Identifier *ident = lookup(currentToken_);
460 if (!getToken(allowString|(dsssl2() ? unsigned(allowFalse) : 0), tok))
463 if (tok == tokenString)
464 pubid = currentToken_;
465 Owner<Expression> expr;
466 Identifier::SyntacticKey key;
467 if (!parseExpression(0, expr, key, tok))
469 if (!getToken(allowCloseParen, tok))
473 if (ident->inheritedCDefined(defPart, defLoc)) {
474 interp_->setNextLocation(loc);
475 interp_->message(InterpreterMessages::duplicateCharacteristic,
476 StringMessageArg(ident->name()),
479 else if (ident->charNICDefined(defPart, defLoc)
480 && defPart <= interp_->currentPartIndex()) {
481 if (defPart == interp_->currentPartIndex()) {
482 interp_->setNextLocation(loc);
483 interp_->message(InterpreterMessages::duplicateCharacteristic,
484 StringMessageArg(ident->name()),
489 interp_->installExtensionCharNIC(ident, pubid, loc);
490 interp_->addCharProperty(ident, expr);
495 bool SchemeParser::doDeclareCharacteristic()
497 Location loc(in_->currentLocation());
499 if (!getToken(allowIdentifier, tok))
501 Identifier *ident = lookup(currentToken_);
502 if (!getToken(allowString|(dsssl2() ? unsigned(allowFalse) : 0), tok))
505 if (tok == tokenString)
506 pubid = currentToken_;
507 Owner<Expression> expr;
508 Identifier::SyntacticKey key;
509 if (!parseExpression(0, expr, key, tok))
511 if (!getToken(allowCloseParen, tok))
515 if (ident->charNICDefined(defPart, defLoc)) {
516 interp_->setNextLocation(loc);
517 interp_->message(InterpreterMessages::duplicateCharacteristic,
518 StringMessageArg(ident->name()),
521 else if (ident->inheritedCDefined(defPart, defLoc)
522 && defPart <= interp_->currentPartIndex()) {
523 if (defPart == interp_->currentPartIndex()) {
524 interp_->setNextLocation(loc);
525 interp_->message(InterpreterMessages::duplicateCharacteristic,
526 StringMessageArg(ident->name()),
531 interp_->installExtensionInheritedC(ident, pubid, loc);
532 interp_->installInitialValue(ident, expr);
537 bool SchemeParser::doDeclareFlowObjectClass()
539 Location loc(in_->currentLocation());
541 if (!getToken(allowIdentifier, tok))
543 Identifier *ident = lookup(currentToken_);
544 if (!getToken(allowString, tok))
548 if (ident->inheritedCDefined(defPart, defLoc)
549 && defPart <= interp_->currentPartIndex()) {
550 if (defPart == interp_->currentPartIndex()) {
551 interp_->setNextLocation(loc);
552 interp_->message(InterpreterMessages::duplicateFlowObjectClass,
553 StringMessageArg(ident->name()),
558 interp_->installExtensionFlowObjectClass(ident, currentToken_, loc);
559 if (!getToken(allowCloseParen, tok))
564 bool SchemeParser::doDeclareFlowObjectMacro()
566 Location loc(in_->currentLocation());
568 if (!getToken(allowIdentifier, tok))
570 Identifier *ident = lookup(currentToken_);
571 if (ident->flowObj())
572 // FIXME report an error if same part
574 if (!getToken(allowOpenParen, tok))
576 Vector<const Identifier *> nics;
577 NCVector<Owner<Expression> > inits;
578 const Identifier *contentsId = 0;
579 unsigned allowed = (allowOpenParen|allowCloseParen|allowIdentifier|allowHashContents);
581 if (!getToken(allowed, tok))
583 if (tok == tokenCloseParen)
586 case tokenHashContents:
587 if (!getToken(allowIdentifier, tok))
589 contentsId = lookup(currentToken_);
590 allowed = allowCloseParen;
592 case tokenIdentifier:
593 nics.push_back(lookup(currentToken_));
597 if (!getToken(allowIdentifier, tok))
599 nics.push_back(lookup(currentToken_));
600 inits.resize(nics.size());
601 Identifier::SyntacticKey key;
602 if (!parseExpression(0, inits.back(), key, tok))
604 if (!getToken(allowCloseParen, tok))
612 // We could allow sequence which is appended together here.
613 Owner<Expression> body;
614 Identifier::SyntacticKey key;
615 if (!parseExpression(0, body, key, tok))
617 if (!getToken(allowCloseParen, tok))
621 if (ident->inheritedCDefined(defPart, defLoc)
622 && defPart <= interp_->currentPartIndex()) {
623 if (defPart == interp_->currentPartIndex()) {
624 interp_->setNextLocation(loc);
625 interp_->message(InterpreterMessages::duplicateFlowObjectClass,
626 StringMessageArg(ident->name()),
631 MacroFlowObj *flowObj
632 = new (*interp_) MacroFlowObj(nics, inits, contentsId, body);
633 interp_->makePermanent(flowObj);
634 ident->setFlowObj(flowObj);
639 bool SchemeParser::doDeclareClassAttribute()
642 if (!getToken(allowString|allowIdentifier, tok))
644 interp_->addClassAttributeName(currentToken_);
645 if (!getToken(allowCloseParen, tok))
650 bool SchemeParser::doDeclareIdAttribute()
653 if (!getToken(allowString|allowIdentifier, tok))
655 interp_->addIdAttributeName(currentToken_);
656 if (!getToken(allowCloseParen, tok))
661 bool SchemeParser::doDefine()
663 Location loc(in_->currentLocation());
665 if (!getToken(allowOpenParen|allowIdentifier, tok))
667 Vector<const Identifier *> formals;
669 if (tok == tokenOpenParen) {
670 if (!getToken(allowIdentifier, tok))
676 Identifier *ident = lookup(currentToken_);
677 Identifier::SyntacticKey key;
678 if (ident->syntacticKey(key) && key <= int(Identifier::lastSyntacticKey))
679 message(InterpreterMessages::syntacticKeywordAsVariable,
680 StringMessageArg(currentToken_));
681 NCVector<Owner<Expression> > inits;
685 if (isProcedure && !parseFormals(formals, inits, nOptional, hasRest, nKey))
687 Owner<Expression> expr;
689 if (!parseBegin(expr))
693 if (!parseExpression(0, expr, key, tok))
695 if (!getToken(allowCloseParen, tok))
699 expr = new LambdaExpression(formals, inits, nOptional, hasRest, nKey,
703 if (ident->defined(defPart, defLoc)
704 && defPart <= interp_->currentPartIndex()) {
705 if (defPart == interp_->currentPartIndex())
706 message(InterpreterMessages::duplicateDefinition,
707 StringMessageArg(ident->name()),
711 ident->setDefinition(expr, interp_->currentPartIndex(), loc);
715 bool SchemeParser::doDefineUnit()
717 Location loc(in_->currentLocation());
719 if (!getToken(allowIdentifier, tok))
722 for (i = 0; i < currentToken_.size(); i++)
723 if (interp_->lexCategory(currentToken_[i]) != Interpreter::lexLetter)
725 if ((i < currentToken_.size())
726 || ((currentToken_.size() == 1) && (currentToken_[0] =='e'))) {
727 message(InterpreterMessages::invalidUnitName,
728 StringMessageArg(currentToken_));
732 Unit *unit = interp_->lookupUnit(currentToken_);
733 Owner<Expression> expr;
734 Identifier::SyntacticKey key;
735 if (!parseExpression(0, expr, key, tok))
737 if (!getToken(allowCloseParen, tok))
741 if (unit->defined(defPart, defLoc)
742 && defPart <= interp_->currentPartIndex()) {
743 if (defPart == interp_->currentPartIndex())
744 message(InterpreterMessages::duplicateUnitDefinition,
745 StringMessageArg(unit->name()),
749 unit->setDefinition(expr, interp_->currentPartIndex(), loc);
753 bool SchemeParser::skipForm()
755 static const unsigned allow = (~0 & ~allowEndOfEntity);
759 if (!getToken(allow, tok))
765 case tokenCloseParen:
777 bool SchemeParser::parseExpression(unsigned allowed,
778 Owner<Expression> &expr,
779 Identifier::SyntacticKey &key,
783 key = Identifier::notKey;
785 if (!parseSelfEvaluating(allowed, obj, tok))
788 interp_->makePermanent(obj);
789 expr = new ConstantExpression(obj, in_->currentLocation());
796 if (!parseDatum(0, obj, loc, tok))
798 interp_->makePermanent(obj);
799 expr = new ConstantExpression(obj, loc);
802 case tokenQuasiquote:
805 return parseQuasiquoteTemplate(0, 0, expr, key, tok, spliced);
809 Location loc(in_->currentLocation());
810 if (!parseExpression(allowExpressionKey, expr, key, tok))
813 NCVector<Owner<Expression> > args;
815 args.resize(args.size() + 1);
816 if (!parseExpression(allowCloseParen, args.back(), key, tok))
819 args.resize(args.size() - 1);
823 expr = new CallExpression(expr, args, loc);
827 case Identifier::keyQuote:
828 return parseQuote(expr);
829 case Identifier::keyLambda:
830 return parseLambda(expr);
831 case Identifier::keyIf:
832 return parseIf(expr);
833 case Identifier::keyCond:
834 return parseCond(expr);
835 case Identifier::keyAnd:
836 return parseAnd(expr);
837 case Identifier::keyOr:
838 return parseOr(expr);
839 case Identifier::keyCase:
840 return parseCase(expr);
841 case Identifier::keyLet:
842 return parseLet(expr);
843 case Identifier::keyLetStar:
844 return parseLetStar(expr);
845 case Identifier::keyLetrec:
846 return parseLetrec(expr);
847 case Identifier::keyThereExists:
848 return parseSpecialQuery(expr, "node-list-some?");
849 case Identifier::keyForAll:
850 return parseSpecialQuery(expr, "node-list-every?");
851 case Identifier::keySelectEach:
852 return parseSpecialQuery(expr, "node-list-filter");
853 case Identifier::keyUnionForEach:
854 return parseSpecialQuery(expr, "node-list-union-map");
855 case Identifier::keyMake:
856 return parseMake(expr);
857 case Identifier::keyStyle:
858 return parseStyle(expr);
859 case Identifier::keyWithMode:
860 return parseWithMode(expr);
861 case Identifier::keyQuasiquote:
862 return parseQuasiquote(expr);
863 case Identifier::keySet:
864 return parseSet(expr);
865 case Identifier::keyBegin:
866 return parseBegin(expr);
873 case tokenIdentifier:
875 const Identifier *ident = lookup(currentToken_);
876 if (ident->syntacticKey(key) && key <= int(Identifier::lastSyntacticKey)) {
878 case Identifier::keyDefine:
879 if (allowed & allowKeyDefine)
882 case Identifier::keyArrow:
883 if (allowed & allowKeyArrow)
886 case Identifier::keyElse:
887 if (allowed & allowKeyElse)
890 case Identifier::keyUnquote:
891 case Identifier::keyUnquoteSplicing:
894 if (allowed & allowExpressionKey)
898 message(InterpreterMessages::syntacticKeywordAsVariable,
899 StringMessageArg(currentToken_));
901 expr = new VariableExpression(ident, in_->currentLocation());
911 bool SchemeParser::parseQuote(Owner<Expression> &expr)
916 if (!parseDatum(0, obj, loc, tok))
918 if (!getToken(allowCloseParen, tok))
920 interp_->makePermanent(obj);
921 expr = new ConstantExpression(obj, loc);
925 bool SchemeParser::parseQuasiquote(Owner<Expression> &expr)
929 Identifier::SyntacticKey key;
930 if (!parseQuasiquoteTemplate(0, 0, expr, key, tok, spliced))
932 return getToken(allowCloseParen, tok);
935 bool SchemeParser::parseQuasiquoteTemplate(unsigned level,
937 Owner<Expression> &expr,
938 Identifier::SyntacticKey &key,
942 key = Identifier::notKey;
945 if (!parseSelfEvaluating(allowed|allowUnquote|allowVector, obj, tok))
948 case tokenQuasiquote:
949 if (!parseQuasiquoteTemplate(level + 1, 0, expr, key, tok, spliced))
951 createQuasiquoteAbbreviation("quasiquote", expr);
954 if (!parseQuasiquoteTemplate(level, 0, expr, key, tok, spliced))
956 createQuasiquoteAbbreviation("quote", expr);
959 case tokenUnquoteSplicing:
961 spliced = (tok == tokenUnquoteSplicing);
962 if (!parseExpression(0, expr, key, tok))
967 if (!parseQuasiquoteTemplate(level - 1, 0, expr, key, tem, spliced))
969 createQuasiquoteAbbreviation(tok == tokenUnquote ? "unquote" : "unquote-splicing", expr);
975 QuasiquoteExpression::Type type
976 = (tok == tokenVector
977 ? QuasiquoteExpression::vectorType
978 : QuasiquoteExpression::listType);
979 Location loc(in_->currentLocation());
980 NCVector<Owner<Expression> > exprs(1);
981 Vector<PackedBoolean> exprsSpliced;
983 if (!parseQuasiquoteTemplate(level,
984 allowCloseParen|allowQuasiquoteKey|allowUnquoteSplicing,
985 exprs[0], key, tok, temSpliced))
989 case Identifier::keyQuasiquote:
990 if (!parseQuasiquoteTemplate(level + 1, 0, expr, key, tok, spliced))
992 createQuasiquoteAbbreviation("quasiquotation", expr);
994 case Identifier::keyUnquoteSplicing:
997 case Identifier::keyUnquote:
999 if (!parseExpression(0, expr, key, tok))
1003 if (!parseQuasiquoteTemplate(level - 1, 0, expr, key, tok, temSpliced))
1005 createQuasiquoteAbbreviation(spliced ? "unquote-splicing" : "unquote", expr);
1010 expr = new ConstantExpression(interp_->makeNil(), loc);
1013 return getToken(allowCloseParen, tok);
1015 exprsSpliced.push_back(PackedBoolean(temSpliced));
1017 Owner<Expression> tem;
1018 if (!parseQuasiquoteTemplate(level,
1019 allowCloseParen|allowUnquoteSplicing
1020 |(type == QuasiquoteExpression::vectorType
1023 tem, key, tok, temSpliced))
1026 if (tok == tokenCloseParen)
1028 exprs.resize(exprs.size() + 1);
1029 type = QuasiquoteExpression::improperType;
1030 if (!parseQuasiquoteTemplate(level, 0, exprs.back(), key, tok, temSpliced))
1032 if (!getToken(allowCloseParen, tok))
1034 exprsSpliced.push_back(0);
1037 exprs.resize(exprs.size() + 1);
1038 exprs.back().swap(tem);
1039 exprsSpliced.push_back(PackedBoolean(temSpliced));
1041 expr = new QuasiquoteExpression(exprs, exprsSpliced, type, loc);
1044 case tokenIdentifier:
1045 if (allowed & allowQuasiquoteKey) {
1046 const Identifier *ident = lookup(currentToken_);
1047 if (ident->syntacticKey(key)) {
1049 case Identifier::keyUnquoteSplicing:
1050 case Identifier::keyUnquote:
1051 case Identifier::keyQuasiquote:
1058 obj = interp_->makeSymbol(currentToken_);
1062 interp_->makePermanent(obj);
1063 expr = new ConstantExpression(obj, in_->currentLocation());
1070 void SchemeParser::createQuasiquoteAbbreviation(const char *sym, Owner<Expression> &expr)
1072 Location loc(expr->location());
1073 NCVector<Owner<Expression> > v(2);
1075 v[0] = new ConstantExpression(interp_->makeSymbol(Interpreter::makeStringC(sym)), loc);
1076 Vector<PackedBoolean> spliced;
1077 spliced.push_back(0);
1078 spliced.push_back(0);
1079 expr = new QuasiquoteExpression(v, spliced, QuasiquoteExpression::listType, loc);
1082 bool SchemeParser::parseIf(Owner<Expression> &expr)
1084 Location loc(in_->currentLocation());
1085 Owner<Expression> expr0, expr1, expr2;
1087 Identifier::SyntacticKey key;
1088 if (!parseExpression(0, expr0, key, tok)
1089 || !parseExpression(0, expr1, key, tok)
1090 || !parseExpression(dsssl2() ? allowCloseParen : 0, expr2, key, tok))
1093 expr2 = new ConstantExpression(interp_->makeUnspecified(), in_->currentLocation());
1094 else if (!getToken(allowCloseParen, tok))
1096 expr = new IfExpression(expr0, expr1, expr2, loc);
1100 bool SchemeParser::parseCond(Owner<Expression> &expr, bool opt)
1102 Location loc(in_->currentLocation());
1104 if (!getToken(allowOpenParen|(opt ? unsigned(allowCloseParen) : 0), tok))
1106 if (tok == tokenCloseParen) {
1108 expr = new ConstantExpression(interp_->makeUnspecified(), loc);
1110 expr = new CondFailExpression(loc);
1113 Identifier::SyntacticKey key;
1114 Owner<Expression> testExpr;
1115 if (!parseExpression(allowKeyElse, testExpr, key, tok))
1118 if (!parseBegin(expr))
1120 return getToken(allowCloseParen, tok);
1122 NCVector<Owner<Expression> > valExprs;
1124 Owner<Expression> tem;
1125 if (!parseExpression(allowCloseParen, tem, key, tok))
1129 valExprs.resize(valExprs.size() + 1);
1130 tem.swap(valExprs.back());
1132 Owner<Expression> valExpr;
1133 if (valExprs.size() == 1)
1134 valExprs[0].swap(valExpr);
1135 else if (valExprs.size())
1136 valExpr = new SequenceExpression(valExprs, valExprs[0]->location());
1137 Owner<Expression> elseExpr;
1138 if (!parseCond(elseExpr, 1))
1141 expr = new IfExpression(testExpr, valExpr, elseExpr, loc);
1143 expr = new OrExpression(testExpr, elseExpr, loc);
1147 bool SchemeParser::parseCase(Owner<Expression> &expr)
1149 Owner<Expression> keyExpr;
1150 Owner<Expression> elseClause;
1151 NCVector<CaseExpression::Case> cases;
1152 Location loc(in_->currentLocation());
1154 Identifier::SyntacticKey key;
1155 if (!parseExpression(0, keyExpr, key, tok))
1158 if (!getToken(allowOpenParen
1159 |(cases.size() ? unsigned(allowCloseParen) : 0), tok))
1161 if (tok == tokenCloseParen)
1163 if (!getToken(allowOpenParen|allowIdentifier, tok))
1165 if (tok == tokenOpenParen) {
1166 cases.resize(cases.size() + 1);
1170 if (!parseDatum(allowCloseParen, obj, loc, tok))
1172 if (tok == tokenCloseParen)
1174 interp_->makePermanent(obj);
1175 cases.back().datums.push_back(obj);
1177 if (!parseBegin(cases.back().expr))
1181 const Identifier *ident = lookup(currentToken_);
1182 if (ident->syntacticKey(key) && key == Identifier::keyElse) {
1183 if (!parseBegin(elseClause))
1185 if (!getToken(allowCloseParen, tok))
1190 message(InterpreterMessages::caseElse,
1191 StringMessageArg(currentToken_));
1196 if (dsssl2() && !elseClause)
1197 elseClause = new ConstantExpression(interp_->makeUnspecified(), loc);
1198 expr = new CaseExpression(keyExpr, cases, elseClause, loc);
1202 bool SchemeParser::parseOr(Owner<Expression> &expr)
1204 Location loc(in_->currentLocation());
1206 Identifier::SyntacticKey key;
1207 Owner<Expression> test1Expr;
1208 if (!parseExpression(allowCloseParen, test1Expr, key, tok))
1211 expr = new ConstantExpression(interp_->makeFalse(), loc);
1214 Owner<Expression> test2Expr;
1215 if (!parseOr(test2Expr))
1217 expr = new OrExpression(test1Expr, test2Expr, loc);
1221 bool SchemeParser::parseAnd(Owner<Expression> &expr, bool opt)
1223 Location loc(in_->currentLocation());
1225 Identifier::SyntacticKey key;
1226 Owner<Expression> testExpr;
1227 if (!parseExpression(allowCloseParen, testExpr, key, tok))
1231 expr = new ConstantExpression(interp_->makeTrue(), loc);
1234 Owner<Expression> restExpr;
1235 if (!parseAnd(restExpr, 1))
1238 testExpr.swap(expr);
1240 // This relies on the fact that #f is the only false value.
1241 Owner<Expression> falseExpr(new ConstantExpression(interp_->makeFalse(), loc));
1242 expr = new IfExpression(testExpr, restExpr, falseExpr, loc);
1247 bool SchemeParser::parseBegin(Owner<Expression> &expr)
1249 Location loc(in_->currentLocation());
1251 Identifier::SyntacticKey key;
1252 if (!parseExpression(0, expr, key, tok))
1255 NCVector<Owner<Expression> > exprs;
1256 for (size_t i = 1;; i++) {
1257 Owner<Expression> tem;
1258 if (!parseExpression(allowCloseParen, tem, key, tok))
1262 exprs.resize(i + 1);
1266 expr.swap(exprs[0]);
1267 expr = new SequenceExpression(exprs, loc);
1272 return getToken(allowCloseParen, tok);
1275 bool SchemeParser::parseSet(Owner<Expression> &expr)
1277 Location loc(in_->currentLocation());
1279 if (!getToken(allowIdentifier, tok))
1281 const Identifier *var = lookup(currentToken_);
1282 Identifier::SyntacticKey key;
1283 Owner<Expression> value;
1284 if (!parseExpression(0, value, key, tok))
1286 if (!getToken(allowCloseParen, tok))
1288 expr = new AssignmentExpression(var, value, loc);
1292 bool SchemeParser::parseWithMode(Owner<Expression> &expr)
1294 Location loc(in_->currentLocation());
1296 if (!getToken(allowIdentifier|allowFalse, tok))
1298 const ProcessingMode *mode;
1299 if (tok == tokenFalse)
1300 mode = interp_->initialProcessingMode();
1302 mode = interp_->lookupProcessingMode(currentToken_);
1303 Owner<Expression> content;
1304 Identifier::SyntacticKey key;
1305 if (!parseExpression(0, content, key, tok))
1307 if (!getToken(allowCloseParen, tok))
1309 expr = new WithModeExpression(mode, content, loc);
1313 bool SchemeParser::parseMake(Owner<Expression> &expr)
1315 Location loc(in_->currentLocation());
1317 if (!getToken(allowIdentifier, tok))
1319 const Identifier *foc = lookup(currentToken_);
1320 NCVector<Owner<Expression> > exprs;
1321 Vector<const Identifier *> keys;
1323 Owner<Expression> tem;
1324 Identifier::SyntacticKey key;
1325 if (!parseExpression(allowCloseParen, tem, key, tok))
1329 if (keys.size() == exprs.size()) {
1330 const Identifier *k = tem->keyword();
1333 if (!parseExpression(0, tem, key, tok))
1336 for (i = 0; i < keys.size(); i++)
1337 if (keys[i]->name() == k->name())
1339 if (i < keys.size())
1344 exprs.resize(exprs.size() + 1);
1345 tem.swap(exprs.back());
1347 expr = new MakeExpression(foc, keys, exprs, loc);
1351 bool SchemeParser::parseStyle(Owner<Expression> &expr)
1353 Location loc(in_->currentLocation());
1354 NCVector<Owner<Expression> > exprs;
1355 Vector<const Identifier *> keys;
1358 if (!getToken(allowKeyword|allowCloseParen, tok))
1360 if (tok == tokenCloseParen)
1362 keys.resize(keys.size() + 1);
1363 keys.back() = lookup(currentToken_);
1364 exprs.resize(exprs.size() + 1);
1365 Identifier::SyntacticKey key;
1366 if (!parseExpression(0, exprs.back(), key, tok))
1369 expr = new StyleExpression(keys, exprs, loc);
1373 bool SchemeParser::parseLambda(Owner<Expression> &expr)
1375 Location loc(in_->currentLocation());
1377 if (!getToken(allowOpenParen, tok))
1379 Vector<const Identifier *> formals;
1380 NCVector<Owner<Expression> > inits;
1384 if (!parseFormals(formals, inits, nOptional, hasRest, nKey))
1386 Owner<Expression> body;
1387 if (!parseBegin(body))
1389 expr = new LambdaExpression(formals, inits, nOptional, hasRest, nKey,
1394 // The rest arg is put last.
1396 bool SchemeParser::parseFormals(Vector<const Identifier *> &formals,
1397 NCVector<Owner<Expression> > &inits,
1403 enum FormalType { required, optional, rest, key } type = required;
1404 unsigned allowed = (allowCloseParen|allowIdentifier
1405 |allowHashOptional|allowHashRest|allowHashKey);
1407 for (int i = 0; i < 4; i++)
1410 if (!getToken(allowed, tok))
1413 case tokenHashOptional:
1414 allowed |= allowOpenParen;
1415 allowed &= ~allowHashOptional;
1419 allowed = allowIdentifier;
1423 allowed = (allowOpenParen|allowCloseParen|allowIdentifier);
1426 case tokenOpenParen:
1428 if (!getToken(allowIdentifier, tok))
1431 formals.push_back(lookup(currentToken_));
1432 inits.resize(argCount[optional] + argCount[key]);
1433 Identifier::SyntacticKey key;
1434 if (!parseExpression(0, inits.back(), key, tok))
1436 if (!getToken(allowCloseParen, tok))
1440 case tokenIdentifier:
1442 formals.push_back(lookup(currentToken_));
1445 allowed = (allowHashKey|allowCloseParen);
1448 case tokenCloseParen:
1455 nOptional = argCount[optional];
1456 nKey = argCount[key];
1457 inits.resize(nOptional + nKey);
1458 hasRest = argCount[rest];
1462 bool SchemeParser::parseLet(Owner<Expression> &expr)
1464 Location loc(in_->currentLocation());
1466 if (!getToken(allowOpenParen|allowIdentifier, tok))
1468 Vector<const Identifier *> vars;
1469 NCVector<Owner<Expression> > inits;
1470 Owner<Expression> body;
1471 const Identifier *name;
1472 if (tok == tokenOpenParen) {
1474 if (!parseBindingsAndBody1(vars, inits, body))
1478 name = lookup(currentToken_);
1479 if (!parseBindingsAndBody(vars, inits, body))
1484 NCVector<Owner<Expression> > loopInit(1);
1485 NCVector<Owner<Expression> > argsInit;
1486 loopInit[0] = new LambdaExpression(vars, argsInit, 0, 0, 0, body, loc);
1487 Vector<const Identifier *> loopFormal(1);
1488 loopFormal[0] = name;
1489 expr = new VariableExpression(name, loc);
1490 expr = new LetrecExpression(loopFormal, loopInit, expr, loc);
1491 expr = new CallExpression(expr, inits, loc);
1494 expr = new LetExpression(vars, inits, body, loc);
1498 bool SchemeParser::parseLetStar(Owner<Expression> &expr)
1500 Location loc(in_->currentLocation());
1501 Vector<const Identifier *> vars;
1502 NCVector<Owner<Expression> > inits;
1503 Owner<Expression> body;
1504 if (!parseBindingsAndBody(vars, inits, body))
1506 expr = new LetStarExpression(vars, inits, body, loc);
1510 bool SchemeParser::parseLetrec(Owner<Expression> &expr)
1512 Location loc(in_->currentLocation());
1513 Vector<const Identifier *> vars;
1514 NCVector<Owner<Expression> > inits;
1515 Owner<Expression> body;
1516 if (!parseBindingsAndBody(vars, inits, body))
1518 expr = new LetrecExpression(vars, inits, body, loc);
1522 bool SchemeParser::parseBindingsAndBody(Vector<const Identifier *> &vars,
1523 NCVector<Owner<Expression> > &inits,
1524 Owner<Expression> &body)
1527 if (!getToken(allowOpenParen, tok))
1529 return parseBindingsAndBody1(vars, inits, body);
1532 bool SchemeParser::parseBindingsAndBody1(Vector<const Identifier *> &vars,
1533 NCVector<Owner<Expression> > &inits,
1534 Owner<Expression> &body)
1537 Identifier::SyntacticKey key;
1539 if (!getToken(allowCloseParen|allowOpenParen, tok))
1541 if (tok == tokenCloseParen)
1543 if (!getToken(allowIdentifier, tok))
1545 vars.push_back(lookup(currentToken_));
1546 inits.resize(inits.size() + 1);
1547 if (!parseExpression(0, inits.back(), key, tok))
1549 if (!getToken(allowCloseParen, tok))
1552 return parseBegin(body);
1555 bool SchemeParser::parseDatum(unsigned otherAllowed,
1560 if (!parseSelfEvaluating(otherAllowed|allowVector|allowUnquote|allowUnquoteSplicing, result, tok))
1562 loc = in_->currentLocation();
1566 case tokenIdentifier:
1567 result = interp_->makeSymbol(currentToken_);
1570 return parseAbbreviation("quote", result);
1571 case tokenQuasiquote:
1572 return parseAbbreviation("quasiquote", result);
1574 return parseAbbreviation("unquote", result);
1575 case tokenUnquoteSplicing:
1576 return parseAbbreviation("unquote-splicing", result);
1577 case tokenOpenParen:
1581 if (!parseDatum(allowCloseParen, tem, ignore, tok))
1584 result = interp_->makeNil();
1587 ELObjDynamicRoot list(*interp_, tem);
1588 PairObj *last = new (*interp_) PairObj(tem, 0);
1591 if (!parseDatum(allowCloseParen|allowPeriod, tem, ignore, tok))
1594 if (tok == tokenCloseParen) {
1595 last->setCdr(interp_->makeNil());
1598 if (!parseDatum(0, tem, ignore, tok))
1601 if (!getToken(allowCloseParen, tok))
1605 last->setCdr(tem); // to protect it
1606 PairObj *p = new (*interp_) PairObj(tem, 0);
1615 VectorObj *v = new (*interp_) VectorObj;
1616 ELObjDynamicRoot protect(*interp_, v);
1617 Vector<ELObj *> &vec = *v;
1621 if (!parseDatum(allowCloseParen, tem, ignore, tok))
1636 bool SchemeParser::parseSelfEvaluating(unsigned otherAllowed,
1640 if (!getToken(allowExpr|otherAllowed, tok))
1644 result = interp_->makeTrue();
1647 result = interp_->makeFalse();
1650 result = interp_->makeUnspecified();
1653 result = new (*interp_) StringObj(currentToken_);
1656 result = interp_->makeKeyword(currentToken_);
1659 result = interp_->makeChar(currentToken_[0]);
1662 result = interp_->convertNumber(currentToken_);
1664 message(InterpreterMessages::invalidNumber,
1665 StringMessageArg(currentToken_));
1666 result = interp_->makeError();
1670 result = convertAfiiGlyphId(currentToken_);
1679 bool SchemeParser::parseAbbreviation(const char *sym, ELObj *&result)
1681 SymbolObj *quoteSym = interp_->makeSymbol(Interpreter::makeStringC(sym));
1685 if (!parseDatum(0, obj, ignore, tok))
1687 ELObjDynamicRoot protect(*interp_, obj);
1688 protect = new (*interp_) PairObj(protect, interp_->makeNil());
1689 result = interp_->makePair(quoteSym, protect);
1693 bool SchemeParser::getToken(unsigned allowed, Token &tok)
1695 InputSource *in = in_.pointer();
1698 Xchar c = in->tokenChar(*this);
1700 case InputSource::eE:
1701 if (!(allowed & allowEndOfEntity))
1702 return tokenRecover(allowed, tok);
1703 tok = tokenEndOfEntity;
1706 if (!(allowed & allowOpenParen))
1707 return tokenRecover(allowed, tok);
1708 tok = tokenOpenParen;
1711 if (!(allowed & allowCloseParen))
1712 return tokenRecover(allowed, tok);
1713 tok = tokenCloseParen;
1716 if (!(allowed & allowOtherExpr))
1717 return tokenRecover(allowed, tok);
1721 if (!(allowed & allowOtherExpr))
1722 return tokenRecover(allowed, tok);
1723 tok = tokenQuasiquote;
1726 c = in->tokenChar(*this);
1728 if (!(allowed & allowUnquoteSplicing))
1729 return tokenRecover(allowed, tok);
1730 tok = tokenUnquoteSplicing;
1733 if (!(allowed & allowUnquote))
1734 return tokenRecover(allowed, tok);
1747 c = in->tokenChar(*this);
1750 if (!(allowed & allowOtherExpr))
1751 return tokenRecover(allowed, tok);
1755 if (!(allowed & allowFalse))
1756 return tokenRecover(allowed, tok);
1761 c = in->tokenChar(*this);
1762 if (c == InputSource::eE) {
1763 message(InterpreterMessages::unexpectedEof);
1764 if (allowed & allowEndOfEntity) {
1765 tok = tokenEndOfEntity;
1770 if (!(allowed & allowOtherExpr)) {
1772 return tokenRecover(allowed, tok);
1774 in->discardInitial();
1777 if (in->currentTokenLength() == 1) {
1778 currentToken_.assign(in->currentTokenStart(), 1);
1781 StringC tem(in->currentTokenStart(), in->currentTokenLength());
1782 currentToken_.resize(1);
1783 if (!interp_->convertCharName(tem, currentToken_[0])) {
1784 message(InterpreterMessages::unknownCharName,
1785 StringMessageArg(tem));
1786 currentToken_[0] = defaultChar;
1794 StringC tem(in->currentTokenStart() + 2,
1795 in->currentTokenLength() - 2);
1796 if (tem == Interpreter::makeStringC("optional")) {
1797 if (!(allowed & allowHashOptional))
1798 return tokenRecover(allowed, tok);
1799 tok = tokenHashOptional;
1802 if (tem == Interpreter::makeStringC("key")) {
1803 if (!(allowed & allowHashKey))
1804 return tokenRecover(allowed, tok);
1808 if (tem == Interpreter::makeStringC("rest")) {
1809 if (!(allowed & allowHashRest))
1810 return tokenRecover(allowed, tok);
1811 tok = tokenHashRest;
1814 if (tem == Interpreter::makeStringC("contents")) {
1815 if (!(allowed & allowHashContents))
1816 return tokenRecover(allowed, tok);
1817 tok = tokenHashContents;
1820 message(InterpreterMessages::unknownNamedConstant,
1821 StringMessageArg(tem));
1829 if (!(allowed & allowOtherExpr))
1830 return tokenRecover(allowed, tok);
1832 currentToken_.assign(in->currentTokenStart(),
1833 in->currentTokenLength());
1837 if (!(allowed & allowOtherExpr))
1838 return tokenRecover(allowed, tok);
1840 currentToken_.assign(in->currentTokenStart() + 2,
1841 in->currentTokenLength() - 2);
1843 case InputSource::eE:
1844 message(InterpreterMessages::unexpectedEof);
1845 if (allowed & allowEndOfEntity) {
1846 tok = tokenEndOfEntity;
1852 if (!(allowed & allowOtherExpr))
1853 return tokenRecover(allowed, tok);
1860 if (!(allowed & allowVector))
1861 return tokenRecover(allowed, tok);
1867 message(InterpreterMessages::unknownHash);
1872 if (!(allowed & allowString))
1873 return tokenRecover(allowed, tok);
1874 return scanString(allowed, tok);
1880 switch (in->currentTokenLength()) {
1882 if (!(allowed & allowPeriod))
1883 return tokenRecover(allowed, tok);
1887 if (in_->currentTokenStart()[1] == '.'
1888 && in_->currentTokenStart()[2] == '.')
1889 return handleIdentifier(allowed, tok);
1892 return handleNumber(allowed, tok);
1894 switch (interp_->lexCategory(c)) {
1895 case Interpreter::lexAddWhiteSpace:
1897 case Interpreter::lexOtherNumberStart:
1899 // handle + and - as identifiers
1900 if (in->currentTokenLength() == 1)
1901 return handleIdentifier(allowed, tok);
1902 return handleNumber(allowed, tok);
1903 case Interpreter::lexDigit:
1905 return handleNumber(allowed, tok);
1906 case Interpreter::lexOther:
1908 // ignore control characters
1909 message(InterpreterMessages::invalidChar);
1917 size_t length = in->currentTokenLength();
1919 Interpreter::LexCategory lc = interp_->lexCategory(in->tokenChar(*this));
1920 if (lc > Interpreter::lexOther)
1922 if (lc == Interpreter::lexOther)
1926 in->endToken(length);
1928 if (in->currentTokenEnd()[-1] == ':'
1929 && in->currentTokenLength() > 1) {
1930 if (!(allowed & allowKeyword))
1931 return tokenRecover(allowed, tok);
1932 currentToken_.assign(in->currentTokenStart(),
1933 in->currentTokenLength() - 1);
1935 if (invalid || (currentToken_.size() > 1
1936 && currentToken_[currentToken_.size() - 1] == ':'))
1937 message(InterpreterMessages::invalidIdentifier,
1938 StringMessageArg(currentToken_));
1942 message(InterpreterMessages::invalidIdentifier,
1943 StringMessageArg(StringC(in->currentTokenStart(),
1944 in->currentTokenLength())));
1945 return handleIdentifier(allowed, tok);
1952 bool SchemeParser::handleNumber(unsigned allowed, Token &tok)
1954 if (!(allowed & allowOtherExpr))
1955 return tokenRecover(allowed, tok);
1957 currentToken_.assign(in_->currentTokenStart(),
1958 in_->currentTokenLength());
1962 bool SchemeParser::handleIdentifier(unsigned allowed, Token &tok)
1964 if (!(allowed & allowIdentifier))
1965 return tokenRecover(allowed, tok);
1966 currentToken_.assign(in_->currentTokenStart(),
1967 in_->currentTokenLength());
1968 tok = tokenIdentifier;
1972 bool SchemeParser::tokenRecover(unsigned allowed, Token &tok)
1974 if (allowed == allowCloseParen) {
1976 tok = tokenCloseParen;
1977 message(InterpreterMessages::missingCloseParen);
1980 if (in_->currentTokenLength() == 0)
1981 message(InterpreterMessages::unexpectedEof);
1983 message(InterpreterMessages::unexpectedToken,
1984 StringMessageArg(StringC(in_->currentTokenStart(),
1985 in_->currentTokenLength())));
1989 void SchemeParser::extendToken()
1991 // extend to a delimiter
1992 InputSource *in = in_.pointer();
1993 size_t length = in->currentTokenLength();
1994 while (interp_->lexCategory(in->tokenChar(*this))
1995 <= Interpreter::lexOther)
1997 in->endToken(length);
2000 bool SchemeParser::scanString(unsigned allowed, Token &tok)
2002 InputSource *in = in_.pointer();
2003 currentToken_.resize(0);
2005 Xchar c = in->tokenChar(*this);
2007 case InputSource::eE:
2008 message(InterpreterMessages::unterminatedString);
2015 c = in->tokenChar(*this);
2016 if (c == '\\' || c == '"')
2018 else if (c == InputSource::eE)
2023 while (interp_->lexCategory(c = in->tokenChar(*this)) < Interpreter::lexOther)
2026 in->endToken(in->currentTokenLength() - 1);
2028 if (interp_->convertCharName(name, ch))
2029 currentToken_ += ch;
2031 message(InterpreterMessages::unknownCharName, StringMessageArg(name));
2039 return 0; // not reached
2042 void SchemeParser::skipComment()
2045 Xchar c = in_->get(*this);
2046 if (c == InputSource::eE || c == '\r')
2051 ELObj *SchemeParser::convertAfiiGlyphId(const StringC &str)
2053 unsigned long n = 0;
2054 for (size_t i = 0; i < str.size(); i++) {
2055 if (str[i] < '0' || str[i] > '9') {
2059 // FIXME check for overflow
2060 n = n*10 + (str[i] - '0');
2063 message(InterpreterMessages::invalidAfiiGlyphId, StringMessageArg(str));
2066 return new (*interp_) GlyphIdObj(FOTBuilder::GlyphId(afiiPublicId_, n));
2069 void SchemeParser::dispatchMessage(Message &msg)
2071 interp_->dispatchMessage(msg);
2074 void SchemeParser::dispatchMessage(const Message &msg)
2076 interp_->dispatchMessage(msg);
2079 void SchemeParser::initMessage(Message &msg)
2082 msg.loc = in_->currentLocation();
2085 bool SchemeParser::doDeclareDefaultLanguage()
2087 Location loc(in_->currentLocation());
2088 Owner<Expression> expr;
2090 Identifier::SyntacticKey key;
2091 if (!parseExpression(0, expr, key, tok))
2093 if (!getToken(allowCloseParen, tok))
2097 if(interp_->defaultLanguageSet(defPart, defLoc)
2098 && defPart <= interp_->currentPartIndex()) {
2099 if(defPart == interp_->currentPartIndex()) {
2100 interp_->setNextLocation(loc);
2101 message(InterpreterMessages::duplicateDefLangDecl, defLoc);
2105 interp_->setDefaultLanguage(expr, interp_->currentPartIndex(), loc);
2109 bool SchemeParser::doDefineLanguage()
2111 Location loc(in_->currentLocation());
2113 if (!getToken(allowIdentifier, tok))
2115 Identifier *ident = lookup(currentToken_);
2116 Identifier::SyntacticKey key;
2117 if (ident->syntacticKey(key) && (key <= int(Identifier::lastSyntacticKey)))
2118 message(InterpreterMessages::syntacticKeywordAsVariable,
2119 StringMessageArg(currentToken_));
2122 if (ident->defined(defPart, defLoc)
2123 && defPart <= interp_->currentPartIndex()) {
2124 if (defPart == interp_->currentPartIndex()) {
2125 message(InterpreterMessages::duplicateDefinition,
2126 StringMessageArg(ident->name()),
2131 lang_ = new (*interp_) LangObj;
2133 if (!getToken(allowOpenParen|allowCloseParen, tok))
2135 if (tok == tokenCloseParen)
2137 if (!getToken(allowIdentifier, tok))
2139 const Identifier *ident = lookup(currentToken_);
2140 Identifier::SyntacticKey key;
2141 if (!ident->syntacticKey(key))
2145 case Identifier::keyCollate:
2149 case Identifier::keyToupper:
2153 case Identifier::keyTolower:
2162 if (!lang_->compile())
2164 interp_->makePermanent(lang_);
2165 Owner<Expression> expr;
2166 expr = new ConstantExpression(lang_, in_->currentLocation());
2168 ident->setDefinition(expr, interp_->currentPartIndex(), loc);
2172 bool SchemeParser::doCollate()
2176 if (!getToken(allowOpenParen|allowCloseParen, tok))
2178 if (tok == tokenCloseParen)
2180 if (!getToken(allowIdentifier, tok))
2182 const Identifier *ident = lookup(currentToken_);
2183 Identifier::SyntacticKey key;
2184 if (!ident->syntacticKey(key)) {
2188 case Identifier::keyElement:
2189 if (!doMultiCollatingElement())
2192 case Identifier::keySymbol:
2193 if (!doCollatingSymbol())
2196 case Identifier::keyOrder:
2197 if (!doCollatingOrder())
2208 bool SchemeParser::doMultiCollatingElement()
2211 if (!getToken(allowIdentifier, tok))
2213 StringC sym(currentToken_);
2214 if (!getToken(allowString, tok))
2216 StringC str(currentToken_);
2217 if (!getToken(allowCloseParen, tok))
2219 lang_->addMultiCollatingElement(sym, str);
2223 bool SchemeParser::doCollatingSymbol()
2226 if (!getToken(allowIdentifier, tok))
2228 StringC sym(currentToken_);
2229 if (!getToken(allowCloseParen, tok))
2231 lang_->addCollatingSymbol(sym);
2235 bool SchemeParser::doCollatingOrder()
2238 if (!getToken(allowOpenParen, tok))
2241 LangObj::LevelSort sort = { 0, 0, 0};
2243 if (!getToken(((nested == 0) ? allowOpenParen : 0)|
2244 allowCloseParen|allowIdentifier, tok))
2246 if (tok == tokenOpenParen)
2248 else if (tok == tokenCloseParen)
2251 const Identifier *ident = lookup(currentToken_);
2252 Identifier::SyntacticKey key;
2253 if (!ident->syntacticKey(key))
2256 case Identifier::keyForward:
2261 case Identifier::keyBackward:
2266 case Identifier::keyPosition:
2278 lang_->addLevel(sort);
2282 if (!getToken(allowOpenParen|
2285 allowOtherExpr, tok))
2287 if (tok == tokenCloseParen)
2292 lang_->addDefaultPos();
2293 for(Char i = 0; i < lang_->levels(); i++)
2294 lang_->addLevelWeight(i, empty);
2296 case tokenIdentifier:
2298 if (!lang_->addCollatingPos(currentToken_))
2300 for (unsigned i = 0; i < lang_->levels(); i++)
2301 lang_->addLevelWeight(i, currentToken_);
2303 case tokenOpenParen:
2314 bool SchemeParser::doWeights()
2317 if (!getToken(allowIdentifier|allowOtherExpr, tok))
2319 StringC sym(currentToken_);
2320 if (!lang_->addCollatingPos(sym))
2325 if (!getToken((nested ? 0 : allowOpenParen)|
2331 if (tok == tokenOpenParen)
2333 else if (tok == tokenCloseParen)
2338 for (size_t i = 0; i < currentToken_.size(); i++) {
2339 StringC ctok(&(currentToken_[i]), 1);
2340 if (!lang_->addLevelWeight(l, ctok))
2344 case tokenIdentifier:
2346 if (!lang_->addLevelWeight(l, currentToken_))
2361 bool SchemeParser::doToupper()
2365 if (!getToken(allowOpenParen|allowCloseParen, tok))
2367 if (tok == tokenCloseParen) break;
2368 if (!getToken(allowOtherExpr, tok) || (tok != tokenChar))
2370 Char lc = currentToken_[0];
2371 if (!getToken(allowOtherExpr, tok) || (tok != tokenChar))
2373 Char uc = currentToken_[0];
2374 if (!getToken(allowCloseParen, tok))
2376 lang_->addToupper(lc, uc);
2381 bool SchemeParser::doTolower()
2385 if (!getToken(allowOpenParen|allowCloseParen, tok))
2387 if (tok == tokenCloseParen) break;
2388 if (!getToken(allowOtherExpr, tok) || (tok != tokenChar))
2390 Char uc = currentToken_[0];
2391 if (!getToken(allowOtherExpr, tok) || (tok != tokenChar))
2393 Char lc = currentToken_[0];
2394 if (!getToken(allowCloseParen, tok))
2396 lang_->addTolower(uc, lc);
2401 bool SchemeParser::parseSpecialQuery(Owner<Expression> &rexp, const char *query)
2403 Location loc(in_->currentLocation());
2405 if (!getToken(allowIdentifier, tok))
2407 Vector<const Identifier *> vars;
2408 vars.push_back(lookup(currentToken_));
2409 Identifier::SyntacticKey key;
2410 if (vars.back()->syntacticKey(key) && key <= int(Identifier::lastSyntacticKey))
2411 message(InterpreterMessages::syntacticKeywordAsVariable,
2412 StringMessageArg(currentToken_));
2414 Owner<Expression> op(new ConstantExpression(
2415 interp_->lookup(interp_->makeStringC(query))->computeBuiltinValue(1, *interp_),
2417 NCVector<Owner<Expression> > inits, args(2);
2418 Owner<Expression> expr;
2419 if (!parseExpression(0, args[1], key, tok)
2420 || !parseExpression(0, expr, key, tok)
2421 || !getToken(allowCloseParen, tok))
2423 args[0] = new LambdaExpression(vars, inits, 0, 0, 0, expr, loc);
2424 rexp = new CallExpression(op, args, loc);
2428 bool SchemeParser::doDeclareCharProperty()
2431 if (!getToken(allowIdentifier, tok))
2433 Identifier *ident = lookup(currentToken_);
2434 Owner<Expression> expr;
2435 Identifier::SyntacticKey key;
2436 if (!parseExpression(0, expr, key, tok))
2438 if (!getToken(allowCloseParen, tok))
2440 interp_->addCharProperty(ident, expr);
2444 bool SchemeParser::doAddCharProperties()
2446 NCVector<Owner<Expression> > exprs;
2447 Vector<const Identifier *> keys;
2450 if (!getToken(allowKeyword|allowOtherExpr, tok))
2452 if (tok!=tokenKeyword)
2454 keys.push_back(lookup(currentToken_));
2455 exprs.resize(exprs.size() + 1);
2456 Identifier::SyntacticKey key;
2457 if (!parseExpression(0, exprs.back(), key, tok))
2462 if (tok!=tokenChar) {
2463 message(InterpreterMessages::badAddCharProperty);
2466 for (size_t j = 0; j < keys.size(); j++)
2467 interp_->setCharProperty(keys[j], currentToken_[0], exprs[j]);
2468 if(!getToken(allowOtherExpr|allowCloseParen, tok))
2470 if (tok==tokenCloseParen)
2477 #ifdef DSSSL_NAMESPACE