This appendix contains a VHDL-93 formatter, a program to produce readable text files from data structures representing a VHDL-93 design. This version basically fixes bugs in the original formatter program for VHDL-87 written by Peter B. Reintjes and upgrades it to the VHDL-93 standard. It has been tested on the accompanying VHDL-87 and VHDL-93 test programs.
The declarative nature of logic programs suggests that a program to produce the textual form of a parse-tree should be identical to a parser for that language. Although this is possible, it is impractical for two reasons:
Both of these rules result from a very simple principle: there are an exponential number of ways to compose the tokens to produce a legal output file. While the parser has to be ready to accept this diversity, if the parser is used as a generator, this non-determinism is counter productive. In particular, we want the output to be indented and spaced in a specific readable way, independent of how the original source was formatted.
Like the VHDL-93 parser, the formatter is largely a collection of grammar rules which describe the IEEE Standard 1076-1993 of VHDL language. These grammar rules have been numbered to correspond with the rules in VHDL-93 parser described earlier.
There are essentially three categories of grammar rules in the VHDL-93 formatter. The first includes rules which are no different from the rules in the parser, primarily because they define simple conjunctions of non-terminals. Rule 128 is a good example:
write_vhdl_opt_binding_indication(binding(EA,GAL,PAL)) -->
write_vhdl_opt_entity_aspect(EA),
[indent],
write_vhdl_opt_generic_map_statement(GAL),
newline,
write_vhdl_opt_port_map_statement(PAL).
[undent],
The second category includes rules which only differ from their parser counterparts because of the inclusion of whitespace and formatting directives. Large structures like process and architecture blocks must have this additional information in order to produce readable texts. Rule 108 shows the use of indentation and newline control.
write_vhdl_case_statement_alternatives([vhdl_case(Choices,Ss)|Cases]) -->
" when ", write_vhdl_choices(Choices), " => ", newline,
[indent],
write_vhdl_sequential_statements(Ss),
[undent],
write_vhdl_case_statement_alternatives(Cases).
Where newline//1 inserts an ASCII newline character into the output list. This can be easily changed to have a newline and a carriage return in non-UNIX systems.
newline --> [10].
Rules in the third category differ from the parser rules in ways that affect the program flow-of-control. The resulting rules still look like grammar rules, but may have the clauses ordered differently and contain extra cuts.A simple example of how the parser and the formatter must differ can be found in the rule for an optional association-list in VHDL-93 (It is not even necessary to understand what an association-list is to follow this example).
In the parser, Rule 24 first tries to recognize an association list (whatever that is). If the first clause fails, the second clause returns a nil list to indicate that the optional association-list is empty.
vhdl_opt_association_list(A) --> vhdl_association_list(A). vhdl_opt_association_list([]) --> [].
On the other hand, if we encounter the nil list when preparing to print out the optional association-list, we want to know this first. In this case, we commit to this clause while adding nothing to the output.
The second clause is only taken if the list contains something.
write_vhdl_opt_association_list([]) --> !, []. write_vhdl_opt_association_list(A) --> write_vhdl_association_list(A).
As an aside, we should note that the absence of a cut in the parser code is rather subtle. We may not want to commit, even if after a legal association-list has been parsed. For example, imagine the following grammar rule as it encounters a single association-list.
two_lists(A1,A2) -->
vhdl_opt_association_list(A1), vhdl_association_list(A2).
Although we cannot use exactly the same code for the parser and the formatter, their similarity can be exploited by using the parser as a template for the formatter. Currently, this is a manual task, but it is considerably easier than trying to write a formatter from scratch.
This VHDL-93 formatter has the same number of rules as the parser, and their form is nearly identical. The DCG list arguments are not lists of tokens being consumed but lists of characters being built-up as we insert the appropriate tokens, identifiers, and whitespace. Terminals appear in the formatter as lists of characters (``architecture'', ``if'', ``when'', etc.). As we produce this list of characters, we insert the two tokens, indent and undent , which will be used as signals to control the correct tabbing when this list of characters is sent to the output.
Thus, to produce a formatter for a language from a parser, we must do the following:
After this character list has been created by the ``grammar'', the following code writes the list of characters to the output.
write_list([],_).
write_list([undent,0';|Cs],Indent) :-
!, write_list([0';,undent|Cs],Indent).
write_list([C|Cs],Indent) :-
process(C,Indent,NewIndent),
write_list(Cs,NewIndent).
The first rule in process/3 ensures that the correct number of spaces (the current indent) follow each newline character. The second, third and fourth clauses recognize the indent, undent and dent tokens and modify the current tab value appropriately. These tokens also generate a newline with the new indent. The last clause simply puts out the current character.
process(10,Indent,Indent) :- !,
put(10), putn(Indent,32).
process(indent,Indent,NewIndent) :- !,
NewIndent is Indent + 4,
process(10,NewIndent,_).
process(undent,Indent,NewIndent) :- !,
NewIndent is Indent - 4,
process(10,NewIndent,_).
process(dent,Indent,NewIndent) :- !,
NewIndent is Indent - 4.
process(C,Indent,Indent) :- put(C).
Thus, a modified grammar, together with these 13 lines of code produce a cleanly formatted text from a parse tree.
The following program will read a VHDL-93 source file into Prolog terms and then produce a formatted version of that description. By itself, it implements a pretty-printer which will produce source-files with standard indentation and uniform case for keywords, but it is also a template for any program which must process VHDL-93 designs.
main(+File) :-
vhdl_read(+File,-Design_Units),
% Place any algorithm in here ...
write_vhdl_design_units(+Design_Units,0,-L,[]),
write_list(-L,0).
write_vhdl_design_units([]) --> [].
write_vhdl_design_units([Design|Designs]) -->
newline,
write_vhdl_design_unit(Design),
write_vhdl_design_units(Designs).
Additionally, this formatter can be used as the back-end of a schematic editor to produce VHDL-93 source-files from the internal data structures built during schematic entry.
Like the parser upon which it is based, the size of this program is near the lower-limit for a program to accomplish this task. Since it describes the language completely, it cannot have less rules than the grammar. The thirteen lines above, together with the [indent] and [undent] tokens inserted into the grammar seem like a minimal price to pay for the function of generating readable VHDL-93 source.
putn(N,_) :- N < 1, !.
putn(N,C) :- put(C), NN is N-1, putn(NN,C).
write_vhdl_design_units([],_) --> !, newline, [].
write_vhdl_design_units([Design|Designs],N) -->
{ NN is N+1, name(NN,NNCs) },
newline,
"-- VHDL DESIGN UNIT #", [ NNCs ],
newline,
write_vhdl_design_unit(Design),
write_vhdl_design_units(Designs,NN).
To write fragments of the original source file including documentation, we define the following predicates.
write_file_fragment(File, StartPos, EndPos) :-
seeing(Current_File),
see(File),
StartPos = '$stream_position'(SChPos,_,_),
EndPos = '$stream_position'(EChPos,_,_),
current_input(Stream),
stream_position(Stream,_,StartPos),
copy_from_to(Stream,SChPos,EChPos),
seen,
see(Current_File).
copy_from_to(Stream,SP,EP) :-
( at_end_of_stream(Stream) ; EP is SP + 1)
-> true;
( get0(Ch), put(Ch), NP is SP + 1,
copy_from_to(Stream,NP,EP) ).
test_write_file(Name) :-
vhdl_read(Name),
file_path(Name,File),
assoc_file_design_unit(_,File,StartPos,EndPos), nl,
nl, write('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'), nl,
write_file_fragment(File,StartPos,EndPos),fail.
test_write_file(_).
Rule 1
write_vhdl_designator(op(S),A,B) :- !, name(S,ST),
append([0'"|ST],[0'"|B],A).
write_vhdl_designator(ID) --> write_vhdl_identifier(ID).
Rule 2
write_vhdl_literal(null) --> !, " null ".
write_vhdl_literal(L) --> write_vhdl_physical_literal(L).
write_vhdl_literal(L) --> write_vhdl_enumeration_literal(L).
%write_vhdl_literal(L) --> write_vhdl_abstract_literal(L).
write_vhdl_literal(L,A,B) :- double_the_quotes(L,LL),
append([0'"|LL],[0'"|B],A). %***FIX
%string or bit-string
double_the_quotes([],[]).
double_the_quotes([0'"|T],[0'",0'"|TT]) :- !, double_the_quotes(T,TT).
double_the_quotes([H|T],[H|TT]) :- double_the_quotes(T,TT).
Rule 3
write_vhdl_abstract_literal(F) --> write_vhdl_identifier(F).
Rule 4
write_vhdl_enumeration_literal(char(L)) --> !, "'", [L], "'". write_vhdl_enumeration_literal(ID) --> write_vhdl_identifier(ID).
Rule 5
write_vhdl_physical_literal(pl(AL,ID)) -->
write_vhdl_abstract_literal(AL), " ",
write_vhdl_identifier(ID), " ".
Rule 6
write_vhdl_identifier(ID) -->
{ atomic(ID), name(ID,IDC) },
{ process_extended_id(IDC,IDCs) }, [ IDCs ]. %***FIX
process_extended_id([0'\|TB],[0'\|TT]) :- !, double_the_backslash(TB,TT).
process_extended_id(TT,TT).
double_the_backslash([0'\],[0'\]) :- !.
double_the_backslash([0'\|T],[0'\,0'\|TT]) :- !, double_the_backslash(T,TT).
double_the_backslash([H|T],[H|TT]) :- double_the_backslash(T,TT).
write_vhdl_identifier_list([]) --> [].
write_vhdl_identifier_list([ID]) --> !,
write_vhdl_identifier(ID).
write_vhdl_identifier_list([ID|IDs]) -->
write_vhdl_identifier(ID), ", ",
write_vhdl_identifier_list(IDs).
Rule 7
write_vhdl_design_unit(design_unit(CI,Unit)) -->
write_vhdl_opt_context_items(CI),
write_vhdl_library_unit(Unit), ";", newline.
Rule 8
write_vhdl_library_unit(LU) --> write_vhdl_entity_declaration(LU). write_vhdl_library_unit(LU) --> write_vhdl_configuration_declaration(LU). write_vhdl_library_unit(LU) --> write_vhdl_package_declaration(LU). write_vhdl_library_unit(LU) --> write_vhdl_architecture_body(LU). write_vhdl_library_unit(LU) --> write_vhdl_package_body(LU).
Rule 9
write_vhdl_opt_context_items([]) --> [].
write_vhdl_opt_context_items([CI|CIs]) -->
write_vhdl_library_clause(CI), !,
";", newline,
write_vhdl_opt_context_items(CIs).
write_vhdl_opt_context_items([CI|CIs]) -->
write_vhdl_use_clause(CI),
";", newline,
write_vhdl_opt_context_items(CIs).
Rule 10
write_vhdl_library_clause(library(IL)) -->
"library ", write_vhdl_identifier_list(IL).
Rule 11
write_vhdl_opt_use_clauses([ ]) --> !, [ ].
write_vhdl_opt_use_clauses([UC|UCs]) -->
write_vhdl_use_clause(UC),
write_vhdl_opt_use_clauses(UCs).
write_vhdl_use_clause(use([Name|Names])) -->
" use ", write_vhdl_selected_name(Name),
write_vhdl_selected_names(Names).
write_vhdl_selected_names([]) --> [].
write_vhdl_selected_names([Name|Names]) -->
",", write_vhdl_selected_name(Name),
write_vhdl_selected_names(Names).
Rule 12
write_vhdl_entity_declaration(entity(ID,GIL,PIL,DIs,Ss)) -->
"entity ", write_vhdl_identifier(ID), " is ",
[indent],
write_vhdl_opt_generic_statement(GIL),
write_vhdl_opt_port_statement(PIL),
write_vhdl_opt_declarative_items(DIs),
write_vhdl_opt_entity_body(Ss),
[undent],
"end ", write_vhdl_identifier(ID).
write_vhdl_opt_entity_body([]) --> [].
write_vhdl_opt_entity_body(Ss) -->
"begin ",
[indent],
write_vhdl_concurrent_statements(Ss),
[undent].
write_vhdl_opt_generic_statement(null) --> !,[].
write_vhdl_opt_generic_statement(IL) -->
" generic ",
[indent],
write_vhdl_interface_list(one_per_line,IL), ";",
[undent].
write_vhdl_opt_port_statement(null) --> !, [].
write_vhdl_opt_port_statement(IL) -->
" port ",
[indent],
write_vhdl_interface_list(one_per_line,IL), ";",
[undent].
Rule 13
write_vhdl_architecture_body(arch(ID,Entity,DIs,Ss)) -->
"architecture ", write_vhdl_identifier(ID),
" of ", write_vhdl_mark(Entity), " is ",
[indent],
write_vhdl_opt_declarative_items(DIs),
"begin ",
[indent],
write_vhdl_concurrent_statements(Ss),
[dent, undent],
"end ", write_vhdl_identifier(ID).
Rule 14
write_vhdl_configuration_declaration(conf(ID,Entity,DIs,Block)) -->
"configuration ", write_vhdl_identifier(ID),
" of ", write_vhdl_mark(Entity), " is ",
[indent],
write_vhdl_opt_declarative_items(DIs),
write_vhdl_block_configuration(Block),
[undent],
"end ", write_vhdl_identifier(ID).
Rule 15
write_vhdl_package_declaration(package(ID,Declarations)) -->
"package ", write_vhdl_identifier(ID), " is ",
[indent],
write_vhdl_opt_declarative_items(Declarations),
[undent],
"end ", write_vhdl_identifier(ID). %*** deleted OPT
Rule 16
write_vhdl_package_body(package_body(ID,DIs)) -->
"package body ", write_vhdl_identifier(ID), " is ",
[indent],
write_vhdl_opt_declarative_items(DIs),
[undent],
"end ", write_vhdl_identifier(ID).
Rule 17
write_vhdl_declarative_item(DI) --> write_vhdl_type_declaration(DI). write_vhdl_declarative_item(DI) --> write_vhdl_subtype_declaration(DI). write_vhdl_declarative_item(DI) --> write_vhdl_object_declaration(DI). write_vhdl_declarative_item(DI) --> write_vhdl_file_declaration(DI). write_vhdl_declarative_item(DI) --> write_vhdl_alias_declaration(DI). write_vhdl_declarative_item(DI) --> write_vhdl_subprogram_declaration_or_body(DI). write_vhdl_declarative_item(DI) --> write_vhdl_component_declaration(DI). write_vhdl_declarative_item(DI) --> write_vhdl_attribute_declaration(DI). write_vhdl_declarative_item(DI) --> write_vhdl_attribute_specification(DI). write_vhdl_declarative_item(DI) --> write_vhdl_configuration_specification(DI). write_vhdl_declarative_item(DI) --> write_vhdl_disconnection_specification(DI). write_vhdl_declarative_item(DI) --> write_vhdl_use_clause(DI). write_vhdl_declarative_item(DI) --> write_vhdl_group_declaration(DI). write_vhdl_declarative_item(DI) --> write_vhdl_group_template_declaration(DI).
write_vhdl_opt_declarative_items([]) --> [].
write_vhdl_opt_declarative_items([I|Is]) -->
write_vhdl_declarative_item(I), ";", newline,
write_vhdl_opt_declarative_items(Is).
VHDL-93 supports the concept of groups and group templates not present in VHDL-87.
Rule 17a
write_vhdl_group_template_declaration(group_template(TID,CL)) -->
"group ", write_vhdl_identifier(TID), " is ",
"(", write_vhdl_entity_class_entry_list(CL), ")".
write_vhdl_entity_class_entry_list([C|CL]) -->
write_vhdl_entity_class_entry(C), !,
write_vhdl_entity_class_entry_list_aux(CL).
write_vhdl_entity_class_entry_list_aux([]) --> [ ].
write_vhdl_entity_class_entry_list_aux([C|CL]) -->
", ", !, write_vhdl_entity_class_entry(C),
write_vhdl_entity_class_entry_list_aux(CL).
write_vhdl_entity_class_entry(entity_class(EC,any)) -->
!, write_vhdl_entity_class(EC), " <> ".
write_vhdl_entity_class_entry(entity_class(EC,null)) -->
write_vhdl_entity_class(EC).
Rule 17b
write_vhdl_group_declaration(group(ID,TID,CL)) -->
"group ", write_vhdl_identifier(ID), " : ",
write_vhdl_name(TID),
"(", write_vhdl_group_constituents(CL), ")".
write_vhdl_group_constituents([L|CL]) -->
write_vhdl_constituent(L),
write_vhdl_group_constituents_aux(CL).
write_vhdl_group_constituents_aux([]) --> [ ].
write_vhdl_group_constituents_aux([L|CL]) -->
", ", write_vhdl_constituent(L),
write_vhdl_group_constituents_aux(CL).
write_vhdl_constituent(L) --> write_vhdl_name(L).
write_vhdl_constituent(char(L)) --> "'", [ L ], "'".
Rule 18
write_vhdl_subprogram_declaration_or_body(sub_program(SS,Body)) -->
newline,
write_vhdl_subprogram_specification(Name,SS),
write_vhdl_opt_subprogram_body(Name,Body).
Rule 19
write_vhdl_subprogram_specification(D,sub_spec(D,IL,null,null)) -->
!, "procedure ", write_vhdl_designator(D),
write_vhdl_opt_interface_list(all_in_line,IL).
write_vhdl_subprogram_specification(D,sub_spec(D,IL,TM,P)) -->
({ P = impure } -> "impure " ; []),
"function ", write_vhdl_designator(D),
write_vhdl_opt_interface_list(all_in_line,IL),
" return ", write_vhdl_mark(TM).
Rule 20
write_vhdl_opt_subprogram_body(_,null) --> !, [].
write_vhdl_opt_subprogram_body(Name,program_body(Is,Ss)) -->
" is ",
[indent],
write_vhdl_opt_declarative_items(Is),
[undent],
"begin ",
[indent],
write_vhdl_sequential_statements(Ss),
[undent],
"end ", write_vhdl_designator(Name).
Rule 21
write_vhdl_opt_interface_list(_,[]) --> !, [].
write_vhdl_opt_interface_list(Indent_Mode,Is) -->
write_vhdl_interface_list(Indent_Mode,Is).
write_vhdl_interface_list(Indent_Mode,Is) -->
"(", write_vhdl_interface_elements(Indent_Mode,Is).
write_vhdl_interface_elements(Indent_Mode,[I|Is]) -->
write_vhdl_interface_element(I),
write_vhdl_ie_sub(Indent_Mode,Is).
write_vhdl_ie_sub(all_in_line,[]) --> !, ")".
write_vhdl_ie_sub(all_in_line,Is) --> "; ",
write_vhdl_interface_elements(all_in_line,Is).
write_vhdl_ie_sub(one_per_line,[]) --> !, ")".
write_vhdl_ie_sub(one_per_line,Is) --> ";", newline,
write_vhdl_interface_elements(one_per_line,Is).
Rule 22
write_vhdl_interface_element(interface_element(Class,IL,Mode,SubType,Bus,Expr)) -->
write_vhdl_opt_object_class(Class),
write_vhdl_identifier_list(IL), " :",
write_vhdl_opt_mode(Mode),
write_vhdl_subtype_indication(SubType),
write_vhdl_opt_bus(Bus), write_vhdl_opt_assignment(Expr).
Rule 23
write_vhdl_opt_mode(in) --> "in ". write_vhdl_opt_mode(out) --> "out ". write_vhdl_opt_mode(inout) --> "inout ". write_vhdl_opt_mode(buffer) --> "buffer ". write_vhdl_opt_mode(linkage) --> "linkage ". write_vhdl_opt_mode(null) --> [].
write_vhdl_opt_bus(null) --> []. write_vhdl_opt_bus(bus) --> " bus ".
Rule 24
write_vhdl_association_list([A|As]) -->
"(", write_vhdl_association_element(A),
write_vhdl_more_association_list(As).
write_vhdl_more_association_list([]) --> !, ")".
write_vhdl_more_association_list([A|As]) -->
", ", write_vhdl_association_element(A),
write_vhdl_more_association_list(As).
write_vhdl_opt_association_list([]) --> !, []. write_vhdl_opt_association_list(A) --> write_vhdl_association_list(A).
Rule 25
write_vhdl_association_element(element(Formal,Actual)) -->
write_vhdl_opt_formal_part(Formal),
write_vhdl_actual_part(Actual).
Rule 26
write_vhdl_formal_part(Name) --> write_vhdl_name(Name).
write_vhdl_formal_part(formal(FM,Name)) -->
write_vhdl_mark(FM), "(", write_vhdl_name(Name), ")".
write_vhdl_opt_formal_part(null) --> !, []. write_vhdl_opt_formal_part(Name) --> write_vhdl_formal_part(Name), " => ".
Rule 27
write_vhdl_actual_part(open) --> !, " open ". write_vhdl_actual_part(Expr) --> write_vhdl_expression(Expr).
Rule 28
write_vhdl_mark(attr_name([N,A|As])) -->
write_vhdl_identifier(N), !, write_vhdl_opt_attrs([A|As]).
write_vhdl_mark(SN) --> write_vhdl_selected_name(SN).
write_vhdl_mark(ID) --> write_vhdl_identifier(ID).
write_vhdl_opt_mark(null) --> !, []. write_vhdl_opt_mark(M) --> write_vhdl_mark(M).
Rule 29
write_vhdl_expression(expr(Op,[F|EL])) -->
!, write_vhdl_relation(F),
write_vhdl_relation_list(Op,EL).
write_vhdl_expression(expr(Op,F,E)) -->
!, write_vhdl_relation(F),
write_vhdl_boolop_non_associative(Op),
write_vhdl_relation(E).
write_vhdl_expression(E) --> write_vhdl_relation(E).
write_vhdl_relation_list(_,[ ]) --> [ ].
write_vhdl_relation_list(Op,[E|EL]) -->
write_vhdl_boolop_associative(Op),
write_vhdl_relation(E),
write_vhdl_relation_list(Op,EL).
write_vhdl_relation(rel(Op,F,E)) -->
!, write_vhdl_shift_expression(F),
write_vhdl_relational_operator(Op),
write_vhdl_shift_expression(E).
write_vhdl_relation(E) --> write_vhdl_shift_expression(E).
write_vhdl_shift_expression(shift(Op,F,E)) -->
!, "(",
write_vhdl_simple_expression(F),
write_vhdl_shift_operator(Op),
write_vhdl_simple_expression(E),
")".
write_vhdl_shift_expression(E) -->
write_vhdl_simple_expression(E).
write_vhdl_simple_expression(signed(Uop,F)) -->
!, write_vhdl_sign(Uop), write_vhdl_term(F).
write_vhdl_simple_expression(term(T,Op,F)) -->
!, write_vhdl_simple_expression(T),
write_vhdl_adding_operator(Op),
write_vhdl_term(F).
write_vhdl_simple_expression(E) -->
write_vhdl_term(E).
write_vhdl_term(factor(T,Op,F)) -->
!, write_vhdl_term(T),
write_vhdl_multiplying_operator(Op),
write_vhdl_factor(F).
write_vhdl_term(F) -->
write_vhdl_factor(F).
write_vhdl_factor(nott(P)) -->
!, " not ", write_vhdl_primary(P).
write_vhdl_factor(abs(P)) -->
!, " abs ", write_vhdl_primary(P).
write_vhdl_factor(expt(P1,P2)) -->
!, write_vhdl_primary(P1),
" ** ", write_vhdl_primary(P2).
write_vhdl_factor(F) --> write_vhdl_primary(F).
Rule 30
write_vhdl_primary(P) --> write_vhdl_aggregate(P).
write_vhdl_primary(P) --> write_vhdl_function_call(P).
write_vhdl_primary(P) --> write_vhdl_qualified_expression(P).
write_vhdl_primary(P) --> write_vhdl_name(P).
write_vhdl_primary(P) --> write_vhdl_literal(P).
write_vhdl_primary(P) --> write_vhdl_type_conversion(P).
write_vhdl_primary(P) --> write_vhdl_allocator(P).
% write_vhdl_primary(P) --> "(", write_vhdl_expression(P),")".
write_vhdl_primary(P) -->
({functor(P,F,_),
member(F,[expr,rel,shift,signed,term,factor,nott,abs,expt] )}
-> "(", write_vhdl_expression(P), ")"
; [ ]).
%HACK: to avoid infinite loop thro parenthesized primary
Rule 31
write_vhdl_name(attr_name([N,A|As])) --> !,
write_vhdl_designator(N),
write_vhdl_attr(A),
write_vhdl_opt_attrs(As).
write_vhdl_name(N) --> write_vhdl_indexed_name(N).
write_vhdl_name(N) --> write_vhdl_selected_name(N).
write_vhdl_name(N) --> write_vhdl_slice_name(N).
write_vhdl_name(N) --> write_vhdl_designator(N).
write_vhdl_name(N) --> write_vhdl_attribute_name(N).
write_vhdl_opt_attrs([]) --> [].
write_vhdl_opt_attrs([A|As]) -->
write_vhdl_attr(A),
write_vhdl_opt_attrs(As).
write_vhdl_attr(A) --> "'", write_vhdl_identifier(A).
Rule 32
write_vhdl_selected_name(vhdl_name(P,S)) -->
write_vhdl_prefix(P), ".", write_vhdl_suffix(S).
Rule 33
This rule is much simpler than its parser counterpart. Since it merely has to write out the prefix subunits as it encounters them. The version of Rule 33 in the parser had to construct a binary tree by passing the first part of the prefix down as it searched for trailing components of a complex prefix.
write_vhdl_prefix(prefix(Prefix)) --> !,
write_vhdl_prefix(Prefix).
write_vhdl_prefix(function_call(P1,Args,P2)) --> !,
write_vhdl_prefix(P1),
write_vhdl_association_list(Args),
write_vhdl_prefix(P2).
write_vhdl_prefix(slice(P1,R,P2)) --> !,
write_vhdl_prefix(P1),
"(", write_vhdl_discrete_range(R), ")",
write_vhdl_prefix(P2).
write_vhdl_prefix(select(P1,P2)) --> !,
write_vhdl_prefix(P1), ".", write_vhdl_prefix(P2).
write_vhdl_prefix(attribute(P1,Attr,E,P2)) --> !,
write_vhdl_prefix(P1),
write_vhdl_attr(Attr),
write_vhdl_opt_paren_expression(E),
write_vhdl_prefix(P2).
write_vhdl_prefix(P) --> write_vhdl_identifier(P).
write_vhdl_opt_paren_expression(null) --> !, [].
write_vhdl_opt_paren_expression(E) -->
"(", write_vhdl_expression(E), ")".
Rule 34
write_vhdl_suffix(char(C)) --> !, "'",[C],"' ".
write_vhdl_suffix(all) --> !, " all ".
write_vhdl_suffix(dot(S,S2)) --> !,
write_vhdl_designator(S), ".",
write_vhdl_suffix(S2).
write_vhdl_suffix(S) --> write_vhdl_designator(S).
Rule 35
write_vhdl_indexed_name(vhdl_name(P,[E|Es])) -->
write_vhdl_prefix(P), "(",
write_vhdl_expression(E),
write_vhdl_expression_list(Es).
write_vhdl_expression_list([]) --> ")".
write_vhdl_expression_list([Expr|Exprs]) -->
",", write_vhdl_expression(Expr),
write_vhdl_expression_list(Exprs).
Rule 36
write_vhdl_slice_name(vhdl_name(P,Range)) -->
write_vhdl_prefix(P),
"(", write_vhdl_discrete_range(Range), ")".
Rule 37
write_vhdl_attribute_name(vhdl_name(P,Attr,Expr)) -->
write_vhdl_prefix(P),
write_vhdl_attr(Attr),
write_vhdl_opt_static_expression(Expr).
write_vhdl_opt_static_expression(null) --> !, [].
write_vhdl_opt_static_expression(Expr) -->
"(", write_vhdl_expression(Expr), ")".
Rule 38
write_vhdl_function_call(vhdl_call(Call,Args)) -->
write_vhdl_name(Call), write_vhdl_opt_association_list(Args).
Rule 39
write_vhdl_aggregate([A|As]) -->
"(", write_vhdl_element_association(A),
write_vhdl_more_aggregate(As).
write_vhdl_more_aggregate([]) --> ")".
write_vhdl_more_aggregate([A|As]) -->
", ", write_vhdl_element_association(A),
write_vhdl_more_aggregate(As).
Rule 40
write_vhdl_qualified_expression(qual_expr(Type,Expr)) -->
write_vhdl_mark(Type), "'",
"(", write_vhdl_expression_or_aggregate(Expr), ")".
write_vhdl_expression_or_aggregate(Expr) -->
write_vhdl_expression(Expr).
write_vhdl_expression_or_aggregate(aggregate(Ag)) -->
write_vhdl_aggregate(Ag).
Rule 41
write_vhdl_type_conversion(type_conversion(Type,Expr)) -->
write_vhdl_mark(Type), "(", write_vhdl_expression(Expr), ")".
Rule 42
write_vhdl_allocator(A) --> " new ", write_vhdl_alloc_subterm(A).
write_vhdl_alloc_subterm(A) -->
write_vhdl_subtype_indication(A).
write_vhdl_alloc_subterm(A) -->
write_vhdl_qualified_expression(A).
Rule 43
write_vhdl_boolop_associative(and) --> " and ".
write_vhdl_boolop_associative(or) --> " or ".
write_vhdl_boolop_associative(xor) --> " xor ".
write_vhdl_boolop_associative(xnor) --> " xnor ".
write_vhdl_boolop_non_associative(nand) --> " nand ".
write_vhdl_boolop_non_associative(nor) --> " nor ".
write_vhdl_relational_operator('=') --> " = ".
write_vhdl_relational_operator('/=') --> " /= ".
write_vhdl_relational_operator('<') --> " < ".
write_vhdl_relational_operator('>') --> " > ".
write_vhdl_relational_operator('<=') --> " <= ".
write_vhdl_relational_operator('>=') --> " >= ".
write_vhdl_shift_operator(sll) --> " sll ".
write_vhdl_shift_operator(srl) --> " srl ".
write_vhdl_shift_operator(sla) --> " sla ".
write_vhdl_shift_operator(sra) --> " sra ".
write_vhdl_shift_operator(rol) --> " rol ".
write_vhdl_shift_operator(ror) --> " ror ".
write_vhdl_adding_operator('+') --> " + ".
write_vhdl_adding_operator('-') --> " - ".
write_vhdl_adding_operator('&') --> " & ".
write_vhdl_sign('+') --> " + ".
write_vhdl_sign('-') --> " - ".
write_vhdl_multiplying_operator('*') --> " * ".
write_vhdl_multiplying_operator('/') --> " / ".
write_vhdl_multiplying_operator(mod) --> " mod ".
write_vhdl_multiplying_operator(rem) --> " rem ".
Rule 44
Rule 45
We need an entirely new clause (the first one) to handle the case of an empty set of choices.
write_vhdl_element_association(element_association(null,Expr)) -->
!, write_vhdl_expression(Expr).
write_vhdl_element_association(element_association(C,Expr)) -->
write_vhdl_choices(C), " => ", write_vhdl_expression(Expr).
Rule 46
write_vhdl_choices([C|Cs]) -->
write_vhdl_choice(C), write_vhdl_more_choices(Cs).
write_vhdl_more_choices([]) --> [].
write_vhdl_more_choices([C|Cs]) -->
" | ", write_vhdl_choice(C),
write_vhdl_more_choices(Cs).
Rule 47
write_vhdl_choice(others) --> !, " others ". write_vhdl_choice(C) --> write_vhdl_discrete_range(C). write_vhdl_choice(C) --> write_vhdl_expression(C).
Rule 48
write_vhdl_type_declaration(vhdl_type(ID,null)) -->
!, "type ", write_vhdl_identifier(ID).
write_vhdl_type_declaration(vhdl_type(ID,Definition)) -->
"type ", write_vhdl_identifier(ID), " is ",
[indent], write_vhdl_type_definition_2(Definition), [undent], !.
write_vhdl_type_declaration(vhdl_type(ID,Definition)) -->
"type ", write_vhdl_identifier(ID), " is ",
write_vhdl_type_definition_1(Definition).
Rule 49
write_vhdl_type_definition_1(Def) -->
write_vhdl_enumeration_type_definition(Def).
write_vhdl_type_definition_1(Range) -->
write_vhdl_range_constraint(Range).
write_vhdl_type_definition_1(Physical) -->
write_vhdl_physical_type_definition(Physical).
write_vhdl_type_definition_2(Array) -->
write_vhdl_unconstrained_array_definition(Array).
write_vhdl_type_definition_2(Array) -->
write_vhdl_constrained_array_definition(Array).
write_vhdl_type_definition_2(RType) -->
write_vhdl_record_type_definition(RType).
write_vhdl_type_definition_2(Access) -->
write_vhdl_access_type_definition(Access).
write_vhdl_type_definition_2(FileType) -->
write_vhdl_file_type_definition(FileType).
Rule 50
write_vhdl_enumeration_type_definition([E|Enums]) -->
"(", write_vhdl_enumeration_literal(E),
write_vhdl_enumeration_literal_list(Enums).
write_vhdl_enumeration_literal_list([]) --> !, ")".
write_vhdl_enumeration_literal_list([E|Es]) -->
",", write_vhdl_enumeration_literal(E),
write_vhdl_enumeration_literal_list(Es).
Rule 51
write_vhdl_physical_type_definition(vhdl_type(Range,Base,Secondary)) -->
write_vhdl_range_constraint(Range),
"units ",
write_vhdl_base_unit_declaration(Base),
write_vhdl_secondary_unit_declarations(Secondary),
"end units".
write_vhdl_secondary_unit_declarations([]) --> [].
write_vhdl_secondary_unit_declarations([S|Ss]) -->
write_vhdl_secondary_unit_declaration(S),
write_vhdl_secondary_unit_declarations(Ss).
Rule 52
write_vhdl_base_unit_declaration(ID) -->
write_vhdl_identifier(ID).
Rule 53
write_vhdl_secondary_unit_declaration(vhdl_sec(ID,PL)) -->
write_vhdl_identifier(ID), "=",
write_vhdl_physical_literal(PL).
Rule 54
write_vhdl_unconstrained_array_definition(vhdl_array([ISD|ISDs],SI)) -->
" array (",
write_vhdl_index_subtype_definition(ISD),
write_vhdl_index_subtype_definitions(ISDs),
" of ", write_vhdl_subtype_indication(SI).
write_vhdl_index_subtype_definitions([]) --> ")".
write_vhdl_index_subtype_definitions([I|Is]) -->
",", write_vhdl_index_subtype_definition(I),
write_vhdl_index_subtype_definitions(Is).
Rule 55
write_vhdl_index_subtype_definition(TM) -->
write_vhdl_mark(TM), " range <>".
Rule 56
write_vhdl_constrained_array_definition(vhdl_array(IC,SI)) -->
" array ", write_vhdl_index_constraint(IC),
" of ", write_vhdl_subtype_indication(SI).
Rule 57
write_vhdl_record_type_definition(record(EDs)) -->
"record ",
[indent],
write_vhdl_element_declarations(EDs),
[undent],
"end record".
Rule 58
write_vhdl_element_declaration(vhdl_element(Is,SI)) -->
write_vhdl_identifier_list(Is), " : ",
write_vhdl_subtype_indication(SI), ";".
write_vhdl_element_declarations([]) --> [].
write_vhdl_element_declarations([E|Es]) -->
write_vhdl_element_declaration(E),
write_vhdl_element_declarations(Es).
Rule 59
write_vhdl_access_type_definition(vhdl_access(TD)) -->
"access ", write_vhdl_subtype_indication(TD).
Rule 60
write_vhdl_file_type_definition(vhdl_filetype(Type)) -->
"file of ", write_vhdl_mark(Type).
Rule 61
write_vhdl_subtype_declaration(vhdl_subtype(ID,TD)) -->
"subtype ", write_vhdl_identifier(ID), " is ",
[indent], write_vhdl_subtype_indication(TD), [undent].
Rule 62
write_vhdl_subtype_indication(vhdl_subtype(FM,TM,C))-->
write_vhdl_opt_mark(FM), " ",
write_vhdl_mark(TM),
write_vhdl_opt_constraint(C).
Rule 63
write_vhdl_opt_constraint(null) --> !, []. write_vhdl_opt_constraint(C) --> write_vhdl_constraint(C). write_vhdl_constraint(R) --> write_vhdl_range_constraint(R). write_vhdl_constraint(I) --> write_vhdl_index_constraint(I).
Rule 64
write_vhdl_range_constraint(S) -->
" range ", write_vhdl_range_specification(S).
Rule 65
write_vhdl_index_constraint(index([R|Rs])) -->
"(", write_vhdl_discrete_range(R),
write_vhdl_more_discrete_ranges(Rs).
write_vhdl_more_discrete_ranges([]) --> ")".
write_vhdl_more_discrete_ranges([R|Rs]) -->
",", write_vhdl_discrete_range(R),
write_vhdl_more_discrete_ranges(Rs).
Rule 66
write_vhdl_discrete_range(R) -->
write_vhdl_range_specification(R).
write_vhdl_discrete_range(R) -->
write_vhdl_subtype_indication(R).
Rule 67
write_vhdl_range_specification(vhdl_range(vhdl_name(P,Exprs,range),SE)) -->
!, write_vhdl_indexed_name(vhdl_name(P,Exprs,[range])),
write_vhdl_opt_static_expression(SE).
write_vhdl_range_specification(vhdl_range(E1,D,E2)) -->
write_vhdl_expression(E1),
write_vhdl_direction(D), !,
write_vhdl_expression(E2).
write_vhdl_range_specification(vhdl_range(TM,Sign,SE)) -->
write_vhdl_mark(TM),
write_vhdl_opt_signature(Sign), "'range ", !,
write_vhdl_opt_static_expression(SE).
write_vhdl_range_specification(vhdl_range(TM,Sign,SE)) -->
write_vhdl_function_call(TM),
write_vhdl_opt_signature(Sign), "'range ", !,
write_vhdl_opt_static_expression(SE).
Rule 68
write_vhdl_direction(to) --> " to ". write_vhdl_direction(downto) --> " downto ".
Rule 69
write_vhdl_object_declaration(object_declaration(Class,IDs,Type,Kind,Expr)) -->
write_vhdl_object_class(Class),
write_vhdl_identifier_list(IDs), " : ",
write_vhdl_subtype_indication(Type),
write_vhdl_opt_signal_kind(Kind),
write_vhdl_opt_assignment(Expr).
write_vhdl_opt_assignment(null) --> !, [].
write_vhdl_opt_assignment(vhdl_assign(Expr)) -->
" := ", write_vhdl_expression(Expr).
Rule 70
write_vhdl_object_class(signal) --> "signal ". write_vhdl_object_class(constant) --> "constant ". write_vhdl_object_class(variable) --> "variable ". write_vhdl_object_class(shared_variable) --> "shared variable ". write_vhdl_object_class(file) --> "file ".
write_vhdl_opt_object_class(null) --> !, []. write_vhdl_opt_object_class(Class) --> write_vhdl_object_class(Class).
Rule 71
write_vhdl_opt_signal_kind(bus) --> " bus ". write_vhdl_opt_signal_kind(register) --> " register ". write_vhdl_opt_signal_kind(null) --> [].
Rule 72
write_vhdl_alias_declaration(vhdl_alias(ID,null,Name,Sign)) -->
!, "alias ", write_vhdl_alias_designator(ID), " is ",
write_vhdl_name(Name), write_vhdl_opt_signature(Sign).
write_vhdl_alias_declaration(vhdl_alias(ID,Type,Name,Sign)) -->
!, "alias ", write_vhdl_alias_designator(ID), ":",
write_vhdl_subtype_indication(Type), " is ",
write_vhdl_name(Name), write_vhdl_opt_signature(Sign).
write_vhdl_alias_designator(char(L)) --> !, ['''',L,'''']. %**FIX
write_vhdl_alias_designator(ID) --> write_vhdl_designator(ID).
Rule 73
write_vhdl_file_declaration(vhdl_file(IDs,SI,Mode,null)) -->
!, "file ", write_vhdl_identifier_list(IDs), " : ",
write_vhdl_subtype_indication(SI), newline,
write_vhdl_opt_file_open_kind(Mode).
write_vhdl_file_declaration(vhdl_file(IDs,SI,Mode,Se)) -->
"file ", write_vhdl_identifier_list(IDs), " : ",
write_vhdl_subtype_indication(SI), newline,
write_vhdl_opt_file_open_kind(Mode), " is ",
write_vhdl_expression(Se), newline.
write_vhdl_opt_file_open_kind(null) --> !, [ ].
write_vhdl_opt_file_open_kind(Mode) -->
" open ", write_vhdl_file_mode(Mode).
write_vhdl_file_mode(read_mode) --> " read_mode ".
write_vhdl_file_mode(write_mode) --> " write_mode ".
write_vhdl_file_mode(append_mode) --> " append_mode ".
Rule 74
write_vhdl_disconnection_specification(disconnect_spec(SL,Type,Time)) -->
"disconnect ",
write_vhdl_signal_list(SL), " : ", write_vhdl_mark(Type),
" after ", write_vhdl_expression(Time), newline.
Rule 75
write_vhdl_signal_list(others) --> " others ".
write_vhdl_signal_list(all) --> " all ".
write_vhdl_signal_list([S]) --> !, write_vhdl_name(S).
write_vhdl_signal_list([S|Ss]) -->
write_vhdl_name(S), ",",
write_vhdl_signal_list(Ss).
Rule 75.5
write_vhdl_opt_mark_list([]) --> !, [].
write_vhdl_opt_mark_list([ID]) --> !, write_vhdl_mark(ID).
write_vhdl_opt_mark_list([ID|IDs]) -->
write_vhdl_mark(ID), " , ",
write_vhdl_opt_mark_list(IDs).
write_vhdl_opt_signature(null) --> [].
write_vhdl_opt_signature(signature(Ids,null)) -->
!, " [ ", write_vhdl_opt_mark_list(Ids), " ] ".
write_vhdl_opt_signature(signature(Ids,Id)) -->
" [ ", write_vhdl_opt_mark_list(Ids),
" return ", write_vhdl_mark(Id), " ] ".
Rule 76
write_vhdl_attribute_declaration(attribute_declaration(ID,Type)) -->
"attribute ",
write_vhdl_identifier(ID), " : ", write_vhdl_mark(Type).
Rule 77
write_vhdl_attribute_specification(attr_spec(ID,Entity,Expr)) -->
"attribute ", write_vhdl_identifier(ID),
" of ", write_vhdl_entity_specification(Entity), " is ",
write_vhdl_expression(Expr).
Rule 78
write_vhdl_entity_specification(entity_spec(Names,Class)) -->
write_vhdl_entity_name_list(Names),
" : ", write_vhdl_entity_class(Class).
Rule 79
write_vhdl_entity_name_list(others) --> " others".
write_vhdl_entity_name_list(all) --> " all".
write_vhdl_entity_name_list([D]) --> !, write_vhdl_entity_designator(D).
write_vhdl_entity_name_list([D|Ds]) -->
write_vhdl_entity_designator(D), ",", write_vhdl_entity_name_list(Ds).
write_vhdl_entity_designator(tag_sign(T,S)) -->
write_vhdl_entity_tag(T), write_vhdl_opt_signature(S).
write_vhdl_entity_tag(char(L)) --> !, [ L ].
write_vhdl_entity_tag(T) --> write_vhdl_designator(T).
Rule 80
write_vhdl_entity_class(entity) --> "entity ". write_vhdl_entity_class(architecture) --> "architecture ". write_vhdl_entity_class(package) --> "package ". write_vhdl_entity_class(configuration)--> "configuration ". write_vhdl_entity_class(component) --> "component ". write_vhdl_entity_class(label) --> "label ". write_vhdl_entity_class(type) --> "type ". write_vhdl_entity_class(subtype) --> "subtype ". write_vhdl_entity_class(procedure) --> "procedure ". write_vhdl_entity_class(function) --> "function ". write_vhdl_entity_class(signal) --> "signal ". write_vhdl_entity_class(variable) --> "variable ". write_vhdl_entity_class(constant) --> "constant ". write_vhdl_entity_class(literal) --> "literal ". write_vhdl_entity_class(units) --> "units ". write_vhdl_entity_class(group) --> "group ". write_vhdl_entity_class(file) --> "file ".
Rule 81
write_vhdl_generation_scheme(S) --> write_vhdl_if_scheme(S). write_vhdl_generation_scheme(S) --> write_vhdl_for_scheme(S).
Rule 82
write_vhdl_iteration_scheme(S) --> write_vhdl_for_scheme(S), !. write_vhdl_iteration_scheme(S) --> write_vhdl_while_scheme(S). write_vhdl_opt_iteration_scheme(null) --> !, []. write_vhdl_opt_iteration_scheme(S) --> write_vhdl_iteration_scheme(S).
Rule 83
write_vhdl_if_scheme(if(Expr)) -->
" if ", write_vhdl_expression(Expr).
Rule 84
write_vhdl_for_scheme(for(ID,Range)) -->
"for ", write_vhdl_identifier(ID),
" in ", write_vhdl_discrete_range(Range).
Rule 85
write_vhdl_while_scheme(while(Expr)) -->
" while ", write_vhdl_expression(Expr), newline.
Rule 86
write_vhdl_concurrent_statements([]) --> [].
write_vhdl_concurrent_statements([S]) -->
!, write_vhdl_concurrent_statement(S), ";".
write_vhdl_concurrent_statements([S|Ss]) -->
write_vhdl_concurrent_statement(S), ";", newline,
write_vhdl_concurrent_statements(Ss).
Rule 87
write_vhdl_concurrent_statement(S) -->
write_vhdl_block_statement(S).
write_vhdl_concurrent_statement(S) -->
write_vhdl_concurrent_assertion_statement(S).
write_vhdl_concurrent_statement(S) -->
write_vhdl_concurrent_procedure_call(S).
write_vhdl_concurrent_statement(S) -->
write_vhdl_component_instantiation_statement(S).
write_vhdl_concurrent_statement(S) -->
write_vhdl_concurrent_signal_assignment_statement(S).
write_vhdl_concurrent_statement(S) -->
write_vhdl_generate_statement(S).
write_vhdl_concurrent_statement(S) -->
write_vhdl_process_statement(S).
Rule 88
write_vhdl_block_statement(block(ID,Expr,GIL,GAL,PIL,PAL,ODI,Ss)) -->
write_vhdl_identifier(ID), " : ",
"block ",
[indent],
write_vhdl_opt_paren_expression(Expr),
" is ",
write_vhdl_opt_generic_semi(GIL),
write_vhdl_opt_generic_map_semi(GAL),
write_vhdl_opt_port_semi(PIL),
write_vhdl_opt_port_map_semi(PAL),
write_vhdl_opt_declarative_items(ODI),
[undent],
"begin ",
[indent],
write_vhdl_concurrent_statements(Ss),
[undent],
"end block ", write_vhdl_identifier(ID).
Rule 89
write_vhdl_component_instantiation_statement(comp_instant(ID,IU,AL1,AL2)) -->
write_vhdl_identifier(ID), " : ",
write_vhdl_instantiated_unit(IU),
write_vhdl_opt_generic_map_statement(AL1),
write_vhdl_opt_port_map_statement(AL2).
Rule 89a
write_vhdl_instantiated_unit(comp(CM)) -->
" component ", write_vhdl_mark(CM).
write_vhdl_instantiated_unit(entity(EID,null)) -->
!, " entity ", write_vhdl_mark(EID).
write_vhdl_instantiated_unit(entity(EID,AID)) -->
" entity ", write_vhdl_mark(EID),
" (", write_vhdl_identifier(AID), ") ".
write_vhdl_instantiated_unit(config(CID)) -->
" configuration ", write_vhdl_mark(CID).
Rule 90
write_vhdl_concurrent_assertion_statement(concurrent_assertion(ID,Post,Stmt)) -->
write_vhdl_opt_label(ID), vhdl_opt_postponed(Post),
write_vhdl_assertion_statement(Stmt).
write_vhdl_opt_postponed(postponed) --> " postponed ".
write_vhdl_opt_postponed(null) --> [ ].
Rule 91
write_vhdl_concurrent_procedure_call(cpc(ID,Post,S)) -->
write_vhdl_opt_label(ID), vhdl_opt_postponed(Post),
write_vhdl_procedure_call_statement(S).
Rule 92
write_vhdl_concurrent_signal_assignment_statement(csas(ID,Post,CSAS)) -->
write_vhdl_opt_label(ID), vhdl_opt_postponed(Post),
write_vhdl_conditional_signal_assignment(CSAS).
write_vhdl_concurrent_signal_assignment_statement(ssas(ID,Post,CSAS)) -->
write_vhdl_opt_label(ID), write_vhdl_opt_postponed(Post),
write_vhdl_selected_signal_assignment_statement(CSAS).
write_vhdl_concurrent_signal_assignment_statement(null) --> [ ].
Rule 93
write_vhdl_conditional_signal_assignment(csa(T,G,RT,Tr,W)) -->
write_vhdl_target(T), " <= ",
write_vhdl_opt_delay_mechanism(G,RT,Tr),
write_vhdl_conditional_waveforms(W).
Rule 94
write_vhdl_conditional_waveforms([wave(W,Cond)|Ws]) -->
write_vhdl_waveform(W),
write_vhdl_opt_conditional_waveforms(Cond,Ws).
write_vhdl_opt_conditional_waveforms(null,[]) --> !, [].
write_vhdl_opt_conditional_waveforms(Expr,[]) -->
!, " when ", write_vhdl_expression(Expr).
write_vhdl_opt_conditional_waveforms(Expr,Ws) -->
" when ", write_vhdl_expression(Expr),
" else ", write_vhdl_conditional_waveforms(Ws).
Rule 95
write_vhdl_waveform(unaffected) --> " unaffected ".
write_vhdl_waveform([WE|WEs]) -->
write_vhdl_waveform_element(WE), write_vhdl_opt_waveforms(WEs).
write_vhdl_opt_waveforms([]) --> [].
write_vhdl_opt_waveforms([WE|WEs]) -->
",", write_vhdl_waveform_element(WE),
write_vhdl_opt_waveforms(WEs).
Rule 96
write_vhdl_waveform_element(event(null,Time)) --> !,
" null ", write_vhdl_opt_delay(Time).
write_vhdl_waveform_element(event(Expr,Time)) -->
write_vhdl_expression(Expr), write_vhdl_opt_delay(Time).
write_vhdl_opt_delay(null) --> !, [].
write_vhdl_opt_delay(Time) -->
" after ", write_vhdl_expression(Time).
Rule 97
write_vhdl_target(N) --> write_vhdl_name(N). write_vhdl_target(A) --> write_vhdl_aggregate(A).
Rule 98
write_vhdl_opt_delay_mechanism(null,null,null) --> !, [].
write_vhdl_opt_delay_mechanism(null,null,transport) --> !, " transport ".
write_vhdl_opt_delay_mechanism(null,null,inertial) --> !, " inertial ".
write_vhdl_opt_delay_mechanism(null,RT,inertial) -->
!, " reject ", write_vhdl_expression(RT), " inertial ".
write_vhdl_opt_delay_mechanism(guarded,RT,TM) -->
!, " guarded ", write_vhdl_opt_delay_mechanism(null,RT,TM).
Rule 99
write_vhdl_selected_signal_assignment_statement(selected(Expr,Target,G,RT,T,Ws)) -->
"with ", write_vhdl_expression(Expr), " select ",
[indent],
write_vhdl_target(Target),
" <= ", write_vhdl_opt_delay_mechanism(G,RT,T),
[indent],
write_vhdl_selected_waveforms(Ws),
[dent, undent].
Rule 100
write_vhdl_selected_waveform(vhdl_waveform(W,Cs)) -->
write_vhdl_waveform(W), " when ", write_vhdl_choices(Cs).
write_vhdl_selected_waveforms([SW|SWs]) -->
write_vhdl_selected_waveform(SW),
write_vhdl_additional_selected_waveforms(SWs).
write_vhdl_additional_selected_waveforms([]) --> !, [].
write_vhdl_additional_selected_waveforms(SWs) -->
",", newline, write_vhdl_selected_waveforms(SWs).
Rule 101
write_vhdl_generate_statement(generate(ID,Scheme,null,Ss)) -->
!, write_vhdl_identifier(ID), " : ",
write_vhdl_generation_scheme(Scheme), " generate ",
[indent],
write_vhdl_concurrent_statements(Ss),
[undent],
"end generate ", write_vhdl_identifier(ID).
write_vhdl_generate_statement(generate(ID,Scheme,DI,Ss)) -->
write_vhdl_identifier(ID), " : ",
write_vhdl_generation_scheme(Scheme), " generate ",
[indent],
newline, write_vhdl_opt_declarative_items(DI), newline,
"begin ",
write_vhdl_concurrent_statements(Ss),
[undent],
"end generate ", write_vhdl_identifier(ID).
Rule 102
write_vhdl_process_statement(vhdl_process(ID,Post,SL,DI,Ss)) -->
write_vhdl_opt_label(ID), write_vhdl_opt_postponed(Post),
"process ", write_vhdl_opt_sensitivity_list(SL), " is ",
[indent],
write_vhdl_opt_declarative_items(DI),
"begin ",
[indent],
write_vhdl_sequential_statements(Ss),
[dent, undent],
"end process ".
write_vhdl_opt_label(null) --> !, [].
write_vhdl_opt_label(ID) --> write_vhdl_identifier(ID), " : ".
write_vhdl_opt_label_use(null) --> !, [].
write_vhdl_opt_label_use(ID) --> write_vhdl_identifier(ID).
write_vhdl_opt_sensitivity_list([]) --> [].
write_vhdl_opt_sensitivity_list(SL) -->
"(", write_vhdl_sensitivity_list(SL), ")".
Rule 103
write_vhdl_sensitivity_list([S]) --> !, write_vhdl_name(S).
write_vhdl_sensitivity_list([S|Ss]) -->
write_vhdl_name(S), ",", write_vhdl_sensitivity_list(Ss).
Rule 104
write_vhdl_sequential_statements([]) --> [].
write_vhdl_sequential_statements([S]) -->
!, write_vhdl_sequential_statement(S), ";".
write_vhdl_sequential_statements([S|Ss]) -->
write_vhdl_sequential_statement(S), ";", newline,
write_vhdl_sequential_statements(Ss).
Rule 105
write_vhdl_sequential_statement(S) --> write_vhdl_assertion_statement(S). write_vhdl_sequential_statement(S) --> write_vhdl_report_statement(S). write_vhdl_sequential_statement(S) --> write_vhdl_case_statement(S). write_vhdl_sequential_statement(S) --> write_vhdl_exit_statement(S). write_vhdl_sequential_statement(S) --> write_vhdl_if_statement(S). write_vhdl_sequential_statement(S) --> write_vhdl_loop_statement(S). write_vhdl_sequential_statement(S) --> write_vhdl_next_statement(S). write_vhdl_sequential_statement(S) --> write_vhdl_null_statement(S). write_vhdl_sequential_statement(S) --> write_vhdl_procedure_call_statement(S). write_vhdl_sequential_statement(S) --> write_vhdl_return_statement(S). write_vhdl_sequential_statement(S) --> write_vhdl_signal_assignment_statement(S). write_vhdl_sequential_statement(S) --> write_vhdl_variable_assignment_statement(S). write_vhdl_sequential_statement(S) --> write_vhdl_wait_statement(S).
Rule 106
write_vhdl_assertion_statement(assert(LID,Assertion,String,Severity)) -->
write_vhdl_opt_label(LID),
"assert ", write_vhdl_expression(Assertion), " ",
write_vhdl_opt_report(String),
write_vhdl_opt_severity(Severity).
write_vhdl_opt_report(null) --> !, [].
write_vhdl_opt_report(R) --> "report ", write_vhdl_expression(R).
write_vhdl_opt_severity(null) --> !, [].
write_vhdl_opt_severity(S) --> " severity ", write_vhdl_expression(S).
Rule 106a
write_vhdl_report_statement(report(LID,String,Severity)) -->
write_vhdl_opt_label(LID),
"report ", !,
write_vhdl_expression(String),
write_vhdl_opt_severity(Severity).
Rule 107
write_vhdl_case_statement(case(LID,Cond,Cases)) -->
write_vhdl_opt_label(LID),
"case ", write_vhdl_expression(Cond), " is ",
[indent],
write_vhdl_case_statement_alternatives(Cases),
[undent],
"end case".
Rule 108
write_vhdl_case_statement_alternatives([]) --> [].
write_vhdl_case_statement_alternatives([vhdl_case(Choices,Ss)|Cases]) -->
" when ", write_vhdl_choices(Choices), " => ",
[indent],
write_vhdl_sequential_statements(Ss),
[undent],
write_vhdl_case_statement_alternatives(Cases).
Rule 109
write_vhdl_exit_statement(vhdl_exit(LID,ID,null)) -->
!, write_vhdl_opt_label(LID),
"exit ", write_vhdl_opt_label_use(ID).
write_vhdl_exit_statement(vhdl_exit(LID,ID,Expr)) -->
write_vhdl_opt_label(LID),
"exit ", write_vhdl_opt_label_use(ID),
"when ", write_vhdl_expression(Expr).
Rule 110
write_vhdl_if_statement(vhdl_if(LID,Cond,Thens,Elses)) -->
write_vhdl_opt_label(LID),
"if ", write_vhdl_expression(Cond), " then ",
[indent],
write_vhdl_sequential_statements(Thens),
[undent],
write_vhdl_else(Elses),
"end if".
write_vhdl_else([]) --> !, [].
write_vhdl_else(elsif(ECond,Thens,Else)) --> !,
"elsif ",
[indent],
write_vhdl_expression(ECond),
[undent],
"then ",
[indent],
write_vhdl_sequential_statements(Thens),
[undent],
write_vhdl_else(Else).
write_vhdl_else(Elses) -->
"else ",
[indent],
write_vhdl_sequential_statements(Elses),
[undent].
Rule 111
write_vhdl_loop_statement(vhdl_loop(ID,IScheme,Ss)) -->
write_vhdl_opt_label(ID),
write_vhdl_opt_iteration_scheme(IScheme),
" loop ",
[indent],
write_vhdl_sequential_statements(Ss),
[undent],
"end loop ".
Rule 112
write_vhdl_next_statement(vhdl_next(LID,ID,null)) -->
!, write_vhdl_opt_label(LID),
"next ", write_vhdl_opt_label_use(ID).
write_vhdl_next_statement(vhdl_next(LID,ID,Expr)) -->
write_vhdl_opt_label(LID),
"next ", write_vhdl_opt_label_use(ID),
" when ", write_vhdl_expression(Expr).
Rule 113
write_vhdl_null_statement(null(LID)) -->
write_vhdl_opt_label(LID), "null ".
Rule 114
write_vhdl_procedure_call_statement(vhdl_call(LID,ID,Args)) -->
write_vhdl_opt_label(LID),
write_vhdl_name(ID), write_vhdl_opt_association_list(Args).
Rule 115
write_vhdl_return_statement(return(LID,Expr)) -->
write_vhdl_opt_label(LID),
"return ", write_vhdl_expression(Expr).
Rule 116
write_vhdl_signal_assignment_statement(signal(LID,T,RT,Mode,W)) -->
write_vhdl_opt_label(LID),
write_vhdl_target(T), " <= ",
write_vhdl_opt_delay_mechanism(null,RT,Mode),
write_vhdl_waveform(W).
Rule 117
write_vhdl_variable_assignment_statement(assign(LID,Var,Expr)) -->
write_vhdl_opt_label(LID),
write_vhdl_target(Var), " := ", write_vhdl_expression(Expr).
Rule 118
write_vhdl_wait_statement(vhdl_wait(LID,SL,Expr,Time)) -->
write_vhdl_opt_label(LID),
"wait ", write_vhdl_opt_on(SL),
write_vhdl_opt_until(Expr),
write_vhdl_opt_for_time(Time).
write_vhdl_opt_on(null) --> !, [].
write_vhdl_opt_on(SL) --> " on ", write_vhdl_sensitivity_list(SL).
write_vhdl_opt_until(null) --> !, [].
write_vhdl_opt_until(Expr) -->
" until ", write_vhdl_expression(Expr).
write_vhdl_opt_for_time(0) --> !, [].
write_vhdl_opt_for_time(Time) -->
" for ", write_vhdl_expression(Time).
Rule 119
write_vhdl_component_declaration(vhdl_comp(ID,GIL,PIL)) -->
"component ", write_vhdl_identifier(ID), " is ",
write_vhdl_opt_generic_statement(GIL),
write_vhdl_opt_port_statement(PIL),
"end component ", write_vhdl_identifier(ID).
Rule 120
write_vhdl_block_configuration(vhdl_conf(Spec,Use,CI)) -->
"for ", write_vhdl_block_specification(Spec), newline,
write_vhdl_opt_use_clauses(Use),
[indent],
write_vhdl_opt_configuration_items(CI),
[undent],
"end for;",
newline.
Rule 121
write_vhdl_block_specification(vhdl_name(ID,Index)) --> !,
write_vhdl_mark(ID),
"(", write_vhdl_index_specification(Index), ")".
write_vhdl_block_specification(vhdl_name(ID,null)) -->
write_vhdl_mark(ID).
Rule 122
write_vhdl_index_specification(Range) -->
write_vhdl_discrete_range(Range).
write_vhdl_index_specification(Expr) -->
write_vhdl_expression(Expr).
Rule 123
write_vhdl_opt_configuration_items([]) --> [ ].
write_vhdl_opt_configuration_items([CI|CIs]) -->
write_vhdl_configuration_item(CI),
write_vhdl_opt_configuration_items(CIs).
write_vhdl_configuration_item(BC) -->
write_vhdl_block_configuration(BC).
write_vhdl_configuration_item(CC) -->
write_vhdl_component_configuration(CC).
Rule 124
write_vhdl_component_configuration(vhdl_spec(CSpec,BI,null)) -->
!,"for ", write_vhdl_component_specification(CSpec),
[indent],
write_vhdl_opt_binding_indication(BI),
[undent],
"end for;",
newline.
write_vhdl_component_configuration(vhdl_spec(CSpec,BI,Ss)) -->
"for ", write_vhdl_component_specification(CSpec),
[indent],
write_vhdl_opt_binding_indication(BI),
[indent],
write_vhdl_block_configuration(Ss),
[undent],
[undent],
"end for;",
newline.
Rule 125
write_vhdl_configuration_specification(vhdl_spec(CSpec,BI)) -->
"for ", write_vhdl_component_specification(CSpec), " ",
[indent],
write_vhdl_opt_binding_indication(BI),
[undent]. % newline.
Rule 126
write_vhdl_component_specification(spec(Spec,ID)) -->
write_vhdl_instantiation_list(Spec), " : ", write_vhdl_mark(ID).
Rule 127
write_vhdl_instantiation_list(all) --> !, " all ". write_vhdl_instantiation_list(others) --> !, " others". write_vhdl_instantiation_list(IL) --> write_vhdl_identifier_list(IL).
Rule 128
write_vhdl_opt_binding_indication(binding(EA,GAL,PAL)) -->
write_vhdl_opt_entity_aspect(EA),
write_vhdl_opt_generic_map_statement(GAL),
write_vhdl_opt_port_map_statement(PAL).
write_vhdl_opt_generic_map_statement(null) --> !,[].
write_vhdl_opt_generic_map_statement(IL) -->
[indent],
" generic map ",
write_vhdl_association_list(IL),
[undent].
write_vhdl_opt_port_map_statement(null) --> !, [].
write_vhdl_opt_port_map_statement(IL) -->
[indent],
" port map ",
write_vhdl_association_list(IL),
[undent].
write_vhdl_opt_generic_map_semi(null) --> !,[].
write_vhdl_opt_generic_map_semi(IL) -->
[indent],
" generic map ",
write_vhdl_association_list(IL), ";",
[undent].
write_vhdl_opt_port_map_semi(null) --> !, [].
write_vhdl_opt_port_map_semi(IL) -->
[indent],
" port map ",
write_vhdl_association_list(IL), ";",
[undent].
write_vhdl_opt_generic_semi(null) --> !,[].
write_vhdl_opt_generic_semi(IL) -->
[indent],
" generic ",
write_vhdl_interface_list(one_per_line,IL), ";",
[undent].
write_vhdl_opt_port_semi(null) --> !, [].
write_vhdl_opt_port_semi(IL) -->
[indent],
" port ",
write_vhdl_interface_list(one_per_line,IL), ";",
[undent].
Rule 129
write_vhdl_opt_entity_aspect(null) --> !, [ ].
write_vhdl_opt_entity_aspect(EA) -->
" use ", write_vhdl_entity_aspect(EA).
write_vhdl_entity_aspect(open) --> " open ".
write_vhdl_entity_aspect(entity_aspect(CM,null)) --> !,
" configuration ", write_vhdl_mark(CM).
write_vhdl_entity_aspect(entity_aspect(Mark,ID)) -->
" entity ",
write_vhdl_mark(Mark),
"(", write_vhdl_identifier(ID), ")".