diff options
author | clean | 2000-07-12 14:59:46 +0000 |
---|---|---|
committer | clean | 2000-07-12 14:59:46 +0000 |
commit | 90461e5831717920426c9c1d7c861a3724f89715 (patch) | |
tree | 59d48b852f0adce522157ff7c27e24b759561b0d /backendC/CleanCompilerSources/result_state_database.c | |
parent | changes to avoid bug in module refmark when compiling compiler with itself (diff) |
clean 1.3.3 backend again again
git-svn-id: https://svn.cs.ru.nl/repos/clean-compiler/trunk@189 1f8540f1-abd5-4d5b-9d24-4c5ce8603e2d
Diffstat (limited to 'backendC/CleanCompilerSources/result_state_database.c')
-rw-r--r-- | backendC/CleanCompilerSources/result_state_database.c | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/backendC/CleanCompilerSources/result_state_database.c b/backendC/CleanCompilerSources/result_state_database.c new file mode 100644 index 0000000..d910db0 --- /dev/null +++ b/backendC/CleanCompilerSources/result_state_database.c @@ -0,0 +1,224 @@ +/* + File: result_state_database.c + Author: John van Groningen + At: University of Nijmegen +*/ + +#if defined (applec) || defined (__MWERKS__) || defined (__MRC__) +# define __ppc__ +#endif + +#include <stdio.h> + +#include "types.t" +#include "syntaxtr.t" +#include "comsupport.h" +#include "result_state_database.h" + +struct state_tree { + struct state_tree * stt_left; + struct state_tree * stt_right; + struct state * stt_state_p; + int stt_label_number; + int stt_label_defined; +}; + +static struct state_tree *state_tree; +static int next_update_label_number; + +static int compare_states (struct state *state1_p,struct state *state2_p) +{ + int r; + + r=state1_p->state_type - state2_p->state_type; + if (r!=0) + return r; + + switch (state1_p->state_type){ + case SimpleState: + r=state1_p->state_kind - state2_p->state_kind; + if (r!=0) + return r; + + return state1_p->state_object - state2_p->state_object; + case ArrayState: + return compare_states (state1_p->state_array_arguments,state2_p->state_array_arguments); + case TupleState: + { + int n; + + r=state1_p->state_arity - state2_p->state_arity; + if (r!=0) + return r; + + n=state1_p->state_arity; + + state1_p=state1_p->state_tuple_arguments; + state2_p=state2_p->state_tuple_arguments; + + while (n>0){ + r=compare_states (state1_p,state2_p); + if (r!=0) + return r; + + --n; + ++state1_p; + ++state2_p; + } + + return 0; + } + case RecordState: + { + struct symbol_def *sdef1,*sdef2; + + sdef1=state1_p->state_record_symbol; + sdef2=state2_p->state_record_symbol; + if (sdef1==sdef2) + return 0; + else + if (sdef1<sdef2) + return -1; + else + return 1; + } + default: + ErrorInCompiler ("compare_states","",""); + return -1; + } +} + +static void store_state_in_database (struct state *state_p) +{ + struct state_tree **state_node_h; + struct state_tree *state_node_p; + + state_node_h=&state_tree; + + while (state_node_p=*state_node_h,state_node_p!=NULL){ + int state_compare_result; + + state_compare_result=compare_states (state_p,state_node_p->stt_state_p); + + if (state_compare_result==0){ + if (state_node_p->stt_label_number==0){ + state_node_p->stt_label_number=next_update_label_number; + ++next_update_label_number; + } + + return; + } else + if (state_compare_result<0) + state_node_h=&state_node_p->stt_left; + else + state_node_h=&state_node_p->stt_right; + } + + state_node_p=CompAllocType (struct state_tree); + + state_node_p->stt_left=NULL; + state_node_p->stt_right=NULL; + state_node_p->stt_state_p=state_p; + state_node_p->stt_label_number=0; + state_node_p->stt_label_defined=0; + + *state_node_h=state_node_p; +} + +void create_result_state_database (struct imp_rule *imp_rules) +{ + struct imp_rule *rule; + + state_tree=NULL; + next_update_label_number=1; + + for (rule=imp_rules; rule; rule=rule->rule_next){ + TypeAlts type_alt; + struct state *state_p; + + if (rule->rule_root->node_symbol->symb_def->sdef_over_arity!=0) + continue; + + type_alt=rule->rule_type; + if (type_alt==NULL) + continue; + +#if 1 + state_p=&rule->rule_state_p[-1]; +#else + state_p=&type_alt->type_alt_lhs->type_node_state; +#endif + if (state_p->state_type==SimpleState){ + if (state_p->state_kind==OnB) + store_state_in_database (state_p); + } else + store_state_in_database (state_p); + } +} + +static int find_state_in_database (struct state *state_p,int mask,int *label_number_p) +{ + struct state_tree *state_node_p; + + state_node_p=state_tree; + + while (state_node_p!=NULL){ + int state_compare_result; + + state_compare_result=compare_states (state_p,state_node_p->stt_state_p); + + if (state_compare_result==0){ + if (state_node_p->stt_label_number==0) + return 0; + + *label_number_p=state_node_p->stt_label_number; + + if ((state_node_p->stt_label_defined & mask)==0){ + state_node_p->stt_label_defined|=mask; + return 1; + } else + return 2; + } else + if (state_compare_result<0) + state_node_p=state_node_p->stt_left; + else + state_node_p=state_node_p->stt_right; + } + + return 0; +} + +/* + get_label_number_from_result_state_database returns: + 0: no label (state occurs only once) + 1: label not yet defined + 2: label already defined +*/ + +#if 1 +int get_label_number_from_result_state_database (StateP result_state_p,int mask,int *label_number_p) +#else +int get_label_number_from_result_state_database (TypeAlts type_alt,int mask,int *label_number_p) +#endif +{ + struct state *state_p; + + *label_number_p=0; + +#if 1 + state_p=result_state_p; +#else + if (type_alt==NULL) + return 0; + + state_p=&type_alt->type_alt_lhs->type_node_state; +#endif + + if (state_p->state_type==SimpleState){ + if (state_p->state_kind==OnB) + return find_state_in_database (state_p,mask,label_number_p); + else + return 0; + } else + return find_state_in_database (state_p,mask,label_number_p); +} |