aboutsummaryrefslogtreecommitdiffstats
path: root/src/vhdl/vhdl-parse.adb
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-12-30 20:07:35 +0100
committerTristan Gingold <tgingold@free.fr>2019-12-30 20:07:35 +0100
commit10b0ac263ed7c59c438c1cb82faef51370cbd67e (patch)
tree0430b5e1ae8c137057832f2946d16f9d5222588a /src/vhdl/vhdl-parse.adb
parent6340fddff21567b10dd774d5459536d37c6239dc (diff)
downloadghdl-10b0ac263ed7c59c438c1cb82faef51370cbd67e.tar.gz
ghdl-10b0ac263ed7c59c438c1cb82faef51370cbd67e.tar.bz2
ghdl-10b0ac263ed7c59c438c1cb82faef51370cbd67e.zip
ams-vhdl: add simultaneous null statement.
Diffstat (limited to 'src/vhdl/vhdl-parse.adb')
-rw-r--r--src/vhdl/vhdl-parse.adb154
1 files changed, 130 insertions, 24 deletions
diff --git a/src/vhdl/vhdl-parse.adb b/src/vhdl/vhdl-parse.adb
index 3ec1777a2..81c5a7b37 100644
--- a/src/vhdl/vhdl-parse.adb
+++ b/src/vhdl/vhdl-parse.adb
@@ -77,6 +77,8 @@ package body Vhdl.Parse is
Label_Loc : Location_Type;
If_Loc : Location_Type;
First_Cond : Iir) return Iir;
+ function Parse_Simultaneous_Case_Statement
+ (Label : Name_Id; Loc : Location_Type; Expr : Iir) return Iir;
-- Maximum number of nested parenthesis, before generating an error.
Max_Parenthesis_Depth : constant Natural := 1000;
@@ -7337,8 +7339,7 @@ package body Vhdl.Parse is
Set_Expression (Stmt, Parse_Expression);
-- Skip 'is'.
- Expect (Tok_Is);
- Scan;
+ Expect_Scan (Tok_Is);
if Current_Token = Tok_End then
Error_Msg_Parse ("missing alternative in case statement");
@@ -9000,18 +9001,31 @@ package body Vhdl.Parse is
Res : Iir;
Alt : Iir;
Last_Alt : Iir;
+ Expr : Iir;
+ Start_Loc : Location_Type;
begin
+ Start_Loc := Get_Token_Location;
+
+ -- Skip 'case'.
+ Scan;
+
+ Expr := Parse_Expression;
+
+ if Current_Token = Tok_Use then
+ if not AMS_Vhdl then
+ Error_Msg_Parse ("if/use is an AMS-VHDL statement");
+ end if;
+ return Parse_Simultaneous_Case_Statement (Label, Loc, Expr);
+ end if;
+
if Label = Null_Identifier then
- Error_Msg_Parse ("a generate statement must have a label");
+ Error_Msg_Parse (Start_Loc, "a generate statement must have a label");
end if;
+
Res := Create_Iir (Iir_Kind_Case_Generate_Statement);
Set_Location (Res, Loc);
Set_Label (Res, Label);
-
- -- Skip 'case'.
- Scan;
-
- Set_Expression (Res, Parse_Expression);
+ Set_Expression (Res, Expr);
-- Skip 'generate'
Expect_Scan (Tok_Generate);
@@ -9131,6 +9145,28 @@ package body Vhdl.Parse is
return Res;
end Parse_Simultaneous_Procedural_Statement;
+ -- precond : NULL
+ --
+ -- AMS-LRM17 11.14 Simultaneous null statement
+ -- simultaneous_null_statement ::=
+ -- [ label : ] NULL ;
+ function Parse_Simultaneous_Null_Statement
+ (Label : Name_Id; Loc : Location_Type) return Iir
+ is
+ Res : Iir;
+ begin
+ Res := Create_Iir (Iir_Kind_Simultaneous_Null_Statement);
+ Set_Location (Res, Loc);
+ Set_Label (Res, Label);
+
+ -- Skip 'procedural'.
+ Scan;
+
+ Scan_Semi_Colon_Declaration ("null statement");
+
+ return Res;
+ end Parse_Simultaneous_Null_Statement;
+
-- precond : first token
-- postcond: next token
--
@@ -9264,16 +9300,16 @@ package body Vhdl.Parse is
--
-- simultaneous_statement_part ::=
-- { simultaneous_statement }
- procedure Parse_Simultaneous_Statements (Parent : Iir)
+ function Parse_Simultaneous_Statements (Parent : Iir) return Iir
is
- Last_Stmt : Iir;
+ First_Stmt, Last_Stmt : Iir;
Stmt: Iir;
Label: Name_Id;
Loc : Location_Type;
Start_Loc : Location_Type;
Expr : Iir;
begin
- Last_Stmt := Null_Iir;
+ Chain_Init (First_Stmt, Last_Stmt);
loop
Stmt := Null_Iir;
Label := Null_Identifier;
@@ -9307,7 +9343,7 @@ package body Vhdl.Parse is
if Label /= Null_Identifier then
Error_Msg_Parse ("label is not allowed here");
end if;
- return;
+ return First_Stmt;
when Tok_Identifier =>
-- FIXME: sign, factor, parenthesis...
Expr := Parse_Name (Allow_Indexes => True);
@@ -9322,9 +9358,18 @@ package body Vhdl.Parse is
Stmt := Parse_Simultaneous_If_Statement
(Label, Loc, Start_Loc, Expr);
+ when Tok_Case =>
+ -- Skip 'case'.
+ Scan;
+
+ Expr := Parse_Expression;
+
+ Stmt := Parse_Simultaneous_Case_Statement (Label, Loc, Expr);
+ when Tok_Null =>
+ Stmt := Parse_Simultaneous_Null_Statement (Label, Loc);
when Tok_Eof =>
Error_Msg_Parse ("unexpected end of file, 'END;' expected");
- return;
+ return First_Stmt;
when others =>
-- FIXME: improve message:
Unexpected ("simultaneous statement list");
@@ -9344,12 +9389,7 @@ package body Vhdl.Parse is
end if;
Set_Parent (Stmt, Parent);
-- Append it to the chain.
- if Last_Stmt = Null_Iir then
- Set_Simultaneous_Statement_Chain (Parent, Stmt);
- else
- Set_Chain (Last_Stmt, Stmt);
- end if;
- Last_Stmt := Stmt;
+ Chain_Append (First_Stmt, Last_Stmt, Stmt);
end if;
end loop;
end Parse_Simultaneous_Statements;
@@ -9391,7 +9431,8 @@ package body Vhdl.Parse is
Expect_Error (Tok_Use, "'use' is expected here");
end if;
- Parse_Simultaneous_Statements (Clause);
+ Set_Simultaneous_Statement_Chain
+ (Clause, Parse_Simultaneous_Statements (Clause));
End_Loc := Get_Token_Location;
@@ -9414,7 +9455,8 @@ package body Vhdl.Parse is
-- Skip 'else'.
Scan;
- Parse_Simultaneous_Statements (Clause);
+ Set_Simultaneous_Statement_Chain
+ (Clause, Parse_Simultaneous_Statements (Clause));
if Flag_Elocations then
Create_Elocations (Clause);
@@ -9441,6 +9483,63 @@ package body Vhdl.Parse is
return Res;
end Parse_Simultaneous_If_Statement;
+ -- simultaneous_case_statement ::=
+ -- /case/_label :
+ -- CASE expression USE
+ -- simultaneous_alternative
+ -- { simultaneous_alternative }
+ -- END CASE [ /case/_label ] ;
+ function Parse_Simultaneous_Case_Statement
+ (Label : Name_Id; Loc : Location_Type; Expr : Iir) return Iir
+ is
+ Res : Iir;
+ When_Loc : Location_Type;
+ Assoc : Iir;
+ First_Assoc, Last_Assoc : Iir;
+ begin
+ Res := Create_Iir (Iir_Kind_Simultaneous_Case_Statement);
+ Set_Location (Res, Loc);
+ Set_Label (Res, Label);
+ Set_Expression (Res, Expr);
+
+ -- Skip 'use'
+ Expect_Scan (Tok_Use);
+
+ if Current_Token = Tok_End then
+ Error_Msg_Parse ("no generate alternative");
+ end if;
+
+ Chain_Init (First_Assoc, Last_Assoc);
+ while Current_Token = Tok_When loop
+ When_Loc := Get_Token_Location;
+
+ -- Skip 'when'.
+ Scan;
+
+ Parse_Choices (Null_Iir, When_Loc, Assoc);
+
+ -- Skip '=>'.
+ Expect_Scan (Tok_Double_Arrow);
+
+ Set_Associated_Chain (Assoc, Parse_Simultaneous_Statements (Res));
+ Chain_Append_Subchain (First_Assoc, Last_Assoc, Assoc);
+ end loop;
+
+ Set_Case_Statement_Alternative_Chain (Res, First_Assoc);
+
+ -- Skip 'end', 'case'
+ Expect_Scan (Tok_End);
+ Expect_Scan (Tok_Case);
+
+ -- LRM93 9.7
+ -- If a label appears at the end of a generate statement, it must repeat
+ -- the generate label.
+ Check_End_Name (Res);
+ Expect_Scan (Tok_Semi_Colon);
+
+ return Res;
+ end Parse_Simultaneous_Case_Statement;
+
-- Parse end of PSL assert/cover statement.
procedure Parse_Psl_Assert_Report_Severity
(Stmt : Iir; Flag_Psl : Boolean) is
@@ -9684,9 +9783,6 @@ package body Vhdl.Parse is
when Tok_Case =>
Postponed_Not_Allowed;
Stmt := Parse_Case_Generate_Statement (Label, Loc);
- when Tok_Eof =>
- Error_Msg_Parse ("unexpected end of file, 'END;' expected");
- return;
when Tok_Component
| Tok_Entity
| Tok_Configuration =>
@@ -9706,6 +9802,13 @@ package body Vhdl.Parse is
when Tok_Procedural =>
Postponed_Not_Allowed;
Stmt := Parse_Simultaneous_Procedural_Statement (Label);
+ when Tok_Null =>
+ if not AMS_Vhdl then
+ Error_Msg_Parse ("concurrent null statement not allowed");
+ else
+ Postponed_Not_Allowed;
+ end if;
+ Stmt := Parse_Simultaneous_Null_Statement (Label, Loc);
when Tok_Default =>
Postponed_Not_Allowed;
Label_Not_Allowed;
@@ -9732,6 +9835,9 @@ package body Vhdl.Parse is
("sequential statement only allowed in processes");
Stmt := Parse_Sequential_Statements (Parent);
Stmt := Null_Iir;
+ when Tok_Eof =>
+ Error_Msg_Parse ("unexpected end of file, 'END;' expected");
+ return;
when others =>
-- FIXME: improve message:
-- instead of 'unexpected token 'signal' in conc stmt list'