aboutsummaryrefslogtreecommitdiffstats
path: root/parse.adb
diff options
context:
space:
mode:
Diffstat (limited to 'parse.adb')
-rw-r--r--parse.adb189
1 files changed, 146 insertions, 43 deletions
diff --git a/parse.adb b/parse.adb
index df8ce384e..9e164046c 100644
--- a/parse.adb
+++ b/parse.adb
@@ -190,6 +190,16 @@ package body Parse is
end loop;
end Eat_Tokens_Until_Semi_Colon;
+ -- Expect and scan ';' emit an error message using MSG if not present.
+ procedure Scan_Semi_Colon (Msg : String) is
+ begin
+ if Current_Token /= Tok_Semi_Colon then
+ Error_Msg_Parse ("missing "";"" at end of " & Msg);
+ else
+ Scan;
+ end if;
+ end Scan_Semi_Colon;
+
-- precond : next token
-- postcond: next token.
--
@@ -1175,21 +1185,17 @@ package body Parse is
El := Get_Chain (El);
end loop;
- if Current_Token /= Tok_Semi_Colon then
- Error_Msg_Parse ("missing "";"" at end of port clause");
- else
- Scan;
- end if;
+ Scan_Semi_Colon ("port clause");
Set_Port_Chain (Parent, Res);
end Parse_Port_Clause;
-- precond : GENERIC
-- postcond: next token
--
- -- [ §1.1.1 ]
+ -- [ LRM93 1.1.1, LRM08 6.5.6.2 ]
-- generic_clause ::= GENERIC ( generic_list ) ;
--
- -- [ §1.1.1.1]
+ -- [ LRM93 1.1.1.1, LRM08 6.5.6.2]
-- generic_list ::= GENERIC_interface_list
procedure Parse_Generic_Clause (Parent : Iir)
is
@@ -1203,12 +1209,9 @@ package body Parse is
Scan;
Res := Parse_Interface_Chain
(Iir_Kind_Constant_Interface_Declaration, Parent);
- if Current_Token /= Tok_Semi_Colon then
- Error_Msg_Parse ("missing "";"" at end of generic clause");
- else
- Scan;
- end if;
Set_Generic_Chain (Parent, Res);
+
+ Scan_Semi_Colon ("generic clause");
end Parse_Generic_Clause;
-- precond : a token.
@@ -1462,17 +1465,25 @@ package body Parse is
begin
Res := Create_Iir (Iir_Kind_Physical_Type_Definition);
Set_Location (Res);
+
+ -- Eat 'units'
Expect (Tok_Units);
Scan;
+
-- Parse primary unit.
Expect (Tok_Identifier);
Unit := Create_Iir (Iir_Kind_Unit_Declaration);
Set_Location (Unit);
Set_Identifier (Unit, Current_Identifier);
+
+ -- Skip identifier
+ Scan;
+
+ Scan_Semi_Colon ("primary unit");
+
Build_Init (Last);
Append (Last, Res, Unit);
- Scan_Expect (Tok_Semi_Colon);
- Scan;
+
-- Parse secondary units.
while Current_Token /= Tok_End loop
Unit := Create_Iir (Iir_Kind_Unit_Declaration);
@@ -1490,8 +1501,7 @@ package body Parse is
Error_Msg_Parse ("a physical literal is expected here");
end case;
Append (Last, Res, Unit);
- Expect (Tok_Semi_Colon);
- Scan;
+ Scan_Semi_Colon ("secondary unit");
end loop;
Scan;
Expect (Tok_Units);
@@ -1555,8 +1565,7 @@ package body Parse is
Subtype_Indication := Parse_Subtype_Indication;
Set_Type (First, Subtype_Indication);
First := Null_Iir;
- Expect (Tok_Semi_Colon);
- Scan;
+ Scan_Semi_Colon ("element declaration");
exit when Current_Token = Tok_End;
end loop;
Scan_Expect (Tok_Record);
@@ -4810,21 +4819,31 @@ package body Parse is
end if;
Build_Init (Last_Assoc);
while Current_Token /= Tok_End loop
+ -- Eat 'when'
Expect (Tok_When);
Scan;
+
if Current_Token = Tok_Double_Arrow then
Error_Msg_Parse ("missing expression in alternative");
+ Assoc := Create_Iir (Iir_Kind_Choice_By_Expression);
+ Set_Location (Assoc);
else
Assoc := Parse_Choices (Null_Iir);
end if;
+
+ -- Eat '=>'
Expect (Tok_Double_Arrow);
Scan;
+
Set_Associated
(Assoc, Parse_Sequential_Statements (Stmt));
Append_Subchain (Last_Assoc, Stmt, Assoc);
end loop;
+
+ -- Eat 'end', 'case'
Scan_Expect (Tok_Case);
Scan;
+
if Flags.Vhdl_Std >= Vhdl_93c then
Check_End_Name (Stmt);
end if;
@@ -4845,8 +4864,7 @@ package body Parse is
Set_Label (Stmt, Label);
end if;
end if;
- Expect (Tok_Semi_Colon);
- Scan;
+ Scan_Semi_Colon ("statement");
-- Append it to the chain.
if First_Stmt = Null_Iir then
@@ -5247,7 +5265,7 @@ package body Parse is
-- precond : GENERIC
-- postcond: next token
--
- -- [ §5.2.1.2 ]
+ -- [ LRM93 5.2.1.2, LRM08 6.5.7.2 ]
-- generic_map_aspect ::= GENERIC MAP ( GENERIC_association_list )
function Parse_Generic_Map_Aspect return Iir is
begin
@@ -5354,16 +5372,14 @@ package body Parse is
Parse_Generic_Clause (Res);
if Current_Token = Tok_Generic then
Set_Generic_Map_Aspect_Chain (Res, Parse_Generic_Map_Aspect);
- Expect (Tok_Semi_Colon);
- Scan;
+ Scan_Semi_Colon ("generic map aspect");
end if;
end if;
if Current_Token = Tok_Port then
Parse_Port_Clause (Res);
if Current_Token = Tok_Port then
Set_Port_Map_Aspect_Chain (Res, Parse_Port_Map_Aspect);
- Expect (Tok_Semi_Colon);
- Scan;
+ Scan_Semi_Colon ("port map aspect");
end if;
end if;
return Res;
@@ -6106,8 +6122,7 @@ package body Parse is
| Tok_Generic
| Tok_Port =>
Set_Binding_Indication (Res, Parse_Binding_Indication);
- Expect (Tok_Semi_Colon);
- Scan;
+ Scan_Semi_Colon ("binding indication");
when others =>
null;
end case;
@@ -6361,26 +6376,50 @@ package body Parse is
Set_Library_Unit (Unit, Res);
end Parse_Configuration_Declaration;
- -- precond : identifier
+ -- precond : generic
+ -- postcond: next token
+ --
+ -- LRM08 4.7
+ -- package_header ::=
+ -- [ generic_clause -- LRM08 6.5.6.2
+ -- [ generic_map aspect ; ] ]
+ function Parse_Package_Header return Iir
+ is
+ Res : Iir;
+ begin
+ Res := Create_Iir (Iir_Kind_Package_Header);
+ Parse_Generic_Clause (Res);
+
+ if Current_Token = Tok_Generic then
+ Set_Generic_Map_Aspect_Chain (Res, Parse_Generic_Map_Aspect);
+ Scan_Semi_Colon ("generic map aspect");
+ end if;
+ return Res;
+ end Parse_Package_Header;
+
+ -- precond : token (after 'IS')
-- postcond: ';'
--
- -- [ §2.5 ]
+ -- [ LRM93 2.5, LRM08 4.7 ]
-- package_declaration ::=
-- PACKAGE identifier IS
+ -- package_header -- LRM08
-- package_declarative_part
-- END [ PACKAGE ] [ PACKAGE_simple_name ] ;
- procedure Parse_Package_Declaration (Unit : Iir_Design_Unit)
+ procedure Parse_Package_Declaration (Unit : Iir_Design_Unit; Id : Name_Id)
is
Res: Iir_Package_Declaration;
begin
Res := Create_Iir (Iir_Kind_Package_Declaration);
Set_Location (Res);
+ Set_Identifier (Res, Id);
- -- Get identifier.
- Expect (Tok_Identifier);
- Set_Identifier (Res, Current_Identifier);
- Scan_Expect (Tok_Is);
- Scan;
+ if Current_Token = Tok_Generic then
+ if Vhdl_Std < Vhdl_08 then
+ Error_Msg_Parse ("generic packages not allowed before vhdl 2008");
+ end if;
+ Set_Package_Header (Res, Parse_Package_Header);
+ end if;
Parse_Declarative_Part (Res);
@@ -6401,7 +6440,7 @@ package body Parse is
-- precond : BODY
-- postcond: ';'
--
- -- [ §2.6 ]
+ -- [ LRM93 2.6, LRM08 4.8 ]
-- package_body ::=
-- PACKAGE BODY PACKAGE_simple_name IS
-- package_body_declarative_part
@@ -6436,6 +6475,76 @@ package body Parse is
Set_Library_Unit (Unit, Res);
end Parse_Package_Body;
+ -- precond : NEW
+ -- postcond: ';'
+ --
+ -- [ LRM08 4.9 ]
+ -- package_instantiation_declaration ::=
+ -- PACKAGE identifier IS NEW uninstantiated_package_name
+ -- [ generic_map_aspect ] ;
+ function Parse_Package_Instantiation_Declaration
+ (Id : Name_Id; Loc : Location_Type)
+ return Iir
+ is
+ Res: Iir;
+ begin
+ Res := Create_Iir (Iir_Kind_Package_Instantiation_Declaration);
+ Set_Location (Res, Loc);
+ Set_Identifier (Res, Id);
+
+ -- Skip 'new'
+ Scan;
+
+ Set_Uninstantiated_Name (Res, Parse_Name (False));
+
+ if Current_Token = Tok_Generic then
+ Set_Generic_Map_Aspect_Chain (Res, Parse_Generic_Map_Aspect);
+ end if;
+
+ Expect (Tok_Semi_Colon);
+
+ return Res;
+ end Parse_Package_Instantiation_Declaration;
+
+ -- precond : PACKAGE
+ -- postcond: ';'
+ --
+ -- package_declaration
+ -- | package_body
+ -- | package_instantiation_declaration
+ procedure Parse_Package (Unit : Iir_Design_Unit)
+ is
+ Loc : constant Location_Type := Get_Token_Location;
+ Id : Name_Id;
+ begin
+ -- Skip 'package'
+ Scan;
+
+ if Current_Token = Tok_Body then
+ -- Skip 'body'
+ Scan;
+
+ Parse_Package_Body (Unit);
+ else
+ Expect (Tok_Identifier);
+ Id := Current_Identifier;
+ Scan;
+
+ Expect (Tok_Is);
+ Scan;
+
+ if Current_Token = Tok_New then
+ Set_Library_Unit
+ (Unit,
+ Parse_Package_Instantiation_Declaration (Id, Loc));
+ -- Note: there is no 'end' in instantiation.
+ Set_End_Location (Unit, Get_Token_Location);
+ else
+ Parse_Package_Declaration (Unit, Id);
+ end if;
+ end if;
+ end Parse_Package;
+
-- Parse a design_unit.
-- The lexical scanner must have been initialized, but without a
-- current_token.
@@ -6502,13 +6611,7 @@ package body Parse is
when Tok_Architecture =>
Parse_Architecture (Res);
when Tok_Package =>
- Scan;
- if Current_Token = Tok_Body then
- Scan;
- Parse_Package_Body (Res);
- else
- Parse_Package_Declaration (Res);
- end if;
+ Parse_Package (Res);
when Tok_Configuration =>
Parse_Configuration_Declaration (Res);
when others =>