/* *------------------------------------------------------------------------ * substring->symbol * * Converting a substring to a Scheme symbol * * This C code implements a function substring->symbol: * substring->symbol STR BEG END * which converts a substring of STR to a symbol. The function can be * defined as * (define (substring->symbol STR BEG END) * (string->symbol (substring STR BEG END))) * However, the current C version is faster and produces no garbage * in case the resulting symbol has already been seen. This function * can be regarded as a "shared substring" implementation of the * above code. * * To use this efficient version in your Scheme code, you have to add * (extern (substring->symbol::symbol (::bstring ::int ::int) * "substring_to_symbol") * (include "substring-symbol.c")) * (pragma * (substring->symbol no-cfa-top nesting)) * to your module declaration. Note the 'include' clause will insert this * present file into the C code generated by the Bigloo compiler. * Therefore, you should not compile this file separately. * * This code is specific to the Bigloo Scheme system by Manuel Serrano. * * The code is almost entirely based on a function 'string_to_symbol' * in bigloo2.4b/runtime/Clib/csymbol.c of Bigloo distribution, * and c_substring of the bigloo2.4b/runtime/Clib/cstring.c * * Note, the previous version of this function had the signature * (substring->symbol::symbol (::string ::int ::int) * "substring_to_symbol") * that is, substring_to_symbol accepted a C string rather than Scheme * (Bigloo) string as its first argument. That was markedly slower: * slower than the composition of string->symbol and substring! The * reason is that ::bstring has its length easily available, while * the length of the ::string has to be computed, by strlen(). Note * that substring->symbol is called by next-token-of-as-symb, which * passes the input buffer as the first argument of substring->symbol. * The input buffer is typically a large string. As it turns out, * the cost of calling strlen repeatedly adds up. The present version * is roughly 30% faster than the composition of string->symbol and * substring, whereas the previous version of this function was 30% slower! * * $Id: substring-symbol.c,v 1.4 2002/06/06 17:03:40 oleg Exp $ *------------------------------------------------------------------------ */ /* * The following two #include only needed if this file is compiled * separately, rather than included #include #include */ #include extern obj_t string_to_symbol( char * ); obj_t substring_to_symbol(obj_t str, const int beg, const int end) { const int total_len = str->string_t.length; #if 0 printf("\nIn substring_to_symbol: %d %d '%.20s' %x\n",beg,end,BSTRING_TO_STRING(str),BSTRING_TO_STRING(str)); #endif assert( beg >= 0 && beg < total_len ); if( end == total_len ) return string_to_symbol(&STRING_REF( str, beg )); assert( end >= 0 && end < total_len ); { char * name = BSTRING_TO_STRING(str); const char c = name[end]; /* Save the character at name[end] */ obj_t symb; name[end] = '\0'; /* Forcibly terminate the string */ symb = string_to_symbol(name+beg); name[end] = c; /* Restore the char name[end] */ return symb; } }