/* Objective Modula-2 Compiler Utility Program (gen_first_and_follow_sets.c) * * @file objm2_tokenset_literals.c * Literal generator implementation * * Tokenset initialiser literal generator * * Author: Benjamin Kowarsch * * Copyright (C) 2009 The Objective Modula-2 Project. All rights reserved. * * License: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met * * 1) This file, or any part thereof, may NOT be hosted on websites which * contain advertising, unless specific prior written permission has been * obtained. The licensor will grant such permission upon request at its * sole discretion to websites the licensor does NOT consider abusive in * their use of advertising. Small notices in the footer of a website * naming corporate rights holders, infrastructure providers or sponsors * are not considered advertising in the context of this license. * * 2) Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 3) Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and other materials provided with the distribution. * * 4) Neither the author's name nor the names of any contributors may be used * to endorse or promote products derived from this software without * specific prior written permission. * * 5) Where this list of conditions or the following disclaimer, in part or * as a whole is overruled or nullified by applicable law, no permission * is granted to use the software. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Version history: * * 2.00 2009-08-15 BK new file */ #include "ASCII.h" #include "common_types.h" #include "common_macros.h" #include "objm2_tokenset_literals.h" #include // import NULL // --------------------------------------------------------------------------- // Integrity checks // --------------------------------------------------------------------------- #if (OBJM2_TOKENSET_BITS_PER_SEGMENT != 32) #error "invalid value for OBJM2_TOKENSET_BITS_PER_SEGMENT" #endif #if (OBJM2_TOKENSET_SEGMENTS_PER_SET != OBJM2_TOKENSET_LITERAL_NUM_OF_TUPLES) #error "invalid value for OBJM2_TOKENSET_LITERAL_NUM_OF_TUPLES" #endif // --------------------------------------------------------------------------- // Total number of bits in a tokenset // --------------------------------------------------------------------------- #define _OBJM2_TOKENSET_TOTAL_BITS \ (OBJM2_TOKENSET_BITS_PER_SEGMENT * OBJM2_TOKENSET_SEGMENTS_PER_SET) // --------------------------------------------------------------------------- // private function: _base16_digit( value ) // --------------------------------------------------------------------------- // // Converts to a base-16 digit and returns its ASCII representation. // If is greater than 15, a C string terminator is returned instead. static char _base16_digit(uint_fast8_t value) { switch (value) { case 0 : case 1 : case 2 : case 3 : case 4 : case 5 : case 6 : case 7 : case 8 : case 9 : return DIGIT_ZERO + (char) value; case 10 : return UPPERCASE_A; case 11 : return UPPERCASE_B; case 12 : return UPPERCASE_C; case 13 : return UPPERCASE_D; case 14 : return UPPERCASE_E; case 15 : return UPPERCASE_F; default : return CSTRING_TERMINATOR; } // end switch } // end _base16_digit // --------------------------------------------------------------------------- // function: objm2_tokenset_to_literal( set, literal ) // --------------------------------------------------------------------------- // // Passes a C string containing an initialiser literal for tokenset back // in parameter . If is NULL, an empty string is passed back. // If is NULL, the function returns without action. void objm2_tokenset_to_literal(objm2_tokenset_t set, objm2_tokenset_literal_t *literal, objm2_tokenset_literal_status_t *status) { uint_fast8_t index = 0, bit = 0; uint_fast8_t bit0, bit1, bit2, bit3; char *_literal = (char *) literal; // literal must not be NULL if (literal == NULL) { ASSIGN_BY_REF(status, OBJM2_TOKENSET_LITERAL_STATUS_INVALID_REFERENCE); return; } // end if // return empty string if set is NULL if (set == NULL) { ASSIGN_BY_REF(status, OBJM2_TOKENSET_LITERAL_STATUS_INVALID_REFERENCE); _literal[0] = CSTRING_TERMINATOR; return; } // end if #ifdef DEBUG int tokens = OBJM2_NUMBER_OF_TOKENS; int tokdiv32 = (tokens - 1) / OBJM2_TOKENSET_BITS_PER_SEGMENT; int tuples = OBJM2_TOKENSET_LITERAL_NUM_OF_TUPLES; #endif while (bit < _OBJM2_TOKENSET_TOTAL_BITS) { // if first bit in tuple ... if ((bit % OBJM2_TOKENSET_BITS_PER_SEGMENT) == 0) { // add separator comma and whitespace unless first tuple if (bit != 0) { _literal[index] = COMMA; index++; _literal[index] = WHITESPACE; index++; } // end if // add ' 0x' before each tuple _literal[index] = DIGIT_ZERO; index++; _literal[index] = LOWERCASE_X; index++; } // end if if (bit < OBJM2_NUMBER_OF_TOKENS) bit0 = objm2_tokenset_is_element(set, (objm2_token_t) bit); else bit0 = 0; bit++; if ( bit < OBJM2_NUMBER_OF_TOKENS) bit1 = objm2_tokenset_is_element(set, (objm2_token_t) bit); else bit1 = 0; bit++; if ( bit < OBJM2_NUMBER_OF_TOKENS) bit2 = objm2_tokenset_is_element(set, (objm2_token_t) bit); else bit2 = 0; bit++; if ( bit < OBJM2_NUMBER_OF_TOKENS) bit3 = objm2_tokenset_is_element(set, (objm2_token_t) bit); else bit3 = 0; bit++; // determine the next digit in the tuple _literal[index] = _base16_digit((bit0 << 3) + (bit1 << 2) + (bit2 << 1) + bit3); if (_literal[index] == CSTRING_TERMINATOR) { ASSIGN_BY_REF(status, OBJM2_TOKENSET_LITERAL_STATUS_OUT_OF_RANGE); _literal[0] = CSTRING_TERMINATOR; return; } // end if index++; } // end while // terminate the literal _literal[index] = CSTRING_TERMINATOR; ASSIGN_BY_REF(status, OBJM2_TOKENSET_LITERAL_STATUS_SUCCESS); return; } // end objm2_tokenset_to_literal // END OF FILE