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