/*
 * A wrapper for the other string to bit string conversion functions.
 * Converts an arbitrary length string of base 16, 10, 8, or 2 to a
 * string of 1s and 0s of the given length, padding or truncating
 * the higher accordingly. The returned string will be little
 * endian. Null will be returned if the radix is invalid.
 *
 * Base 10 strings will be limited in length to a long long, but
 * an error will be issued if the number will be truncated.
 *
 */
char *convert_string_of_radix_to_bit_string(char *string, int radix, int binary_size)
{
	if (radix == 16)
	{
		return convert_hex_string_of_size_to_bit_string(0, string, binary_size);
	}
	else if (radix == 10)
	{
		long long number = convert_dec_string_of_size_to_long_long(string, binary_size);
		return convert_long_long_to_bit_string(number, binary_size);
	}
	else if (radix == 8)
	{
		return convert_oct_string_of_size_to_bit_string(string, binary_size);
	}
	else if (radix == 2)
	{
		return convert_binary_string_of_size_to_bit_string(0, string, binary_size);
	}
	else
	{
		return NULL;
	}
}
Example #2
0
/*---------------------------------------------------------------------------------------------
 * (function: create_tree_node_number)
 *-------------------------------------------------------------------------------------------*/
ast_node_t *create_tree_node_number(char* number, int line_number, int file_number)
{
    ast_node_t* new_node = create_node_w_type(NUMBERS, line_number, current_parse_file);
    char *string_pointer = number;
    int index_string_pointer = 0;
    char *temp_string;
    short flag_constant_decimal = FALSE;

    /* find the ' character if it's a base */
    for (string_pointer=number; *string_pointer; string_pointer++)
    {
        if (*string_pointer == '\'')
        {
            break;
        }
        index_string_pointer++;
    }

    if (index_string_pointer == strlen(number))
    {
        flag_constant_decimal = TRUE;
        /* this is base d */
        new_node->types.number.base = DEC;
        /* reset to the front */
        string_pointer = number;

        /* size is the rest of the string */
        new_node->types.number.size = strlen((string_pointer));
        /* assign the remainder of the number to a string */
        new_node->types.number.number = strdup((string_pointer));
    }
    else
    {
        /* there is a base in the form: number[bhod]'number */
        switch(tolower(*(string_pointer+1)))
        {
        case 'd':
            new_node->types.number.base = DEC;
            break;
        case 'h':
            new_node->types.number.base = HEX;
            break;
        case 'o':
            new_node->types.number.base = OCT;
            break;
        case 'b':
            new_node->types.number.base = BIN;
            break;
        default:
            oassert(FALSE);
        }

        /* check if the size matches the design specified size */
        temp_string = strdup(number);
        temp_string[index_string_pointer] = '\0';
        /* size is the rest of the string */
        new_node->types.number.size = atoi(temp_string);
        free(temp_string);

        /* move to the digits */
        string_pointer += 2;

        /* assign the remainder of the number to a string */
        new_node->types.number.number = strdup((string_pointer));
    }

    /* check for decimal numbers without the formal 2'd... format */
    if (flag_constant_decimal == FALSE)
    {
        /* size describes how may bits */
        new_node->types.number.binary_size = new_node->types.number.size;
    }
    else
    {
        /* size is for a constant that needs */
        if (strcmp(new_node->types.number.number, "0") != 0)
        {
            new_node->types.number.binary_size = ceil((log(convert_dec_string_of_size_to_long_long(new_node->types.number.number, new_node->types.number.size)+1))/log(2));
        }
        else
        {
            new_node->types.number.binary_size = 1;
        }
    }
    /* add in the values for all the numbers */
    switch (new_node->types.number.base)
    {
    case(DEC):
        // This will have limited width.
        new_node->types.number.value = convert_dec_string_of_size_to_long_long(new_node->types.number.number, new_node->types.number.size);
        new_node->types.number.binary_string = convert_long_long_to_bit_string(new_node->types.number.value, new_node->types.number.binary_size);
        break;
    case(HEX):
        new_node->types.number.binary_size *= 4;
        new_node->types.number.value = strtoll(new_node->types.number.number,NULL,16); // This will have limited width.
        // This will have full width.
        new_node->types.number.binary_string = convert_hex_string_of_size_to_bit_string(new_node->types.number.number, new_node->types.number.binary_size);
        break;
    case(OCT):
        new_node->types.number.binary_size *= 3;
        new_node->types.number.value = strtoll(new_node->types.number.number,NULL,8); // This will have limited width.
        // This will have full width.
        new_node->types.number.binary_string = convert_oct_string_of_size_to_bit_string(new_node->types.number.number, new_node->types.number.binary_size);
        break;
    case(BIN):
        // This will have limited width.
        new_node->types.number.value = strtoll(new_node->types.number.number,NULL,2);
        // This will have full width.
        new_node->types.number.binary_string = convert_binary_string_of_size_to_bit_string(new_node->types.number.number,  new_node->types.number.binary_size);
        break;
    }

    return new_node;
}