1(* $Id: AST.Mod,v 1.21 2004/03/21 16:09:19 mva Exp $ *) 2MODULE OOC:AST [OOC_EXTENSIONS]; 3(* Creates extended abstract syntax tree from the parser output. 4 Copyright (C) 2000-2004 Michael van Acken 5 6 This file is part of OOC. 7 8 OOC is free software; you can redistribute it and/or modify it 9 under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 OOC is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 16 License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with OOC. If not, write to the Free Software Foundation, 59 20 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21*) 22 23IMPORT 24 Strings, Object, OOC:Scanner:InputBuffer, OOC:Scanner:SymList, OOC:Doc, 25 <*WITH Warnings:=FALSE DO*>OOC:Scanner:Symbol<*END (*for refs in docs*)*>; 26 27 28 29(** 30The syntax tree constructed by this module is a one-to-one representation 31of the data passed to the factory methods of @otype{Builder}. Every call 32to a factory method creates a new object, which is filled with the 33arguments of the method. The result of @oproc{Builder.Module} is the 34root of the generated syntax tree. 35 36The principles behind the design of this module are: 37 38@itemize 39@item 40All syntactic information discovered by the parser must be passed to the 41builder. This includes the structure of the document, as well as @emph{all} 42terminal symbols, and their positions. 43 44@item 45The builder must be simple. The classes and factory methods should be 46easy to grasp, and their granularity should not be too small. 47 48@item 49The interface of the builder makes no assumptions how the parsed 50information is used by the program. It should serve equally well any 51tool that is operating on the source code, for any purpose. 52@end itemize 53 54 55Data types, expressions, and statements are defined by several 56syntactic entities. If a rule of the grammar refers to the 57@samp{Type} production, the actual type description that is part of 58the abstract syntax tree is one of the @emph{concrete} type syntax 59variants. Types can be referenced or defined by one of these 60constructions: 61 62@table @asis 63@item Unqualified Type Name 64Such a type reference is created by @oproc{Builder.Terminal}. 65 66@item Qualified Type Name 67This is represented as a module name, followed by a selector name. A 68qualified type name is the result of @oproc{Builder.Operator}, using the 69symbol @oconst{Symbol.period} as operator. 70 71@item Array Type 72Constructed by a call to @oproc{Builder.ArrayType}. 73 74@item Record Type 75Constructed by a call to @oproc{Builder.RecordType}. 76 77@item Pointer Type 78Constructed by a call to @oproc{Builder.PointerType}. 79 80@item Procedure Type 81Constructed by a call to @oproc{Builder.ProcType}. 82@end table 83 84Likewise, the grammar production @samp{Expr} is broken down into 85several basic expression archetypes. Most kinds of expressions are 86mapped to dyadic or monadic operators, but there are also other 87variants for specialized values. 88 89@table @asis 90@item Designator 91A designator defines the place or the value of a variable, depending 92of the context of its use. Designators are created by repeated 93application of @oproc{Builder.Terminal} (for identifiers), 94@oproc{Builder.Operator} (for qualified identifiers, monadic, and 95dyadic operators), @oproc{Builder.ArrayIndex} (one or more array 96indexes), and @oproc{Builder.FunctionCall} (for function calls, 97procedure calls, and type guards). Please note that type guards are 98mapped to functions calls on the syntax level, and that the designator 99implementation of the parser is less restrictive than the Oberon-2 100syntax, because of the limits of a recursive descent parser that 101does not use any information from a symbol table. 102 103@item Set Constructor 104A set constructor is the result of a call to @oproc{Builder.Set}. The 105set is defined by a sequence of @oproc{Builder.Operator} using 106@oconst{Symbol.upto} as operator. 107 108@item Constants 109Integer, string, and character constants, and the keyword @code{NIL} 110are mapped to instances of @oproc{Builder.Terminal}. 111 112@item Parenthesis 113An expression in parenthesis is represented by @oproc{Builder.Factor}. 114 115@item Operators 116All monadic and dyadic operators, like @samp{~}, @samp{*}, @samp{+}, 117@samp{IN}, and so on, are mapped to results of 118@oproc{Builder.Operator}. 119@end table 120 121 122Statement sequences are respresented by lists of statements, separated 123by @samp{;}. An empty statement is mapped to @code{NIL}. For a 124statement list @samp{statmSeq}, the list has this form: 125 126@table @samp 127@item statmList MOD 2 == 0 128Result of any of the statement factory methods, or a function call, or 129@code{NIL} for the empty statement. 130@item statmList MOD 2 == 1 131The symbol @samp{;}, result of @oproc{Builder.Terminal}. 132@end table 133 134This module defines also a @samp{Visitor} pattern for the syntax tree. 135The base class @otype{Visitor} defines visitor methods for every class 136that is part of the syntax tree, and every node defines a corresponding 137@samp{Accept} method. The default action of the @samp{Visit} methods 138is to do nothing. The method @oproc{Visitor.VisitNodeList} calls 139@samp{Accept} on all element of the list that are not @code{NIL}. 140*) 141 142TYPE 143 Name* = InputBuffer.CharArray; 144 Node* = POINTER TO NodeDesc; 145 NodeArray* = POINTER TO ARRAY OF Node; 146 NodeDesc* = RECORD [ABSTRACT] 147 (**Base type of all nodes that make up the abstract syntax tree. *) 148 END; 149 150TYPE 151 NodeList* = POINTER TO NodeListDesc; 152 NodeListDesc* = RECORD 153 (**Defines a simple list of nodes. This is used to model repetition 154 like @samp{ident @{"," ident@}} in the syntax tree. *) 155 (NodeDesc) 156 len-: LONGINT; 157 (**The number of nodes in the list. A value of zero means that the list 158 is empty. *) 159 n-: NodeArray; 160 (**This array holds the nodes of the list. The elements 161 @samp{[0..@ofield{len}-1]} hold valid data. If @ofield{len} is zero, 162 then @ofield{n} is an array of length zero. *) 163 END; 164 165 166TYPE 167 Builder* = POINTER TO BuilderDesc; 168 BuilderDesc* = RECORD 169 (**Abstract builder class for the parser. During parsing, the module 170 @omodule{*OOC:Parser} will call the factory methods below to create 171 the abstract syntax tree. Typically, a factory method corresponds 172 to the production of the grammar with the same name. *) 173 expectedModuleName-: Name; 174 (**See @oproc{Builder.SetModuleName}. *) 175 END; 176 177 178 179TYPE 180 Flags* = POINTER TO FlagsDesc; 181 Terminal* = POINTER TO TerminalDesc; 182 TerminalDesc = RECORD 183 (NodeDesc) 184 sym-: SymList.Symbol; 185 END; 186 187TYPE 188 IdentDef* = POINTER TO IdentDefDesc; 189 IdentDefDesc = RECORD 190 (NodeDesc) 191 ident-: Terminal; 192 mark-: Terminal; 193 docString-: Doc.Document; 194 END; 195 196TYPE 197 ModuleIdent* = POINTER TO ModuleIdentDesc; 198 ModuleIdentDesc = RECORD 199 (NodeDesc) 200 nameList-: NodeList; 201 docString-: Doc.Document; 202 END; 203 204TYPE 205 Type* = POINTER TO TypeDesc; 206 TypeDesc = RECORD [ABSTRACT] 207 (NodeDesc) 208 END; 209 210TYPE 211 ArrayType* = POINTER TO ArrayTypeDesc; 212 ArrayTypeDesc = RECORD 213 (TypeDesc) 214 array-: Node; 215 flags-: Flags; 216 exprList-: NodeList; 217 of-: Node; 218 type-: Node; 219 END; 220 221TYPE 222 FieldList* = POINTER TO FieldListDesc; 223 FieldListDesc = RECORD 224 (NodeDesc) 225 identList-: NodeList; 226 colon-: Node; 227 type-: Node; 228 END; 229 230TYPE 231 RecordType* = POINTER TO RecordTypeDesc; 232 RecordTypeDesc = RECORD 233 (TypeDesc) 234 record-: Node; 235 flags-: Flags; 236 lParen-: Node; 237 baseType-: Node; 238 rParen-: Node; 239 fieldLists-: NodeList; 240 end-: Node; 241 END; 242 243TYPE 244 PointerType* = POINTER TO PointerTypeDesc; 245 PointerTypeDesc = RECORD 246 (TypeDesc) 247 pointer-: Node; 248 flags-: Flags; 249 to-: Node; 250 type-: Node; 251 END; 252 253 254TYPE 255 FPSection* = POINTER TO FPSectionDesc; 256 FPSectionDesc = RECORD 257 (NodeDesc) 258 var-: Node; 259 identList-: NodeList; 260 colon-: Node; 261 type-: Node; 262 END; 263 264TYPE 265 FormalPars* = POINTER TO FormalParsDesc; 266 FormalParsDesc = RECORD 267 (NodeDesc) 268 flags-: Flags; 269 lParen-: Node; 270 fpSections-: NodeList; (* optional *) 271 rParen-: Node; 272 colon-: Node; 273 result-: Node; 274 raises-: Node; 275 raisesList-: NodeList; 276 END; 277 278TYPE 279 ProcType* = POINTER TO ProcTypeDesc; 280 ProcTypeDesc = RECORD 281 (TypeDesc) 282 procedure-: Node; 283 formalPars-: Node; 284 END; 285 286TYPE 287 TPSection* = POINTER TO TPSectionDesc; 288 TPSectionDesc = RECORD 289 (NodeDesc) 290 var-: Node; 291 identList-: NodeList; 292 colon-: Node; 293 type-: Node; 294 END; 295 296TYPE 297 TypePars* = POINTER TO TypeParsDesc; 298 TypeParsDesc = RECORD 299 (NodeDesc) 300 lParen-: Node; 301 tpSections-: NodeList; 302 rParen-: Node; 303 END; 304 305TYPE 306 QualType* = POINTER TO QualTypeDesc; 307 QualTypeDesc = RECORD 308 (NodeDesc) 309 qualident-: Node; 310 lParen-: Terminal; 311 arguments-: NodeList; 312 rParen-: Terminal; 313 END; 314 315 316TYPE 317 ImportDecl* = POINTER TO ImportDeclDesc; 318 ImportDeclDesc = RECORD 319 (NodeDesc) 320 alias-: Node; (* optional *) 321 becomes-: Node; (* optional *) 322 module-: ModuleIdent; (* required *) 323 moduleName-: Name; 324 END; 325 326TYPE 327 ConstDecl* = POINTER TO ConstDeclDesc; 328 ConstDeclDesc = RECORD 329 (NodeDesc) 330 identDef-: IdentDef; 331 flags-: Flags; 332 equal-: Node; 333 expr-: Node; 334 semicolon-: Node; 335 END; 336 337TYPE 338 TypeDecl* = POINTER TO TypeDeclDesc; 339 TypeDeclDesc = RECORD 340 (NodeDesc) 341 identDef-: IdentDef; 342 flags-: Flags; 343 typePars-: TypePars; 344 equal-: Node; 345 type-: Node; 346 semicolon-: Node; 347 END; 348 349TYPE 350 VarDecl* = POINTER TO VarDeclDesc; 351 VarDeclDesc = RECORD 352 (NodeDesc) 353 identList-: NodeList; 354 colon-: Node; 355 type-: Node; 356 semicolon-: Node; 357 END; 358 359TYPE 360 Receiver* = POINTER TO ReceiverDesc; 361 ReceiverDesc = RECORD 362 (NodeDesc) 363 lParen-: Node; 364 var-: Node; 365 ident-: IdentDef; 366 colon-: Node; 367 type-: Node; 368 lParenAlias-: Terminal; 369 aliasList-: NodeList; 370 rParenAlias-: Terminal; 371 rParen-: Node; 372 END; 373 374TYPE 375 Body* = POINTER TO BodyDesc; 376 BodyDesc = RECORD 377 (NodeDesc) 378 declSeq-: NodeList; 379 begin-: Node; 380 statmSeq-: NodeList; (* may be NIL *) 381 end-: Terminal; 382 name-: Node; 383 END; 384 385TYPE 386 ProcDecl* = POINTER TO ProcDeclDesc; 387 ProcDeclDesc = RECORD 388 (NodeDesc) 389 proc-: Terminal; 390 arrow-: Node; 391 receiver-: Node; 392 flags-: Flags; 393 identDef-: IdentDef; 394 formalPars-: Node; 395 semicolon1-: Node; 396 body-: Body; (* can be NIL *) 397 semicolon2-: Node; 398 END; 399 400TYPE 401 ImportList* = POINTER TO ImportListDesc; 402 ImportListDesc* = RECORD 403 (NodeDesc) 404 import-: Node; 405 imports-: NodeList; 406 semicolon-: Node; 407 END; 408 409TYPE 410 Module* = POINTER TO ModuleDesc; 411 ModuleDesc* = RECORD 412 (NodeDesc) 413 module-: Terminal; 414 name-: ModuleIdent; 415 flags-: Flags; 416 semicolon-: Node; 417 importList-: Node; 418 body-: Body; (* can be NIL *) 419 period-: Node; 420 421 moduleName-: Name; 422 END; 423 424 425TYPE 426 Operator* = POINTER TO OperatorDesc; 427 OperatorDesc = RECORD 428 (NodeDesc) 429 (* Assuming that no errors have been found, the operator field is 430 always non-NIL. For dyadic operators, both operands are non-NIL. 431 For monadic operators, either the left (prefix, like "+a" or "~a") or 432 right (postfix, like "a^") operand is NIL. *) 433 left-: Node; (* can be NIL *) 434 op-: Terminal; 435 right-: Node; (* can be NIL *) 436 END; 437 438TYPE 439 Factor* = POINTER TO FactorDesc; 440 FactorDesc = RECORD 441 (NodeDesc) 442 lParen-: Terminal; 443 expr-: Node; 444 rParen-: Terminal; 445 END; 446 447TYPE 448 Set* = POINTER TO SetDesc; 449 SetDesc = RECORD 450 (NodeDesc) 451 type-: Node; 452 lBrace-: Terminal; 453 elementList-: NodeList; 454 rBrace-: Terminal; 455 END; 456 457TYPE 458 ArrayIndex* = POINTER TO ArrayIndexDesc; 459 ArrayIndexDesc = RECORD 460 (NodeDesc) 461 design-: Node; 462 lBrak-: Terminal; 463 indices-: NodeList; 464 rBrak-: Terminal; 465 END; 466 467TYPE 468 FunctionCall* = POINTER TO FunctionCallDesc; 469 FunctionCallDesc = RECORD 470 (NodeDesc) 471 design-: Node; 472 lParen-: Terminal; 473 arguments-: NodeList; 474 rParen-: Terminal; 475 END; 476 477 478 479TYPE 480 Assignment* = POINTER TO AssignmentDesc; 481 AssignmentDesc = RECORD 482 (NodeDesc) 483 assignment-: Operator; 484 END; 485 486TYPE 487 ProcedureCall* = POINTER TO ProcedureCallDesc; 488 ProcedureCallDesc = RECORD 489 (NodeDesc) 490 call-: Node; (* see @oproc{Builder.ProcedureCall} *) 491 END; 492 493TYPE 494 IfStatm* = POINTER TO IfStatmDesc; 495 IfStatmDesc = RECORD 496 (NodeDesc) 497 guardList-: NodeList; 498 else-: Node; 499 elseStatmSeq-: NodeList; 500 end-: Node; 501 END; 502 503TYPE 504 CaseStatm* = POINTER TO CaseStatmDesc; 505 CaseStatmDesc = RECORD 506 (NodeDesc) 507 case-: Terminal; 508 expr-: Node; 509 of-: Node; 510 caseList-: NodeList; 511 else-: Node; 512 elseStatmSeq-: NodeList; 513 end-: Node; 514 END; 515 516TYPE 517 WhileStatm* = POINTER TO WhileStatmDesc; 518 WhileStatmDesc = RECORD 519 (NodeDesc) 520 while-: Terminal; 521 guard-: Node; 522 do-: Terminal; 523 statmSeq-: NodeList; 524 end-: Terminal; 525 END; 526 527TYPE 528 RepeatStatm* = POINTER TO RepeatStatmDesc; 529 RepeatStatmDesc = RECORD 530 (NodeDesc) 531 repeat-: Terminal; 532 statmSeq-: NodeList; 533 until-: Terminal; 534 expr-: Node; 535 END; 536 537TYPE 538 ForStatm* = POINTER TO ForStatmDesc; 539 ForStatmDesc = RECORD 540 (NodeDesc) 541 for-: Terminal; 542 ident-: Node; 543 becomes-: Terminal; 544 startValue-: Node; 545 to-: Terminal; 546 endValue-: Node; 547 by-: Terminal; 548 step-: Node; 549 do-: Terminal; 550 statmSeq-: NodeList; 551 end-: Terminal; 552 END; 553 554TYPE 555 IterateStatm* = POINTER TO IterateStatmDesc; 556 IterateStatmDesc = RECORD 557 (NodeDesc) 558 for-: Terminal; 559 ident-: Node; 560 in-: Terminal; 561 range-: Node; 562 do-: Terminal; 563 statmSeq-: NodeList; 564 end-: Terminal; 565 END; 566 567TYPE 568 LoopStatm* = POINTER TO LoopStatmDesc; 569 LoopStatmDesc = RECORD 570 (NodeDesc) 571 loop-: Terminal; 572 statmSeq-: NodeList; 573 end-: Terminal; 574 END; 575 576TYPE 577 WithStatm* = POINTER TO WithStatmDesc; 578 WithStatmDesc = RECORD 579 (NodeDesc) 580 guardList-: NodeList; 581 else-: Node; 582 elseStatmSeq-: NodeList; 583 end-: Node; 584 END; 585 586TYPE 587 ExitStatm* = POINTER TO ExitStatmDesc; 588 ExitStatmDesc = RECORD 589 (NodeDesc) 590 exit-: Terminal; 591 END; 592 593TYPE 594 ReturnStatm* = POINTER TO ReturnStatmDesc; 595 ReturnStatmDesc = RECORD 596 (NodeDesc) 597 return-: Terminal; 598 expr-: Node; 599 END; 600 601TYPE 602 Catch* = POINTER TO CatchDesc; 603 CatchDesc = RECORD 604 (NodeDesc) 605 catch-: Terminal; 606 type-: Node; 607 lParen-: Node; (* optional *) 608 ident-: Terminal; (* optional *) 609 rParen-: Node; (* optional *) 610 colon-: Node; 611 statmSeq-: NodeList; 612 END; 613 614TYPE 615 TryStatm* = POINTER TO TryStatmDesc; 616 TryStatmDesc = RECORD 617 (NodeDesc) 618 try-: Terminal; 619 statmSeq-: NodeList; 620 catchList-: NodeList; 621 end-: Terminal; 622 END; 623 624TYPE 625 FlagsDesc = RECORD 626 (NodeDesc) 627 context-: SHORTINT; 628 lBrak-: Node; 629 flagList-: NodeList; 630 rBrak-: Node; 631 END; 632 633TYPE 634 ProcIdFlag* = POINTER TO ProcIdFlagDesc; 635 ProcIdFlagDesc = RECORD 636 (NodeDesc) 637 procId-: Node; 638 equal-: Node; 639 number-: Node; 640 END; 641 642TYPE 643 ModuleFlags* = POINTER TO ModuleFlagsDesc; 644 ModuleFlagsDesc = RECORD 645 (NodeDesc) 646 external-: Terminal; 647 callConv-: Terminal; 648 moduleFlags-: NodeList; 649 semicolon-: Node; 650 link-: Node; 651 linkSections-: NodeList; 652 end-: Node; 653 END; 654 655TYPE 656 LinkFileFlag* = POINTER TO LinkFileFlagDesc; 657 LinkFileFlagDesc = RECORD 658 (NodeDesc) 659 file-: Node; 660 fileName-: Terminal; 661 addOption-: Node; 662 prefixOpt-: Terminal; 663 comma-: Node; 664 suffixOpt-: Terminal; 665 END; 666 667TYPE 668 LinkObjFlag* = POINTER TO LinkObjFlagDesc; 669 LinkObjFlagDesc = RECORD 670 (NodeDesc) 671 obj-: Node; 672 fileName-: Node; 673 END; 674 675TYPE 676 LinkLibFlag* = POINTER TO LinkLibFlagDesc; 677 LinkLibFlagDesc = RECORD 678 (NodeDesc) 679 lib-: Node; 680 libName-: Terminal; 681 lParen-: Node; 682 dependencies-: NodeList; 683 rParen-: Node; 684 addOption-: Node; 685 prefixOpt-: Terminal; 686 comma-: Node; 687 suffixOpt-: Terminal; 688 END; 689 690 691CONST (* ids for the various invocations of Flags(): *) 692 flagsProcType* = 0; 693 flagsArrayType* = 1; 694 flagsRecordType* = 2; 695 flagsPointerType* = 3; 696 flagsConstDecl* = 4; 697 flagsTypeDecl* = 5; 698 flagsVariable* = 6; 699 flagsField* = 7; 700 flagsParameter* = 8; 701 flagsProcedure* = 9; 702 flagsModule* = 10; 703 704 705TYPE 706 Visitor* = POINTER TO VisitorDesc; 707 VisitorDesc* = RECORD [ABSTRACT] 708 END; 709 710 711PROCEDURE (node: Node) [ABSTRACT] Accept* (v: Visitor); 712 END Accept; 713 714PROCEDURE InitVisitor* (v: Visitor); 715 END InitVisitor; 716 717PROCEDURE (v: Visitor) VisitNodeList* (nl: NodeList); 718 VAR 719 i: LONGINT; 720 BEGIN 721 FOR i := 0 TO nl. len-1 DO 722 IF (nl. n[i] # NIL) THEN 723 nl. n[i]. Accept (v) 724 END 725 END 726 END VisitNodeList; 727 728PROCEDURE (v: Visitor) VisitTerminal* (terminal: Terminal); 729 END VisitTerminal; 730 731PROCEDURE (v: Visitor) VisitIdentDef* (identDef: IdentDef); 732 END VisitIdentDef; 733 734PROCEDURE (v: Visitor) VisitModuleIdent* (moduleIdent: ModuleIdent); 735 END VisitModuleIdent; 736 737(* types *) 738PROCEDURE (v: Visitor) VisitArrayType* (arrayType: ArrayType); 739 END VisitArrayType; 740 741PROCEDURE (v: Visitor) VisitFieldList* (fieldList: FieldList); 742 END VisitFieldList; 743 744PROCEDURE (v: Visitor) VisitRecordType* (recordType: RecordType); 745 END VisitRecordType; 746 747PROCEDURE (v: Visitor) VisitPointerType* (pointerType: PointerType); 748 END VisitPointerType; 749 750PROCEDURE (v: Visitor) VisitFPSection* (fpSection: FPSection); 751 END VisitFPSection; 752 753PROCEDURE (v: Visitor) VisitFormalPars* (formalPars: FormalPars); 754 END VisitFormalPars; 755 756PROCEDURE (v: Visitor) VisitProcType* (procType: ProcType); 757 END VisitProcType; 758 759PROCEDURE (v: Visitor) VisitTPSection* (tpSection: TPSection); 760 END VisitTPSection; 761 762PROCEDURE (v: Visitor) VisitTypePars* (typePars: TypePars); 763 END VisitTypePars; 764 765PROCEDURE (v: Visitor) VisitQualType* (qualType: QualType); 766 END VisitQualType; 767 768 769(* declarations *) 770PROCEDURE (v: Visitor) VisitImportDecl* (importDecl: ImportDecl); 771 END VisitImportDecl; 772 773PROCEDURE (v: Visitor) VisitConstDecl* (constDecl: ConstDecl); 774 END VisitConstDecl; 775 776PROCEDURE (v: Visitor) VisitTypeDecl* (typeDecl: TypeDecl); 777 END VisitTypeDecl; 778 779PROCEDURE (v: Visitor) VisitVarDecl* (varDecl: VarDecl); 780 END VisitVarDecl; 781 782PROCEDURE (v: Visitor) VisitReceiver* (receiver: Receiver); 783 END VisitReceiver; 784 785PROCEDURE (v: Visitor) VisitProcDecl* (procDecl: ProcDecl); 786 END VisitProcDecl; 787 788PROCEDURE (v: Visitor) VisitImportList* (importList: ImportList); 789 END VisitImportList; 790 791PROCEDURE (v: Visitor) VisitBody* (body: Body); 792 END VisitBody; 793 794PROCEDURE (v: Visitor) VisitModule* (module: Module); 795 END VisitModule; 796 797(* expressions *) 798PROCEDURE (v: Visitor) VisitOperator* (operator: Operator); 799 END VisitOperator; 800 801PROCEDURE (v: Visitor) VisitFactor* (factor: Factor); 802 END VisitFactor; 803 804PROCEDURE (v: Visitor) VisitSet* (set: Set); 805 END VisitSet; 806 807PROCEDURE (v: Visitor) VisitArrayIndex* (arrayIndex: ArrayIndex); 808 END VisitArrayIndex; 809 810PROCEDURE (v: Visitor) VisitFunctionCall* (functionCall: FunctionCall); 811 END VisitFunctionCall; 812 813(* statements *) 814PROCEDURE (v: Visitor) VisitAssignment* (assignment: Assignment); 815 END VisitAssignment; 816 817PROCEDURE (v: Visitor) VisitProcedureCall* (procedureCall: ProcedureCall); 818 END VisitProcedureCall; 819 820PROCEDURE (v: Visitor) VisitIfStatm* (ifStatm: IfStatm); 821 END VisitIfStatm; 822 823PROCEDURE (v: Visitor) VisitCaseStatm* (caseStatm: CaseStatm); 824 END VisitCaseStatm; 825 826PROCEDURE (v: Visitor) VisitWhileStatm* (whileStatm: WhileStatm); 827 END VisitWhileStatm; 828 829PROCEDURE (v: Visitor) VisitRepeatStatm* (repeatStatm: RepeatStatm); 830 END VisitRepeatStatm; 831 832PROCEDURE (v: Visitor) VisitForStatm* (forStatm: ForStatm); 833 END VisitForStatm; 834 835PROCEDURE (v: Visitor) VisitIterateStatm* (iterStatm: IterateStatm); 836 END VisitIterateStatm; 837 838PROCEDURE (v: Visitor) VisitLoopStatm* (loopStatm: LoopStatm); 839 END VisitLoopStatm; 840 841PROCEDURE (v: Visitor) VisitWithStatm* (withStatm: WithStatm); 842 END VisitWithStatm; 843 844PROCEDURE (v: Visitor) VisitExitStatm* (exitStatm: ExitStatm); 845 END VisitExitStatm; 846 847PROCEDURE (v: Visitor) VisitReturnStatm* (returnStatm: ReturnStatm); 848 END VisitReturnStatm; 849 850PROCEDURE (v: Visitor) VisitCatch* (catch: Catch); 851 END VisitCatch; 852 853PROCEDURE (v: Visitor) VisitTryStatm* (tryStatm: TryStatm); 854 END VisitTryStatm; 855 856(* flags *) 857PROCEDURE (v: Visitor) VisitFlags* (flags: Flags); 858 END VisitFlags; 859 860PROCEDURE (v: Visitor) VisitProcIdFlag* (procIdFlag: ProcIdFlag); 861 END VisitProcIdFlag; 862 863PROCEDURE (v: Visitor) VisitModuleFlags* (moduleFlags: ModuleFlags); 864 END VisitModuleFlags; 865 866PROCEDURE (v: Visitor) VisitLinkFileFlag* (linkFileFlag: LinkFileFlag); 867 END VisitLinkFileFlag; 868 869PROCEDURE (v: Visitor) VisitLinkObjFlag* (linkObjFlag: LinkObjFlag); 870 END VisitLinkObjFlag; 871 872PROCEDURE (v: Visitor) VisitLinkLibFlag* (linkLibFlag: LinkLibFlag); 873 END VisitLinkLibFlag; 874 875 876 877PROCEDURE Init* (b: Builder); 878 BEGIN 879 b.expectedModuleName := NIL; 880 END Init; 881 882PROCEDURE New* (): Builder; 883 VAR 884 b: Builder; 885 BEGIN 886 NEW (b); 887 Init (b); 888 RETURN b 889 END New; 890 891PROCEDURE InitNodeList (nl: NodeList); 892(**Initializes a node list of length zero. *) 893 BEGIN 894 nl. len := 0; 895 NEW (nl. n, 8) 896 END InitNodeList; 897 898PROCEDURE (b: Builder) SetModuleName* (name: ARRAY OF CHAR); 899(**Sets the expected module in the builder instance. If set, then the parser 900 will compare the expected with the actual module name, and report an error 901 if they differ. *) 902 BEGIN 903 NEW (b. expectedModuleName, Strings.Length (name)+1); 904 COPY (name, b. expectedModuleName^); 905 END SetModuleName; 906 907PROCEDURE (b: Builder) NewNodeList* (): NodeList; 908(**Creates a new node list of length zero. *) 909 VAR 910 nl: NodeList; 911 BEGIN 912 NEW (nl); 913 InitNodeList (nl); 914 RETURN nl 915 END NewNodeList; 916 917PROCEDURE (nl: NodeList) Append* (node: Node); 918(**Appends the node @oparam{node} to the list @oparam{nl}. *) 919 VAR 920 i: LONGINT; 921 new: NodeArray; 922 BEGIN 923 IF (nl. len = LEN (nl. n^)) THEN 924 NEW (new, LEN (nl. n^)*2); 925 FOR i := 0 TO LEN (nl. n^)-1 DO 926 new[i] := nl. n[i] 927 END; 928 nl. n := new 929 END; 930 nl. n[nl. len] := node; 931 INC (nl. len) 932 END Append; 933 934PROCEDURE (nl: NodeList) Accept* (v: Visitor); 935 BEGIN 936 v. VisitNodeList (nl) 937 END Accept; 938 939 940PROCEDURE (n: Node) AttachDocString* (docComment: Doc.Document); 941(**If processing of documentation comments is enabled, this procedure is called 942 whenever such a comment is found. The node @oparam{n} is the result of 943 a call to @oproc{Builder.IdentDef} or @oproc{*AST.Builder.ModuleIdent}. The 944 note the name of the nearest preceding valid declaration. The default 945 behaviour of this procedure is to do nothing. It most be redefined in 946 concrete definitions of @otype{Node}, or documentation comments will be 947 silently discarded. 948 949 Note: This procedure can be called more than once for a given node. *) 950 END AttachDocString; 951 952 953 954PROCEDURE (b: Builder) Terminal* (sym: SymList.Symbol): Terminal; 955(**Takes the symbol @oparam{sym} and creates a terminal node of the syntax 956 tree. In this context, @dfn{terminal} means that the node is a leaf of 957 the tree. *) 958 VAR 959 t: Terminal; 960 BEGIN 961 NEW (t); 962 t. sym := sym; 963 RETURN t 964 END Terminal; 965 966PROCEDURE (terminal: Terminal) Accept* (v: Visitor); 967 BEGIN 968 v. VisitTerminal (terminal) 969 END Accept; 970 971PROCEDURE (terminal: Terminal) GetString* (stripQuotes: BOOLEAN): STRING; 972 BEGIN 973 IF stripQuotes THEN 974 RETURN Object.NewLatin1Region (terminal. sym. str^, 975 1, terminal. sym. len-1) 976 ELSE 977 RETURN Object.NewLatin1 (terminal. sym. str^) 978 END 979 END GetString; 980 981 982PROCEDURE (b: Builder) IdentDef* (ident, mark: Terminal): IdentDef; 983(**An identifier, possibly followed by an export mark. This factory method 984 is called for @emph{all} name definitions in a module, excluding import 985 declarations and the module name itself. 986 987 @table @oparam 988 @item ident 989 Result of @oproc{Builder.Terminal}. 990 @item mark 991 Result of @oproc{Builder.Terminal}, or @code{NIL} if no export mark 992 is present. 993 @end table *) 994 VAR 995 id: IdentDef; 996 BEGIN 997 NEW (id); 998 id. ident := ident; 999 id. mark := mark; 1000 id. docString := NIL; 1001 RETURN id 1002 END IdentDef; 1003 1004PROCEDURE (identDef: IdentDef) AttachDocString* (docString: Doc.Document); 1005 BEGIN 1006 IF (identDef. docString # NIL) THEN 1007 identDef. docString. Merge (docString) 1008 ELSE 1009 identDef. docString := docString 1010 END 1011 END AttachDocString; 1012 1013PROCEDURE (identDef: IdentDef) Accept* (v: Visitor); 1014 BEGIN 1015 v. VisitIdentDef (identDef) 1016 END Accept; 1017 1018 1019PROCEDURE (b: Builder) ModuleIdent* (nameList: NodeList): Node; 1020(**A module name. The @oparam{nameList} is is list of 1021 @oproc{Builder.Terminal}, with the even elements being identifiers, and the 1022 odd elements being @samp{:}. *) 1023 VAR 1024 moduleIdent: ModuleIdent; 1025 BEGIN 1026 NEW (moduleIdent); 1027 moduleIdent. nameList := nameList; 1028 moduleIdent. docString := NIL; 1029 RETURN moduleIdent 1030 END ModuleIdent; 1031 1032PROCEDURE (moduleIdent: ModuleIdent) AttachDocString* (docString: Doc.Document); 1033 BEGIN 1034 IF (moduleIdent. docString # NIL) THEN 1035 moduleIdent. docString. Merge (docString) 1036 ELSE 1037 moduleIdent. docString := docString 1038 END 1039 END AttachDocString; 1040 1041PROCEDURE (moduleIdent: ModuleIdent) Accept* (v: Visitor); 1042 BEGIN 1043 v. VisitModuleIdent (moduleIdent) 1044 END Accept; 1045 1046 1047PROCEDURE InitType (t: Type); 1048 BEGIN 1049 END InitType; 1050 1051PROCEDURE (b: Builder) ArrayType* (array: Node; flags: Flags; 1052 exprList: NodeList; of, type: Node): Node; 1053(**Array type constructor. 1054 1055 @table @oparam 1056 @item array 1057 The keyword @code{ARRAY}, result of @oproc{Builder.Terminal}. 1058 1059 @item flags 1060 ... 1061 1062 @item exprList 1063 A list of expressions that define the lengths of the array for dimension 1064 0, 1, and so on. If no length is given, that is, if the array 1065 is of the @samp{open} kind, the length of the expression list is zero. 1066 This value is never @code{NIL}. 1067 1068 @table @samp 1069 @item exprList MOD 2 == 0 1070 Result of any of the expression functions (@oproc{Builder.Operator}, 1071 @oproc{Builder.Factor}, and so on). 1072 @item exprList MOD 2 == 1 1073 The symbol @samp{,}, result of @oproc{Builder.Terminal}. 1074 @end table 1075 1076 @item of 1077 The keyword @code{OF}, result of @oproc{Builder.Terminal}. 1078 1079 @item type 1080 A type reference or type constructor. 1081 @end table *) 1082(**Array type constructor. 1083 1084 @table @oparam 1085 @item array 1086 The keyword @code{ARRAY}, result of @oproc{Builder.Terminal}. 1087 1088 @item flags 1089 ... 1090 1091 @item exprList 1092 A list of expressions that define the lengths of the array for dimension 1093 0, 1, and so on. If no length is given, that is, if the array 1094 is of the @samp{open} kind, the length of the expression list is zero. 1095 This value is never @code{NIL}. 1096 1097 @table @samp 1098 @item exprList MOD 2 == 0 1099 Result of any of the expression functions (@oproc{Builder.Operator}, 1100 @oproc{Builder.Factor}, and so on). 1101 @item exprList MOD 2 == 1 1102 The symbol @samp{,}, result of @oproc{Builder.Terminal}. 1103 @end table 1104 1105 @item of 1106 The keyword @code{OF}, result of @oproc{Builder.Terminal}. 1107 1108 @item type 1109 A type reference or type constructor. 1110 @end table *) 1111 VAR 1112 at: ArrayType; 1113 BEGIN 1114 NEW (at); 1115 InitType (at); 1116 at. array := array; 1117 at. flags := flags; 1118 at. exprList := exprList; 1119 at. of := of; 1120 at. type := type; 1121 RETURN at 1122 END ArrayType; 1123 1124PROCEDURE (arrayType: ArrayType) Accept* (v: Visitor); 1125 BEGIN 1126 v. VisitArrayType (arrayType) 1127 END Accept; 1128 1129 1130PROCEDURE (b: Builder) FieldList* (identList: NodeList; colon, type: Node): Node; 1131(**Field list of a record definition. 1132 1133 @table @oparam 1134 @item identList 1135 A list of identifiers and optional flags, separated by commas. 1136 1137 @table @samp 1138 @item identList MOD 3 == 0 1139 A field name, result of @oproc{Builder.IdentDef}. 1140 @item identList MOD 3 == 1 1141 Flags (optional). 1142 @item identList MOD 3 == 2 1143 The symbol @samp{,}, result of @oproc{Builder.Terminal}. 1144 @end table 1145 1146 @item colon 1147 The symbol @samp{:}, result of @oproc{Builder.Terminal}. 1148 1149 @item type 1150 A type reference or type constructor. 1151 @end table *) 1152 VAR 1153 fl: FieldList; 1154 BEGIN 1155 NEW (fl); 1156 fl. identList := identList; 1157 fl. colon := colon; 1158 fl. type := type; 1159 RETURN fl 1160 END FieldList; 1161 1162PROCEDURE (fieldList: FieldList) Accept* (v: Visitor); 1163 BEGIN 1164 v. VisitFieldList (fieldList) 1165 END Accept; 1166 1167 1168PROCEDURE (b: Builder) RecordType* (record: Node; flags: Flags; 1169 lParen, baseType, rParen: Node; 1170 fieldLists: NodeList; end: Node): Node; 1171(**Record type constructor. 1172 1173 @table @oparam 1174 @item record 1175 The symbol @samp{RECORD}, result of @oproc{Builder.Terminal}. 1176 1177 @item flags 1178 ... 1179 1180 @item lParen 1181 The symbol @samp{(}, result of @oproc{Builder.Terminal}, or @code{NIL} 1182 if the record has no base type. 1183 1184 @item baseType 1185 A possibly qualified identifer, @oproc{Builder.Terminal} or 1186 @oproc{Builder.Operator}. This argument is @code{NIL} if the record 1187 has no base type. 1188 1189 @item rParen 1190 The symbol @samp{)}, result of @oproc{Builder.Terminal}, or @code{NIL} 1191 if the record has no base type. 1192 1193 @item fieldLists 1194 A list of field list definitions and comma symbols. This argument is 1195 never @code{NIL}. A field list declaration is the result of 1196 @oproc{Builder.FieldList}. Empty field list declarations are mapped 1197 to @code{NIL}. 1198 1199 @table @samp 1200 @item fieldLists MOD 2 == 0 1201 A field list, result of @oproc{Builder.FieldList}, or @code{NIL}. 1202 @item identList MOD 2 == 1 1203 The symbol @samp{;}, result of @oproc{Builder.Terminal}. 1204 @end table 1205 1206 @item end 1207 The symbol @samp{END}, result of @oproc{Builder.Terminal}. 1208 @end table *) 1209(**Record type constructor. 1210 1211 @table @oparam 1212 @item record 1213 The symbol @samp{RECORD}, result of @oproc{Builder.Terminal}. 1214 1215 @item flags 1216 ... 1217 1218 @item lParen 1219 The symbol @samp{(}, result of @oproc{Builder.Terminal}, or @code{NIL} 1220 if the record has no base type. 1221 1222 @item baseType 1223 A possibly qualified identifer, @oproc{Builder.Terminal} or 1224 @oproc{Builder.Operator}. This argument is @code{NIL} if the record 1225 has no base type. 1226 1227 @item rParen 1228 The symbol @samp{)}, result of @oproc{Builder.Terminal}, or @code{NIL} 1229 if the record has no base type. 1230 1231 @item fieldLists 1232 A list of field list definitions and comma symbols. This argument is 1233 never @code{NIL}. A field list declaration is the result of 1234 @oproc{Builder.FieldList}. Empty field list declarations are mapped 1235 to @code{NIL}. 1236 1237 @table @samp 1238 @item fieldLists MOD 2 == 0 1239 A field list, result of @oproc{Builder.FieldList}, or @code{NIL}. 1240 @item identList MOD 2 == 1 1241 The symbol @samp{;}, result of @oproc{Builder.Terminal}. 1242 @end table 1243 1244 @item end 1245 The symbol @samp{END}, result of @oproc{Builder.Terminal}. 1246 @end table *) 1247 VAR 1248 rt: RecordType; 1249 BEGIN 1250 NEW (rt); 1251 InitType (rt); 1252 rt. record := record; 1253 rt. flags := flags; 1254 rt. lParen := lParen; 1255 rt. baseType := baseType; 1256 rt. rParen := rParen; 1257 rt. fieldLists := fieldLists; 1258 rt. end := end; 1259 RETURN rt 1260 END RecordType; 1261 1262PROCEDURE (recordType: RecordType) Accept* (v: Visitor); 1263 BEGIN 1264 v. VisitRecordType (recordType) 1265 END Accept; 1266 1267 1268PROCEDURE (b: Builder) PointerType* (pointer: Node; flags: Flags; 1269 to, type: Node): Node; 1270(**Pointer type constructor. 1271 1272 @table @oparam 1273 @item pointer 1274 The symbol @samp{POINTER}, result of @oproc{Builder.Terminal}. 1275 1276 @item flags 1277 ... 1278 1279 @item to 1280 The symbol @samp{TO}, result of @oproc{Builder.Terminal}. 1281 1282 @item type 1283 A type reference or type constructor. 1284 @end table *) 1285 VAR 1286 pt: PointerType; 1287 BEGIN 1288 NEW (pt); 1289 InitType (pt); 1290 pt. pointer := pointer; 1291 pt. flags := flags; 1292 pt. to := to; 1293 pt. type := type; 1294 RETURN pt 1295 END PointerType; 1296 1297PROCEDURE (pointerType: PointerType) Accept* (v: Visitor); 1298 BEGIN 1299 v. VisitPointerType (pointerType) 1300 END Accept; 1301 1302 1303PROCEDURE (b: Builder) FPSection* (var: Node; identList: NodeList; colon, type: Node): Node; 1304(**Section of formal parameters. 1305 1306 @table @oparam 1307 @item var 1308 The keyword @samp{VAR} (created by @oproc{Builder.Terminal}), or @code{NIL} 1309 if the section describes a list of value parameters. 1310 1311 @item identList 1312 A list of identifiers and optional system flags, separated by commas. 1313 1314 @table @samp 1315 @item identList MOD 3 == 0 1316 A field name, result of @oproc{Builder.Terminal}. 1317 @item identList MOD 3 == 1 1318 ... 1319 @item identList MOD 3 == 2 1320 The symbol @samp{,}, result of @oproc{Builder.Terminal}. 1321 @end table 1322 1323 @item colon 1324 The symbol @samp{:}, result of @oproc{Builder.Terminal}. 1325 1326 @item type 1327 A type reference or type constructor. 1328 @end table *) 1329 VAR 1330 fp: FPSection; 1331 BEGIN 1332 NEW (fp); 1333 fp. var := var; 1334 fp. identList := identList; 1335 fp. colon := colon; 1336 fp. type := type; 1337 RETURN fp 1338 END FPSection; 1339 1340PROCEDURE (fpSection: FPSection) Accept* (v: Visitor); 1341 BEGIN 1342 v. VisitFPSection (fpSection) 1343 END Accept; 1344 1345 1346PROCEDURE (b: Builder) FormalPars* (flags: Flags; lParen: Node; fpSections: NodeList; rParen, colon, result, raises: Node; raisesList: NodeList): Node; 1347(**Formal parameter definition. Note: If the formal parameter list is 1348 completely empty, that is, if it does not even contain a parenthesis 1349 pair @samp{()}, all arguments from @oparam{lParen} onward are @code{NIL}. 1350 1351 @table @oparam 1352 @item flags 1353 ... 1354 1355 @item lParen 1356 The symbol @samp{(}, result of @oproc{Builder.Terminal}, or @code{NIL} 1357 if the formal parameter list is completely empty. 1358 1359 @item fpSections 1360 A list of formal parameter sections. This argument is only @code{NIL}, 1361 if the formal parameter list is completely empty. 1362 1363 @table @samp 1364 @item fpSections MOD 2 == 0 1365 A formal parameter section, result of @oproc{Builder.FPSection}, or 1366 possibly, for the last element of the list, the terminal symbol 1367 @oconst{Symbol.threeDots} (result of @oproc{Builder.Terminal}). 1368 @item fpSections MOD 2 == 1 1369 The symbol @samp{;}, result of @oproc{Builder.Terminal}. 1370 @end table 1371 1372 @item rParen 1373 The symbol @samp{)}, result of @oproc{Builder.Terminal}, or @code{NIL} 1374 if the formal parameter list is completely empty. 1375 1376 @item colon 1377 The symbol @samp{:}, result of @oproc{Builder.Terminal}, or @code{NIL} 1378 if the formal parameter list defines a procedure type. 1379 1380 @item result 1381 A type reference or type constructor, or @code{NIL} 1382 if the formal parameter list defines a procedure type. 1383 1384 @item raises 1385 The symbol @samp{RAISES}, result of @oproc{Builder.Terminal}, or @code{NIL} 1386 if the formal parameters do not declare any exceptions. 1387 1388 @item raisesList 1389 A list of type names. This argument is @code{NIL}, 1390 if the formal parameters do not declare any exceptions. 1391 1392 @table @samp 1393 @item raisesList MOD 2 == 0 1394 A qualified identifier, result of @oproc{Builder.Operator} or 1395 @oproc{Builder.Terminal}. 1396 @item fpSections MOD 2 == 1 1397 The symbol @samp{,}, result of @oproc{Builder.Terminal}. 1398 @end table 1399 1400 @end table *) 1401 VAR 1402 fp: FormalPars; 1403 BEGIN 1404 NEW (fp); 1405 fp. flags := flags; 1406 fp. lParen := lParen; 1407 fp. fpSections := fpSections; 1408 fp. rParen := rParen; 1409 fp. colon := colon; 1410 fp. result := result; 1411 fp. raises := raises; 1412 fp. raisesList := raisesList; 1413 RETURN fp 1414 END FormalPars; 1415 1416PROCEDURE (formalPars: FormalPars) Accept* (v: Visitor); 1417 BEGIN 1418 v. VisitFormalPars (formalPars) 1419 END Accept; 1420 1421 1422PROCEDURE (b: Builder) ProcType* (procedure, formalPars: Node): Node; 1423(**Procedure type constructor. 1424 1425 @table @oparam 1426 @item procedure 1427 The symbol @samp{PROCEDURE}, result of @oproc{Builder.Terminal}. 1428 1429 @item formalPars 1430 The formal parameters of the procedure type. This value is created 1431 by @oproc{Builder.FormalPars}. It is never @code{NIL}. 1432 @end table *) 1433 VAR 1434 pt: ProcType; 1435 BEGIN 1436 NEW (pt); 1437 InitType (pt); 1438 pt. procedure := procedure; 1439 pt. formalPars := formalPars; 1440 RETURN pt 1441 END ProcType; 1442 1443PROCEDURE (procType: ProcType) Accept* (v: Visitor); 1444 BEGIN 1445 v. VisitProcType (procType) 1446 END Accept; 1447 1448 1449PROCEDURE (b: Builder) TPSection* (identList: NodeList; colon, type: Node): Node; 1450(**Section of type parameters. 1451 1452 @table @oparam 1453 @item identList 1454 A list of identifiers, separated by commas. 1455 1456 @table @samp 1457 @item identList MOD 3 == 0 1458 A field name, result of @oproc{Builder.Terminal}. 1459 @item identList MOD 3 == 1 1460 The symbol @samp{,}, result of @oproc{Builder.Terminal}. 1461 @end table 1462 1463 @item colon 1464 The symbol @samp{:}, result of @oproc{Builder.Terminal}. 1465 1466 @item type 1467 A type name. 1468 @end table *) 1469 VAR 1470 tp: TPSection; 1471 BEGIN 1472 NEW (tp); 1473 tp. identList := identList; 1474 tp. colon := colon; 1475 tp. type := type; 1476 RETURN tp 1477 END TPSection; 1478 1479PROCEDURE (tpSection: TPSection) Accept* (v: Visitor); 1480 BEGIN 1481 v. VisitTPSection (tpSection) 1482 END Accept; 1483 1484 1485PROCEDURE (b: Builder) TypePars* (lParen: Node; 1486 tpSections: NodeList; 1487 rParen: Node): TypePars; 1488(**Type parameter definition. 1489 1490 @table @oparam 1491 @item lParen 1492 The symbol @samp{<}, result of @oproc{Builder.Terminal}. 1493 1494 @item tpSections 1495 A list of type parameter sections. This list may have a length of zero. 1496 1497 @table @samp 1498 @item tpSections MOD 2 == 0 1499 A formal parameter section, result of @oproc{Builder.TPSection}. 1500 @item fpSections MOD 2 == 1 1501 The symbol @samp{;}, result of @oproc{Builder.Terminal}. 1502 @end table 1503 1504 @item rParen 1505 The symbol @samp{>}, result of @oproc{Builder.Terminal}. 1506 @end table *) 1507 VAR 1508 tp: TypePars; 1509 BEGIN 1510 NEW (tp); 1511 tp. lParen := lParen; 1512 tp. tpSections := tpSections; 1513 tp. rParen := rParen; 1514 RETURN tp 1515 END TypePars; 1516 1517PROCEDURE (typePars: TypePars) Accept* (v: Visitor); 1518 BEGIN 1519 v. VisitTypePars (typePars) 1520 END Accept; 1521 1522 1523PROCEDURE (b: Builder) QualType*(qualident: Node; 1524 lParen: Node; 1525 arguments: NodeList; 1526 rParen: Node): Node; 1527(**A qualified type reference. This method is @emph{only} used if a parameter 1528 list is given. That is, @oparam{lParen}, @oparam{arguments}, and 1529 @oparam{rParen} are never @code{NIL}. 1530 1531 @table @oparam 1532 @item qualident 1533 The type name, @oproc{Builder.Terminal} or @oproc{Builder.Operator}. 1534 1535 @item lParen 1536 The symbol @samp{<}, result of @oproc{Builder.Terminal}. 1537 1538 @item arguments 1539 A list of type parameter sections. This list may have a length of zero. 1540 1541 @table @samp 1542 @item tpSections MOD 2 == 0 1543 A qualified type, @oproc{Builder.Terminal}, @oproc{Builder.Operator}, or 1544 @oproc{Builder.QualType}. 1545 @item fpSections MOD 2 == 1 1546 The symbol @samp{,}, result of @oproc{Builder.Terminal}. 1547 @end table 1548 1549 @item rParen 1550 The symbol @samp{>}, result of @oproc{Builder.Terminal}. 1551 @end table *) 1552 VAR 1553 qt: QualType; 1554 BEGIN 1555 NEW (qt); 1556 qt.qualident := qualident; 1557 qt.lParen := lParen(Terminal); 1558 qt.arguments := arguments; 1559 qt.rParen := rParen(Terminal); 1560 RETURN qt; 1561 END QualType; 1562 1563PROCEDURE (qualType: QualType) Accept* (v: Visitor); 1564 BEGIN 1565 v. VisitQualType (qualType) 1566 END Accept; 1567 1568 1569 1570PROCEDURE (b: Builder) ImportDecl* (alias, becomes, module: Node; 1571 moduleName: Name): Node; 1572(**An import declaration for a single module. 1573 1574 @table @oparam 1575 @item alias 1576 If the declaration defines an alias name, the the value of this argument 1577 is created by @oproc{Builder.Terminal}. Otherwise, it is @code{NIL}. 1578 1579 @item becomes 1580 The symbol @samp{:=}, or @code{NIL} if no alias name is defined. 1581 1582 @item module 1583 The imported module's name. This is is an instance of 1584 @oproc{Builder.ModuleIdent}. 1585 1586 @item moduleName 1587 The textual representation of the module name. Contrary to @oparam{module}, 1588 this is a single string. It is the concatenation of all of the symbols in 1589 @oparam{module}. 1590 @end table *) 1591 VAR 1592 id: ImportDecl; 1593 BEGIN 1594 NEW (id); 1595 id. alias := alias; 1596 id. becomes := becomes; 1597 id. module := module(ModuleIdent); 1598 id. moduleName := moduleName; 1599 RETURN id 1600 END ImportDecl; 1601 1602PROCEDURE (importDecl: ImportDecl) Accept* (v: Visitor); 1603 BEGIN 1604 v. VisitImportDecl (importDecl) 1605 END Accept; 1606 1607 1608PROCEDURE (b: Builder) ConstDecl* (identDef: Node; flags: Flags; 1609 equal, expr, semicolon: Node): Node; 1610(**Constant declaration. 1611 1612 @table @oparam 1613 @item identDef 1614 The identifier, optionally followed by an export mark. Result 1615 of @oproc{Builder.IdentDef}. 1616 1617 @item flags 1618 Declaration flags. 1619 1620 @item equal 1621 The symbol @samp{=}, result of @oproc{Builder.Terminal}. 1622 1623 @item expr 1624 An expression. This can be any value produced by the syntax rule 1625 @samp{Expr} or it subclauses. 1626 1627 @item semicolon 1628 The symbol @samp{;}, result of @oproc{Builder.Terminal}. 1629 @end table *) 1630 VAR 1631 cd: ConstDecl; 1632 BEGIN 1633 NEW (cd); 1634 cd. identDef := identDef(IdentDef); 1635 cd. flags := flags; 1636 cd. equal := equal; 1637 cd. expr := expr; 1638 cd. semicolon := semicolon; 1639 RETURN cd 1640 END ConstDecl; 1641 1642PROCEDURE (constDecl: ConstDecl) Accept* (v: Visitor); 1643 BEGIN 1644 v. VisitConstDecl (constDecl) 1645 END Accept; 1646 1647 1648PROCEDURE (b: Builder) TypeDecl* (identDef: Node; flags: Flags; 1649 typePars: TypePars; equal, 1650 type, semicolon: Node): Node; 1651(**Type declaration. 1652 1653 @table @oparam 1654 @item identDef 1655 The identifier, optionally followed by an export mark. Result of 1656 @oproc{Builder.IdentDef}. 1657 1658 @item flags 1659 Declaration flags. 1660 1661 @item typePars 1662 For a parameterized type, this is the list of type parameters (a result of 1663 @oproc{Builder.TypePars}). Otherwise, it is @code{NIL}. 1664 1665 @item equal 1666 The symbol @samp{=}, result of @oproc{Builder.Terminal}. 1667 1668 @item type 1669 A type reference or type constructor. 1670 1671 @item semicolon 1672 The symbol @samp{;}, result of @oproc{Builder.Terminal}. 1673 @end table *) 1674 VAR 1675 td: TypeDecl; 1676 BEGIN 1677 NEW (td); 1678 td. identDef := identDef(IdentDef); 1679 td. flags := flags; 1680 td. typePars := typePars; 1681 td. equal := equal; 1682 td. type := type; 1683 td. semicolon := semicolon; 1684 RETURN td 1685 END TypeDecl; 1686 1687PROCEDURE (typeDecl: TypeDecl) Accept* (v: Visitor); 1688 BEGIN 1689 v. VisitTypeDecl (typeDecl) 1690 END Accept; 1691 1692 1693PROCEDURE (b: Builder) VarDecl* (identList: NodeList; colon, type, semicolon: Node): Node; 1694(**Declaration of a variable or a list of variables. 1695 1696 @table @oparam 1697 @item identList 1698 @item identList 1699 A list of identifiers and optional system flags, separated by commas. 1700 1701 @table @samp 1702 @item identList MOD 3 == 0 1703 An identifier, optionally followed by an export mark, result of 1704 @oproc{Builder.IdentDef}. 1705 @item identList MOD 3 == 1 1706 ... 1707 @item identList MOD 3 == 2 1708 The symbol @samp{,}, result of @oproc{Builder.Terminal}. 1709 @end table 1710 1711 @item colon 1712 The symbol @samp{:}, result of @oproc{Builder.Terminal}. 1713 1714 @item type 1715 A type reference or type constructor. 1716 1717 @item semicolon 1718 The symbol @samp{;}, result of @oproc{Builder.Terminal}. 1719 @end table *) 1720 VAR 1721 vd: VarDecl; 1722 BEGIN 1723 NEW (vd); 1724 vd. identList := identList; 1725 vd. colon := colon; 1726 vd. type := type; 1727 vd. semicolon := semicolon; 1728 RETURN vd 1729 END VarDecl; 1730 1731PROCEDURE (varDecl: VarDecl) Accept* (v: Visitor); 1732 BEGIN 1733 v. VisitVarDecl (varDecl) 1734 END Accept; 1735 1736 1737PROCEDURE (b: Builder) Receiver* (lParen, var: Node; ident: IdentDef; 1738 colon, type: Node; lParenAlias: Terminal; 1739 aliasList: NodeList; 1740 rParenAlias: Terminal; rParen: Node): Node; 1741(**Receiver of the declaration of a type-bound procedure. 1742 1743 @table @oparam 1744 @item lParen 1745 The symbol @samp{(}, result of @oproc{Builder.Terminal}. 1746 1747 @item var 1748 The keyword @samp{VAR} (created by @oproc{Builder.Terminal}), or @code{NIL} 1749 if the receiver describes value parameter. 1750 1751 @item ident 1752 An identifier, created by @oproc{Builder.Terminal}. 1753 1754 @item colon 1755 The symbol @samp{:}, result of @oproc{Builder.Terminal}. 1756 1757 @item type 1758 A type name, result of @oproc{Builder.Terminal}. 1759 1760 @item lParenAlias 1761 If the receiver is for a parametric record type, this result of 1762 @oproc{Builder.Terminal} introduces the list of aliases for the type 1763 parameters. Otherwise, it is @code{NIL}. 1764 1765 @item aliasList 1766 List of @oproc{Builder.Terminal} values, even elements are identifiers, odd 1767 are @samp{,}. 1768 1769 @item rParenAlias 1770 End of the alias list, result of @oproc{Builder.Terminal}. 1771 1772 @item rParen 1773 The symbol @samp{)}, result of @oproc{Builder.Terminal}. 1774 @end table *) 1775 VAR 1776 r: Receiver; 1777 BEGIN 1778 NEW (r); 1779 r. lParen := lParen; 1780 r. var := var; 1781 r. ident := ident; 1782 r. colon := colon; 1783 r. type := type; 1784 r. lParenAlias := lParenAlias; 1785 r. aliasList := aliasList; 1786 r. rParenAlias := rParenAlias; 1787 r. rParen := rParen; 1788 RETURN r 1789 END Receiver; 1790 1791PROCEDURE (receiver: Receiver) Accept* (v: Visitor); 1792 BEGIN 1793 v. VisitReceiver (receiver) 1794 END Accept; 1795 1796 1797PROCEDURE (b: Builder) ProcDecl*(proc, arrow, receiver: Node; 1798 flags: Flags; 1799 identDef, formalPars, semicolon1: Node; 1800 body: Body; semicolon2: Node): Node; 1801(**Procedure declaration. 1802 1803 @table @oparam 1804 @item proc 1805 The keyword @samp{PROCEDURE}, result of @oproc{Builder.Terminal}. 1806 1807 @item arrow 1808 The symbol @samp{^}, result of @oproc{Builder.Terminal}, if this is a 1809 forward declaration, and @code{NIL} otherwise. 1810 1811 @item receiver 1812 An instance of @oproc{Builder.Receiver}, if this is a declaration of 1813 a type-bound procedure, and @code{NIL} otherwise. 1814 1815 @item flags 1816 ... 1817 1818 @item identDef 1819 The procedure name, optionally followed by an export mark. Result 1820 of @oproc{Builder.IdentDef}. 1821 1822 @item formalPars 1823 The formal parameters of the procedure. This value is created 1824 by @oproc{Builder.FormalPars}. It is never @code{NIL}. 1825 1826 @item semicolon1 1827 The symbol @samp{;}, result of @oproc{Builder.Terminal}. 1828 1829 @item body 1830 For a regular procedure declaration, this argument describes the 1831 procedure body. It is created by @oproc{Builder.Body}. For a forward 1832 declaration, or a procedure prototype, this argument is @code{NIL}. 1833 1834 @item semicolon2 1835 The symbol @samp{;}, result of @oproc{Builder.Terminal}. This argument 1836 is @code{NIL}, iff @oparam{body} is @code{NIL}.. 1837 @end table *) 1838 VAR 1839 pd: ProcDecl; 1840 BEGIN 1841 NEW (pd); 1842 pd. proc := proc(Terminal); 1843 pd. arrow := arrow; 1844 pd. receiver := receiver; 1845 pd. flags := flags; 1846 pd. identDef := identDef(IdentDef); 1847 pd. formalPars := formalPars; 1848 pd. semicolon1 := semicolon1; 1849 pd. body := body; 1850 pd. semicolon2 := semicolon2; 1851 RETURN pd 1852 END ProcDecl; 1853 1854PROCEDURE (procDecl: ProcDecl) Accept* (v: Visitor); 1855 BEGIN 1856 v. VisitProcDecl (procDecl) 1857 END Accept; 1858 1859 1860PROCEDURE (b: Builder) ImportList* (import: Node; 1861 imports: NodeList; semicolon: Node): Node; 1862(**List of import declarations. 1863 1864 @table @oparam 1865 @item import 1866 The keyword @samp{IMPORT} (created by @oproc{Builder.Terminal}). 1867 1868 @item imports 1869 A list of import declarations, separated by commas. 1870 1871 @table @samp 1872 @item identList MOD 2 == 0 1873 An import declaration, result of @oproc{Builder.ImportDecl}. 1874 @item identList MOD 2 == 1 1875 The symbol @samp{,}, result of @oproc{Builder.Terminal}. 1876 @end table 1877 1878 @item semicolon 1879 The symbol @samp{;}, result of @oproc{Builder.Terminal}. 1880 @end table *) 1881 VAR 1882 il: ImportList; 1883 BEGIN 1884 NEW (il); 1885 il. import := import; 1886 il. imports := imports; 1887 il. semicolon := semicolon; 1888 RETURN il 1889 END ImportList; 1890 1891PROCEDURE (importList: ImportList) Accept* (v: Visitor); 1892 BEGIN 1893 v. VisitImportList (importList) 1894 END Accept; 1895 1896 1897PROCEDURE (b: Builder) Body* (declSeq: NodeList; 1898 begin: Node; statmSeq: NodeList; 1899 end, name: Node): Body; 1900(**Module or procedure body. 1901 1902 @table @oparam 1903 @item declSeq 1904 A list of constant, type, variable, or procedure declarations, with an 1905 occasional keyword in between. The keywords @samp{CONST}, @samp{TYPE}, 1906 and @samp{VAR} appear as part of this list, and @emph{not} as part of 1907 any declarations. 1908 1909 This list can contain instances created by these factory methods: 1910 1911 @itemize @bullet 1912 @item @oproc{Builder.Terminal} 1913 @item @oproc{Builder.ConstDecl} 1914 @item @oproc{Builder.TypeDecl} 1915 @item @oproc{Builder.VarDecl} 1916 @item @oproc{Builder.ProcDecl} 1917 @end itemize 1918 1919 @item begin 1920 The keyword @samp{BEGIN}, result of @oproc{Builder.Terminal}. If 1921 the body contains no statements, this keyword is optional and can 1922 be @code{NIL}. 1923 1924 @item statmSeq 1925 A list of statements. If there is no @samp{BEGIN} keyword, this 1926 argument is @code{NIL}. 1927 1928 @table @samp 1929 @item identList MOD 2 == 0 1930 A statement, or @code{NIL}. 1931 @item identList MOD 2 == 1 1932 The symbol @samp{;}, result of @oproc{Builder.Terminal}. 1933 @end table 1934 1935 @item begin 1936 The keyword @samp{END}, result of @oproc{Builder.Terminal}. 1937 1938 @item name 1939 The name of the module or procedure. This is an instance of 1940 @oproc{Builder.ModuleIdent}. Note that the parser checks 1941 if the name of the body matches that of the module or procedure. 1942 @end table *) 1943 VAR 1944 body: Body; 1945 BEGIN 1946 NEW (body); 1947 body. declSeq := declSeq; 1948 body. begin := begin; 1949 body. statmSeq := statmSeq; 1950 body. end := end(Terminal); 1951 body. name := name; 1952 RETURN body 1953 END Body; 1954 1955PROCEDURE (body: Body) Accept* (v: Visitor); 1956 BEGIN 1957 v. VisitBody (body) 1958 END Accept; 1959 1960 1961PROCEDURE (b: Builder) Module* (module: Terminal; name: Node; 1962 flags: Flags; semicolon, importList: Node; 1963 body: Body; period: Node; 1964 moduleName: Name): Node; 1965(**Module declaration. 1966 1967 @table @oparam 1968 @item module 1969 The keyword @samp{MODULE}, result of @oproc{Builder.Terminal}. 1970 1971 @item name 1972 The name of the module, result of @oproc{Builder.ModuleIdent}. 1973 1974 @item flags 1975 Either the result of @oproc{Builder.ModuleFlags} (for @samp{FOREIGN} and 1976 @samp{INTERFACE} modules) or a list of flags. 1977 1978 @item semicolon 1979 The symbol @samp{;}, result of @oproc{Builder.Terminal}. 1980 1981 @item importList 1982 An object create by @oproc{Builder.ImportList}, or @code{NIL} if the 1983 module has no imports. 1984 1985 @item body 1986 The module body, result of @oproc{Builder.Body}. 1987 1988 @item period 1989 The symbol @samp{.}, result of @oproc{Builder.Terminal}. 1990 1991 @item moduleName 1992 The textual representation of the module name. Contrary to @oparam{name}, 1993 this is a single string. It is the concatenation of all of the symbols in 1994 @oparam{name}. 1995 @end table *) 1996 VAR 1997 m: Module; 1998 BEGIN 1999 NEW (m); 2000 m. module := module; 2001 m. name := name(ModuleIdent); 2002 m. flags := flags; 2003 m. semicolon := semicolon; 2004 m. importList := importList; 2005 m. body := body; 2006 m. period := period; 2007 m. moduleName := moduleName; 2008 RETURN m 2009 END Module; 2010 2011PROCEDURE (module: Module) Accept* (v: Visitor); 2012 BEGIN 2013 v. VisitModule (module) 2014 END Accept; 2015 2016 2017 2018PROCEDURE (b: Builder) Operator* (left, op, right: Node): Node; 2019(**This factory method covers all monadic and dyadic operators. Please note 2020 that this also includes the operators of the rules @samp{Qualident}, 2021 @samp{Designator}, and @samp{Assignment}. 2022 2023 @table @oparam 2024 @item left 2025 The left operand, an arbitrary expression. For monadic prefix operators, 2026 like @samp{+a} or @samp{~a}, this argument is @code{NIL}. 2027 2028 @item op 2029 The operator symbol, result of @oproc{Builder.Terminal}. 2030 2031 @item right 2032 The right operand, an arbitrary expression. For monadic prefix operators, 2033 like @samp{a^}, this argument is @code{NIL}. 2034 @end table *) 2035 VAR 2036 o: Operator; 2037 BEGIN 2038 NEW (o); 2039 IF (left = NIL) THEN 2040 o. left := NIL 2041 ELSE 2042 o. left := left 2043 END; 2044 o. op := op(Terminal); 2045 IF (right = NIL) THEN 2046 o. right := NIL 2047 ELSE 2048 o. right := right 2049 END; 2050 RETURN o 2051 END Operator; 2052 2053PROCEDURE (operator: Operator) Accept* (v: Visitor); 2054 BEGIN 2055 v. VisitOperator (operator) 2056 END Accept; 2057 2058 2059PROCEDURE (b: Builder) Factor* (lParen, expr, rParen: Node): Node; 2060(**As far as the abstract syntax tree is concerned, a @samp{Factor} is 2061 a parenthised expression. All other @samp{Factor} variants of the syntax 2062 are covered by other factory methods. 2063 2064 @table @oparam 2065 @item lParen 2066 Left parenthesis, result of @oproc{Builder.Terminal}. 2067 2068 @item expr 2069 An expression. 2070 2071 @item rParen 2072 Right parenthesis, result of @oproc{Builder.Terminal}. 2073 @end table *) 2074 VAR 2075 f: Factor; 2076 BEGIN 2077 NEW (f); 2078 f. lParen := lParen(Terminal); 2079 f. expr := expr; 2080 f. rParen := rParen(Terminal); 2081 RETURN f 2082 END Factor; 2083 2084PROCEDURE (factor: Factor) Accept* (v: Visitor); 2085 BEGIN 2086 v. VisitFactor (factor) 2087 END Accept; 2088 2089 2090PROCEDURE (b: Builder) Set* (type, lBrace: Node; elementList: NodeList; rBrace: Node): Node; 2091(**Set constructor. 2092 2093 @table @oparam 2094 @item type 2095 The optional type designator. For the standard Oberon-2set constructor, 2096 this argument is @code{NIL}. 2097 2098 @item lBrace 2099 Left brace @samp{@{}, result of @oproc{Builder.Terminal}. 2100 2101 @item elementList 2102 A list of set elements, separated by commas. 2103 2104 @table @samp 2105 @item identList MOD 2 == 0 2106 A set element. This is either an expression denoting a single set element, 2107 or an operator of type @oconst{Symbol.upto}, denoting a range of set 2108 elements. 2109 2110 @item identList MOD 2 == 1 2111 The symbol @samp{,}, result of @oproc{Builder.Terminal}. 2112 @end table 2113 2114 @item rBrace 2115 Right brace @samp{@}}, result of @oproc{Builder.Terminal}. 2116 @end table *) 2117 VAR 2118 s: Set; 2119 BEGIN 2120 NEW (s); 2121 s. type := type; 2122 s. lBrace := lBrace(Terminal); 2123 s. elementList := elementList; 2124 s. rBrace := rBrace(Terminal); 2125 RETURN s 2126 END Set; 2127 2128PROCEDURE (set: Set) Accept* (v: Visitor); 2129 BEGIN 2130 v. VisitSet (set) 2131 END Accept; 2132 2133 2134PROCEDURE (b: Builder) ArrayIndex* (design, lBrak: Node; indices: NodeList; rBrak: Node): Node; 2135(**Element selector on array value. 2136 2137 @table @oparam 2138 @item design 2139 The array designator. 2140 2141 @item lBrak 2142 Left brace @samp{[}, result of @oproc{Builder.Terminal}. 2143 2144 @item indices 2145 A list of array indices, separated by commas. 2146 2147 @table @samp 2148 @item identList MOD 2 == 0 2149 An integer expression. 2150 2151 @item identList MOD 2 == 1 2152 The symbol @samp{,}, result of @oproc{Builder.Terminal}. 2153 @end table 2154 2155 @item rBrak 2156 Right brace @samp{]}, result of @oproc{Builder.Terminal}. 2157 @end table *) 2158 VAR 2159 ai: ArrayIndex; 2160 BEGIN 2161 NEW (ai); 2162 ai. design := design; 2163 ai. lBrak := lBrak(Terminal); 2164 ai. indices := indices; 2165 ai. rBrak := rBrak(Terminal); 2166 RETURN ai 2167 END ArrayIndex; 2168 2169PROCEDURE (arrayIndex: ArrayIndex) Accept* (v: Visitor); 2170 BEGIN 2171 v. VisitArrayIndex (arrayIndex) 2172 END Accept; 2173 2174 2175PROCEDURE (b: Builder) FunctionCall* (design, lParen: Node; arguments: NodeList; rParen: Node): Node; 2176(**Function call, procedure call, or type guard. In the general case, the 2177 parser cannot detect, whether parenthesis within a designator is a function 2178 call, or a type guard. For this reason, it treats a type guard as a kind of 2179 generalized function call and handles all function (and procedure) calls as 2180 part of the designator rule. 2181 2182 @table @oparam 2183 @item design 2184 The function designator. 2185 2186 @item lParen 2187 Left argument parenthesis @samp{(}, result of @oproc{Builder.Terminal}. 2188 2189 @item arguments 2190 A list of function arguments, separated by commas. 2191 2192 @table @samp 2193 @item identList MOD 2 == 0 2194 An expression. 2195 2196 @item identList MOD 2 == 1 2197 The symbol @samp{,}, result of @oproc{Builder.Terminal}. 2198 @end table 2199 2200 @item rParen 2201 Right arguments parenthesis @samp{)}, result of @oproc{Builder.Terminal}. 2202 @end table *) 2203 VAR 2204 fc: FunctionCall; 2205 BEGIN 2206 NEW (fc); 2207 fc. design := design; 2208 fc. lParen := lParen(Terminal); 2209 fc. arguments := arguments; 2210 fc. rParen := rParen(Terminal); 2211 RETURN fc 2212 END FunctionCall; 2213 2214PROCEDURE (functionCall: FunctionCall) Accept* (v: Visitor); 2215 BEGIN 2216 v. VisitFunctionCall (functionCall) 2217 END Accept; 2218 2219 2220PROCEDURE (b: Builder) Assignment* (assignment: Node): Node; 2221(**Value assignment. This factory method is called if the statement begins 2222 with a designator, and is followed by a an assignment operator @samp{:=}. 2223 2224 @table @oparam 2225 @item assignment 2226 An assignment operation, that is, an expression whose top node is 2227 the operator @samp{:=}. 2228 @end table *) 2229 VAR 2230 a: Assignment; 2231 BEGIN 2232 NEW (a); 2233 a. assignment := assignment(Operator); 2234 RETURN a 2235 END Assignment; 2236 2237PROCEDURE (assignment: Assignment) Accept* (v: Visitor); 2238 BEGIN 2239 v. VisitAssignment (assignment) 2240 END Accept; 2241 2242 2243PROCEDURE (b: Builder) ProcedureCall* (call: Node): Node; 2244(**Procedure call. This factory method is called if the statement begins 2245 with a designator, but is not followed by a an assignment operator 2246 @samp{:=}. 2247 2248 @table @oparam 2249 @item call 2250 A designator. If @oparam{call} is already an instance of 2251 @oproc{Builder.FunctionCall}, then the additional procedure call 2252 wrapper is redundant and @emph{must} be ignored. 2253 @end table *) 2254 VAR 2255 p: ProcedureCall; 2256 BEGIN 2257 NEW (p); 2258 p. call := call; 2259 RETURN p 2260 END ProcedureCall; 2261 2262PROCEDURE (procedureCall: ProcedureCall) Accept* (v: Visitor); 2263 BEGIN 2264 v. VisitProcedureCall (procedureCall) 2265 END Accept; 2266 2267 2268PROCEDURE (b: Builder) IfStatm* (guardList: NodeList; else: Node; elseStatmSeq: NodeList; end: Node): Node; 2269(**Conditional statement. 2270 2271 @table @oparam 2272 @item guardList 2273 This is the list of all guarded commands. It is a sequence of keywords, 2274 boolean expressions, and statement sequences. 2275 2276 @table @samp 2277 @item guardList MOD 4 == 0 2278 Either the keyword @samp{IF}, for the very first guarded command, and 2279 the keyword @samp{ELSIF} for any further guarded command. 2280 2281 @item guardList MOD 4 == 1 2282 A boolean expression. 2283 2284 @item guardList MOD 4 == 2 2285 The keyword @samp{THEN}. 2286 2287 @item guardList MOD 4 == 3 2288 The statement sequence of the guarded command. 2289 @end table 2290 2291 @item else 2292 The keyword @samp{ELSE}, result of @oproc{Builder.Terminal}, or @code{NIL} 2293 if the statement does not include an @code{ELSE} part. 2294 2295 @item elseStatmSeq 2296 The statement sequence of the optional @code{ELSE} part. This argument 2297 is @code{NIL}, iff @oparam{else} is @code{NIL}. 2298 2299 @item end 2300 The keyword @samp{END}, result of @oproc{Builder.Terminal} 2301 @end table *) 2302 VAR 2303 i: IfStatm; 2304 BEGIN 2305 NEW (i); 2306 i. guardList := guardList; 2307 i. else := else; 2308 IF (elseStatmSeq # NIL) THEN 2309 i. elseStatmSeq := elseStatmSeq; 2310 ELSE 2311 i. elseStatmSeq := NIL; 2312 END; 2313 i. end := end; 2314 RETURN i 2315 END IfStatm; 2316 2317PROCEDURE (ifStatm: IfStatm) Accept* (v: Visitor); 2318 BEGIN 2319 v. VisitIfStatm (ifStatm) 2320 END Accept; 2321 2322 2323PROCEDURE (b: Builder) CaseStatm* (case, expr, of: Node; caseList: NodeList; else: Node; elseStatmSeq: NodeList; end: Node): Node; 2324(**Case statement. 2325 2326 @table @oparam 2327 @item case 2328 The keyword @samp{CASE}. 2329 2330 @item expr 2331 The selection expression of the statement. 2332 2333 @item of 2334 The keyword @samp{OF}. 2335 2336 @item caseList 2337 This is the list of all branches of the @code{CASE} statement. 2338 It is a sequence of instances of lists of case labels, colons, 2339 statements sequences, and separator symbols @samp{|}. 2340 2341 @table @samp 2342 @item caseList MOD 4 == 0 2343 Either a list of case labels, or @code{NIL} if the branch 2344 is completely empty. 2345 2346 @table @samp 2347 @item labelList MOD 2 == 0 2348 An expression, possibly an operator of the class @oconst{Symbol.upto}. 2349 2350 @item labelList MOD 2 == 1 2351 The symbol @samp{,}. 2352 @end table 2353 2354 @item caseList MOD 4 == 1 2355 The symbol @samp{:}, or @code{NIL} if the branch is empty. 2356 2357 @item caseList MOD 4 == 2 2358 The statement sequence of the @code{CASE} branch, or @code{NIL} 2359 if the branch is completely empty. 2360 2361 @item caseList MOD 4 == 3 2362 The symbol @samp{|}, or @code{NIL} if no further case branches 2363 follow. 2364 @end table 2365 2366 @item else 2367 The keyword @samp{ELSE}, result of @oproc{Builder.Terminal}, or @code{NIL} 2368 if the statement does not include an @code{ELSE} part. 2369 2370 @item elseStatmSeq 2371 The statement sequence of the optional @code{ELSE} part. This argument 2372 is @code{NIL}, iff @oparam{else} is @code{NIL}. 2373 2374 @item end 2375 The keyword @samp{END}, result of @oproc{Builder.Terminal} 2376 @end table *) 2377 VAR 2378 c: CaseStatm; 2379 BEGIN 2380 NEW (c); 2381 c. case := case(Terminal); 2382 c. expr := expr; 2383 c. of := of; 2384 c. caseList := caseList; 2385 c. else := else; 2386 IF (elseStatmSeq = NIL) THEN 2387 c. elseStatmSeq := NIL; 2388 ELSE 2389 c. elseStatmSeq := elseStatmSeq; 2390 END; 2391 c. end := end; 2392 RETURN c 2393 END CaseStatm; 2394 2395PROCEDURE (caseStatm: CaseStatm) Accept* (v: Visitor); 2396 BEGIN 2397 v. VisitCaseStatm (caseStatm) 2398 END Accept; 2399 2400 2401PROCEDURE (b: Builder) WhileStatm* (while, guard, do: Node; statmSeq: NodeList; end: Node): Node; 2402(**@code{WHILE} loop. 2403 2404 @table @oparam 2405 @item while 2406 The keyword @samp{WHILE}. 2407 2408 @item guard 2409 A boolean expression. 2410 2411 @item do 2412 The keyword @samp{DO}. 2413 2414 @item statmSeq 2415 The statement sequence of the loop. 2416 2417 @item end 2418 The keyword @samp{END}. 2419 @end table *) 2420 VAR 2421 w: WhileStatm; 2422 BEGIN 2423 NEW (w); 2424 w. while := while(Terminal); 2425 w. guard := guard; 2426 w. do := do(Terminal); 2427 w. statmSeq := statmSeq; 2428 w. end := end(Terminal); 2429 RETURN w 2430 END WhileStatm; 2431 2432PROCEDURE (whileStatm: WhileStatm) Accept* (v: Visitor); 2433 BEGIN 2434 v. VisitWhileStatm (whileStatm) 2435 END Accept; 2436 2437 2438PROCEDURE (b: Builder) RepeatStatm* (repeat: Node; statmSeq: NodeList; until, expr: Node): Node; 2439(**@code{REPEAT} loop. 2440 2441 @table @oparam 2442 @item repeat 2443 The keyword @samp{REPEAT}. 2444 2445 @item statmSeq 2446 The statement sequence of the loop. 2447 2448 @item until 2449 The keyword @samp{UNTIL}. 2450 2451 @item expr 2452 A boolean expression. 2453 @end table *) 2454 VAR 2455 r: RepeatStatm; 2456 BEGIN 2457 NEW (r); 2458 r. repeat := repeat(Terminal); 2459 r. statmSeq := statmSeq; 2460 r. until := until(Terminal); 2461 r. expr := expr; 2462 RETURN r 2463 END RepeatStatm; 2464 2465PROCEDURE (repeatStatm: RepeatStatm) Accept* (v: Visitor); 2466 BEGIN 2467 v. VisitRepeatStatm (repeatStatm) 2468 END Accept; 2469 2470 2471PROCEDURE (b: Builder) ForStatm* (for, ident, becomes, startValue, to, endValue, by, step, do: Node; statmSeq: NodeList; end: Node): Node; 2472(**@code{FOR} loop. 2473 2474 @table @oparam 2475 @item for 2476 The keyword @samp{FOR}. 2477 2478 @item ident 2479 A variable identifier, result of @oproc{Builder.Terminal}. 2480 2481 @item becomes 2482 The symbol @samp{:=}. 2483 2484 @item startValue 2485 An expression. 2486 2487 @item to 2488 The keyword @samp{TO}. 2489 2490 @item endValue 2491 An expression. 2492 2493 @item by 2494 The keyword @samp{BY}. This argument is @code{NIL}, if the loop 2495 does not include a step clause. 2496 2497 @item step 2498 An expression. This argument is @code{NIL}, iff @oparam{by} is @code{NIL}. 2499 2500 @item do 2501 The keyword @samp{DO}. 2502 2503 @item statmSeq 2504 The statement sequence of the loop. 2505 2506 @item end 2507 The keyword @samp{END}. 2508 @end table *) 2509 VAR 2510 f: ForStatm; 2511 BEGIN 2512 NEW (f); 2513 f. for := for(Terminal); 2514 f. ident := ident; 2515 f. becomes := becomes(Terminal); 2516 f. startValue := startValue; 2517 f. to := to(Terminal); 2518 f. endValue := endValue; 2519 IF (step = NIL) THEN 2520 f. by := NIL; 2521 f. step := NIL; 2522 ELSE 2523 f. by := by(Terminal); 2524 f. step := step; 2525 END; 2526 f. do := do(Terminal); 2527 f. statmSeq := statmSeq; 2528 f. end := end(Terminal); 2529 RETURN f 2530 END ForStatm; 2531 2532PROCEDURE (forStatm: ForStatm) Accept* (v: Visitor); 2533 BEGIN 2534 v. VisitForStatm (forStatm) 2535 END Accept; 2536 2537 2538PROCEDURE (b: Builder) IterateStatm* (for, ident, in, range, do: Node; statmSeq: NodeList; end: Node): Node; 2539(**@code{FOR} loop. 2540 2541 @table @oparam 2542 @item for 2543 The keyword @samp{FOR}. 2544 2545 @item ident 2546 A variable identifier, result of @oproc{Builder.Terminal}. 2547 2548 @item in 2549 The symbol @samp{IN}. 2550 2551 @item range 2552 An expression. 2553 2554 @item do 2555 The keyword @samp{DO}. 2556 2557 @item statmSeq 2558 The statement sequence of the loop. 2559 2560 @item end 2561 The keyword @samp{END}. 2562 @end table *) 2563 VAR 2564 f: IterateStatm; 2565 BEGIN 2566 NEW (f); 2567 f. for := for(Terminal); 2568 f. ident := ident; 2569 f. in := in(Terminal); 2570 f. range := range; 2571 f. do := do(Terminal); 2572 f. statmSeq := statmSeq; 2573 f. end := end(Terminal); 2574 RETURN f 2575 END IterateStatm; 2576 2577PROCEDURE (iterStatm: IterateStatm) Accept* (v: Visitor); 2578 BEGIN 2579 v. VisitIterateStatm (iterStatm) 2580 END Accept; 2581 2582 2583PROCEDURE (b: Builder) LoopStatm* (loop: Node; statmSeq: NodeList; end: Node): Node; 2584(**The generic loop. 2585 2586 @table @oparam 2587 @item loop 2588 The keyword @samp{LOOP}. 2589 2590 @item statmSeq 2591 The statement sequence of the loop. 2592 2593 @item end 2594 The keyword @samp{END}. 2595 @end table *) 2596 VAR 2597 l: LoopStatm; 2598 BEGIN 2599 NEW (l); 2600 l. loop := loop(Terminal); 2601 l. statmSeq := statmSeq; 2602 l. end := end(Terminal); 2603 RETURN l 2604 END LoopStatm; 2605 2606PROCEDURE (loopStatm: LoopStatm) Accept* (v: Visitor); 2607 BEGIN 2608 v. VisitLoopStatm (loopStatm) 2609 END Accept; 2610 2611 2612PROCEDURE (b: Builder) WithStatm* (guardList: NodeList; else: Node; elseStatmSeq: NodeList; end: Node): Node; 2613(**Regional type guard. 2614 2615 @table @oparam 2616 @item guardList 2617 This is the list of all guarded commands. It is a sequence of keywords, 2618 type guard expressions, and statement sequences. 2619 2620 @table @samp 2621 @item guardList MOD 4 == 0 2622 Either the keyword @samp{WITH}, for the very first guarded command, and 2623 the symbol @samp{|} for any further guarded command. 2624 2625 @item guardList MOD 4 == 1 2626 A type guard expression, an operator of class @oconst{Symbol.colon}. 2627 2628 @item guardList MOD 4 == 2 2629 The keyword @samp{DO}. 2630 2631 @item guardList MOD 4 == 3 2632 The statement sequence of the guarded command. 2633 @end table 2634 2635 @item else 2636 The keyword @samp{ELSE}, result of @oproc{Builder.Terminal}, or @code{NIL} 2637 if the statement does not include an @code{ELSE} part. 2638 2639 @item elseStatmSeq 2640 The statement sequence of the optional @code{ELSE} part. This argument 2641 is @code{NIL}, iff @oparam{else} is @code{NIL}. 2642 2643 @item end 2644 The keyword @samp{END}, result of @oproc{Builder.Terminal} 2645 @end table *) 2646 VAR 2647 w: WithStatm; 2648 BEGIN 2649 NEW (w); 2650 w. guardList := guardList; 2651 w. else := else; 2652 IF (elseStatmSeq # NIL) THEN 2653 w. elseStatmSeq := elseStatmSeq; 2654 ELSE 2655 w. elseStatmSeq := NIL; 2656 END; 2657 w. end := end; 2658 RETURN w 2659 END WithStatm; 2660 2661PROCEDURE (withStatm: WithStatm) Accept* (v: Visitor); 2662 BEGIN 2663 v. VisitWithStatm (withStatm) 2664 END Accept; 2665 2666 2667PROCEDURE (b: Builder) ExitStatm* (exit: Node): Node; 2668(**@code{EXIT} statement. 2669 2670 @table @oparam 2671 @item exit 2672 The keyword @samp{EXIT}. 2673 @end table *) 2674 VAR 2675 e: ExitStatm; 2676 BEGIN 2677 NEW (e); 2678 e. exit := exit(Terminal); 2679 RETURN e 2680 END ExitStatm; 2681 2682PROCEDURE (exitStatm: ExitStatm) Accept* (v: Visitor); 2683 BEGIN 2684 v. VisitExitStatm (exitStatm) 2685 END Accept; 2686 2687 2688PROCEDURE (b: Builder) ReturnStatm* (return, expr: Node): Node; 2689(**@code{RETURN} statement. 2690 2691 @table @oparam 2692 @item return 2693 The keyword @samp{RETURN}. 2694 2695 @item expr 2696 An expression. This argument is @code{NIL}, if the return statement 2697 does not include a function result. 2698 @end table *) 2699 VAR 2700 r: ReturnStatm; 2701 BEGIN 2702 NEW (r); 2703 r. return := return(Terminal); 2704 r. expr := expr; 2705 RETURN r 2706 END ReturnStatm; 2707 2708PROCEDURE (returnStatm: ReturnStatm) Accept* (v: Visitor); 2709 BEGIN 2710 v. VisitReturnStatm (returnStatm) 2711 END Accept; 2712 2713 2714PROCEDURE (b: Builder) Catch*(catch, type, lParen, ident, rParen, 2715 colon: Node; statmSeq: NodeList): Node; 2716(**Catch clause of a @code{TRY} statement. 2717 2718 @table @oparam 2719 @item catch 2720 The keyword @samp{CATCH}. 2721 2722 @item type 2723 A type name, matching the rule of @samp{Qualident}. 2724 2725 @item lParen 2726 The terminal symbol @samp{(}, or @code{NIL}. 2727 2728 @item ident 2729 The optional exception name. 2730 2731 @item rParen 2732 The terminal symbol @samp{)}, or @code{NIL}. 2733 2734 @item colon 2735 The terminal symbol @samp{:}, or @code{NIL}. 2736 2737 @item statmSeq 2738 The statement sequence of the catch block. 2739 @end table *) 2740 VAR 2741 c: Catch; 2742 BEGIN 2743 NEW(c); 2744 c.catch := catch(Terminal); 2745 c.type := type; 2746 c.lParen := lParen; 2747 IF (ident = NIL) THEN 2748 c.ident := NIL; 2749 ELSE 2750 c.ident := ident(Terminal); 2751 END; 2752 c.rParen := rParen; 2753 c.colon := colon; 2754 c.statmSeq := statmSeq; 2755 RETURN c; 2756 END Catch; 2757 2758PROCEDURE (catch: Catch) Accept* (v: Visitor); 2759 BEGIN 2760 v. VisitCatch (catch) 2761 END Accept; 2762 2763PROCEDURE (b: Builder) TryStatm* (try: Node; statmSeq: NodeList; 2764 catchList: NodeList; end: Node): Node; 2765(**Exception handler statement. 2766 2767 @table @oparam 2768 @item try 2769 The keyword @samp{TRY}, result of @oproc{Builder.Terminal}. 2770 2771 @item statmSeq 2772 The statement sequence of the @samp{TRY}'s body. 2773 2774 @item catchList 2775 This is the list of all catch blocks. It is a sequence of nodes 2776 produced by @oproc{Builder.Catch}. 2777 2778 @item end 2779 The keyword @samp{END}, result of @oproc{Builder.Terminal} 2780 @end table *) 2781 VAR 2782 t: TryStatm; 2783 BEGIN 2784 NEW (t); 2785 t.try := try(Terminal); 2786 t.statmSeq := statmSeq; 2787 t.catchList := catchList; 2788 t.end := end(Terminal); 2789 RETURN t; 2790 END TryStatm; 2791 2792PROCEDURE (tryStatm: TryStatm) Accept* (v: Visitor); 2793 BEGIN 2794 v. VisitTryStatm (tryStatm) 2795 END Accept; 2796 2797 2798 2799PROCEDURE (b: Builder) Flags* (context: SHORTINT; lBrak: Node; 2800 flagList: NodeList; rBrak: Node): Flags; 2801 VAR 2802 f: Flags; 2803 BEGIN 2804 NEW (f); 2805 f. context := context; 2806 f. lBrak := lBrak; 2807 f. flagList := flagList; 2808 f. rBrak := rBrak; 2809 RETURN f 2810 END Flags; 2811 2812PROCEDURE (b: Builder) ProcWithoutBody* (moduleFlags, procFlags: Node): BOOLEAN; 2813(**This predicate determines, if a procedure declaration without a forward 2814 flag has a procedure body. For declarations in a normal body, it returns 2815 always @code{FALSE}. For a procedure declaration in an @samp{INTERFACE} or 2816 @samp{FOREIGN} module, the result depends on the presence of the 2817 @samp{HAS_BODY} flag. *) 2818 VAR 2819 i: LONGINT; 2820 n: Node; 2821 BEGIN 2822 IF (moduleFlags # NIL) & 2823 ~(moduleFlags(Flags). flagList. n[0] IS Terminal) THEN 2824 (* module flags exist, and the flag list does not start with 2825 OOC_EXTENSIONS: assume INTERFACE or FOREIGN module *) 2826 IF (procFlags # NIL) THEN (* search for HAS_BODY flag *) 2827 i := 0; 2828 WHILE (i < procFlags(Flags). flagList. len) DO 2829 n := procFlags(Flags). flagList. n[i]; 2830 IF (n IS Terminal) & (n(Terminal). sym. str^ = "HAS_BODY") THEN 2831 RETURN FALSE 2832 END; 2833 INC (i, 2) 2834 END 2835 END; 2836 RETURN TRUE 2837 ELSE 2838 RETURN FALSE 2839 END 2840 END ProcWithoutBody; 2841 2842 2843PROCEDURE (flags: Flags) Accept* (v: Visitor); 2844 BEGIN 2845 v. VisitFlags (flags) 2846 END Accept; 2847 2848 2849PROCEDURE (b: Builder) ProcIdFlag* (procId, equal, number: Node): Node; 2850 VAR 2851 pid: ProcIdFlag; 2852 BEGIN 2853 NEW (pid); 2854 pid. procId := procId; 2855 pid. equal := equal; 2856 pid. number := number; 2857 RETURN pid 2858 END ProcIdFlag; 2859 2860PROCEDURE (procIdFlag: ProcIdFlag) Accept* (v: Visitor); 2861 BEGIN 2862 v. VisitProcIdFlag (procIdFlag) 2863 END Accept; 2864 2865 2866PROCEDURE (b: Builder) ModuleFlags* ( 2867 external, callConv: Node; moduleFlags: NodeList; 2868 semicolon, link: Node; 2869 linkSections: NodeList; end: Node): Node; 2870 VAR 2871 mf: ModuleFlags; 2872 BEGIN 2873 NEW (mf); 2874 mf. external := external(Terminal); 2875 mf. callConv := callConv(Terminal); 2876 mf. moduleFlags := moduleFlags; 2877 mf. semicolon := semicolon; 2878 mf. link := link; 2879 mf. linkSections := linkSections; 2880 mf. end := end; 2881 RETURN mf 2882 END ModuleFlags; 2883 2884PROCEDURE (moduleFlags: ModuleFlags) Accept* (v: Visitor); 2885 BEGIN 2886 v. VisitModuleFlags (moduleFlags) 2887 END Accept; 2888 2889 2890PROCEDURE (b: Builder) LinkFileFlag* (file, fileName, addOption, prefixOpt, comma, suffixOpt: Node): Node; 2891 VAR 2892 lff: LinkFileFlag; 2893 BEGIN 2894 NEW (lff); 2895 lff. file := file; 2896 lff. fileName := fileName(Terminal); 2897 lff. addOption := addOption; 2898 IF (prefixOpt = NIL) THEN 2899 lff. prefixOpt := NIL 2900 ELSE 2901 lff. prefixOpt := prefixOpt(Terminal) 2902 END; 2903 lff. comma := comma; 2904 IF (suffixOpt = NIL) THEN 2905 lff. suffixOpt := NIL 2906 ELSE 2907 lff. suffixOpt := suffixOpt(Terminal) 2908 END; 2909 RETURN lff 2910 END LinkFileFlag; 2911 2912PROCEDURE (linkFileFlag: LinkFileFlag) Accept* (v: Visitor); 2913 BEGIN 2914 v. VisitLinkFileFlag (linkFileFlag) 2915 END Accept; 2916 2917 2918PROCEDURE (b: Builder) LinkObjFlag* (obj, fileName: Node): Node; 2919 VAR 2920 lof: LinkObjFlag; 2921 BEGIN 2922 NEW (lof); 2923 lof. obj := obj; 2924 lof. fileName := fileName; 2925 RETURN lof 2926 END LinkObjFlag; 2927 2928PROCEDURE (linkObjFlag: LinkObjFlag) Accept* (v: Visitor); 2929 BEGIN 2930 v. VisitLinkObjFlag (linkObjFlag) 2931 END Accept; 2932 2933 2934PROCEDURE (b: Builder) LinkLibFlag* (lib, libName, lParen: Node; 2935 dependencies: NodeList; 2936 rParen, addOption, prefixOpt, comma, suffixOpt: Node): Node; 2937 VAR 2938 llf: LinkLibFlag; 2939 BEGIN 2940 NEW (llf); 2941 llf. lib := lib; 2942 llf. libName := libName(Terminal); 2943 llf. lParen := lParen; 2944 IF (dependencies = NIL) THEN 2945 llf. dependencies := NIL; 2946 ELSE 2947 llf. dependencies := dependencies; 2948 END; 2949 llf. rParen := rParen; 2950 llf. addOption := addOption; 2951 IF (prefixOpt = NIL) THEN 2952 llf. prefixOpt := NIL 2953 ELSE 2954 llf. prefixOpt := prefixOpt(Terminal) 2955 END; 2956 llf. comma := comma; 2957 IF (suffixOpt = NIL) THEN 2958 llf. suffixOpt := NIL 2959 ELSE 2960 llf. suffixOpt := suffixOpt(Terminal) 2961 END; 2962 RETURN llf 2963 END LinkLibFlag; 2964 2965PROCEDURE (linkLibFlag: LinkLibFlag) Accept* (v: Visitor); 2966 BEGIN 2967 v. VisitLinkLibFlag (linkLibFlag) 2968 END Accept; 2969 2970END OOC:AST. 2971