Sie sind auf Seite 1von 3

#include <stdio.

h>
#include <string.h>
#include <stdlib.h>
#include "utils.h"
#include "tables.h"
const int SYMTBL_NON_UNIQUE = 0;
const int SYMTBL_UNIQUE_NAME = 1;
#define INITIAL_SIZE 5
#define SCALING_FACTOR 2
/*******************************
* Helper Functions
*******************************/
void allocation_failed() {
write_to_log("Error: allocation failed\n");
exit(1);
}
void addr_alignment_incorrect() {
write_to_log("Error: address is not a multiple of 4.\n");
}
void name_already_exists(const char* name) {
write_to_log("Error: name '%s' already exists in table.\n", name);
}
void write_symbol(FILE* output, uint32_t addr, const char* name) {
fprintf(output, "%u\t%s\n", addr, name);
}
/*******************************
* Symbol Table Functions
*******************************/
/* Creates a new SymbolTable containing 0 elements and returns a pointer to that
table. Multiple SymbolTables may exist at the same time.
If memory allocation fails, you should call allocation_failed().
Mode will be either SYMTBL_NON_UNIQUE or SYMTBL_UNIQUE_NAME. You will need
to store this value for use during add_to_table().
*/
SymbolTable* create_table(int mode) {
/* YOUR CODE HERE */
(SymbolTable*) new_table_ptr = (SymbolTable*)malloc(INITIAL_SIZE);
new_table_ptr->mode = mode;
new_table_ptr->len = 0;
new_table_ptr->cap = INITIAL_SIZE;
return new_table_ptr;
//when to call allocation_failed()
}
/* Frees the given SymbolTable and all associated memory. */
void free_table(SymbolTable* table) {
/* YOUR CODE HERE */
free(table->tbl);
free(table->len);

free(table->cap);
free(table->mode);
free(table);
}
/* A suggested helper function for copying the contents of a string. */
static char* create_copy_of_str(const char* str) {
size_t len = strlen(str) + 1;
char *buf = (char *) malloc(len);
if (!buf) {
allocation_failed();
}
strncpy(buf, str, len);
return buf;
}
/* Adds a new symbol and its address to the SymbolTable pointed to by TABLE.
ADDR is given as the byte offset from the first instruction. The SymbolTable
must be able to resize itself as more elements are added.
Note that NAME may point to a temporary array, so it is not safe to simply
store the NAME pointer. You must store a copy of the given string.
If ADDR is not word-aligned, you should call addr_alignment_incorrect() and
return -1. If the table's mode is SYMTBL_UNIQUE_NAME and NAME already exists
in the table, you should call name_already_exists() and return -1. If memory
allocation fails, you should call allocation_failed().
Otherwise, you should store the symbol name and address and return 0.
*/
int add_to_table(SymbolTable* table, const char* name, uint32_t addr) {
/* YOUR CODE HERE */
if (addr%4 != 0) {
//checks if word-aligned
addr_alignment_incorrect();
return -1;
}
if ((table->mode == SYMTBL_UNIQUE_NAME)
&& (get_addr_for_symbol(table, name) != -1)) { //name or NAME?
name_already_exists(name);
return -1;
}
//how to check if memory alloc failed?
char* name_copy = create_copy_of_str(name);
if (table->len >= table->cap) { //checks if resize
int size_increment = (SCALING_FACTOR - 1) * table->cap;
int* new_table = (int*)(malloc(size_increment)); //not totally sure if this
part is correct
table->cap*=2;
}
table->len++;
char* sym_name = (char*)(malloc(sizeof(name)));
uint32_t sym_addr = (uint32_t*)(malloc(sizeof(addr)));
table[len]->name = sym_name;
table[len]->addr = sym_addr;

return 0;
}
/* Returns the address (byte offset) of the given symbol. If a symbol with name
NAME is not present in TABLE, return -1.
*/
int64_t get_addr_for_symbol(SymbolTable* table, const char* name) {
/* YOUR CODE HERE */
//iterate thru every symbol in symboltable, check if name matches given name
//if so, return its address
int sym_index;
uint32_t address;
for (sym_index = 0; sym_index < table->len; sym_index++) {
Symbol* sym = table[sym_index];
if (strcmp(sym->name, name) == 0) {
address = sym->addr;
return (int64_t) address; //not totally sure if this casting works
}
}
return -1;
}
/* Writes the SymbolTable TABLE to OUTPUT. You should use write_symbol() to
perform the write. Do not print any additional whitespace or characters.
*/
void write_table(SymbolTable* table, FILE* output) {
/* YOUR CODE HERE */
write_symbol(output, table->tbl->addr, table->tbl->name);
// for (sym_index = 0; sym_index < table->len; sym_index++) {
// write_symbol(output, table[sym_index]->addr, table[sym_index]->name);
// }
}

Das könnte Ihnen auch gefallen