00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "Parser.H"
00030 #include "Files.H"
00031 #include "Lex.H"
00032 #include "ModelState.H"
00033 #include "Err.H"
00034 #include "Expr.H"
00035 #include "Val.H"
00036 #include "Prim.H"
00037 #include <iostream>
00038
00039 using std::istream;
00040
00041 static char *pragmaNoCache = "nocache";
00042 static char *pragmaInPK = "pk";
00043
00044
00045 static Token eatenToken, token, nextToken;
00046 static bool hasNextToken = false;
00047
00048 void PError(const Text& msg) {
00049 outputMu.lock();
00050 Error(msg, token.loc);
00051 outputMu.unlock();
00052 throw "\nParsing terminated.\n";
00053 }
00054
00055 inline void NextToken() {
00056 if (hasNextToken) {
00057 token.TokenAssign(nextToken);
00058 hasNextToken = false;
00059 }
00060 else
00061 token.Next();
00062 return;
00063 }
00064
00065 inline void TokenLookAhead() {
00066 if (!hasNextToken) {
00067 nextToken.Next();
00068 hasNextToken = true;
00069 }
00070 return;
00071 }
00072
00073 bool AtToken(TokenClass tc) {
00074 while (token.tclass == TkPragma &&
00075 strcmp(token.Bytes(), pragmaInPK) &&
00076 strcmp(token.Bytes(), pragmaNoCache)) {
00077 NextToken();
00078 }
00079 return (token.tclass == tc);
00080 }
00081
00082 bool AtDelimiter() {
00083 while (token.tclass == TkPragma &&
00084 strcmp(token.Bytes(), pragmaInPK) &&
00085 strcmp(token.Bytes(), pragmaNoCache)) {
00086 NextToken();
00087 }
00088 return ((token.tclass == TkSlash) ||
00089 (token.tclass == TkBackSlash));
00090 }
00091
00092 bool AtArc() {
00093 while (token.tclass == TkPragma &&
00094 strcmp(token.Bytes(), pragmaInPK) &&
00095 strcmp(token.Bytes(), pragmaNoCache)) {
00096 NextToken();
00097 }
00098 return ((token.tclass == TkId) ||
00099 (token.tclass == TkNumber) ||
00100 (token.tclass == TkString));
00101 }
00102
00103 inline bool EatPragma() {
00104 if (token.tclass == TkPragma) {
00105 eatenToken.TokenAssign(token);
00106 NextToken();
00107 return true;
00108 }
00109 return false;
00110 }
00111
00112 inline bool EatToken(TokenClass tc) {
00113 if (AtToken(tc)) {
00114 eatenToken.TokenAssign(token);
00115 NextToken();
00116 return true;
00117 }
00118 return false;
00119 }
00120
00121 inline bool EatName(Name& name) {
00122 if (AtToken(TkId)) {
00123 name = (Name)(token.expr);
00124 eatenToken.TokenAssign(token);
00125 NextToken();
00126 return true;
00127 }
00128 return false;
00129 }
00130
00131 inline bool EatArc(Name& arc) {
00132 if (AtArc()) {
00133 arc = NEW_CONSTR(NameEC, (token.AsText(), token.loc));
00134 eatenToken.TokenAssign(token);
00135 NextToken();
00136 return true;
00137 }
00138 return false;
00139 }
00140
00141 inline bool EatDelimiter() {
00142 if (AtDelimiter()) {
00143 eatenToken.TokenAssign(token);
00144 NextToken();
00145 return true;
00146 }
00147 return false;
00148 }
00149
00150 void Expect(TokenClass tk, char *msg) {
00151 if (!EatToken(tk))
00152 PError(Text("Expected ") + msg + " Current token class: "
00153 + TokenNames[token.tclass] + ", `" + token.AsText() + "'.\n");
00154 }
00155
00156 inline Name GetName() {
00157 Expect(TkId, "identifier.");
00158
00159 Name name = (Name)(eatenToken.expr);
00160 return name;
00161 }
00162
00163 Text ModelPath(const Text& from, const Text& path) {
00164 int fromLast = from.Length()-1;
00165
00166 if (fromLast < 0) return path;
00167 if (path.Empty()) return from;
00168 if (IsDelimiter(from[fromLast])) {
00169 if (IsDelimiter(path[0]))
00170 return from + path.Sub(1);
00171 else
00172 return from + path;
00173 }
00174 else {
00175 if (IsDelimiter(path[0]))
00176 return from + path;
00177 else
00178 return from + PathnameSep + path;
00179 }
00180 }
00181
00182 Expr ConvertToBindElem(Expr lhs, Expr rhs) {
00183
00184 Name name;
00185
00186 switch (lhs->kind) {
00187 case NameEK:
00188 ((Name)lhs)->ClearFreeVars();
00189 return NEW_CONSTR(BindEC, (lhs, rhs, lhs->loc));
00190 case ConstantEK:
00191 {
00192 Val v = ((ConstantEC*)lhs)->val;
00193 if (v->vKind == IntegerVK)
00194 name = NEW_CONSTR(NameEC, (PrintForm(v), lhs->loc));
00195 else if (v->vKind == TextVK)
00196 name = NEW_CONSTR(NameEC, (((TextVC*)v)->NDS(), lhs->loc));
00197 else {
00198 Error("Expected left side of binding, found: `", lhs->loc);
00199 ErrorVal(v);
00200 ErrorDetail("'.\n");
00201 return NEW_CONSTR(ErrorEC, (token.loc));
00202 }
00203 name->ClearFreeVars();
00204 return NEW_CONSTR(BindEC, (name, rhs, lhs->loc));
00205 }
00206 case SelectEK:
00207 {
00208 BindingEC *be = NEW_CONSTR(BindingEC, (1, token.loc));
00209 SelectEC *sel = (SelectEC*)lhs;
00210 be->AddExpr(NEW_CONSTR(BindEC, (sel->field, rhs, sel->field->loc)));
00211 return ConvertToBindElem(sel->binding, be);
00212 }
00213 default:
00214 Error("Invalid left side of binding element: `", lhs->loc);
00215 ErrorExpr(lhs);
00216 ErrorDetail("'.\n");
00217 return NEW_CONSTR(ErrorEC, (token.loc));
00218 }
00219
00220 }
00221
00222 void InitState(istream *lexIn, const Text& modelName, ShortId sid,
00223 VestaSource *modelRoot) {
00224 ModelStateInit(lexIn, modelRoot);
00225 token.Init(modelName, sid);
00226 NextToken();
00227 }
00228
00229
00230 Expr Model ();
00231
00232 ExprList Files ();
00233 Expr FileItem (bool couldBeList);
00234 Expr FileList ();
00235
00236 ExprList Imports ();
00237 Expr IncItem (const Text& from, bool hasForm, bool couldBeList);
00238 Expr IncList (const Text& from, bool hasForm);
00239 Text DelimPath (Name& arc, bool arcSeen);
00240
00241 Expr Block ();
00242 Expr Stmt ();
00243 Expr Func (const Text& name, bool noCache);
00244 ArgList Formals ();
00245 Expr Assign (Name name);
00246 Expr Iterate ();
00247 Expr Control ();
00248
00249 Expr Expression ();
00250 Expr Expr1 ();
00251 Expr Expr2 ();
00252 Expr Expr3 ();
00253 Expr Expr4 ();
00254 Expr Expr5 ();
00255 Expr Expr6 ();
00256 Expr Expr7 ();
00257 Expr Expr8 ();
00258 Expr Primary ();
00259
00260 Expr BindingCons (Expr e);
00261 Expr BindElem ();
00262 Expr ListCons (Expr e);
00263 Expr GenArc ();
00264 ArgList Actuals ();
00265 Expr TypeDef ();
00266 Expr Type ();
00267
00269 Expr Model() {
00270 ExprList files = Files();
00271 ExprList imports = Imports();
00272 Expr block = Block();
00273 return NEW_CONSTR(ModelEC, (files, imports, block, mRoot, files->loc));
00274 }
00275
00276 ExprList Files() {
00277 ExprList dir = NEW_CONSTR(ExprListEC, (5, token.loc));
00278 bool looking;
00279
00280 while (EatToken(TkFiles)) {
00281 looking = true;
00282 while (looking && (AtArc() || AtDelimiter())) {
00283 dir->AddExpr(FileItem(true));
00284 looking = EatToken(TkSemicolon);
00285 }
00286 }
00287 return dir;
00288 }
00289
00290 Expr FileItem(bool couldBeList) {
00291 SrcLoc *eL = token.loc;
00292 Text path;
00293 Name arc, junque;
00294 Expr item;
00295
00296
00297 if (EatArc(arc)) {
00298 if (EatToken(TkEqual))
00299 if (EatToken(TkLBracket))
00300 if (couldBeList)
00301 item = FileList();
00302 else
00303 PError("Nested file lists not allowed.");
00304 else
00305 item = NEW_CONSTR(FileEC,
00306 (arc, DelimPath(junque, false), mRoot, false, eL));
00307 else if (AtDelimiter()) {
00308 path = DelimPath(arc, true);
00309 item = NEW_CONSTR(FileEC, (arc, path, mRoot, false, eL));
00310 }
00311 else
00312 item = NEW_CONSTR(FileEC, (arc, arc->id, mRoot, false, eL));
00313 }
00314 else if (AtDelimiter()) {
00315 path = DelimPath(arc, false);
00316 item = NEW_CONSTR(FileEC, (arc, path, mRoot, false, eL));
00317 }
00318 else
00319 PError("Must be an arc: identifier, integer, or string.");
00320 return NEW_CONSTR(BindEC, (arc, item, eL));
00321 }
00322
00323 Expr FileList() {
00324 BindingEC *files = NEW_CONSTR(BindingEC, (5, token.loc));
00325 bool looking = true;
00326
00327 while (looking && (AtArc() || AtDelimiter())) {
00328 files->AddExpr(FileItem(false));
00329 looking = EatToken(TkComma);
00330 }
00331 Expect(TkRBracket, "`]' to terminate file list.");
00332 return files;
00333 }
00334
00335 ExprList Imports() {
00336 SrcLoc *eL = token.loc;;
00337 Text from;
00338 Name name, junque;
00339 ExprList dir = NEW_CONSTR(ExprListEC, (5, eL));
00340 bool hasFrom, looking;
00341
00342
00343 Name arc = NEW_CONSTR(NameEC, ("_self", eL));
00344 Text selfHead, selfTail;
00345 SplitPath(eL->file, selfHead, selfTail);
00346 Expr item = NEW_CONSTR(FileEC, (arc, selfTail, mRoot, true, eL));
00347 dir->AddExpr(NEW_CONSTR(BindEC, (arc, item, eL)));
00348
00349 while (AtToken(TkFrom) || AtToken(TkImport)) {
00350 hasFrom = false;
00351 if (EatToken(TkFrom)) {
00352 from = DelimPath(junque, false);
00353 hasFrom = true;
00354 }
00355 Expect(TkImport, "`import' at head of model list.");
00356 looking = true;
00357 while (looking && AtArc()) {
00358 dir->AddExpr(IncItem(from, hasFrom, true));
00359 looking = EatToken(TkSemicolon);
00360 }
00361 }
00362 return dir;
00363 }
00364
00365 Expr IncItem(const Text& from, bool hasFrom, bool couldBeList) {
00366 SrcLoc *eL = token.loc;
00367 Text path, rest;
00368 Name arc, junque;
00369 Expr item;
00370 bool isList = false;
00371
00372 if (!EatArc(arc)) {
00373 PError("Must be an arc: identifier, integer, or string.");
00374 }
00375
00376 if (EatToken(TkEqual))
00377 if (EatToken(TkLBracket))
00378 if (couldBeList) {
00379 item = IncList(from, hasFrom);
00380 isList = true;
00381 }
00382 else
00383 PError("Nested import lists not allowed.");
00384 else if (hasFrom && AtDelimiter())
00385 PError("A delimiter is not permitted after this equality sign.");
00386 else {
00387 rest = DelimPath(junque, false);
00388 path = ModelPath(from, rest);
00389 }
00390 else if (!hasFrom) {
00391 PError("An explicit `id =' must precede this path.");
00392 }
00393 else if (AtDelimiter()) {
00394 Name more = arc;
00395 rest = DelimPath(more, true);
00396 path = ModelPath(from, rest);
00397 }
00398 else {
00399 path = ModelPath(from, arc->id);
00400 }
00401
00402 if (!isList)
00403 item = NEW_CONSTR(FileEC, (arc, path, mRoot, true, eL));
00404 return NEW_CONSTR(BindEC, (arc, item, eL));
00405 }
00406
00407 Expr IncList(const Text& from, bool hasFrom) {
00408 BindingEC *imports = NEW_CONSTR(BindingEC, (5, token.loc));
00409 bool looking = true;
00410
00411 while (looking && AtArc()) {
00412 imports->AddExpr(IncItem(from, hasFrom, false));
00413 looking = EatToken(TkComma);
00414 }
00415 Expect(TkRBracket, "`]' to terminate import list.");
00416 return imports;
00417 }
00418
00419 Text DelimPath(Name& arc, bool arcSeen) {
00420 Text path;
00421
00422 if (arcSeen) {
00423 if (!AtDelimiter())
00424 return arc->id;
00425 path = arc->id;
00426 }
00427
00428
00429
00430
00431
00432 else {
00433 if (AtDelimiter()) {
00434 path += token.AsText();
00435 NextToken();
00436 }
00437 if (EatArc(arc)) {
00438 path += arc->id;
00439 }
00440 else {
00441 PError("Must be an arc: identifier, integer, or string.");
00442 }
00443 }
00444
00445 while (AtDelimiter()) {
00446 path += token.AsText();
00447 NextToken();
00448 if (EatArc(arc))
00449 path += arc->id;
00450 else break;
00451 }
00452 return path;
00453 }
00454
00455 Expr Block() {
00456 SrcLoc *eL = token.loc;
00457 StmtListEC *assocs = NEW_CONSTR(StmtListEC, (token.loc));
00458 bool looking = true;
00459
00460 Expect(TkLBrace, "`{' at start of block.");
00461 while (looking && !EatToken(TkReturn) && !EatToken(TkValue)) {
00462 assocs->AddExpr(Stmt());
00463 looking = EatToken(TkSemicolon);
00464 }
00465 if (looking) {
00466 bool ret = (eatenToken.tclass == TkReturn);
00467 Expr body = Expression();
00468 looking = EatToken(TkSemicolon);
00469 Expect(TkRBrace, "`}' at end of block.");
00470 return NEW_CONSTR(BlockEC, (assocs, body, ret, eL));
00471 }
00472 else
00473 PError("Expecting semicolon.\n");
00474 return NULL;
00475 }
00476
00477 Expr Stmt() {
00478 Name name;
00479 bool noCache = false;
00480
00481 if (EatPragma()) {
00482 noCache = !strcmp(eatenToken.Bytes(), pragmaNoCache);
00483 }
00484 if (EatName(name)) {
00485 if (AtToken(TkLParen)) {
00486 return NEW_CONSTR(AssignEC,
00487 (name, Func(name->id, noCache), true, name->loc));
00488 }
00489 else {
00490 return NEW_CONSTR(AssignEC,
00491 (name, Assign(name), false, name->loc));
00492 }
00493 }
00494 if (EatToken(TkType)) {
00495 return TypeDef();
00496 }
00497 if (AtToken(TkForeach)) {
00498 return Iterate();
00499 }
00500 PError("Expected assignment, function def, type def, or iteration.\n");
00501 return NULL;
00502 }
00503
00504 Expr Func(const Text& name, bool noCache) {
00505 SrcLoc *eL = token.loc;
00506 Expr type = NULL;
00507
00508 if (EatToken(TkLParen))
00509 {
00510 ArgList l_formals = Formals();
00511 Expr l_body = Func(name + "()", noCache);
00512 return NEW_CONSTR(FuncEC, (noCache, name, l_formals, l_body, eL));
00513 }
00514 if (EatToken(TkColon))
00515 type = Type();
00516 return Block();
00517 }
00518
00519 ArgList Formals() {
00520 ArgList formals = NEW_CONSTR(ArgListEC, (5, token.loc));
00521 Name name;
00522 bool looking = true;
00523 bool eqSeen = false;
00524 Expr type = NULL;
00525
00526 if (EatToken(TkRParen)) {
00527 return formals;
00528 }
00529 while (looking) {
00530 SrcLoc *eL = token.loc;
00531 bool inPK = false;
00532 if (EatPragma()) {
00533 inPK = !strcmp(eatenToken.Bytes(), pragmaInPK);
00534 }
00535 if (EatName(name)) {
00536 if (name->id == nameDot) {
00537 PError("`.' not allowed as a formal parameter.\n");
00538 }
00539 for (int i = 0; i < formals->elems.size(); i++) {
00540 if (((Name)formals->elems.get(i))->id == name->id)
00541 PError(Text("`") + name->id
00542 + Text("' occurs more than once in parameter list.\n"));
00543 }
00544 if (EatToken(TkColon)) type = Type();
00545 eqSeen = (eqSeen || AtToken(TkEqual));
00546 if (eqSeen) {
00547 Expect(TkEqual, "`=' for parameter default.");
00548 formals->AddExpr(NEW_CONSTR(AssignEC, (name, Expression(), false, eL)),
00549 inPK);
00550 }
00551 else {
00552 name->ClearFreeVars();
00553 formals->AddExpr(name, inPK);
00554 }
00555 looking = EatToken(TkComma);
00556 }
00557 else {
00558
00559 Expect(TkId, "identifier for formals.");
00560 }
00561 }
00562 assert(formals->Length() < 65);
00563 Expect(TkRParen, "`)' at end of formal list.");
00564 return formals;
00565 }
00566
00567 Expr Assign(Name name) {
00568 Text op;
00569 Expr type = NULL;
00570
00571 if (EatToken(TkColon))
00572 type = Type();
00573 if (AtToken(TkPlus) || AtToken(TkPlusPlus) || AtToken(TkMinus) ||
00574 AtToken(TkStar)) {
00575 op = token.AsText();
00576 NextToken();
00577 }
00578 Expect(TkEqual, "`=' in assignment.");
00579 Expr e = Expression();
00580 if (op.Empty())
00581 return e;
00582 return NEW_CONSTR(ApplyOpEC, (name, op, e, name->loc));
00583 }
00584
00585 Expr Iterate() {
00586 SrcLoc *eL = token.loc;
00587
00588 Expect(TkForeach, "`foreach' or other statement starter.");
00589 Expr control = Control();
00590 Expect(TkIn, "`in' following iteration variable.");
00591 Expr e = Expression();
00592 Expect(TkDo, "`do' following iteration expression.");
00593 StmtListEC *stmts = NEW_CONSTR(StmtListEC, (token.loc));
00594
00595 bool looking = true;
00596 if (EatToken(TkLBrace)) {
00597 while (looking && !AtToken(TkRBrace)) {
00598 stmts->AddExpr(Stmt());
00599 looking = EatToken(TkSemicolon);
00600 }
00601 Expect(TkRBrace, "`}' following statements of iteration body.");
00602 }
00603 else
00604 stmts->AddExpr(Stmt());;
00605 return NEW_CONSTR(IterateEC, (control, e, stmts, eL));
00606 }
00607
00608 Expr Control() {
00609 SrcLoc *eL = token.loc;
00610 Name name1, name2;
00611 Expr type = NULL;
00612
00613 if (EatToken(TkLBracket)) {
00614 name1 = GetName();
00615 if (EatToken(TkColon)) type = Type();
00616 Expect(TkEqual, "`=' in iteration control pair.");
00617 name2 = GetName();
00618 if (EatToken(TkColon)) type = Type();
00619 Expect(TkRBracket, "`]' following iteration control pair.");
00620 return NEW_CONSTR(PairEC, (name1, name2, eL));
00621 }
00622 name1 = GetName();
00623 if (EatToken(TkColon)) type = Type();
00624 return name1;
00625 }
00626
00627 Expr Expression() {
00628 SrcLoc *eL = token.loc;
00629
00630 if (EatToken(TkIf)) {
00631 Expr e1 = Expression();
00632 Expect(TkThen, "`then' following `if' expression.");
00633 Expr e2 = Expression();
00634 Expect(TkElse, "`else' following `then' expression.");
00635 return NEW_CONSTR(IfEC, (e1, e2, Expression(), eL));
00636 }
00637 return Expr1();
00638 }
00639
00640 Expr Expr1() {
00641 SrcLoc *eL = token.loc;
00642
00643 Expr e = Expr2();
00644 while (EatToken(TkImplies))
00645 e = NEW_CONSTR(ApplyOpEC, (e, "=>", Expr2(), eL));
00646 return e;
00647 }
00648
00649 Expr Expr2() {
00650 SrcLoc *eL = token.loc;
00651
00652 Expr e = Expr3();
00653 while (EatToken(TkOr))
00654 e = NEW_CONSTR(ApplyOpEC, (e, "||", Expr3(), eL));
00655 return e;
00656 }
00657
00658 Expr Expr3() {
00659 SrcLoc *eL = token.loc;
00660
00661 Expr e = Expr4();
00662 while (EatToken(TkAnd))
00663 e = NEW_CONSTR(ApplyOpEC, (e, "&&", Expr4(), eL));
00664 return e;
00665 }
00666
00667 Expr Expr4() {
00668 SrcLoc *eL = token.loc;
00669
00670 Expr e = Expr5();
00671 if (AtToken(TkGreater)) {
00672 TokenLookAhead();
00673 if ((nextToken.tclass == TkNumber) ||
00674 (nextToken.tclass == TkString) ||
00675 (nextToken.tclass == TkId) ||
00676 (nextToken.tclass == TkTrue) ||
00677 (nextToken.tclass == TkFalse) ||
00678 (nextToken.tclass == TkErr) ||
00679 (nextToken.tclass == TkMinus) ||
00680 (nextToken.tclass == TkBang) ||
00681 (nextToken.tclass == TkLParen) ||
00682 (nextToken.tclass == TkLess) ||
00683 (nextToken.tclass == TkLBracket) ||
00684 (nextToken.tclass == TkLBrace)) {
00685
00686 EatToken(TkGreater);
00687 Text l_op = eatenToken.AsText();
00688 return NEW_CONSTR(ApplyOpEC, (e, l_op, Expr5(), eL));
00689 }
00690 }
00691 else if (EatToken(TkEqEq) ||
00692 EatToken(TkNotEq) ||
00693 EatToken(TkLess) ||
00694 EatToken(TkLessEq) ||
00695 EatToken(TkGreaterEq))
00696 {
00697 Text l_op = eatenToken.AsText();
00698 return NEW_CONSTR(ApplyOpEC, (e, l_op, Expr5(), eL));
00699 }
00700 return e;
00701 }
00702
00703 Expr Expr5() {
00704 SrcLoc *eL = token.loc;
00705 Text op;
00706
00707 Expr e = Expr6();
00708 while (AtToken(TkPlus) || AtToken(TkPlusPlus) ||
00709 AtToken(TkMinus)) {
00710 op = token.AsText();
00711 NextToken();
00712 e = NEW_CONSTR(ApplyOpEC, (e, op, Expr6(), eL));
00713 }
00714 return e;
00715 }
00716
00717 Expr Expr6() {
00718 SrcLoc *eL = token.loc;
00719
00720 Expr e = Expr7();
00721 while (AtToken(TkStar)) {
00722 NextToken();
00723 e = NEW_CONSTR(ApplyOpEC, (e, "*", Expr7(), eL));
00724 }
00725 return e;
00726 }
00727
00728 Expr Expr7() {
00729 SrcLoc *eL = token.loc;
00730
00731 if (EatToken(TkMinus))
00732 return NEW_CONSTR(ApplyUnOpEC, ("-", Primary(), eL));
00733 if (EatToken(TkBang))
00734 return NEW_CONSTR(ApplyUnOpEC, ("!", Primary(), eL));
00735 return Expr8();
00736 }
00737
00738 Expr Expr8() {
00739 SrcLoc *eL = token.loc;
00740 Expr e = Primary();
00741 Expr type = NULL;
00742
00743 if (EatToken(TkColon))
00744 type = Type();
00745 return e;
00746 }
00747
00748 Expr Primary() {
00749 SrcLoc *eL = token.loc;
00750 Expr primary;
00751 ExprList elems;
00752
00753 switch (token.tclass) {
00754 case TkId:
00755 {
00756 Name name = (Name)token.expr;
00757 PrimExec prim = LookupPrim(name->id);
00758 if (prim == NULL)
00759 primary = name;
00760 else
00761 primary = NEW_CONSTR(PrimitiveEC, (name->id, prim, eL));
00762 NextToken();
00763 break;
00764 }
00765 case TkString: case TkNumber:
00766 primary = token.expr;
00767 NextToken();
00768 return primary;
00769 case TkErr:
00770 NextToken();
00771 return NEW_CONSTR(ErrorEC, (token.loc, false));
00772 case TkTrue:
00773 NextToken();
00774 return NEW_CONSTR(ConstantEC, (valTrue, eL));
00775 case TkFalse:
00776 NextToken();
00777 return NEW_CONSTR(ConstantEC, (valFalse, eL));
00778 case TkLParen:
00779 NextToken();
00780 primary = Expression();
00781 Expect(TkRParen, "`)' to match `(' in primary.");
00782 break;
00783 case TkLBracket:
00784 NextToken();
00785 if (EatToken(TkRBracket))
00786 primary = NEW_CONSTR(BindingEC, (0, eL));
00787 else
00788 primary = BindingCons(BindElem());
00789 break;
00790 case TkLess:
00791 NextToken();
00792 if (EatToken(TkGreater))
00793 primary = NEW_CONSTR(ListEC, (0, eL));
00794 else
00795 primary = ListCons(Expression());
00796 break;
00797 case TkLBrace:
00798 primary = Block();
00799 break;
00800 default:
00801 PError(Text("Expected primary, saw `") + token.AsText() + "'.\n");
00802 break;
00803 }
00804 while (true) {
00805 if (EatToken(TkSlash) || EatToken(TkBackSlash))
00806 primary = NEW_CONSTR(SelectEC, (primary, GenArc(), false, primary->loc));
00807 else if (EatToken(TkBang))
00808 primary = NEW_CONSTR(SelectEC, (primary, GenArc(), true, primary->loc));
00809 else if (EatToken(TkLParen))
00810 primary = NEW_CONSTR(ApplyEC, (primary, Actuals(), primary->loc));
00811 else return primary;
00812 }
00813 }
00814
00815 Expr GenArc() {
00816 Name name;
00817 Expr computed;
00818
00819 if (EatArc(name)) {
00820 name->ClearFreeVars();
00821 return name;
00822 }
00823 if (EatToken(TkDollar)) {
00824 if (EatToken(TkLParen)) {
00825 computed = Expression();
00826 Expect(TkRParen, "`)' at end of computed field.");
00827 }
00828 else
00829 computed = GetName();
00830 }
00831 else if (EatToken(TkPercent)) {
00832 computed = Expression();
00833 Expect(TkPercent, "`%' at end of computed field.");
00834 }
00835 else
00836 Expect(TkErr, "name in binding field.");
00837 return NEW_CONSTR(ComputedEC, (computed));
00838 }
00839
00840 Expr BindingCons(Expr e) {
00841 BindingEC *be = NEW_CONSTR(BindingEC, (5, e->loc));
00842
00843 be->AddExpr(e);
00844 while (EatToken(TkComma) && !AtToken(TkRBracket))
00845 be->AddExpr(BindElem());
00846 Expect(TkRBracket, "`]' to end binding.");
00847 return be;
00848 }
00849
00850 Expr BindElem() {
00851 Expr name = GenArc();
00852
00853 if (EatDelimiter()) {
00854 if (EatToken(TkEqual))
00855 return NEW_CONSTR(BindEC, (name, Expression(), name->loc));
00856 BindingEC *be = NEW_CONSTR(BindingEC, (1, token.loc));
00857 be->AddExpr(BindElem());
00858 return NEW_CONSTR(BindEC, (name, be, name->loc));
00859 }
00860 if (EatToken(TkEqual))
00861 return NEW_CONSTR(BindEC, (name, Expression(), name->loc));
00862 if (eatenToken.tclass == TkId &&
00863 name->kind == NameEK) {
00864 Expr name1 = NEW_CONSTR(NameEC, (((NameEC*)name)->id, name->loc));
00865 return NEW_CONSTR(BindEC, (name, name1, name->loc));
00866 }
00867 PError(Text("Expected identifier.\n"));
00868 return NULL;
00869 }
00870
00871 Expr ListCons(Expr e) {
00872 ListEC *elst = NEW_CONSTR(ListEC, (5, e->loc));
00873
00874 elst->AddExpr(e);
00875 while (EatToken(TkComma) && !AtToken(TkGreater))
00876 elst->AddExpr(Expression());
00877 Expect(TkGreater, "`>' to end list.");
00878 return elst;
00879 }
00880
00881 ArgList Actuals() {
00882 SrcLoc *eL = token.loc;
00883 ArgList actuals = NEW_CONSTR(ArgListEC, (5, token.loc));
00884 bool looking = true;
00885
00886 while (looking && !AtToken(TkRParen)) {
00887 actuals->AddExpr(Expression(), false);
00888 looking = EatToken(TkComma);
00889 }
00890 Expect(TkRParen, "`)' at end of actual parameter list.");
00891 return actuals;
00892 }
00893
00894 Expr TypeDef() {
00895 Name name;
00896
00897 if (EatName(name)) {
00898 Expect(TkEqual, "`=' following identifier in type definition.");
00899 return NEW_CONSTR(AssignEC, (name, Type(), false, name->loc));
00900 }
00901 else
00902 PError("Expected type identifier.\n");
00903 return NULL;
00904 }
00905
00906 Expr Type() {
00907 bool looking = true;
00908 Name name;
00909 SrcLoc *eL;
00910
00911 if (EatToken(TkBool) || EatToken(TkInt) || EatToken(TkText))
00912 eL = token.loc;
00913 else if (EatToken(TkList)) {
00914 eL = token.loc;
00915 if (EatToken(TkLBracket)) {
00916
00917 Type();
00918 Expect(TkRBracket, "`]' to close list type.");
00919 }
00920 else if (EatToken(TkLParen)) {
00921 Type();
00922 Expect(TkRParen, "`)' to close list type.");
00923 }
00924 }
00925 else if (EatToken(TkBinding)) {
00926 eL = token.loc;
00927 if (EatToken(TkLBracket)) {
00928
00929 if (EatToken(TkColon))
00930 Type();
00931 else {
00932 while (looking && EatName(name)) {
00933 if (EatToken(TkColon))
00934 Type();
00935 looking = EatToken(TkComma);
00936 }
00937 }
00938 Expect(TkRBracket, "`]' to close binding type.");
00939 }
00940 else if (EatToken(TkLParen)) {
00941 if (EatToken(TkColon))
00942 Type();
00943 else {
00944 while (looking && EatName(name)) {
00945 if (EatToken(TkColon))
00946 Type();
00947 looking = EatToken(TkComma);
00948 }
00949 }
00950 Expect(TkRParen, "`)' to close binding type.");
00951 }
00952 }
00953 else if (EatToken(TkFunction)) {
00954 eL = token.loc;
00955 if (EatToken(TkLParen)) {
00956 while (looking && !AtToken(TkRParen)) {
00957 if (EatToken(TkId)) {
00958 if (EatToken(TkColon)) Type();
00959 }
00960 else
00961 Type();
00962 looking = EatToken(TkComma);
00963 }
00964 Expect(TkRParen, "`)' to close function type.");
00965 }
00966 if (EatToken(TkColon))
00967 Type();
00968 }
00969 else {
00970 eL = token.loc;
00971 Expect(TkId, "type identifier or type expression.");
00972 }
00973 return NEW_CONSTR(BaseTEC, ("<Type>", eL));
00974 }
00975
00976
00977 Expr Parse(istream *lexIn, const Text& name, ShortId sid,
00978 VestaSource *modelRoot) {
00979 InitState(lexIn, name, sid, modelRoot);
00980 Expr result = Model();
00981 token.LexFlush();
00982 return result;
00983 }