PIPS
fsm_tools.c
Go to the documentation of this file.
1 /*
2 
3  $Id: fsm_tools.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 /*
28  *
29  * This phase is used for PHRASE project.
30  *
31  * NB: The PHRASE project is an attempt to automatically (or
32  * semi-automatically) transform high-level language for partial
33  * evaluation in reconfigurable logic (such as FPGAs or DataPaths).
34  *
35  * This file provides functions used in context of FSM generation/modifications
36  *
37  */
38 
39 #include <stdio.h>
40 #include <ctype.h>
41 
42 #include "genC.h"
43 #include "linear.h"
44 #include "ri.h"
45 #include "effects.h"
46 
47 #include "resources.h"
48 
49 #include "misc.h"
50 #include "ri-util.h"
51 #include "prettyprint.h"
52 #include "effects-util.h"
53 
54 #include "text-util.h"
55 
56 #include "dg.h"
57 
58 
59 #include "phrase_tools.h"
60 #include "fsm_generation.h"
61 
62 /**
63  * Build and return an expression (eg. state = 23), given an entity
64  * state_variable, an int value value, and an intrinsic name
65  */
67  int value,
68  string intrinsic_name)
69 {
70  return MakeBinaryCall (entity_intrinsic(intrinsic_name),
71  entity_to_expression (state_variable),
73 }
74 
75 /**
76  * This function creates (and add declaration) state variable.
77  * The name of this variable is obtained by the concatenation of
78  * string STATE_VARIABLE_NAME and name identifier.
79  * If the variable doesn't exist with this name, then the variable
80  * is created, added to declarations, and returned. If this variable
81  * exists, then this functions search a new name by incrementing the
82  * integer name_identifier
83  */
85  int name_identifier)
86 {
87  entity module;
88  entity new_state_variable;
89  string state_variable_name;
90  //char *buffer;
91 
93 
94  /* Assert that module represent a value code */
95  pips_assert("it is a code", value_code_p(entity_initial(module)));
96 
97  if (name_identifier == 0) {
98  state_variable_name = strdup (STATE_VARIABLE_NAME_NO_REF);
99  }
100  else {
101  asprintf(&state_variable_name, STATE_VARIABLE_NAME, name_identifier);
102  }
103 
106  state_variable_name,
107  NULL),
109 
110  /* This variable doesn't exist */
111 
112  new_state_variable = find_or_create_scalar_entity (state_variable_name,
113  module_name,
114  is_basic_int);
115  AddEntityToDeclarations( new_state_variable,module);
116  return new_state_variable;
117  }
118  else {
120  name_identifier+1);
121  }
122 }
123 
124 /**
125  * This function build and return a statement representing the
126  * initial assigment of the state_variable, given the UNSTRUCTURED
127  * statement stat.
128  */
130  entity state_variable,
131  int assignement_value)
132 {
133  statement returned_statement;
134  instruction new_instruction;
135  call assignment_call;
136 
137  assignment_call = make_call (entity_intrinsic(ASSIGN_OPERATOR_NAME),
139  entity_to_expression(state_variable),
140  CONS(EXPRESSION, int_to_expression (assignement_value), NIL)));
141 
142  new_instruction
144  assignment_call);
145 
146  returned_statement = make_statement(entity_empty_label(),
147  /*statement_label(stat),*/
148  statement_number(stat),
149  statement_ordering(stat),
151  new_instruction,
152  NIL,NULL,
154 
155  return returned_statement;
156 }
157 
158 /**
159  * Return the state variable value corresponding to the entry
160  * in a unstructured statement
161  */
163 {
164  unstructured u;
165 
166  pips_assert("Statement is UNSTRUCTURED in FSM_GENERATION",
169 
171 
173 }
174 
175 /**
176  * Return the state variable value corresponding to the exit
177  * in a unstructured statement
178  * NB: always return 0
179  */
181 {
182  pips_assert("Statement is UNSTRUCTURED in FSM_GENERATION",
185 
186  return 0;
187 }
188 
189 /**
190  * This function build and return a statement representing the
191  * initial assigment of the state_variable, given the UNSTRUCTURED
192  * statement stat.
193  */
195  entity state_variable)
196 {
198  (stat,
199  state_variable,
201 }
202 
203 /**
204  * This function build a transition statement (a TEST statement)
205  * corresponding to the current control current_node and the
206  * root_statement root_statement. This TEST statement takes a condition on
207  * the state_variable having the value matching the statement ordering
208  * value, and the control statement for the test_true value. The
209  * test_false value is set with a continue statement, before to be
210  * eventually replaced in next control node by a new statement.
211  */
213  statement root_statement,
214  entity state_variable,
215  const char* module_name)
216 {
217  statement returned_statement = NULL;
218  statement transition_statement = NULL;
219  statement stat = control_statement (current_node);
220  instruction test_instruction;
221  instruction transition_instruction;
222  sequence transition_sequence;
223  test new_test;
225  int successors_nb;
226  int current_transition_number;
227  /*string comment;
228  char buffer[50];*/
229 
230  debug_control ("TRANSITION: Module statement", current_node, 2);
231 
232  current_transition_number = beautify_ordering (statement_ordering(stat));
233 
235  = make_expression_with_state_variable (state_variable,
236  current_transition_number,
238 
239  successors_nb = gen_length(control_successors(current_node));
240 
241  if ((successors_nb == 0) || (successors_nb == 1)) {
242  /* This is the exit node, or a non-test statement */
243  int next_value;
244  statement state_variable_assignement;
245 
246  if (successors_nb == 0) {
247  /* This is the exit node, just generate exit code for state_variable */
248  next_value = exit_state_variable_value_for_unstructured (root_statement);
249  }
250  else { /* successors_nb == 1 */
251  /* This is a "normal" node, ie not a TEST statement, just add
252  assignement for state_variable with new value */
253  next_value
256  (CONTROL(gen_nth(0,control_successors(current_node))))));
257  }
258 
259  state_variable_assignement
261  (stat, state_variable, next_value);
262 
263  transition_sequence
265  fsmize_statement(stat, NULL, module_name),
266  /* NULL here because we will generate
267  * a new state variable, since the potential
268  * other FSMs are deeper */
269  CONS(STATEMENT, state_variable_assignement, NIL)));
270 
271  transition_instruction
273  transition_sequence);
274 
275  transition_statement = make_statement(entity_empty_label(),
276  statement_number(stat),
277  statement_ordering(stat),
279  transition_instruction,NIL,NULL,
281  }
282  else if (successors_nb == 2) {
283  /* This is a "test" node, ie with a TEST statement, just add
284  assignement for state_variable with new value after each
285  statement in TEST */
286  int value_if_true = beautify_ordering (statement_ordering
288  (CONTROL(gen_nth(0,control_successors(current_node))))));
289  int value_if_false = beautify_ordering (statement_ordering
291  (CONTROL(gen_nth(1,control_successors(current_node))))));
292  statement transition_statement_if_true;
293  statement transition_statement_if_false;
294  sequence transition_sequence_if_true;
295  sequence transition_sequence_if_false;
296  instruction transition_instruction_if_true;
297  instruction transition_instruction_if_false;
298  statement state_variable_assignement_if_true;
299  statement state_variable_assignement_if_false;
300  statement old_statement_if_true;
301  statement old_statement_if_false;
302  test current_test;
303 
304  pips_assert("Statement with 2 successors is a TEST in FSM_GENERATION",
307 
308  current_test = instruction_test (statement_instruction(stat));
309 
310  // Begin computing for the true statement
311 
312  old_statement_if_true = test_true(current_test);
313 
314  state_variable_assignement_if_true
316  (stat, state_variable, value_if_true);
317 
318  transition_sequence_if_true
320  old_statement_if_true,
321  CONS(STATEMENT, state_variable_assignement_if_true, NIL)));
322 
323  transition_instruction_if_true
325  transition_sequence_if_true);
326 
327  transition_statement_if_true = make_statement (entity_empty_label(),
328  statement_number(stat),
329  statement_ordering(stat),
331  transition_instruction_if_true,
332  NIL,NULL,
334 
335  test_true(current_test) = transition_statement_if_true;
336 
337  // Begin computing for the false statement
338 
339  old_statement_if_false = test_false(current_test);
340 
341  state_variable_assignement_if_false
343  (stat, state_variable, value_if_false);
344 
345  transition_sequence_if_false
347  old_statement_if_false,
348  CONS(STATEMENT, state_variable_assignement_if_false, NIL)));
349 
350  transition_instruction_if_false
352  transition_sequence_if_false);
353 
354  transition_statement_if_false
357  statement_number(stat),
358  statement_ordering(stat),
360  transition_instruction_if_false,NIL,NULL,
362 
363  test_false(current_test) = transition_statement_if_false;
364 
365  transition_statement = stat;
366 
367  }
368  else {
369  pips_assert("I should NOT be there :-)", 2+2 != 4); /* :-) */
370  }
371 
372  new_test = make_test (test_condition, transition_statement,
374 
375  test_instruction = make_instruction (is_instruction_test,new_test);
376 
377  /*sprintf (buffer,
378  FSM_TRANSITION_COMMENT,
379  entity_local_name(state_variable),
380  current_transition_number);
381  comment = strdup(buffer);*/
382 
383  returned_statement = make_statement (entity_empty_label(),
384  /*statement_label(root_statement),*/
385  statement_number(root_statement),
386  statement_ordering(root_statement),
388  test_instruction,NIL,NULL,
390 
391  return returned_statement;
392 
393 }
394 
395 /**
396  * This function build and return a statement representing the
397  * transitions computation in the FSM, given the UNSTRUCTURED
398  * statement stat.
399  */
401  entity state_variable,
402  const char* module_name)
403 {
404  statement returned_statement = NULL;
406  unstructured nodes_graph;
407  list blocs = NIL ;
408 
409  pips_assert("Statement is UNSTRUCTURED in FSM_GENERATION",
412 
413  nodes_graph = instruction_unstructured(statement_instruction(stat));
414 
415  /*gen_recurse(unstructured_entry(nodes_graph), control_domain,
416  transitions_filter, transitions_statements);*/
417  CONTROL_MAP (current_control, {
418  statement transition_statement;
419  transition_statement = make_transition_statement (current_control,
420  stat,
421  state_variable,
422  module_name);
423  if (returned_statement == NULL) {
424  returned_statement = transition_statement;
425  current_statement = returned_statement;
426  }
427  else {
429  test t;
430  pips_assert("Statement is TEST in FSM_GENERATION transitions",
432  t = instruction_test(i);
433  test_false (t) = transition_statement;
434  current_statement = transition_statement;
435  }
436  }, unstructured_entry(nodes_graph), blocs);
437 
438  pips_debug(2,"blocs count = %zd\n", gen_length(blocs));
439 
440  return returned_statement;
441 }
442 
443 /**
444  * This function build and return a statement representing the
445  * FSM code equivalent to the given unstructured statement stat.
446  */
448  entity state_variable,
449  const char* module_name)
450 {
451  statement returned_statement;
452  statement loop_statement;
453  whileloop new_whileloop;
454  expression loop_condition;
456  entity loop_entity = NULL;
457  evaluation loop_evaluation = NULL;
458  instruction loop_instruction;
459  instruction sequence_instruction;
460  sequence new_sequence;
461  /*string comment;
462  char buffer[256];*/
463 
464  /* Assert that given stat is UNSTRUCTURED */
465  pips_assert("Statement is UNSTRUCTURED in FSM_GENERATION",
468 
469  /* Create loop condition: state variable is not equal to exit value */
470  loop_condition
472  (state_variable,
475 
476  /* Evaluation is done BEFORE to enter the loop */
477  loop_evaluation = make_evaluation_before();
478 
479  /* No label for loop */
480  loop_entity = entity_empty_label();
481 
482  /* Computes the statement representing the transitions */
484  state_variable,
485  module_name);
486 
487  /* Build the loop */
488  new_whileloop = make_whileloop(loop_condition,
489  loop_body,
490  loop_entity,
491  loop_evaluation);
492 
493  loop_instruction = make_instruction(is_instruction_whileloop,new_whileloop);
494 
495  /*sprintf (buffer, FSM_BEGIN_COMMENT, entity_local_name(state_variable));
496  comment = strdup(buffer);*/
497 
498  loop_statement = make_statement(statement_label(stat),
499  statement_number(stat),
500  statement_ordering(stat),
502  loop_instruction,NIL,NULL,
504 
505 
506  new_sequence
509  state_variable),
510  CONS(STATEMENT, loop_statement, NIL)));
511 
512  sequence_instruction
514  new_sequence);
515 
516  returned_statement = make_statement(entity_empty_label(),
517  statement_number(stat),
518  statement_ordering(stat),
520  sequence_instruction,NIL,NULL,
522  /*statement_instruction(loop_body)
523  = make_instruction_block(CONS(STATEMENT,returned_statement,NIL));
524  */
525  return returned_statement;
526 }
527 
528 /*
529  * This function is recursively called during FSMization. It takes
530  * the statement to fsmize stat as parameter, while module_name is
531  * the name of the module where FSMization is applied.
532  * If global variable is used for the whole module, state_variable
533  * contains this element. If state_variable is null, then new
534  * state_variable is created for this statement.
535  */
537  entity state_variable,
538  const char* module_name)
539 {
540  // Defaut behaviour is to return parameter statement stat
541  statement returned_statement = stat;
543 
544  pips_debug(2,"\nFSMize: Module statement: =====================================\n");
545  ifdebug(2) {
546  print_statement(stat);
547  }
548  pips_debug(2,"domain number = %"PRIdPTR"\n", statement_domain_number(stat));
549  pips_debug(2,"entity = UNDEFINED\n");
550  pips_debug(2,"statement number = %"PRIdPTR"\n", statement_number(stat));
551  pips_debug(2,"statement ordering = %"PRIdPTR"\n", statement_ordering(stat));
552  if (statement_with_empty_comment_p(stat)) {
553  pips_debug(2,"statement comments = EMPTY\n");
554  }
555  else {
556  pips_debug(2,"statement comments = %s\n", statement_comments(stat));
557  }
558  pips_debug(2,"statement instruction = %s\n", statement_type_as_string(stat));
559  switch (instruction_tag(i)) {
560  case is_instruction_test:
561  {
562  // Declare the test data structure which will be used
563  test current_test = instruction_test(i);
564  statement true_statement, new_true_statement;
565  statement false_statement, new_false_statement;
566 
567  pips_debug(2, "TEST\n");
568 
569  // Compute new statement for true statement, and replace
570  // the old one by the new one
571  true_statement = test_true (current_test);
572  new_true_statement = fsmize_statement(true_statement, state_variable, module_name);
573  if (new_true_statement != NULL) {
574  test_true (current_test) = new_true_statement;
575  }
576 
577  // Do the same for the false statement
578  false_statement = test_false (current_test);
579  new_false_statement = fsmize_statement(false_statement, state_variable, module_name);
580  if (new_false_statement != NULL) {
581  test_false (current_test) = new_false_statement;
582  }
583 
584  break;
585  }
587  {
589  pips_debug(2, "SEQUENCE\n");
590  MAP(STATEMENT, current_stat,
591  {
592  statement new_stat = fsmize_statement(current_stat, state_variable, module_name);
593  if (new_stat != NULL) {
594  gen_list_patch (sequence_statements(seq), current_stat, new_stat);
595  }
596  }, sequence_statements(seq));
597  break;
598  }
599  case is_instruction_loop: {
600  pips_debug(2, "LOOP\n");
601  break;
602  }
604  pips_debug(2, "WHILELOOP\n");
605  break;
606  }
607  case is_instruction_forloop: {
608  pips_debug(2, "FORLOOP\n");
609  break;
610  }
611  case is_instruction_call: {
612  pips_debug(2, "CALL\n");
613  break;
614  }
616  pips_debug(2, "UNSTRUCTURED\n");
617  if (state_variable == NULL) {
618  entity new_state_variable;
619  int state_variable_identifier
620  /* = beautify_ordering (statement_ordering(stat)); */
621  = statement_ordering(stat);
622 
623  pips_debug(2, "Creating state variable with identifier %d\n",
624  state_variable_identifier);
625  new_state_variable
627  state_variable_identifier);
628  returned_statement = make_fsm_from_statement (stat,
629  new_state_variable,
630  module_name);
631  }
632  else {
633  returned_statement = make_fsm_from_statement (stat,
634  state_variable,
635  module_name);
636  }
637  pips_debug(2, "Displaying statement\n");
638  ifdebug(2) {
639  print_statement (returned_statement);
640  }
641  break;
642  }
643  case is_instruction_goto: {
644  pips_debug(2, "GOTO\n");
645  break;
646  }
647  default:
648  pips_debug(2, "UNDEFINED\n");
649  break;
650  }
651 
652  return returned_statement;
653 }
evaluation make_evaluation_before(void)
Definition: ri.c:786
call make_call(entity a1, list a2)
Definition: ri.c:269
whileloop make_whileloop(expression a1, statement a2, entity a3, evaluation a4)
Definition: ri.c:2937
test make_test(expression a1, statement a2, statement a3)
Definition: ri.c:2607
statement make_statement(entity a1, intptr_t a2, intptr_t a3, string a4, instruction a5, list a6, string a7, extensions a8, synchronization a9)
Definition: ri.c:2222
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
synchronization make_synchronization_none(void)
Definition: ri.c:2424
sequence make_sequence(list a)
Definition: ri.c:2125
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
#define STATE_VARIABLE_NAME_NO_REF
#define STATE_VARIABLE_NAME
statement fsmize_statement(statement stat, entity state_variable, const char *module_name)
This function is recursively called during FSMization.
Definition: fsm_tools.c:536
statement make_fsm_transitions_statement(statement stat, entity state_variable, const char *module_name)
This function build and return a statement representing the transitions computation in the FSM,...
Definition: fsm_tools.c:400
statement make_state_variable_assignement_statement(statement stat, entity state_variable, int assignement_value)
This function build and return a statement representing the initial assigment of the state_variable,...
Definition: fsm_tools.c:129
statement make_transition_statement(control current_node, statement root_statement, entity state_variable, const char *module_name)
This function build a transition statement (a TEST statement) corresponding to the current control cu...
Definition: fsm_tools.c:212
entity create_state_variable(const char *module_name, int name_identifier)
This function creates (and add declaration) state variable.
Definition: fsm_tools.c:84
statement make_fsm_from_statement(statement stat, entity state_variable, const char *module_name)
This function build and return a statement representing the FSM code equivalent to the given unstruct...
Definition: fsm_tools.c:447
int exit_state_variable_value_for_unstructured(statement stat)
Return the state variable value corresponding to the exit in a unstructured statement NB: always retu...
Definition: fsm_tools.c:180
statement make_reset_state_variable_statement(statement stat, entity state_variable)
This function build and return a statement representing the initial assigment of the state_variable,...
Definition: fsm_tools.c:194
int entry_state_variable_value_for_unstructured(statement stat)
Return the state variable value corresponding to the entry in a unstructured statement.
Definition: fsm_tools.c:162
expression make_expression_with_state_variable(entity state_variable, int value, string intrinsic_name)
Build and return an expression (eg.
Definition: fsm_tools.c:66
#define CONTROL_MAP(ctl, code, c, list)
Macro to walk through all the controls reachable from a given control node of an unstructured.
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710
void gen_list_patch(list l, const void *x, const void *y)
Replace all the reference to x in list l by a reference to y:
Definition: list.c:985
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
statement make_continue_statement(entity)
Definition: statement.c:953
bool statement_with_empty_comment_p(statement)
Return true if the statement has an empty statement:
Definition: statement.c:126
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define asprintf
Definition: misc-local.h:225
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define MODULE_SEP_STRING
Definition: naming-local.h:30
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
string statement_type_as_string(statement)
phrase_tools.c
Definition: phrase_tools.c:65
void debug_control(const char *, control, int)
DEBUG FUNCTION: print debugging informations for a control a_control.
Definition: phrase_tools.c:134
int beautify_ordering(int)
Special function made for Ronan Keryell who likes a lot when a integer number is coded on 3 bits :-)
Definition: phrase_tools.c:407
static char * module
Definition: pips.c:74
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
#define EQUAL_OPERATOR_NAME
#define empty_comments
Empty comments (i.e.
#define NON_EQUAL_OPERATOR_NAME
#define ASSIGN_OPERATOR_NAME
Definition: ri-util-local.h:95
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
entity entity_empty_label(void)
Definition: entity.c:1105
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
void AddEntityToDeclarations(entity, entity)
END_EOLE.
Definition: variable.c:108
entity find_or_create_scalar_entity(const char *, const char *, tag)
Looks for an entity which should be a scalar of the specified basic.
Definition: variable.c:1025
#define loop_body(x)
Definition: ri.h:1644
@ is_basic_int
Definition: ri.h:571
#define value_code_p(x)
Definition: ri.h:3065
#define statement_ordering(x)
Definition: ri.h:2454
#define test_false(x)
Definition: ri.h:2837
#define CONTROL(x)
CONTROL.
Definition: ri.h:910
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define statement_label(x)
Definition: ri.h:2450
#define entity_undefined
Definition: ri.h:2761
@ is_instruction_goto
Definition: ri.h:1473
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_sequence
Definition: ri.h:1469
@ is_instruction_forloop
Definition: ri.h:1477
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define test_true(x)
Definition: ri.h:2835
#define statement_domain_number(x)
Definition: ri.h:2448
#define sequence_statements(x)
Definition: ri.h:2360
#define statement_extensions(x)
Definition: ri.h:2464
#define instruction_sequence(x)
Definition: ri.h:1514
#define control_successors(x)
Definition: ri.h:945
#define test_condition(x)
Definition: ri.h:2833
#define unstructured_entry(x)
Definition: ri.h:3004
#define statement_instruction(x)
Definition: ri.h:2458
#define statement_comments(x)
Definition: ri.h:2456
#define control_statement(x)
Definition: ri.h:941
#define instruction_test(x)
Definition: ri.h:1517
#define statement_number(x)
Definition: ri.h:2452
#define instruction_unstructured(x)
Definition: ri.h:1532
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define entity_initial(x)
Definition: ri.h:2796
char * strdup()
static statement current_statement
#define ifdebug(n)
Definition: sg.c:47
The structure used to build lists in NewGen.
Definition: newgen_list.h:41