/* * 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; } }
/*--------------------------------------------------------------------------------------------- * (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; }