%{ CODE HEADER /* * The Termprocessor Kimwitu * * Copyright (c) 1991 University of Twente, Dept TIOS. * All rights reserved. * */ %} /* * gutil.k */ %{ #if ! (defined(lint) || defined(SABER) || defined(CODECENTER)) static char gutil_kAccesSid[] = "@(#)$Id: gutil.k,v 1.29 1998/01/29 10:57:34 belinfan Rel $"; #endif %} /***************************************************************************/ %{ KC_UNPARSE #include "gutil.h" %} %{ KC_UNPARSE static int g_no_of_phyla; static int g_no_of_operators; static int gl_no_of_args; #define PHYLUMNUMBEROFFSET 0 /* should be >= 0; == the index of the last dummy element */ #define OPERATORNUMBEROFFSET 0 /* should be >= 0; == the index of the last dummy element */ %} %{ KC_UNPARSE static selvarstack cl_selvarstack = 0; /* initialised by the view_init_stacks view in util.k */ #define cf_pushselvar(o) do { cl_selvarstack = Consselvarstack( o, cl_selvarstack ); \ g_ctext_level++; \ } while(kc_zero_constant) #define cf_topselvar() (cl_selvarstack->u.Consselvarstack.ID_1) #define cf_popselvar() do { selvarstack tmp_cl_selvarstack = cl_selvarstack; \ cl_selvarstack = cl_selvarstack->u.Consselvarstack.selvarstack_1; \ free_selvarstack( tmp_cl_selvarstack, False ); \ g_ctext_level--; \ } while(kc_zero_constant) static selvarstack cl_dollarvarstack = 0; /* initialised by the view_init_stacks view in util.k */ #define cf_pushdollarvar(o) do { cl_dollarvarstack = Consselvarstack( o, cl_dollarvarstack ); \ } while(kc_zero_constant) #define cf_topdollarvar() (cl_dollarvarstack->u.Consselvarstack.ID_1) #define cf_popdollarvar() do { selvarstack tmp_cl_dollarvarstack = cl_dollarvarstack; \ cl_dollarvarstack = cl_dollarvarstack->u.Consselvarstack.selvarstack_1; \ free_selvarstack( tmp_cl_dollarvarstack, False ); \ } while(kc_zero_constant) static selvarstack cl_dollarvarextstack = 0; /* initialised by the view_init_stacks view in util.k */ #define cf_pushdollarvarext(o) do { cl_dollarvarextstack = Consselvarstack( o, cl_dollarvarextstack ); \ } while(kc_zero_constant) #define cf_topdollarvarext() (cl_dollarvarextstack->u.Consselvarstack.ID_1) #define cf_popdollarvarext() do { selvarstack tmp_cl_dollarvarextstack = cl_dollarvarextstack; \ cl_dollarvarextstack = cl_dollarvarextstack->u.Consselvarstack.selvarstack_1; \ free_selvarstack( tmp_cl_dollarvarextstack, False ); \ } while(kc_zero_constant) static ID gl_phylum = 0; static phylumdeclaration gl_phydecl = 0; static ID gl_view = 0; static ID gl_operator = 0; static Ccode_option gl_cco = 0; static storageoption gl_storageoption = 0; static int gl_atomicity; /*used as boolean*/ static boolean gl_no_attributes; static arguments gl_args = 0; static rewriterulesinfo gl_rewrite_rewriteinfo = 0; static char *g_emptystring = ""; static int g_ctext_level = 0; static int g_withexpr_nr = 0; static int g_fe_selvar_nr = 0; static char *gl_return_type = ""; static ID gl_return_ID = 0; static char *gl_star_string = ""; static char *gl_function = ""; static ID gl_sto = 0; static int gl_hashtablenr_next = 0; static int gl_hashtablenr_prev = 0; static int gl_nr_of_hashtables = 0; static boolean gl_rewrite_goto_used = False; static boolean gl_unparse_goto_used = False; static boolean gl_outmost_nonleaf_predicates = False; static ID gl_type = 0; static int gl_j = 0; static boolean gl_print_line_directive = False; %} %{ /* string(s) stuff */ #include #if (! defined(KC_STDC) ) && defined(sun) extern char *sprintf(); #endif %} /***************************************************************************/ boolean f_something_to_initialize( cco ) Ccode_option cco; { with( cco ) { CcodeOption( attr, ct ): { return (boolean)(f_attributes_to_initialize( attr ) || (! f_NilCtexts( ct ))); } } } boolean f_NilCtexts( c ) Ctexts c; { with( c ) { NilCtexts(): { return True; } ConsCtexts( *, * ): { return False; } } } static boolean f_attributes_to_initialize( attr ) attributes attr; { foreach( a; attributes attr ) { with( a ) { Attribute( *, *, Noattribute_initialisation() ): {/*EMPTY*/} Attribute( *, *, Yesattribute_initialisation( * )): { return True; } } } return False; } boolean f_no_attrs_in_Ccode_option( cco ) Ccode_option cco; { with( cco ) { CcodeOption( Nilattributes(), * ): { return True; } CcodeOption( Consattributes( *, *), *): { return False; } } } /***************************************************************************/ /* * we use it in the unparse stuff */ %{ KC_UNPARSE_HEADER #include "gen.h" %} boolean f_all_alternatives_nullary( a ) alternatives a; { foreach( alt; alternatives a ) { with( alt ) { Alternative( *, Consarguments( *, * )): { return False; } Alternative( *, Nilarguments() ): {/*EMPTY*/} } } return True; } /***************************************************************************/ %{ #include "util.h" %} ID f_phylumofwithcasesinfo( wcso ) withcasesinfo wcso; { ID id; with( wcso ) { Nilwithcasesinfo(): { v_report(NonFatal( NoFileLine(), Problem1S( "Error: can not find type of with expression" ))); return Id( Str( mkcasestring( "KC_ERRORunknownTYPE" ))); } Conswithcasesinfo( wco, r_wcso ): { with( wco ) { Withcaseinfo( patrep, *, * ): { if ( eq_ID(id = f_phylumofpatternrepresentation( patrep ), f_emptyId() )) { return f_phylumofwithcasesinfo( r_wcso ); } else { return id; } } } } } } ID f_phylumofpatternrepresentation( a_patrep ) patternrepresentation a_patrep; { with( a_patrep ) { Nilpatternrepresentation(): { return f_emptyId(); } Conspatternrepresentation( a_patrep_elem, r_patrep ): { with( a_patrep_elem ) { PRBinding( *, * ): { return f_phylumofpatternrepresentation( r_patrep ); } PRNonLeafBinding( *, *, * ): { return f_phylumofpatternrepresentation( r_patrep ); } PRVarPredicate( *, *, * ): { return f_phylumofpatternrepresentation( r_patrep ); } PROperPredicate( *, id ): { return f_phylumofoperator( id ); } PRDefault(): { return f_phylumofpatternrepresentation( r_patrep ); } PRWildcard( * ): { return f_phylumofpatternrepresentation( r_patrep ); } PRStringLiteral( *, * ): { return f_phylumofpatternrepresentation( r_patrep ); } PRIntLiteral( *, * ): { return f_phylumofpatternrepresentation( r_patrep ); } } } } } /***************************************************************************/ Cvariabledeclarations sort_extend_Cvariabledeclarations( C_vardecls, fn_args ) Cvariabledeclarations C_vardecls; fnarguments fn_args; { return t_sort_extend_Cvariabledeclarations( C_vardecls, fn_args, NilCvariabledeclarations() ); } Cvariabledeclarations t_sort_extend_Cvariabledeclarations( C_vardecls, fn_args, temp ) Cvariabledeclarations C_vardecls; fnarguments fn_args; Cvariabledeclarations temp; { with( fn_args ){ Nilfnarguments() : { return temp; } Consfnarguments( a_fnarg, r_fnargs ): { temp = t_sort_extend_Cvariabledeclarations( C_vardecls, r_fnargs, temp ); return ConsCvariabledeclarations( lookup_and_createCvariabledeclaration( a_fnarg, C_vardecls ), temp ); } } } static Cvariabledeclaration lookup_and_createCvariabledeclaration( a_fnarg, C_vardecls ) ID a_fnarg; Cvariabledeclarations C_vardecls; { Cvariabledeclaration result = 0; int number_of_results = 0; foreach( vard ; Cvariabledeclarations C_vardecls ) { with( vard ) { CVariabledeclaration( type, cvars ): { foreach( cvar; Cvariables cvars ) { with( cvar ) { CVPointer( *, name ): { if (eq_ID( name, a_fnarg ) ) { result = CVariabledeclaration( type, ConsCvariables( cvar , NilCvariables() )); number_of_results++; } } CVFunction( *, *, name ): { if (eq_ID( name, a_fnarg ) ) { result = CVariabledeclaration( type, ConsCvariables( cvar , NilCvariables() )); number_of_results++; } } } } } Fnargfpdecl( type, cvars ): { foreach( cvar; Cvariables cvars ) { with( cvar ) { CVPointer( *, name ): { if (eq_ID( name, a_fnarg ) ) { result = CVariabledeclaration( type, ConsCvariables( cvar , NilCvariables() )); number_of_results++; } } CVFunction( *, *, name ): { if (eq_ID( name, a_fnarg ) ) { result = CVariabledeclaration( type, ConsCvariables( cvar , NilCvariables() )); number_of_results++; } } } } } } } if (number_of_results == 1) { return result; } else { /* error */ if (number_of_results > 1) { v_report(Warning( FileLine( a_fnarg->file, a_fnarg->line ), Problem1S1ID( "more than one type defined for function argument:", a_fnarg ))); } else { /* (number_of_results < 1) */ v_report(Warning( FileLine( a_fnarg->file, a_fnarg->line ), Problem1S1ID( "can not find type of function argument:", a_fnarg ))); } /* should be handled more gracefully */ return CVariabledeclaration( Id( Str( mkcasestring( "KC_ERRORunknownTYPE" ))), ConsCvariables( CVPointer( 0, a_fnarg ), NilCvariables() )); } } /***************************************************************************/ %{ #include "parse.h" %} ac_parameter_type_list sort_extend_parameter_type_list( C_vardecls, $decl ) ac_declaration_list C_vardecls; ac_declarator decl; { AcDeclarator( *, add ): { with( add ) { AcDirectDeclId( * ), AcDirectDeclPack( * ), AcDirectDeclArray( *, * ): { return AcParList( Nilac_parameter_list() ); } AcDirectDeclProto( *, fn_proto ): { return fn_proto; } AcDirectDeclKandR( *, Consac_identifier_list( Id( Str( "void" )), Nilac_identifier_list() ) ): { /* trick to get an empty parameter list but check the decls */ check_ac_parameter_declaration( C_vardecls, Nilac_identifier_list() ); return AcParList( t_sort_extend_parameter_list( C_vardecls, Nilac_identifier_list(), Nilac_parameter_list() ) ); } AcDirectDeclKandR( *, fn_args ): { check_ac_parameter_declaration( C_vardecls, fn_args ); return AcParList( t_sort_extend_parameter_list( C_vardecls, fn_args, Nilac_parameter_list() ) ); } } } } ac_parameter_list t_sort_extend_parameter_list( C_vardecls, fn_args, temp ) ac_declaration_list C_vardecls; ac_identifier_list fn_args; ac_parameter_list temp; { with( fn_args ){ Nilac_identifier_list() : { return temp; } Consac_identifier_list( a_fnarg, r_fnargs ): { temp = t_sort_extend_parameter_list( C_vardecls, r_fnargs, temp ); return Consac_parameter_list( lookup_and_create_ac_parameter_declaration( a_fnarg, C_vardecls ), temp ); } } } static ac_parameter_declaration lookup_and_create_ac_parameter_declaration( a_fnarg, C_vardecls ) ID a_fnarg; ac_declaration_list C_vardecls; { ac_parameter_declaration result = 0; int number_of_results = 0; foreach( $vard ; ac_declaration_list C_vardecls ) { AcDeclaration( type, cvars ): { foreach( $cvar; ac_init_declarator_list cvars ) { AcInitDecl( decl ): { ID name = f_ID_of_declarator( decl ); if (eq_ID( name, a_fnarg ) ) { result = AcParDeclDecl( type, decl ); number_of_results++; } } } } } if (number_of_results == 1) { return result; } else { /* error */ if (number_of_results > 1) { v_report(Warning( FileLine( a_fnarg->file, a_fnarg->line ), Problem1S1ID( "more than one type defined for function argument:", a_fnarg ))); } else { /* (number_of_results < 1) */ v_report(Warning( FileLine( a_fnarg->file, a_fnarg->line ), Problem1S1ID( "can not find type of function argument:", a_fnarg ))); } /* should be handled more gracefully */ return AcParDeclDecl( Consac_declaration_specifiers( AcDeclSpecTypeSpec( AcTypeSpec( Id( Str( mkcasestring( "KC_ERRORunknownTYPE" ))))), Nilac_declaration_specifiers()), AcDeclarator( Nopointer(), AcDirectDeclId( a_fnarg ))); } } static void check_ac_parameter_declaration( C_vardecls, fn_args ) ac_declaration_list C_vardecls; ac_identifier_list fn_args; { foreach( $vard ; ac_declaration_list C_vardecls ) { AcDeclaration( *, cvars ): { foreach( $cvar; ac_init_declarator_list cvars ) { AcInitDecl( decl ): { ID name = f_ID_of_declarator( decl ); int number_of_results = 0; foreach( a_fnarg; ac_identifier_list fn_args) { if (eq_ID( name, a_fnarg ) ) { number_of_results++; } } if (number_of_results > 1) { v_report(Warning( FileLine( name->file, name->line ), Problem1S1ID( "more than one function argument for type definition:", name ))); } else if (number_of_results < 1) { v_report(Warning( FileLine( name->file, name->line ), Problem1S1ID( "can not find declared function argument:", name ))); } } } } } } /***************************************************************************/ %{ #include "unpk.h" #ifndef MALLOC # define MALLOC emalloc #endif #ifndef REALLOC /* * # ifdef lint * # define REALLOC(kc_p,kc_s) (kc_p,kc_s,0) * # else */ # define REALLOC erealloc /* * # endif */ #endif #ifndef FREE # define FREE efree #endif #ifndef efree /* * # ifdef lint * # define efree(kc_p) * # else */ # define efree(kc_p) free((kc_malloc_t)(kc_p)) /* * # endif */ #endif %} void unparse_charptr( s, printer_fn, v ) char *s; void (*printer_fn)(char *dummy1, uview dummy2); view v; { printer_fn( s, v ); } char *f_mkstars( i ) int i; { static char star_string[] = "**************"; static char *malloced_star_string = 0; static char empty_string[] = ""; if (i <= 0 ) { return empty_string; } else if (i <= (int)strlen(star_string)) { return &(star_string[strlen(star_string)-i]); } else { char *ptr = 0; int j; if (malloced_star_string == 0) { malloced_star_string = (char *)MALLOC((kc_size_t) i+1 ); ptr = malloced_star_string; } else if ( i > (int)strlen(malloced_star_string) ) { malloced_star_string = (char *)REALLOC((kc_voidptr_t)malloced_star_string, (kc_size_t)i+1 ); ptr = malloced_star_string; } if (ptr != 0) { for (j = 0; j< i; j++) { *ptr++ = '*'; } *ptr = '\0'; } return &(malloced_star_string[strlen(malloced_star_string)-i]); } } char *f_mknls( i ) int i; { static char empty_string[] = ""; static char nl_string[] = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; static char *malloced_nl_string = 0; if (i <= 0 ) { return empty_string; } else if (i <= (int)strlen(nl_string)) { return &(nl_string[strlen(nl_string)-i]); } else { char *ptr = 0; int j; if (malloced_nl_string == 0) { malloced_nl_string = (char *)MALLOC( (kc_size_t)i+1 ); ptr = malloced_nl_string; } else if ( i > (int)strlen(malloced_nl_string) ) { malloced_nl_string = (char *)REALLOC( (kc_voidptr_t)malloced_nl_string, (kc_size_t)i+1 ); ptr = malloced_nl_string; } if (ptr != 0) { for (j = 0; j< i; j++) { *ptr++ = '\n'; } *ptr = '\0'; } return &(malloced_nl_string[strlen(malloced_nl_string)-i]); } } /* * HACK to get rid of backslash problems */ %{ #define QUOTEDBACKSLASH '\\' %} char *f_mkquotednls( ii ) int ii; { static char empty_string[] = ""; static char nl_string[] = "\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n"; static char *malloced_nl_string = 0; int i = 4*ii; if (i <= 0 ) { return empty_string; } else if (i <= (int)strlen(nl_string)) { return &(nl_string[strlen(nl_string)-i]); } else { char *ptr = 0; int j; if (malloced_nl_string == 0) { malloced_nl_string = (char *)MALLOC( (kc_size_t)i+1 ); ptr = malloced_nl_string; } else if ( i > (int)strlen(malloced_nl_string) ) { malloced_nl_string = (char *)REALLOC( (kc_voidptr_t)malloced_nl_string, (kc_size_t)i+1 ); ptr = malloced_nl_string; } if (ptr != 0) { for (j = 0; j< i; j+=4) { *ptr++ = QUOTEDBACKSLASH; *ptr++ = '\n'; *ptr++ = QUOTEDBACKSLASH; *ptr++ = 'n'; } *ptr = '\0'; } return &(malloced_nl_string[strlen(malloced_nl_string)-i]); } } %{ #define MKSELVARMAXINTREPR 30 %} ID f_mkselvar( prefix, level) char *prefix; int level; { /* HACK we suppose that MKSELVARMAXINTREPR charcters for the integer will be sufficient * we test for MKSELVARMAXINTREPR+1 for the \0 */ char fixbuf[BUFSIZ]; char *dynbuf = 0; char *buf = 0; ID id; if (strlen(prefix) + MKSELVARMAXINTREPR + 1 > BUFSIZ) { dynbuf = (char*)MALLOC((kc_size_t) strlen(prefix) + MKSELVARMAXINTREPR + 1); buf = dynbuf; } else { buf = fixbuf; } (void)strcpy( buf, prefix ); (void)sprintf( &buf[strlen(prefix)], "%d", level ); id = Id( Str( mkcasestring( buf ))); if (dynbuf != 0) { FREE((kc_voidptr_t) dynbuf ); } return id; } ID f_mkselvar2( prefix, level, branch) char *prefix; int level; int branch; { /* HACK we suppose that 2*MKSELVARMAXINTREPR charcters for the integers will be sufficient * (2 integers, 1 underscore, 1 \0) * we test for 2*MKSELVARMAXINTREPR+2 for the \0 */ char fixbuf[BUFSIZ]; char *dynbuf = 0; char *buf = 0; ID id; int constant_factor = MKSELVARMAXINTREPR + 1 + MKSELVARMAXINTREPR + 1; if (strlen(prefix) + constant_factor > BUFSIZ) { dynbuf = (char*)MALLOC((kc_size_t) strlen(prefix) + constant_factor); buf = dynbuf; } else { buf = fixbuf; } (void)strcpy( buf, prefix ); (void)sprintf( &buf[strlen(prefix)], "%d_%d", level, branch ); id = Id( Str( mkcasestring( buf ))); if (dynbuf != 0) { FREE((kc_voidptr_t) dynbuf ); } return id; } /* * make a file name from a (likely quoted) string, that may contain * a complete (absolute or relative path), and may, or may not end in * `.k'. if the ending is .k, then replace it by the (one letter) suffix; * if we don't have a .k ending, it will probably be stdin, so we * extend the name. * We keep in mind that we may have to remove quotes (") * The _caller_ will have to FREE filename. */ char *f_mk_filename( a_casestring, suffix ) casestring a_casestring; char suffix; { char *filename, *basename; int baselen; if ((basename = strrchr( a_casestring->name, '/' )) == 0) { basename = a_casestring->name; } if (*basename == '/') { basename++; } else if (*basename == '"') { basename++; } baselen = strlen(basename); filename = (char*)MALLOC((kc_size_t)baselen+3); /* for .c\0 */ (void)strcpy( filename, basename ); if (baselen > 0 && filename[baselen-1] == '"' ) { filename[baselen-1] = '\0'; baselen--; } if ( baselen > 1 && (filename[baselen-1] == 'k' && filename[baselen-2] == '.' )) { filename[baselen-1] = suffix; } else { filename[baselen] = '.'; filename[baselen+1] = suffix; filename[baselen+2] = '\0'; } return filename; } /***************************************************************************/ /* * make a name that can be used in the #define file/guard name * derive it from the .c or .h file * (we expect a basename with suffix) */ %{ #include %} char *f_make_identifier_basename( fn ) char *fn; { int len, i; char *nn; len = strlen(fn); /*SUPPRESS 622*/ assert(len >2); nn = (char*)MALLOC((kc_size_t)(len-2+1)); /* -2: drop .c; +1: add '\0' */ (void)strncpy(nn, fn, len-2); nn[len-2] = '\0'; for (i=0; i< len-2; i++) { if (! isalnum(nn[i])) { nn[i] = '_'; } } return nn; } /**************************************************************************/ /* * this function reorders the rewrite/unparsedeclsinfo in a phylum as follows: * the rewrite/unparsedeclsinfos per phylum are collected * (concatenated one after the other) * and then, for each view an rewrite/unparseviewsinfo is created, containing * the 'projection' of the collected rewrite/unparsedeclsinfo on this * particular view. */ %{ static ID global_filterview; /* to be used by filteronview */ %} rewriterulesinfo f_rewriterulesinfoofalternativeinview( a_alternative, a_view ) alternative a_alternative; ID a_view; { global_filterview = a_view; return filter_rewriterulesinfo( a_alternative->rewriteinfo, filterrewriteruleinfoonview ); } rewriteviewsinfo f_rewriteviewsinfoofalternatives( a_alternatives, a_views ) alternatives a_alternatives; viewnames a_views; { rewriterulesinfo tmp_rewriterulesinfo = f_rewriterulesinfoofalternatives( a_alternatives ); rewriteviewsinfo tmp_rewriteviewsinfo = Nilrewriteviewsinfo(); foreach (a_view; viewnames a_views ) { global_filterview = a_view; tmp_rewriteviewsinfo = Consrewriteviewsinfo( Rewriteviewinfo( a_view, filter_rewriterulesinfo( tmp_rewriterulesinfo, filterrewriteruleinfoonview )), tmp_rewriteviewsinfo ); } return tmp_rewriteviewsinfo; } unparseviewsinfo f_unparseviewsinfoofalternatives( a_alternatives, a_views ) alternatives a_alternatives; viewnames a_views; { unparsedeclsinfo tmp_unparsedeclsinfo = f_unparsedeclsinfoofalternatives( a_alternatives ); unparseviewsinfo tmp_unparseviewsinfo = Nilunparseviewsinfo(); foreach (a_view; viewnames a_views ) { global_filterview = a_view; tmp_unparseviewsinfo = Consunparseviewsinfo( Unparseviewinfo( a_view, filter_unparsedeclsinfo( tmp_unparsedeclsinfo, filterunparsedeclinfoonview )), tmp_unparseviewsinfo ); } return tmp_unparseviewsinfo; } static boolean filterrewriteruleinfoonview( a_rewriteruleinfo ) rewriteruleinfo a_rewriteruleinfo; { return is_viewname_in_rewriteruleinfo( global_filterview, a_rewriteruleinfo ); } static boolean filterunparsedeclinfoonview( a_unparsedeclinfo ) unparsedeclinfo a_unparsedeclinfo; { return is_viewname_in_unparsedeclinfo( global_filterview, a_unparsedeclinfo ); } static boolean is_viewname_in_rewriteruleinfo( a_view, a_rewriteruleinfo ) ID a_view; rewriteruleinfo a_rewriteruleinfo; { with( a_rewriteruleinfo ) { Rewriteruleinfo( *, *, RewriteClause( a_viewnames, * )): { return is_viewname_in_viewnames( a_view, a_viewnames ); } } } static boolean is_viewname_in_unparsedeclinfo( a_view, a_unparsedeclinfo ) ID a_view; unparsedeclinfo a_unparsedeclinfo; { with( a_unparsedeclinfo ) { Unparsedeclinfo( *, *, UnparseClause( a_viewnames, * )): { return is_viewname_in_viewnames( a_view, a_viewnames ); } } } static boolean is_viewname_in_viewnames( a_view, a_viewnames ) ID a_view; viewnames a_viewnames; { foreach( a_viewname; viewnames a_viewnames ) { if ( eq_ID( a_view, a_viewname ) ) { return True; } } return False; } /* * collect the rewrite/unparsedeclsinfo of the alternatives. * NOTE: it is of vital importance that the rewrite/unparsedeclsinfo is _not_ * reordered, because the current order corresponds to the tree/pattern * matching strategy. */ static rewriterulesinfo f_rewriterulesinfoofalternatives( a_alternatives ) alternatives a_alternatives; { rewriterulesinfo tmp = Nilrewriterulesinfo(); foreach( a_alternative; alternatives a_alternatives ) { tmp = concat_rewriterulesinfo( a_alternative->rewriteinfo, tmp ); } return tmp; } static unparsedeclsinfo f_unparsedeclsinfoofalternatives( a_alternatives ) alternatives a_alternatives; { unparsedeclsinfo tmp = Nilunparsedeclsinfo(); foreach( a_alternative; alternatives a_alternatives ) { tmp = concat_unparsedeclsinfo( a_alternative->unparseinfo, tmp ); } return tmp; } ID f_typeof( a_path ) path a_path; { if (eq_ID(a_path->id, f_emptyId())) { with( a_path ) { Nilpath(): { return f_phylumofoperator( a_path->op ); } Conspath( i, r_path ): { return f_subphylumofoperator( r_path->op, Int( i ) ); } } } else { return a_path->id; } } ID f_operatorofpatternrepresentation( a_patternrepresentation ) patternrepresentation a_patternrepresentation; { with( a_patternrepresentation ) { Nilpatternrepresentation(): { return f_emptyId(); } Conspatternrepresentation( e, * ): { return f_operatorofelem_patternrepresentation( e ); } } } static ID f_operatorofelem_patternrepresentation(a_elem_patternrepresentation ) elem_patternrepresentation a_elem_patternrepresentation; { with( a_elem_patternrepresentation ) { PRBinding( p, * ): { return f_operatorofpath( p ); } PRVarPredicate( ps, *, * ): { return f_operatorofpaths( ps ); } PROperPredicate( p, * ): { return f_operatorofpath( p ); } PRNonLeafBinding( p, *, * ): { return f_operatorofpath( p ); } PRDefault(): { return f_emptyId(); } PRWildcard( p ): { return f_operatorofpath( p ); } PRStringLiteral( p, * ): { return f_operatorofpath( p ); } PRIntLiteral( p, * ): { return f_operatorofpath( p ); } } } static ID f_operatorofpaths( a_paths ) paths a_paths; { with( a_paths ) { Nilpaths(): { return f_emptyId(); } Conspaths( p, * ): { return f_operatorofpath( p ); } } } static ID f_operatorofpath( a_path ) path a_path; { with( a_path ) { Nilpath(): { return a_path->op; } Conspath( *, r_path ): { return r_path->op; } } } ID f_typeofunpsubterm( a_unpsubterm, a_operator ) unpsubterm a_unpsubterm; ID a_operator; { with( a_unpsubterm ) { UnpSubTerm( a_id ): { return f_phylumofpatternID( a_id ); } UnpDollarvarTerm( i ): { return f_subphylumofoperator( a_operator, i ); } UnpSubAttr( an_id, an_unpattributes ): { return f_check_unpattributes_in_phylum( an_unpattributes, f_phylumofpatternID( an_id ) ); } UnpDollarvarAttr( i, a_unpattributes ): { return f_check_unpattributes_in_phylum( a_unpattributes, f_subphylumofoperator( a_operator, i ) ); } UnpCastedVariable( a_cast, * ): { return a_cast; } } } /**************************************************************************/ boolean f_outmost_nl_preds_in_rewriterulesinfo( ri ) rewriterulesinfo ri; { with( ri ) { Nilrewriterulesinfo(): { return False; } Consrewriterulesinfo( Rewriteruleinfo( preds, *, * ), r_ri ): { return (boolean) (f_outmost_nl_preds_in_patternrepresentation( preds ) || f_outmost_nl_preds_in_rewriterulesinfo( r_ri )); } } } static boolean f_outmost_nl_preds_in_patternrepresentation( p ) patternrepresentation p; { with( p ) { Nilpatternrepresentation(): { return False; } Conspatternrepresentation( a_p, r_p ): { return (boolean) (f_outmost_nl_preds_in_elem_patternrepresentation( a_p ) || f_outmost_nl_preds_in_patternrepresentation( r_p )); } } } static boolean f_outmost_nl_preds_in_elem_patternrepresentation( e_p ) elem_patternrepresentation e_p; { with( e_p ) { PRBinding( *, * ): { return False; } PRVarPredicate( a_p, *, * ): { return f_outmost_nl_preds_in_paths( a_p ); } PROperPredicate( *, * ): { return False; } PRNonLeafBinding( *, *, * ): { return False; } PRDefault(): { return False; } PRWildcard( * ): { return False; } PRStringLiteral( *, * ): { return False; } PRIntLiteral( *, * ): { return False; } } } static boolean f_outmost_nl_preds_in_paths( p ) paths p; { with( p ) { Nilpaths(): { return False; } Conspaths( Nilpath(), * ): { return True; } Conspaths( Conspath( *, * ), r_p ): { return f_outmost_nl_preds_in_paths( r_p ); } } } /***************************************************************************/ /* * this function is called when deciding to print (dummy) `return (cast)0;' * code in a default with case of a non-void function, to suppress lint * messages about `has both return(e); and return;' * * the idea is that when this function is called we know that the return-type * is not a ptr type, nor is it a phylum. * This routine should check if it is something else that we now (ie. that we * generate in kc (eg. a view, a hashtable, a boolean, etc.) * * right now we use a terrible search strategy (linear!), * we should use the the uniq strategy, and have a new IDtype * for types. */ boolean f_is_known_ptr_type( id ) ID id; { static phylumnames known = 0; if (! known ) { /* to be extended with new types */ known = Nilphylumnames(); known = Consphylumnames( Id( Str( mkcasestring( "kc_voidptr_t" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_malloc_t" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_voidfnptr_t" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_realloc_arg_t" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_size_t" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "size_t" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "unsigned" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_memset_size_t" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_memory_blocksinfo_t" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_enum_phyla" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_enum_operators" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_enum_phyla_list" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_size_t_list" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "KC_UNIQ_INFO" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_hashnode_t" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_tp_boolean" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "boolean" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_hastable_storage_mode_t" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_hashtable_t" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_private_malloc_t" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_Align" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "kc_qsort_firstarg_t" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "KC_IO_STATUS" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "view" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "uview" ))), known ); known = Consphylumnames( Id( Str( mkcasestring( "rview" ))), known ); } foreach( pn; phylumnames known ) { if ( eq_ID( pn, id )) { return True; } } return False; } /***************************************************************************/ /* * rewrite rules to simplify the pattern representations, * by eliminating the PRWildcard(*) and PRDefault() * This rules will be used just before code is generared */ Conspatternrepresentation( PRWildcard( * ), r ) -> r; Conspatternrepresentation( PRDefault(), r ) -> r; /* * we need the routine below to make sure that we only rewrite the * predicates in the withcaseinfo. * If we would also rewrite the bindings, we would loose the 'type' * attribute that contains important type information. */ %{ #include "rk.h" /* for the rewrite_withcasesinfo call below */ %} withcasesinfo my_rewrite_withcasesinfo(withcasesinfo $a_withcasesinfo) { Nilwithcasesinfo(): { return $0; } Conswithcasesinfo( Withcaseinfo( p, b, ct ), r ): { return Conswithcasesinfo( Withcaseinfo( rewrite_patternrepresentation(p, base_rview), b, ct ), my_rewrite_withcasesinfo( r ) ); } } /***************************************************************************/ /* * Compute the position of the sole (single) dollar variable or * pattern in a patternchain. This is to be used to set the right $0 * for a foreach statement. * NOTE: if there is more than a single pattern or dollar variable, * then we don't set $0. We call this failure. * We indicate failure by returning -1. * We start with inital return value of -2, meaning: mothing found, but * no failure yet. * A zero or positive return value indicates the index of the pattern * or dollar variable. */ int pos_of_sole_dollar_or_pattern_in_patternchain(patternchain a_patternchain) { return t_pos_of_sole_dollar_or_pattern_in_patternchain(a_patternchain, -2, 1); } int t_pos_of_sole_dollar_or_pattern_in_patternchain(patternchain a_patternchain, int tmp_result, int pos) { if (tmp_result == -1) { /*failure*/ return tmp_result; } with( a_patternchain ) { Conspatternchain( h, t ): { tmp_result = t_pos_of_sole_dollar_or_pattern_in_patternchain( t, tmp_result, pos+1 ); if (tmp_result == -1) { /*failure*/ return tmp_result; } with( h ) { PatternchainitemOutmost( p ): { with( p ) { OPOperatorWildcard( id ): { with( id ) { Id( uid ): { with( uid->type ) { ITPatternVariable( *, * ), ITUnknown(): { /* only variable */ return tmp_result; } default: { if (tmp_result >= 0) { return -1; /*failure*/ } else { return pos; } } } } } } default: { if (tmp_result >= 0) { return -1; /*failure*/ } else { return pos; } } } } PatternchainitemGroup( * ): { return -1; /* ERROR found */ } PatternchainitemDollarid( * ): { if (tmp_result >= 0) { return -1; /*failure*/ } else { return pos; } } } } Nilpatternchain(): { return tmp_result; } } }