-
Notifications
You must be signed in to change notification settings - Fork 0
/
sprut.info
1764 lines (1409 loc) · 79.8 KB
/
sprut.info
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
This is sprut.info, produced by makeinfo version 5.2 from
sgmltmp.sprut.2.texi.
File: sprut.info, Node: Top, Next: Introduction, Up: (dir)
SPRUT (internal representation description translator)
******************************************************
Vladimir Makarov, `[email protected]'
Apr 5, 2001
This document describes SPRUT (translator of a compiler internal
representation into standard procedural interface).
* Menu:
* Introduction::
* Internal representation description language::
* Standard Procedural Interface::
* SPRUT Usage::
* Appendix 1 - Syntax of internal representation description language::
File: sprut.info, Node: Introduction, Next: Internal representation description language, Prev: Top, Up: Top
1 Introduction
**************
SPRUT is a translator of a compiler internal representation description
(IRD) into Standard Procedural Interface (SPI). The most convenient form
of the internal representation is a directed graph. IRD defines
structure of the graph. SPI provides general graph manipulating
functions. The defined graph nodes can be decorated with attributes of
arbitrary types.
IRD declares types of nodes of the graph. Nodes contains fields,
part of them represents links between nodes, and another part of them
stores attributes of arbitrary types. To make easy describing internal
representation the IRD supports explicitly single inheritance in node
types and also can model multiple inheritance. There can be several
levels of internal representation description in separate files. The
nodes of one level refer to the nodes of previous levels. Therefore
each next level enriches source program internal representation. For
example, the zero level representation may be internal representation
for scanner, the first level may be internal representation for parser,
and so on.
SPI can contains functions to construct and destroy graphs and graph
nodes, to copy graphs or graph nodes, to read and write graphs or graph
nodes from (to) files, to print graphs or graph nodes, to check up
constraints on graph, to traverse graphs, and to transform acyclic
graphs in some commonly used manners. SPI can also check up the most
important constraints on internal representation during work with node
fields. SPI can automatically maintain back links between internal
representation nodes.
Using SPRUT has the following advantages:
1. brief and concise notation for internal representation
2. improving maintainability and as consequence reliability of the
compiler
3. user is freed from the task of writing large amounts of relatively
simple code
The following sections define the internal representation description
language, explain SPI, and present some examples.
File: sprut.info, Node: Internal representation description language, Next: Standard Procedural Interface, Prev: Introduction, Up: Top
2 Internal representation description language
**********************************************
IRD declares types of nodes of the graph. Nodes contains fields, part
of them represents links between nodes, and another part of them stores
attributes of arbitrary types. To make easy describing internal
representation the IRD supports explicitly single inheritance in node
types and also can model multiple inheritance. There can be several
levels of internal representation description in separate files. The
nodes of one level refer to the nodes of previous levels. Therefore
each next level enriches source program internal representation.
* Menu:
* Layout of internal representation description::
* Declarations::
* Types of nodes::
File: sprut.info, Node: Layout of internal representation description, Next: Declarations, Up: Internal representation description language
2.1 Layout of internal representation description
=================================================
To describe internal representation a special language is used. An
internal representation description structure has the following layout
which is similar to one of YACC file.
DECLARATIONS
%%
TYPES OF NODES
%%
ADDITIONAL C/C++ CODE
The '%%' serves to separate the sections of description. All
sections are optional. The first '%%' starts section of description of
types of internal representation nodes and is obligatory even if the
section is empty, the second '%%' may be absent if section of additional
C/C++ code is absent too.
The section of declarations may contain names of predefined types of
fields of internal representation nodes and names of types of double
linked nodes. The section also contains name of original internal
representation description if given file contains extension of an
internal representation description. And finally the section may
contains sections of code on C/C++.
The next section contains description of types of internal
representation nodes.
The additional C/C++ code can contain any C/C++ code you want to use.
Often functions which are not generated by the translator but are needed
to work with internal representation go here. This code without changes
is placed at the end of file generated by the translator.
File: sprut.info, Node: Declarations, Next: Types of nodes, Prev: Layout of internal representation description, Up: Internal representation description language
2.2 Declarations
================
The section of declarations may contain the following construction.
%type IDENTIFIER ...
All predefined types must be defined in constructions of such kind.
The same name can be defined repeatedly. All references to node whose
type is a sub-type of type with name present in the following
construction will be double linked.
%double IDENTIFIER ...
It means that SPI will generates functions (macros) which permit to
examine all fields (may be in other nodes) described as of given node
type (or its subtype) which refer to node of given type (or its
sub-type), i.e. fields which are described as of given node type (or
its subtype) will be double linked (see below). SPI will automatically
maintain such double links. The simplest way to describe double linked
graph is to insert construction
%double %root
Last construction in the section of declarations of kind
%extend IDENTIFIER
defines name (without suffix) of file containing source internal
representation which is extended by given file. The file contains
original internal representation if there is no one such construction.
The original specification file has level 0, the extensions have level
1, 2, and so on. This feature permits sequentially to develop an
internal representation and to save and restore any its level (see SPI)
to additional tools, e.g. browsers. For example, there may be three
levels of source program internal representation. The zero level
representation may be internal representation for semantic analysis, the
first level may be a low level machine-dependent internal
representation, and the second level may be used to generate object
code. Only first such construction in one file is essential. All
subsequent such constructions are ignored.
There may be also the following constructions in the declaration
section
%local {
C/C++ DECLARATIONS
}
%import {
C/C++ DECLARATION
}
and
%export {
C/C++ DECLARATION
}
which contain any C/C++ declarations (types, variables, macros, and
so on) used in the description sections.
The local C/C++ declarations are inserted at the begin of generated
implementation file (see SPI description) but after include-directive of
interface file.
C/C++ declarations which start with '%import' are inserted at the
begin of generated interface file. For example, such C/C++ code may
contain C/C++ definitions of predefined types which are used in field
declarations of node types.
C/C++ declarations which start with '%export' are inserted at the end
of generated interface file. For example, such C/C++ code may contain
definitions of external variables and functions which refer to node type
representation (see type 'IR_node_t' in SPI description).
All C/C++ declarations can redefine all type specific and internal
macros (see SPI) because they are placed in implementation file. All
C/C++ declarations are placed in the same order as in the section of
declarations. C/C++ declarations from IRD file with smaller level
number (see construction '%extend') are placed in interface or
implementation files firstly.
File: sprut.info, Node: Types of nodes, Prev: Declarations, Up: Internal representation description language
2.3 Types of nodes
==================
The section of declarations is followed by section defining internal
representation node types. An internal node type is described by the
following construction
%abstract
IDENTIFIER :: IDENTIFIER (or %root)
CLASS FIELDS
SKELETON FIELDS
OTHER FIELDS
Keywords '%abstract' is optional. Node type description which starts
with this keyword denotes abstract node type, i.e. node of such type
does not exist in internal representation of any source program.
Abstract nodes types serve only to description of common fields of
several node types.
The first identifier defines name of internal representation node
type, the second defines name of node type all declarations of fields of
which are inherited into the given node type. In this construction the
first node type is so called immediate super type, the second is
immediate sub-type.
Node type A is a super-type of node type B (and node type B is a
sub-type of node type A) iff node type A is immediate super-type of
super-type of node type B. All node types are sub-types of implicitly
declared node type with name '%root'. There are also nodes of special
type (error nodes). Type of these nodes are believed to be sub-type of
all declared node types. The definition of type of error nodes are
absent in any internal representation description.
The identifier of immediate super-type (with '::') can be absent. In
this case the construction is continuation of given type node
declaration. There can be only the single main node type declaration
and many its continuations. The order of main node type declaration and
its continuations can be arbitrary. The continuations can not start
with keyword '%abstract'.
Construction of the following kind
A, B, ... :: C
DECLARATIONS OF FIELDS
is abbreviation of the following constructions
A :: C
DECLARATIONS OF FIELDS
B :: C
DECLARATIONS OF FIELDS
...
The fields are sub-divided on kinds. There are three kinds of
fields.
1. Class fields. There is the single instance of a class field for
all nodes of given type.
2. Skeleton fields. There is the single instance of a skeleton fields
for each node of given type. The value of skeleton field is to be
given by user at the node creation moment (see SPI description).
3. Other fields. This kind of fields is analogous to one of skeleton
fields but value of such field is not given by user at the node
creation moment.
Optional sections of declarations of class fields, skeleton fields,
and other fields start correspondingly with keywords '%class',
'%skeleton', and '%other'.
%class LIST OF DECLARATIONS OF FIELDS
%skeleton LIST OF DECLARATIONS OF FIELDS
%other LIST OF DECLARATIONS OF FIELDS
These keywords are followed by may be empty list of declarations of
fields. The list elements are field declaration or target code. Field
declaration is described by the following construction:
IDENTIFIER : FIELD %double TYPE CONSTRAINTS ACTIONS
Identifier is name of given field. All declarations of fields of a
node type must have unique names. But declarations of fields of
different node types can have the same names if the types of such fields
are the same, the fields are simultaneously described as double linked
or not, and all such fields are class or any non-class fields. Owing to
the feature it is possible to model multiple inheritance. Semicolon ':'
is followed by the field type. There are the following types of nodes
fields:
1. identifier from a clause '%type'. The identifier represents
predefined type and must be declared anywhere by the construction
'typedef' of C/C++.
2. node name. This type represents arc to a node of given type or its
subtypes and is implemented by pointer of C/C++.
These constructions can have optional clause '%double'. Its sense is
slightly different from the one in the declarations section. This
clause means that SPI will generate functions (macros) which permits to
examine all nodes of the declared type (or its sub-type) which refer
through given field to a node of the field type (or its sub-type). The
clause '%double' can not be given for class fields.
The field type may be followed by constraints and actions in any
order. The constraint is usually present for non-null value node
reference. The constraint is a boolean expression on C/C++ in brackets
'[' and ']'. The constraints are tested with the aid of some generated
functions in the same order as they are present in corresponding type
node declaration. The actions can contain any statements on C/C++ in
figure brackets '{' and '}' (the brackets are also output therefore
C/C++ declarations can be in actions). The actions for skeleton and
other fields are fulfilled at the node creation time in the same order
as they are present in corresponding type node declaration. The actions
for class fields are fulfilled at the internal representation initiation
time.
Constructions '$$', '$' in the constraints and the actions represent
correspondingly current node and previous field. But '$' is not changed
by the previous field if the previous field in given node type
declaration is of other kind than the constraint or action (e.g. the
field of skeleton kind and the constraint of class kind) or such field
does not exist in the current node type declaration. Also it should be
remembered that '$' can not be used in left hand side of assignment if
the construction represent double linked fields.
The construction 'IDENTIFIER : FIELD TYPE' may be absent. This case
is convenient for definition of additional constraints and actions for
fields which declared in a super-type of given node type.
Construction of kind
A, B, ... : C ...
is abbreviation of the following constructions
A : C ...
B : C ...
Full YACC syntax of internal representation description language is
placed in Appendix 1.
File: sprut.info, Node: Standard Procedural Interface, Next: SPRUT Usage, Prev: Internal representation description language, Up: Top
3 Standard Procedural Interface
*******************************
An internal representation description is translated by SPRUT (internal
representation definition translator) into a standard procedural
interface (SPI). If the specification file is an extension (see the
language description) of another specification file the later is also
used to SPI generation and so on. SPI consists of interface and
implementation files having the same names as one of the specification
file and correspondingly suffixes '.h' and '.c' (C code) or '.cpp' (C++
code).
* Menu:
* C SPI::
* C++ SPI::
* Type specific macros::
* Storage management macros::
File: sprut.info, Node: C SPI, Next: C++ SPI, Up: Standard Procedural Interface
3.1 C SPI
=========
By default (when option '-c++' is not present on the command line) SPRUT
generates C SPI. The following subsections describe C SPI.
* Menu:
* C SPI types variables macros::
* C Functions::
File: sprut.info, Node: C SPI types variables macros, Next: C Functions, Up: C SPI
3.1.1 C SPI types variables macros
----------------------------------
Interface file of SPI consists of C declarations of the following types,
variables and macros.
1. Type 'IR_node_mode_t' is represented by enumeration definition.
There is enumeration constant with node type name and prefix
'IR_NM_' for each node type declaration even for abstract node
type. Also there are enumeration constants with names
'IR_NM__root' and 'IR_NM__error' for and predefined type '%root'
and for error nodes. 'IR_NM' is abbreviation of internal
representation node mode. There is also the enumeration name
'IR_node_mode_enum' which is convenient to use in imported section
for forward definition of pointer to this enumeration.
2. Type 'IR_node_t' represents a node (more correctly pointer to a
structure representing node). There are the type value 'NULL'
reserved to represent none node. The structure of this type is
opaque and all work with nodes are to be fulfilled through macros
(or/and functions). But to show efficacy of types implementation
it should be said that every node type is turned into a structure
declaration. All these structures have first member of type
'IR_node_mode_t'. Other members represent the node fields except
for class field. Depending on SPRUT command line option
'-flat-structure' (see SPRUT usage) this structure can contain also
members corresponding to fields declared in super types of given
node type or member which type is structure corresponding to
immediate super type of given node type. Class fields for each
non-abstract node type are represented by only one separate
structure.
The fields in different node types with the same name (when it is
consequence of existing common super type with this field) have the
same displacement from the structure begin because types of
previous fields is guaranteed to be the same in these structures.
The fields in different node types with the same name (when it is
not consequence of existing common super type with this field) may
have the different displacement from the structure begin therefore
access to such fields requires additional indirect addressing.
Double linked field (see internal representation description
language) requires more memory (about in five times) for its
implementation. Speed of SPI work with double linked fields is
sightly slower. Because additional work is needed only to setting
up the field value and my experience shows that usually number of
setting up fields value is less than number of their fetching about
in ten times.
Type 'IR_node_t' is simply pointer to struct representing node type
'%root'. The name of this structure is 'IR_node'. This name can
be used in imported section for forward reference for nodes
(instead of 'IR_node_t').
3. Optional variable 'IR_node_name' is array mapping values of type
'IR_node_mode_t' to names (strings) in C. (see also option
-no-node-name in SPRUT usage).
4. Variable 'IR_node_size' is array mapping values of type
'IR_node_mode_t' to size of corresponding structures on C.
5. Macro 'IR_IS_TYPE(type, supertype)' is evaluated as nonzero if the
first argument of type 'IR_node_mode_t' is equal to the second
argument or node type represented by the first argument is a
sub-type of node type represented by the second argument.
Otherwise the macro returns zero. But this macro returns always
zero for any error node, i.e. this macro can be used to define
that the node of the first mode has fields of the node of the
second mode.
6. Macro 'IR_NODE_MODE(node)' returns node mode represented by value
of type 'IR_node_mode_t' for node given as the macro argument of
type 'IR_node_t'.
7. Macro 'IR_IS_OF_TYPE(node, supertype)' is abbreviation of
frequently used 'IR_IS_TYPE (IR_NODE_MODE (node), supertype)'.
8. Macro 'IR_NODE_LEVEL(node)' has value which is internal
representation description level in which declaration of given node
type starts.
File: sprut.info, Node: C Functions, Prev: C SPI types variables macros, Up: C SPI
3.1.2 C Functions
-----------------
SPI interface file also contains definitions of generated functions to
creation, deletion, modification, comparison, copy, check, print, and
binary input/output of internal representation nodes and functions for
access to values of internal representation node fields.
These functions do not permit to work with abstract nodes. Only one
graph function can be active, e.g. call of function 'IR_check_graph' is
not permitted during work of any traverse or transformation function.
Macros can be generated with or instead of the functions for access
to internal representation node fields. This feature should be used if
used C preprocessor has not rigid constraints on number of defined
macros. Because macros arguments may be evaluated many times no
side-effects should be in the arguments.
1. Access functions (or/and macros). These functions are generated
when option '-access' is present in the SPRUT command line. If
option '-macro' is used the access functions and macros are
generated. If option '-only-macro' is used only access macros are
generated. Only option '-macro' or '-only-macro' can be on the
command line of SPRUT. There is one function for each field with
unique name. Access function has name formed from prefix 'IR_' and
corresponding field name. There is one exception. When access
functions and macros are generated, macros have names starting with
prefix 'IR_' and the functions have names starting with prefix
'IR_F_'. Access function has one argument of type 'IR_node_t'.
The argument represents node which must have such field. Type of
returned value is predefined type (if the field is of such type) or
'IR_node_t' (if the field is of a node type). Functions
`IR_double_link_t IR__first_double_link (IR_node_t node)',
`IR_double_link_t IR__next_double_link
(IR_double_link_t prev_double_link)',
`IR_double_link_t IR__previous_double_link
(IR_double_link_t next_double_link)'
return references to fields which have double links to given node.
Functions 'IR__first_double_link' is always implemented by
function. The node itself which contains such links can be
determined by function
`IR_node_t IR__owner (IR_double_link_t link)'.
Here type 'IR_double_link_t' represents pointer to double fields.
The functions may also check up that the node has given field (see
SPRUT options).
2. Modification functions. These functions are generated when option
'-set' is present in the SPRUT command line. There is one
functions for each field with unique name. Modification function
has name formed from prefix 'IR_set_' and corresponding field name.
Modification function has two arguments. The first argument of
type 'IR_node_t' represents node which must have such field. The
second argument of predefined type (if the field is of such type)
or of type 'IR_node_t' (if the field is of a node type) represents
new value of the field.
The function may check up constraint if the field represents arc to
node of a node type or its sub-types (see SPRUT options). The
functions may also check up that the node has given field.
There is also function for modification of double links
`void IR__set_double_link (IR_double_link_t double_link,
IR_node_t value)'
Remember that values of 'IR__next_double_link' and
'IR__previous_double_link' are changed after calling this function.
3. Function
`IR_node_t IR_create_node (IR_node_mode_t node_mode)'
is generated in any case. This function allocates storage for node
of any type (except for abstract) represented by the argument (it
can be also 'IRNM__error), sets up node mode and node level,
fulfills fields assignments (except for class fields) in the same
order as the fields are declared. The field assignment is
fulfilled according to type specific operation (see section 'Type
specific macros') and actions which are defined after given field
in sections of skeleton and other fields of corresponding node
type. After that the function returns the created node. The
single way to create error nodes is to use this function with
argument 'IRNM__error'.
4. Node type specific creation functions. These functions are
generated when option '-new' is present in the SPRUT command line.
There is one function for each node type (except for abstract).
Names of functions are formed from prefix 'IR_new_' and
corresponding node type name. The number of parameters of a
function is equal to one of skeleton fields of corresponding node
type. The parameters of these functions have to be given in the
order of the skeleton fields in the specification. Fields of the
super-type (recursively) precede the ones of the sub-type. These
functions may check up constraints on skeleton fields which
represent arc to node of a node type or its sub-types (see SPRUT
options). These functions call node creation function and after
that assign parameters values to corresponding skeleton fields.
After that the functions return the created node. These functions
provide a mechanism similar to record aggregates. Nested calls of
such functions allow programming with terms as in LISP.
5. Function
`void IR_free_node (IR_node_t node)'
is generated when option '-free' or '-free-graph' is present in the
SPRUT command line. This function deletes given node. The
deletion consists of evaluation of finalization macros for node
fields (see field type specific macros) in reverse order and all
node space deallocation. The function also delete double linked
fields of given node from the corresponding lists of double linked
fields. But the user should know that there may be dangling
references to given node itself after the function call. The
function does nothing if the parameter value is equal to NULL.
6. Function
`void IR_free_graph (IR_node_t graph)'
is generated when option '-free-graph' is present in the SPRUT
command line. This function deletes given node and all nodes
accessible from given node 'graph'. The nodes are deleted in depth
first order. The function does nothing if the parameter value is
equal to NULL.
7. Function
`void IR_conditional_free_graph
(IR_node_t graph,
int (*guard) (IR_node_t node))'
is generated when option '-free-graph' is present in the SPRUT
command line. This function deletes given node and all nodes
accessible from given node 'graph'. The nodes are deleted in depth
first order. The function does nothing if the parameter value is
equal to NULL. The processing (traversing and deleting) children of
node which is passed to the parameter-function is not fulfilled if
the parameter-function returns zero. All graph is deleted when the
returned value is always nonzero.
8. Function
`IR_node_t IR_copy_node (IR_node_t node)'
is generated when option '-copy' or '-copy-graph' is present in the
SPRUT command line. This function makes copy of given node. Field
type specific macros are used (see section 'Type specific macros')
to make this. The function only returns NULL if the parameter
value is equal to NULL.
9. Function
`IR_node_t IR_copy_graph (IR_node_t graph)'
is generated when option '-copy-graph' is present in the command
line. This function makes copy of graph given by its node 'graph'.
The function only returns NULL if the parameter value is equal to
NULL.
10. Function
`IR_node_t IR_conditional_copy_graph
(IR_node_t graph,
int (*guard) (IR_node_t node))'
is generated when option '-copy-graph' is present in the command
line. This function makes copy of graph given by its node 'graph'.
The function only returns NULL if the parameter value is equal to
NULL. The processing (traversing and copying) children of node
which is passed to the parameter-function is not fulfilled if the
parameter-function returns zero. All nodes of graph are copied
when the returned value is always nonzero.
11. Function
`int IR_is_equal_node (IR_node_t node_1,
IR_node_t node_2)'.
is generated when option '-equal' or '-equal-graph' is present in
the SPRUT command line. This function returns nonzero iff 'node_1'
is equal to 'node_2', i.e. node_1 and node_2 have the same type
and all fields of 'node_1' are equal to the corresponding fields of
'node_2'. Field type specific macros are used (see section 'Type
specific macros') to make this. The function return nonzero if
parameter values are equal to NULL.
12. Function
`int IR_is_equal_graph (IR_node_t graph_1,
IR_node_t graph_2)'
is generated when option '-equal-graph' is present in the SPRUT
command line. This function returns nonzero iff graph starting
with node 'graph_1' is equal to graph starting with node 'graph_2',
i.e. the graphs have the same structure and all predefined type
fields of 'graph_1' are equal to the corresponding fields of
'graph_2'. The function returns TRUE if parameter values are equal
to NULL.
13. Function
`int IR_is_conditional_equal_graph
(IR_node_t graph_1, IR_node_t graph_2,
int (*guard) (IR_node_t node))'
is generated when option '-equal-graph' is present in the SPRUT
command line. This function returns nonzero iff graph starting
with node 'graph_1' is equal to graph starting with node 'graph_2',
i.e. the graphs have the same structure and all predefined type
fields of 'graph_1' are equal to the corresponding fields of
'graph_2'. The function returns TRUE if parameter values are equal
to NULL. The processing (traversing and comparing) children of node
which is passed to the parameter-function is not fulfilled if the
parameter-function returns zero. All nodes of the graphs are
compared when the returned value is always nonzero. Unprocessed
graph nodes are believed to be equal.
14. Function
`int IR_check_node (IR_node_t node,
int class_field_flag)'
This function is generated when option '-check' or '-check-graph'
is present in the SPRUT command line. By default the most of
generated functions (and macros) which work with internal
representation nodes do not check up constraints which described in
the specification. There are two kinds of constraints. The first
is constraint on field which represents arc to node of given type
or its sub-types. The second is constraint which defined by target
code (see the internal representation definition language). The
user is responsible to adhere to the constraints. Function
'IR_check_node' can be used to check all constraints corresponding
to given node. The function does nothing if the parameter value is
equal to null. In case of a constraint violation the involved node
and all child nodes are printed on standard error and the function
returns nonzero (error flag). If the second parameter value is
zero then class fields of given node are not checked up.
15. Function
`int IR_check_graph (IR_node_t graph,
int class_field_flag)'
is generated when option '-check-graph' is present in the sprut
command line. This function checks given node 'graph' and all
nodes accessible from given node. It should be known that a class
field is processed only when the second parameter value is nonzero.
The function does nothing if the parameter value is equal to null.
In case of fixing any constraint violation returns nonzero (error
flag).
16. Function
`int IR_conditional_check_graph
(IR_node_t graph, int class_field_flag,
int (*guard) (IR_node_t node))'
is generated when option '-check-graph' is present in the sprut
command line. This function checks given node 'graph' and all
nodes accessible from given node. It should be known that a class
field is processed only when the second parameter value is nonzero.
The function does nothing if the parameter value is equal to null.
In case of fixing any constraint violation returns nonzero (error
flag). The processing (traversing and checking) children of node
which is passed to the parameter-function is not fulfilled if the
parameter-function returns zero. All nodes of graph are checked
when the returned value is always nonzero. It is better to free
changed nodes which are not used after transformation especially
when there are double links to the nodes (otherwise the nodes can
be accessible with the aid of functions for work with double
links).
17. Function
`void IR_print_node (IR_node_t node,
int class_field_flag)'
is generated when option '-print' is present in the sprut command
line or options '-check' or 'check-graph' is present because check
functions use this print function. The function outputs values of
node fields with their names to standard output in readable form.
To make this the function outputs sequentially all the node fields
(including class fields if the second parameter value is nonzero)
with the aid of field type specific macros (see below). The
function does nothing if the parameter value is equal to null.
18. Functions
`int IR_output_node (FILE *output_file, IR_node_t node,
int level)',
`IR_node_t IR_input_node (FILE *input_file,
IR_node_t *original_address)'
are generated when option correspondingly '-output' or '-input' is
present in the SPRUT command line. Function 'IR_output_node'
writes node to given file. To make this the function outputs the
second parameter value, node address and after that sequentially
all the node fields (except for class fields) whose declarations
are present in internal representation description of 'level' or
less than the one (see internal representation description
language). The node type must be also declared in internal
representation description of 'level' or less than the one. The
function does nothing if the value of parameter 'node' is equal to
NULL. A nonzero function result code means fixing an error during
output.
Function 'IR_input_node' reads node from given file, allocates
space for the node, initiates its fields and changes the node
fields output early. To make this the function uses function
'create_node'. The output level of input node must be less or
equal to the internal representation level of given SPI. Null value
returned by the function means fixing an error during input. The
function returns original address of input node through the second
parameter. The output and input of fields is fulfilled with the
aid of field type specific macros (see section 'Type specific
macros').
19. Function
`void IR_traverse_depth_first
(IR_node_t graph, int class_field_flag,
void (*function) (IR_node_t node))'
is generated when option '-traverse' is present in the SPRUT
command line. This function traverses graph given by its node
'graph' depth first (it means bottom up for tree). Arcs
represented by class fields are included in this graph if the
second parameter value is nonzero. At every node a function given
as parameter is executed. Arcs implementing lists of double linked
fields are not traversed. The function does nothing if the 'graph'
parameter value is equal to NULL.
20. Function
`void IR_traverse_reverse_depth_first
(IR_node_t graph, int class_field_flag,
int (*function) (IR_node_t node))'
is generated when option '-reverse-traverse' is present in the
SPRUT command line. This function is analogous to the previous but
the graph is traversed in reverse depth first order (it means top
down order for tree). The traverse of children of node which is
passed to the parameter-function is not fulfilled if the
parameter-function returns zero. All graph is traversed when the
returned value is always nonzero.
21. Function
`IR_node_t IR_transform_dag
(IR_node_t graph, int class_field_flag,
int (*guard_function) (IR_node_t node),
IR_node_t (*transformation_function) (IR_node_t node))'
is generated when option '-transform' is present in the SPRUT
command line. This function is used for transformation of directed
acyclic graphs. This is needed for various goals, e.g. for
constant folding optimization. At first the function calls guard
function. If the guard function returns zero, the function return
the first parameter. Otherwise when the guard function returns
nonzero, all fields (including class fields if parameter
'class_field_flag' is nonzero) of given node are also processed,
i.e. the fields values are changed. And finally the node itself
is processed by the transformation function (remember that the
transformation function is never called for nodes which are parts
of a graph cycle), and the result of transformation function is the
result of given function.
22. Function
`void IR_start (void)'
is generated in any case. This function is to be called before any
work with internal representation. The function initiates internal
representation storage management (see next section), fulfills
class field type specific initializations, evaluates actions bound
to class fields, and make some other initiations.
23. Function
`void IR_stop (void)'
is generated in any case. The call of this function is to be last.
The function fulfills class field type specific finalizations and
finishes internal representation storage management.
File: sprut.info, Node: C++ SPI, Next: Type specific macros, Prev: C SPI, Up: Standard Procedural Interface
3.2 C++ SPI
===========
SPRUT generates C++ SPI only when option '-c++' is present on the
command line. Mainly C++ SPI is analogous to one on C. Major difference
is that 'IR_node_t' and 'IR_double_link_t' are pointer to classes not to
structures. As the consequence, the most of functions are public or
friend functions of the classes.
* Menu:
* C++ SPI types variables macros::
* C++ Functions::
File: sprut.info, Node: C++ SPI types variables macros, Next: C++ Functions, Up: C++ SPI
3.2.1 C++ SPI types variables macros
------------------------------------
C++ interface file of SPI consists of C++ declarations of the following
types, variables.
1. Type 'IR_node_mode_t' is represented by enumeration definition.
There is enumeration constant with node type name and prefix
'IR_NM_' for each node type declaration even for abstract node
type. Also there are enumeration constants with names
'IR_NM__root' and 'IR_NM__error' for and predefined type '%root'
and for error nodes. 'IR_NM' is abbreviation of internal
representation node mode. There is also the enumeration name
'IR_node_mode_enum' which is convenient to use in imported section
for forward definition of pointer to this enumeration.
2. Type 'IR_node_t' represents a node (more correctly pointer to a
class representing node). There are the type value 'NULL' reserved
to represent none node. The class of this type is opaque (i.e.
there are not public variables in the class) and all work with
nodes are to be fulfilled through public or friend functions. But
to show efficacy of types implementation it should be said that
every node type is turned into a structure declaration. All these
structures have first member of type 'IR_node_mode_t'. Other
members represent the node fields except for SPRUT class field.
Depending on SPRUT command line option '-flat-structure' (see SPRUT
usage) this structure can contain also members corresponding to
fields declared in super types of given node type or member which
type is structure corresponding to immediate super type of given
node type. SPRUT class fields for each non-abstract node type are
represented by only one separate structure.
The fields in different node types with the same name (when it is
consequence of existing common super type with this field) have the
same displacement from the structure begin because types of
previous fields is guaranteed to be the same in these structures.
The fields in different node types with the same name (when it is
not consequence of existing common super type with this field) may
have the different displacement from the structure begin therefore
access to such fields requires additional indirect addressing.
Double linked field (see internal representation description
language) requires more memory (about in five times) for its
implementation. Speed of SPI work with double linked fields is
sightly slower. Because additional work is needed only to setting
up the field value and my experience shows that usually number of
setting up fields value is less than number of their fetching about
in ten times.
Type 'IR_node_t' is simply pointer to class representing node type
'%root'. The name of this class is 'IR_node'. This name can be
used in imported section for forward reference for nodes (instead
of 'IR_node_t').
3. Optional variable 'IR_node_name' is array mapping values of type
'IR_node_mode_t' to names (strings) in C++ (see also option
-no-node-name in SPRUT usage).
4. Variable 'IR_node_size' is array mapping values of type
'IR_node_mode_t' to size of corresponding structures on C++.
File: sprut.info, Node: C++ Functions, Prev: C++ SPI types variables macros, Up: C++ SPI
3.2.2 C++ Functions
-------------------
C++ SPI interface file also contains definitions of generated functions
to quering characteritics of nodes, creation, deletion, modification,
comparison, copy, check, print, and binary input/output of internal
representation nodes and functions for access to values of internal
representation node fields.
These functions do not permit to work with abstract nodes. Only one
graph function can be active, e.g. call of function 'IR_check_graph' is
not permitted during work of any traverse or transformation function.
For sake of efficacy, the part of functions (access to internal
representation node fields and quering charateristics of the nodes) is
generated as inline.
1. Function 'IR_is_type (IR_node_mode_t type, IR_node_mode_t super)'
which is public static (i.e. which is relative to class not to a
object of the class) function of class 'IR_node' is evaluated as
nonzero if the first argument of type 'IR_node_mode_t' is equal to
the second argument or node type represented by the first argument
is a sub-type of node type represented by the second argument.
Otherwise the function returns zero. But this function returns
always zero for any error node, i.e. this function can be used to
define that the node of the first mode has fields of the node of
the second mode.
2. Function 'IR_node_mode (void)' declared as public in the class
'IR_node' returns node mode represented by value of type
'IR_node_mode_t' for given node.
3. Function 'IR_is_of_type (IR_node_mode_t super)' declared as public
in the class 'IR_node' is abbreviation of frequently used
'IR_is_type (node->IR_node_mode (), super)'.
4. Function 'IR_node_level (void)' declared as public in the class
'IR_node' has value which is internal representation description
level in which declaration of given node type starts.
5. Access functions. These functions declared as public in the class
'IR_node' are generated when option '-access' is present in the
SPRUT command line. There is one function for each field with
unique name. Access function has name formed from prefix 'IR_' and
corresponding field name. Access function has no arguments. Type
of returned value is predefined type (if the field is of such type)
or 'IR_node_t' (if the field is of a node type). Function declared
as public in the class 'IR_node'
`IR_double_link_t IR__first_double_link (void)'
and functions declared as public in the class for which pointer of
type 'IR_double_link_t' refers
`IR_double_link_t IR__next_double_link (void)',
`IR_double_link_t IR__previous_double_link (void)'
return pointer to fields which have double links to given node.
The node itself which contains such links can be determined by
function declared as public in the class for which pointer of type
'IR_double_link_t' refers
`IR_node_t IR__owner (void)'.
Here type 'IR_double_link_t' represents pointer to class
representing double fields. The functions may also check up that
the node has given field (see SPRUT options).