2 -- m2-c.bnf grammar and associated actions for pass C.
4 -- Copyright (C) 2001-2022 Free Software Foundation, Inc.
5 -- Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
7 -- This file is part of GNU Modula-2.
9 -- GNU Modula-2 is free software; you can redistribute it and/or modify
10 -- it under the terms of the GNU General Public License as published by
11 -- the Free Software Foundation; either version 3, or (at your option)
14 -- GNU Modula-2 is distributed in the hope that it will be useful, but
15 -- WITHOUT ANY WARRANTY; without even the implied warranty of
16 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 -- General Public License for more details.
19 -- You should have received a copy of the GNU General Public License
20 -- along with GNU Modula-2; see the file COPYING3. If not see
21 -- <http://www.gnu.org/licenses/>.
22 % module PCBuild begin
23 (* output from m2-c.bnf, automatically generated do not edit if these
24 are the top two lines in the file.
26 Copyright (C) 2001-2022 Free Software Foundation, Inc.
27 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
29 This file is part of GNU Modula-2.
31 GNU Modula-2 is free software; you can redistribute it and/or modify
32 it under the terms of the GNU General Public License as published by
33 the Free Software Foundation; either version 3, or (at your option)
36 GNU Modula-2 is distributed in the hope that it will be useful, but
37 WITHOUT ANY WARRANTY; without even the implied warranty of
38 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
39 General Public License for more details.
41 You should have received a copy of the GNU General Public License
42 along with GNU Modula-2; see the file COPYING. If not,
43 see <https://www.gnu.org/licenses/>. *)
45 IMPLEMENTATION MODULE PCBuild ;
47 FROM M2LexBuf IMPORT currentstring, currenttoken, GetToken, InsertToken,
48 InsertTokenAndRewind, GetTokenNo, MakeVirtualTok ;
50 FROM M2Error IMPORT ErrorStringAt, WriteFormat1, WriteFormat2 ;
51 FROM NameKey IMPORT NulName, Name, makekey ;
52 FROM DynamicStrings IMPORT String, InitString, KillString, Mark, ConCat, ConCatChar ;
53 FROM M2Printf IMPORT printf0 ;
54 FROM M2Debug IMPORT Assert ;
55 FROM P2SymBuild IMPORT BuildString, BuildNumber ;
57 FROM M2Reserved IMPORT tokToTok, toktype,
58 NulTok, ImportTok, ExportTok, QualifiedTok, UnQualifiedTok,
59 EqualTok, HashTok, LessGreaterTok, LessTok, LessEqualTok,
60 GreaterTok, GreaterEqualTok, InTok, PlusTok, MinusTok,
61 OrTok, TimesTok, DivTok, DivideTok, ModTok, RemTok,
62 AndTok, AmbersandTok, PeriodPeriodTok, ByTok ;
64 FROM M2Quads IMPORT Top, PushT, PopT, PushTF, PopTF, PopNothing, OperandT, PushTFA,
65 PushTFn, PopTFn, PushTFtok, PopTtok, PopTFtok, PushTtok,
66 PushT, PushTF, IsAutoPushOn, PushAutoOff, PushAutoOn, PopAuto,
67 BuildTypeForConstructor, BuildConstructor, BuildConstructorEnd,
68 NextConstructorField, SilentBuildConstructor ;
70 FROM P3SymBuild IMPORT CheckCanBeImported ;
72 FROM PCSymBuild IMPORT PCStartBuildProgModule,
75 PCStartBuildDefModule,
78 PCStartBuildImpModule,
81 PCStartBuildInnerModule,
82 PCEndBuildInnerModule,
84 PCStartBuildProcedure,
85 PCBuildProcedureHeading,
87 PCBuildImportOuterModule,
88 PCBuildImportInnerModule,
96 PushConstructorCastType,
99 PushConstFunctionType,
101 PushConstAttributeType,
102 PushConstAttributePairType,
105 FROM SymbolTable IMPORT MakeGnuAsm, PutGnuAsmVolatile, PutGnuAsm, PutGnuAsmInput,
106 PutGnuAsmOutput, PutGnuAsmTrash, PutGnuAsmVolatile,
109 GetSymName, GetType, SkipType,
111 StartScope, EndScope,
113 IsVarParam, IsProcedure, IsDefImp, IsModule,
114 IsRecord, IsProcType,
116 GetSym, GetLocalSym ;
118 FROM M2Batch IMPORT IsModuleKnown ;
128 WasNoError : BOOLEAN ;
131 PROCEDURE ErrorString (s: String) ;
133 ErrorStringAt(s, GetTokenNo()) ;
138 PROCEDURE ErrorArray (a: ARRAY OF CHAR) ;
140 ErrorString(InitString(a))
144 % declaration PCBuild begin
148 SyntaxError - after a syntax error we skip all tokens up until we reach
152 PROCEDURE SyntaxError (stopset0: SetOfStop0; stopset1: SetOfStop1; stopset2: SetOfStop2) ;
157 printf0('\nskipping token *** ')
159 (* --fixme-- this assumes a 32 bit word size. *)
160 WHILE NOT (((ORD(currenttoken)<32) AND (currenttoken IN stopset0)) OR
161 ((ORD(currenttoken)>=32) AND (ORD(currenttoken)<64) AND (currenttoken IN stopset1)) OR
162 ((ORD(currenttoken)>=64) AND (currenttoken IN stopset2)))
177 PROCEDURE SyntaxCheck (stopset0: SetOfStop0; stopset1: SetOfStop1; stopset2: SetOfStop2) ;
179 (* --fixme-- this assumes a 32 bit word size. *)
180 IF NOT (((ORD(currenttoken)<32) AND (currenttoken IN stopset0)) OR
181 ((ORD(currenttoken)>=32) AND (ORD(currenttoken)<64) AND (currenttoken IN stopset1)) OR
182 ((ORD(currenttoken)>=64) AND (currenttoken IN stopset2)))
184 SyntaxError(stopset0, stopset1, stopset2)
190 WarnMissingToken - generates a warning message about a missing token, t.
193 PROCEDURE WarnMissingToken (t: toktype) ;
212 str := DescribeStop(s0, s1, s2) ;
214 str := ConCat(InitString('syntax error,'), Mark(str)) ;
215 ErrorStringAt(str, GetTokenNo())
216 END WarnMissingToken ;
220 MissingToken - generates a warning message about a missing token, t.
223 PROCEDURE MissingToken (t: toktype) ;
225 WarnMissingToken(t) ;
226 IF (t#identtok) AND (t#integertok) AND (t#realtok) AND (t#stringtok)
230 printf0('inserting token\n')
241 PROCEDURE CheckAndInsert (t: toktype; stopset0: SetOfStop0; stopset1: SetOfStop1; stopset2: SetOfStop2) : BOOLEAN ;
243 IF ((ORD(t)<32) AND (t IN stopset0)) OR
244 ((ORD(t)>=32) AND (ORD(t)<64) AND (t IN stopset1)) OR
245 ((ORD(t)>=64) AND (t IN stopset2))
247 WarnMissingToken(t) ;
248 InsertTokenAndRewind(t) ;
260 PROCEDURE InStopSet (t: toktype; stopset0: SetOfStop0; stopset1: SetOfStop1; stopset2: SetOfStop2) : BOOLEAN ;
262 IF ((ORD(t)<32) AND (t IN stopset0)) OR
263 ((ORD(t)>=32) AND (ORD(t)<64) AND (t IN stopset1)) OR
264 ((ORD(t)>=64) AND (t IN stopset2))
274 PeepToken - peep token checks to see whether the stopset is satisfied by currenttoken
275 If it is not then it will insert a token providing the token
276 is one of ; ] ) } . OF END ,
278 if the stopset contains <identtok> then we do not insert a token
281 PROCEDURE PeepToken (stopset0: SetOfStop0; stopset1: SetOfStop1; stopset2: SetOfStop2) ;
283 (* and again (see above re: ORD)
285 IF (NOT (((ORD(currenttoken)<32) AND (currenttoken IN stopset0)) OR
286 ((ORD(currenttoken)>=32) AND (ORD(currenttoken)<64) AND (currenttoken IN stopset1)) OR
287 ((ORD(currenttoken)>=64) AND (currenttoken IN stopset2)))) AND
288 (NOT InStopSet(identtok, stopset0, stopset1, stopset2))
290 (* SyntaxCheck would fail since currentoken is not part of the stopset
291 we check to see whether any of currenttoken might be a commonly omitted token *)
292 IF CheckAndInsert(semicolontok, stopset0, stopset1, stopset2) OR
293 CheckAndInsert(rsbratok, stopset0, stopset1, stopset2) OR
294 CheckAndInsert(rparatok, stopset0, stopset1, stopset2) OR
295 CheckAndInsert(rcbratok, stopset0, stopset1, stopset2) OR
296 CheckAndInsert(periodtok, stopset0, stopset1, stopset2) OR
297 CheckAndInsert(oftok, stopset0, stopset1, stopset2) OR
298 CheckAndInsert(endtok, stopset0, stopset1, stopset2) OR
299 CheckAndInsert(commatok, stopset0, stopset1, stopset2)
310 PROCEDURE Expect (t: toktype; stopset0: SetOfStop0; stopset1: SetOfStop1; stopset2: SetOfStop2) ;
317 PeepToken(stopset0, stopset1, stopset2)
322 SyntaxCheck(stopset0, stopset1, stopset2)
327 CompilationUnit - returns TRUE if the input was correct enough to parse
331 PROCEDURE CompilationUnit () : BOOLEAN ;
334 FileUnit(SetOfStop0{eoftok}, SetOfStop1{}, SetOfStop2{}) ;
336 END CompilationUnit ;
340 Ident - error checking varient of Ident
343 PROCEDURE Ident (stopset0: SetOfStop0; stopset1: SetOfStop1; stopset2: SetOfStop2) ;
347 PushTF(makekey(currentstring), identtok)
349 Expect(identtok, stopset0, stopset1, stopset2)
357 PROCEDURE string (stopset0: SetOfStop0; stopset1: SetOfStop1; stopset2: SetOfStop2) ;
361 PushTF(makekey(currentstring), stringtok) ;
364 Expect(stringtok, stopset0, stopset1, stopset2)
372 PROCEDURE Integer (stopset0: SetOfStop0; stopset1: SetOfStop1; stopset2: SetOfStop2) ;
376 PushTFtok (makekey(currentstring), integertok, GetTokenNo ()) ;
379 Expect(integertok, stopset0, stopset1, stopset2)
387 PROCEDURE Real (stopset0: SetOfStop0; stopset1: SetOfStop1; stopset2: SetOfStop2) ;
391 PushTFtok (makekey(currentstring), realtok, GetTokenNo ()) ;
394 Expect(realtok, stopset0, stopset1, stopset2)
400 error 'ErrorArray' 'ErrorString'
401 tokenfunc 'currenttoken'
403 token '' eoftok -- internal token
408 token ':=' becomestok
409 token '&' ambersandtok
412 token ";" semicolontok
415 token '[' lsbratok -- left square brackets
416 token ']' rsbratok -- right square brackets
417 token '{' lcbratok -- left curly brackets
418 token '}' rcbratok -- right curly brackets
420 token "'" singlequotetok
425 token '<>' lessgreatertok
426 token '<=' lessequaltok
427 token '>=' greaterequaltok
428 token '<*' ldirectivetok
429 token '*>' rdirectivetok
430 token '..' periodperiodtok
432 token '"' doublequotestok
435 token 'ARRAY' arraytok
436 token 'BEGIN' begintok
439 token 'CONST' consttok
440 token 'DEFINITION' definitiontok
444 token 'ELSIF' elsiftok
446 token 'EXCEPT' excepttok
448 token 'EXPORT' exporttok
449 token 'FINALLY' finallytok
453 token 'IMPLEMENTATION' implementationtok
454 token 'IMPORT' importtok
458 token 'MODULE' moduletok
462 token 'PACKEDSET' packedsettok
463 token 'POINTER' pointertok
464 token 'PROCEDURE' proceduretok
465 token 'QUALIFIED' qualifiedtok
466 token 'UNQUALIFIED' unqualifiedtok
467 token 'RECORD' recordtok
469 token 'REPEAT' repeattok
470 token 'RETRY' retrytok
471 token 'RETURN' returntok
476 token 'UNTIL' untiltok
478 token 'WHILE' whiletok
481 token 'VOLATILE' volatiletok
482 token '...' periodperiodperiodtok
483 token '__DATE__' datetok
484 token '__LINE__' linetok
485 token '__FILE__' filetok
486 token '__ATTRIBUTE__' attributetok
487 token '__BUILTIN__' builtintok
488 token '__INLINE__' inlinetok
489 token 'integer number' integertok
490 token 'identifier' identtok
491 token 'real number' realtok
492 token 'string' stringtok
494 special Ident first { < identtok > } follow { }
495 special Integer first { < integertok > } follow { }
496 special Real first { < realtok > } follow { }
497 special string first { < stringtok > } follow { }
501 -- the following are provided by the module m2flex and also handbuild procedures below
502 -- Ident := Letter { ( Letter | Digit ) } =:
503 -- Integer := Digit { Digit } | OctalDigit { OctalDigit } ( " B " | " C " ) |
504 -- Digit { HexDigit } " H " =:
505 -- Real := Digit { Digit } " . " { Digit } [ ScaleFactor ] =:
506 -- ScaleFactor := " E " [ ( " + " | " - " ) ] Digit { Digit } =:
507 -- HexDigit := Digit | " A " | " B " | " C " | " D " | " E " | " F " =:
508 -- Digit := OctalDigit | " 8 " | " 9 " =:
509 -- OctalDigit := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" =:
512 FileUnit := % PushAutoOff %
514 ImplementationOrProgramModule ) % PopAuto %
517 ProgramModule := "MODULE" % M2Error.DefaultProgramModule %
519 Ident % PCStartBuildProgModule %
524 { Import % PCBuildImportOuterModule %
527 Ident % PCEndBuildProgModule %
528 "." % PopAuto ; PopAuto %
531 ImplementationModule := "IMPLEMENTATION" % M2Error.DefaultImplementationModule %
532 "MODULE" % PushAutoOn %
533 Ident % PCStartBuildImpModule %
537 { Import % PCBuildImportOuterModule %
541 Ident % PCEndBuildImpModule %
542 "." % PopAuto ; PopAuto ; PopAuto %
545 ImplementationOrProgramModule := % PushAutoOff %
546 ( ImplementationModule | ProgramModule ) % PopAuto %
549 Number := Integer | Real =:
551 Qualident := % VAR name : Name ;
553 tokstart, tok : CARDINAL ; %
557 PopTtok(name, tokstart) ;
559 init := RequestSym (tok, name) ;
560 WHILE IsDefImp (init) OR IsModule (init) DO
561 Expect (periodtok, stopset0, stopset1, stopset2 + SetOfStop2{identtok}) ;
563 Ident (stopset0, stopset1, stopset2) ;
564 PopTtok (name, tok) ;
565 ip1 := RequestSym (tok, name) ;
568 CheckCanBeImported(init, ip1) ;
573 tok := MakeVirtualTok (tokstart, tokstart, tok)
575 IF IsProcedure(init) OR IsProcType(init)
579 PushTFtok(init, GetType(init), tok) ;
582 { "." Ident } % END %
585 ConstantDeclaration := % VAR top: CARDINAL ; %
588 ( Ident "=" % StartDesConst %
590 ConstExpression % PopAuto %
594 % Assert(top=Top()) %
597 ConstExpression := % VAR top: CARDINAL ; %
600 SimpleConstExpr [ Relation SimpleConstExpr % BuildRelationConst %
602 % Assert(top=Top()) %
605 Relation := "=" % PushT(EqualTok) %
606 | "#" % PushT(HashTok) %
607 | "<>" % PushT(LessGreaterTok) %
608 | "<" % PushT(LessTok) %
609 | "<=" % PushT(LessEqualTok) %
610 | ">" % PushT(GreaterTok) %
611 | ">=" % PushT(GreaterEqualTok) %
612 | "IN" % PushT(InTok) %
615 SimpleConstExpr := % VAR top: CARDINAL ; %
617 UnaryOrConstTerm { ConstAddOperator ConstTerm % BuildBinaryConst %
618 } % Assert(top=Top()) %
621 UnaryOrConstTerm := "+" % PushT(PlusTok) %
622 ConstTerm % BuildUnaryConst %
623 | "-" % PushT(MinusTok) %
624 ConstTerm % BuildUnaryConst %
628 ConstAddOperator := "+" % PushT(PlusTok) %
629 | "-" % PushT(MinusTok) %
630 | "OR" % PushT(OrTok) %
633 AddOperator := "+" | "-" | "OR" =:
635 ConstTerm := % VAR top: CARDINAL ; %
637 ConstFactor % Assert(top=Top()) %
638 { ConstMulOperator ConstFactor % BuildBinaryConst %
639 % Assert(top=Top()) %
640 } % Assert(top=Top()) %
643 ConstMulOperator := "*" % PushT(TimesTok) %
644 | "/" % PushT(DivideTok) %
645 | "DIV" % PushT(DivTok) %
646 | "MOD" % PushT(ModTok) %
647 | "REM" % PushT(RemTok) %
648 | "AND" % PushT(AndTok) %
649 | "&" % PushT(AmbersandTok) %
652 MulOperator := "*" | "/" | "DIV" | "MOD" | "REM" | "AND" | "&"
655 ConstFactor := ConstNumber | ConstString |
656 ConstSetOrQualidentOrFunction |
657 "(" ConstExpression ")" |
662 ConstNumber := % PushAutoOn %
663 ( Integer % PushIntegerType %
668 -- to help satisfy LL1
670 ConstString := % PushAutoOn %
671 string % PushStringType %
675 ComponentElement := ConstExpression [ ".." ConstExpression ] =:
677 ComponentValue := ComponentElement [ 'BY' ConstExpression ] =:
679 ArraySetRecordValue := ComponentValue { ',' % NextConstructorField %
682 Constructor := '{' % PushConstructorCastType %
683 % PushInConstructor %
685 [ ArraySetRecordValue ] % BuildConstructorEnd %
686 '}' % PopInConstructor %
689 ConstructorOrConstActualParameters := Constructor | ConstActualParameters % PushConstFunctionType %
690 % PopNothing (* pop function *) %
693 -- the entry to Constructor
695 ConstSetOrQualidentOrFunction := % PushAutoOff %
698 ( ConstructorOrConstActualParameters | % PushConstType %
701 | % BuildTypeForConstructor %
702 Constructor ) % PopAuto %
705 ConstActualParameters := % PushT(0) %
706 "(" [ ConstExpList ] ")" =:
708 ConstExpList := % VAR n: CARDINAL ; %
709 ConstExpression % PopT(n) %
713 { "," ConstExpression % PopT(n) %
718 ConstAttribute := % VAR top: CARDINAL ; %
720 "__ATTRIBUTE__" "__BUILTIN__" "(" "(" % PushAutoOn %
721 ConstAttributeExpression % PopAuto %
722 ")" ")" % Assert(top=Top()) %
725 ConstAttributeExpression :=
726 Ident % PushConstAttributeType %
728 | "<" Qualident ',' Ident ">" % PushConstAttributePairType %
729 % PopNothing ; PopNothing %
732 ByteAlignment := '<*' AttributeExpression '*>' =:
734 Alignment := [ ByteAlignment ] =:
736 TypeDeclaration := Ident "=" Type Alignment =:
740 ( SimpleType | ArrayType
744 | ProcedureType ) % PopAuto %
747 SimpleType := Qualident [ SubrangeType ] | Enumeration | SubrangeType =:
749 Enumeration := "(" IdentList ")" =:
751 IdentList := Ident % VAR
754 % on := IsAutoPushOn() ;
769 SubrangeType := "[" ConstExpression ".." ConstExpression "]" =:
780 RecordType := "RECORD" [ DefaultRecordAttributes ] FieldListSequence "END" =:
782 DefaultRecordAttributes := '<*' AttributeExpression '*>' =:
784 RecordFieldPragma := [ '<*' FieldPragmaExpression
785 { ',' FieldPragmaExpression } '*>' ] =:
787 FieldPragmaExpression := % PushAutoOff %
788 Ident [ '(' ConstExpression ')' ]
792 AttributeExpression := % PushAutoOff %
793 Ident '(' ConstExpression ')' % PopAuto %
796 FieldListSequence := FieldListStatement { ";" FieldListStatement } =:
798 FieldListStatement := [ FieldList ] =:
800 FieldList := IdentList ":"
801 Type RecordFieldPragma
805 Varient { "|" Varient }
811 TagIdent := [ Ident ] =:
813 CaseTag := TagIdent [":" Qualident ] =:
815 Varient := [ VarientCaseLabelList ":" FieldListSequence ] =:
817 VarientCaseLabelList := VarientCaseLabels { "," VarientCaseLabels } =:
819 VarientCaseLabels := ConstExpression ( ".." ConstExpression
825 -- the following rules are a copy of the ConstExpression ebnf rules but without
826 -- any actions all prefixed with Silent.
827 -- At present they are only used by CaseLabels, if this continues to be true we
828 -- might consider restricting the SilentConstExpression. Eg it makes no sence to allow
829 -- String in these circumstances!
832 SilentConstExpression := % PushAutoOff %
833 SilentSimpleConstExpr
834 [ SilentRelation SilentSimpleConstExpr ] % PopAuto %
837 SilentRelation := "=" | "#" | "<>" | "<" | "<=" | ">" | ">=" | "IN" =:
839 SilentSimpleConstExpr := SilentUnaryOrConstTerm { SilentAddOperator SilentConstTerm } =:
841 SilentUnaryOrConstTerm := "+" SilentConstTerm | "-" SilentConstTerm | SilentConstTerm =:
843 SilentAddOperator := "+" | "-" | "OR" =:
845 SilentConstTerm := SilentConstFactor { SilentMulOperator SilentConstFactor } =:
847 SilentMulOperator := "*" | "/" | "DIV" | "MOD" | "REM" | "AND" | "&" =:
849 SilentConstFactor := Number | SilentConstString | SilentConstSetOrQualidentOrFunction |
850 "(" SilentConstExpression ")" | "NOT" SilentConstFactor
851 | SilentConstAttribute =:
853 SilentConstString := string =:
855 SilentConstAttribute := "__ATTRIBUTE__" "__BUILTIN__" "(" "(" SilentConstAttributeExpression ")" ")" =:
857 SilentConstAttributeExpression := Ident | "<" Ident ',' SilentConstString ">" =:
859 SilentComponentElement := SilentConstExpression [ ".." SilentConstExpression ] =:
861 SilentComponentValue := SilentComponentElement [ 'BY' SilentConstExpression ] =:
863 SilentArraySetRecordValue := SilentComponentValue { ',' SilentComponentValue } =:
865 SilentConstructor := '{' % SilentBuildConstructor %
866 [ SilentArraySetRecordValue ] '}' =:
868 SilentConstSetOrQualidentOrFunction := SilentConstructor | Qualident
869 [ SilentConstructor | SilentActualParameters ] =:
871 SilentActualParameters := "(" [ SilentExpList ] ")" =:
873 SilentExpList := SilentConstExpression { "," SilentConstExpression } =:
875 -- end of the Silent constant rules
877 SetType := ( "SET" | "PACKEDSET" ) "OF" SimpleType =:
879 PointerType := "POINTER" "TO"
883 ProcedureType := "PROCEDURE"
884 [ FormalTypeList ] =:
886 FormalTypeList := "(" ( ")" FormalReturn |
887 ProcedureParameters ")" FormalReturn ) =:
889 FormalReturn := [ ":" OptReturnType ] =:
891 OptReturnType := "[" Qualident "]" | Qualident =:
893 ProcedureParameters := ProcedureParameter
894 { "," ProcedureParameter } =:
896 ProcedureParameter := "..." | "VAR" FormalType | FormalType =:
899 VarIdent := Ident [ "[" ConstExpression "]" ]
902 VarIdentList := VarIdent { "," VarIdent }
905 VariableDeclaration := VarIdentList ":" Type Alignment
908 Designator := Qualident { SubDesignator } =:
910 SubDesignator := "." Ident | "[" ArrayExpList "]" | "^"
913 ArrayExpList := Expression { "," Expression } =:
915 ExpList := Expression { "," Expression } =:
917 Expression := SimpleExpression [ SilentRelation SimpleExpression ]
920 SimpleExpression := UnaryOrTerm { AddOperator Term } =:
922 UnaryOrTerm := "+" Term | "-" Term | Term =:
924 Term := Factor { MulOperator Factor } =:
926 Factor := Number | string | SetOrDesignatorOrFunction |
927 "(" Expression ")" | "NOT" ( Factor | ConstAttribute ) =:
929 PushQualident := % VAR name : Name ;
930 init, ip1: CARDINAL ; %
932 Ident % IF IsAutoPushOn()
935 init := GetSym(name) ;
938 PushTFn(NulSym, NulSym, name)
940 WHILE IsDefImp(init) OR IsModule(init) DO
941 IF currenttoken#periodtok
943 ErrorArray("expecting '.' after module in the construction of a qualident") ;
948 Expect(periodtok, stopset0, stopset1, stopset2 + SetOfStop2{identtok}) ;
950 Ident(stopset0, stopset1, stopset2) ;
952 ip1 := GetSym(name) ;
955 ErrorArray("unknown ident in the construction of a qualident") ;
957 PushTFn(NulSym, NulSym, name) ;
964 CheckCanBeImported(init, ip1) ;
968 IF IsProcedure(init) OR IsProcType(init)
972 PushTF(init, GetType(init))
976 { "." Ident } % END %
980 ConstructorOrSimpleDes := Constructor | % PopNothing %
981 SimpleDes [ ActualParameters ]
984 SetOrDesignatorOrFunction := % PushAutoOff %
987 ( ConstructorOrSimpleDes | % PopNothing %
990 % BuildTypeForConstructor %
995 -- SimpleDes := { "." Ident | "[" ExpList "]" | "^" } =:
996 SimpleDes := { SubDesignator } =:
998 ActualParameters := "(" [ ExpList ] ")" =:
1000 ExitStatement := "EXIT" =:
1002 ReturnStatement := "RETURN" [ Expression ] =:
1004 Statement := % PushAutoOff %
1005 [ AssignmentOrProcedureCall | IfStatement | CaseStatement |
1006 WhileStatement | RepeatStatement | LoopStatement |
1007 ForStatement | WithStatement | AsmStatement |
1008 ExitStatement | ReturnStatement | RetryStatement
1012 RetryStatement := "RETRY" =:
1014 AssignmentOrProcedureCall := % VAR top: CARDINAL ; %
1016 Designator ( ":=" Expression |
1017 ActualParameters | % (* epsilon *) %
1018 ) % Assert(top=Top()) %
1021 -- these two break LL1 as both start with a Designator
1022 -- ProcedureCall := Designator [ ActualParameters ] =:
1023 -- Assignment := Designator ":=" Expression =:
1025 StatementSequence := % VAR top: CARDINAL ; %
1027 Statement % Assert(top=Top()) %
1029 Statement % Assert(top=Top()) %
1033 IfStatement := "IF" Expression "THEN"
1035 { "ELSIF" Expression "THEN" StatementSequence
1037 [ "ELSE" StatementSequence ] "END"
1040 CaseStatement := "CASE" Expression "OF" Case { "|" Case }
1044 CaseEndStatement := "END" | "ELSE" StatementSequence "END"
1047 Case := [ CaseLabelList ":" StatementSequence ]
1050 CaseLabelList := CaseLabels { "," CaseLabels } =:
1052 CaseLabels := ConstExpression [ ".." ConstExpression ] =:
1054 WhileStatement := "WHILE" Expression "DO" StatementSequence "END" =:
1056 RepeatStatement := "REPEAT" StatementSequence "UNTIL" Expression =:
1058 ForStatement := "FOR" Ident ":=" Expression "TO" Expression
1059 [ "BY" ConstExpression ] "DO"
1064 LoopStatement := "LOOP" StatementSequence "END" =:
1066 WithStatement := "WITH" Designator "DO"
1071 ProcedureDeclaration := ProcedureHeading ";" % PushAutoOff %
1072 ProcedureBlock % PopAuto ; PushAutoOn %
1073 Ident % PCEndBuildProcedure ;
1077 DefineBuiltinProcedure := [ "__ATTRIBUTE__" "__BUILTIN__"
1078 "(" "(" % PushAutoOff %
1080 ")" ")" | "__INLINE__" ]
1083 ProcedureHeading := "PROCEDURE" % M2Error.DefaultProcedure %
1085 DefineBuiltinProcedure
1087 % PCStartBuildProcedure ;
1089 [ FormalParameters ] AttributeNoReturn
1090 % PCBuildProcedureHeading ;
1095 Builtin := [ "__BUILTIN__" | "__INLINE__" ] =:
1097 DefProcedureHeading := "PROCEDURE" % M2Error.DefaultProcedure %
1101 % PCStartBuildProcedure ;
1103 [ DefFormalParameters ] AttributeNoReturn
1104 % PCBuildProcedureHeading ;
1107 % M2Error.LeaveErrorScope %
1110 AttributeNoReturn := [ "<*" Ident "*>" ] =:
1112 AttributeUnused := [ "<*" Ident "*>" ] =:
1114 -- introduced procedure block so we can produce more informative
1117 ProcedureBlock := % VAR top: CARDINAL ; %
1119 { Declaration % Assert(top=Top()) %
1120 } [ "BEGIN" ProcedureBlockBody % Assert(top=Top()) %
1121 ] "END" % Assert(top=Top()) %
1124 Block := % VAR top: CARDINAL ; %
1126 { Declaration } InitialBlock FinalBlock
1127 "END" % Assert(top=Top()) %
1130 InitialBlock := [ "BEGIN" InitialBlockBody ] =:
1132 FinalBlock := [ "FINALLY" FinalBlockBody ] =:
1134 InitialBlockBody := NormalPart [ "EXCEPT" ExceptionalPart ] =:
1136 FinalBlockBody := NormalPart [ "EXCEPT" ExceptionalPart ] =:
1138 ProcedureBlockBody := NormalPart [ "EXCEPT" ExceptionalPart ] =:
1140 NormalPart := StatementSequence =:
1142 ExceptionalPart := StatementSequence =:
1144 Declaration := "CONST" { ConstantDeclaration ";" } |
1145 "TYPE" { TypeDeclaration ";" } |
1146 "VAR" { VariableDeclaration ";" } |
1147 ProcedureDeclaration ";" |
1148 ModuleDeclaration ";" =:
1150 DefFormalParameters := "(" [ DefMultiFPSection ] ")" FormalReturn =:
1152 DefMultiFPSection := DefExtendedFP |
1153 FPSection [ ";" DefMultiFPSection ] =:
1155 FormalParameters := "(" [ MultiFPSection ] ")" FormalReturn =:
1157 MultiFPSection := ExtendedFP |
1158 FPSection [ ";" MultiFPSection ] =:
1160 FPSection := NonVarFPSection | VarFPSection =:
1162 DefExtendedFP := DefOptArg | "..." =:
1164 ExtendedFP := OptArg | "..." =:
1166 VarFPSection := "VAR" IdentList ":" FormalType [ AttributeUnused ] =:
1168 NonVarFPSection := IdentList ":" FormalType [ AttributeUnused ] =:
1170 OptArg := "[" Ident ":" FormalType [ "=" ConstExpression ] "]" =:
1172 DefOptArg := "[" Ident ":" FormalType "=" ConstExpression "]" =:
1174 FormalType := { "ARRAY" "OF" } Qualident =:
1176 ModuleDeclaration := "MODULE" % M2Error.DefaultInnerModule %
1178 Ident % PCStartBuildInnerModule %
1181 { Import % PCBuildImportInnerModule %
1184 Block % PushAutoOn %
1185 Ident % PCEndBuildInnerModule %
1186 % PopAuto ; PopAuto ; PopAuto %
1189 Priority := "[" ConstExpression "]" =:
1191 Export := "EXPORT" ( "QUALIFIED"
1197 Import := % PushAutoOn %
1198 ( "FROM" Ident "IMPORT" IdentList ";" |
1199 "IMPORT" % PushT(ImportTok)
1200 (* determines whether Ident or Module *) %
1201 IdentList ";" ) % PopAuto %
1204 DefinitionModule := "DEFINITION" % M2Error.DefaultDefinitionModule %
1205 "MODULE" % PushAutoOn %
1207 Ident % PCStartBuildDefModule ;
1210 { Import % PCBuildImportOuterModule %
1214 "END" % PushAutoOn %
1215 Ident % PCEndBuildDefModule %
1216 "." % PopAuto ; PopAuto ; PopAuto %
1219 Definition := "CONST" { ConstantDeclaration ";" } |
1222 | "=" Type Alignment ";" )
1225 "VAR" { VariableDeclaration ";" } |
1226 DefProcedureHeading ";" =:
1228 AsmStatement := 'ASM' [ 'VOLATILE' ] '(' AsmOperands ')' =:
1230 NamedOperand := '[' Ident ']' =:
1232 AsmOperandName := [ NamedOperand ] =:
1234 AsmOperands := string [ ':' AsmList [ ':' AsmList [ ':' TrashList ] ] ] =:
1236 AsmList := [ AsmElement ] { ',' AsmElement } =:
1238 AsmElement := AsmOperandName string '(' Expression ')' =:
1240 TrashList := [ string ] { ',' string } =: