From 6cf6246f9efd6d58a8aa51cdaa85c0f96dc42c43 Mon Sep 17 00:00:00 2001 From: Steven Schronk Date: Fri, 5 Feb 2010 22:46:41 -0600 Subject: [PATCH] Continued to add symbol support. Moved load_symbols code into main function. Added reset_buffer function that moves current_command pointer back to beginning of input buffer. This was required as the has_more_commands and advance functions are now used to travel through the code twice. Function enc_symbol now passes an integer value instead of an array of type char. Function symbol no longer requires an array. Now converts chars into an integer and returns int value to caller. New function symbol_load pushes symbols into the hash array. Uses new rom_address as location for symbol. Address for RAM has been created, but not fully implemented. --- asm.c | 46 +++++++++++++++++---- code.c | 21 ++++------ code.h | 2 +- parse.c | 142 +++++++++++++++++++++++++++++++-------------------------------- parse.h | 20 +++++---- symbol.c | 31 +++++++++++--- symbol.h | 19 +++++++++ 7 files changed, 174 insertions(+), 107 deletions(-) diff --git a/asm.c b/asm.c index 8b5a564..bc11806 100644 --- a/asm.c +++ b/asm.c @@ -14,6 +14,7 @@ int main(int argc, char *argv[]) { char FilenameBuff[80]; register int i = 0; + int address = 0; if(argc != 2) { exit_error(1, "No Input Files."); } /* TODO: future versions will accept more than one file */ @@ -36,24 +37,55 @@ int main(int argc, char *argv[]) FilenameBuff[i+1] = 'k'; FilenameBuff[i+2] = '\0'; - load_symbols(); + /* load symbol table with pre-defined symbols */ + add_entry("SP", 0); + add_entry("LCL", 1); + add_entry("ARG", 2); + add_entry("THIS", 3); + add_entry("THAT", 4); + add_entry("SCREEN", 16384); + add_entry("KBD", 24576); + + add_entry("R0", 0); + add_entry("R1", 1); + add_entry("R2", 2); + add_entry("R3", 3); + add_entry("R4", 4); + add_entry("R5", 5); + add_entry("R6", 6); + add_entry("R7", 7); + add_entry("R8", 8); + add_entry("R9", 9); + add_entry("R10", 10); + add_entry("R11", 11); + add_entry("R12", 12); + add_entry("R13", 13); + add_entry("R14", 14); + add_entry("R15", 15); - init_coder(FilenameBuff); + while(has_more_commands()) + { + advance(); + if(command_type() == A_COMMAND || command_type() == C_COMMAND) + inc_rom_address(); + if(command_type() == L_COMMAND) + symbol_load(); + } - /* TODO: verify output buffer has not been overflowed */ + print_hash(); + init_coder(FilenameBuff); + reset_buffer(); while(has_more_commands()) { char sym[MAXCOMMAND]; advance(); - /* printf("TYPE: %d ", command_type()); */ - /* print_current_command(); */ if(command_type() == A_COMMAND || command_type() == L_COMMAND) { - symbol(sym); - enc_symbol(sym); + address = symbol(sym); + enc_symbol(address); } if(command_type() == C_COMMAND) diff --git a/code.c b/code.c index 2dfac50..0949978 100644 --- a/code.c +++ b/code.c @@ -12,20 +12,17 @@ int init_coder(const char *filename) return 0; } -int enc_symbol(const char mnemonic[]) +void enc_symbol(int number) { - int value = 0; - int i = 0; + int i, j; + i = j = 0; - value = strtol(mnemonic, NULL, 10); - for( i = 15; i >= 0; i--) - { - if( (1 << i) & value) - putchar('1'); - else - putchar('0'); - } - return 0; + for(j = 15; j >= 0; j--) + { + i = number / (1 << j); + number = number - i * (1 << j); + printf("%d", i); + } } int enc_dest(const char mnemonic[]) diff --git a/code.h b/code.h index aa05813..1cff784 100644 --- a/code.h +++ b/code.h @@ -9,7 +9,7 @@ int init_coder(const char *filename); * mnemonic is array of chars with A_COMMAND or L_COMMAND. * code array will be modified to binary chars of command. */ -int enc_symbol(const char mnemonic[]); +void enc_symbol(int number); /* * Returns binary code of the dest mnemonic diff --git a/parse.c b/parse.c index 616e32e..1ec57c9 100644 --- a/parse.c +++ b/parse.c @@ -29,6 +29,11 @@ void dump_buffer() printf("\n"); } +void reset_buffer() +{ + current_command = InBuff; +} + int find_line_num() { int i = 1; @@ -122,15 +127,18 @@ int command_type() if(*current_command == '@') { current_command_type = A_COMMAND; + inc_ram_address(); return A_COMMAND; } else if(search_command(current_command, '(') > 0 || search_command(current_command, ')') > 0) { current_command_type = L_COMMAND; return L_COMMAND; } else if(!isdigit(*current_command)){ current_command_type = C_COMMAND; + inc_ram_address(); return C_COMMAND; } else if(isdigit(*current_command)){ current_command_type = C_COMMAND; + inc_ram_address(); return C_COMMAND; } else { int i = find_line_num(); @@ -140,35 +148,84 @@ int command_type() } } -int symbol(char sym[]) +int symbol() { - int i = 0; + int convert = 0, i = 0; + char sym[MAXSYMBOL]; + + /* determine if this is a symbol or an address */ + convert = isdigit(*(current_command+1)); if(current_command_type == A_COMMAND) { - while(!isspace(*(current_command+i+1))) + if(convert == 0) { - sym[i] = *(current_command+i+1); - ++i; + /* lookup this symbol in hash table and get it's address */ + i = 0; + while(!isspace(*(current_command+i+1))) + { + sym[i] = *(current_command+i+1); + ++i; + } + sym[i++] = '\0'; + return get_address(sym); + } else { + /* convert numbers into integer and return current symbol as integer */ + i = 0; + while(!isspace(*(current_command+i+1))) + { + sym[i] = *(current_command+i+1); + ++i; + } + sym[i++] = '\0'; + /* convert string into an int for return */ + return (int)strtol(sym, (char **) NULL, 10); } - sym[i++] = '\0'; - return 1; } if(current_command_type == L_COMMAND) { - while(!isspace(*(current_command+i+1)) && *(current_command+i+1) != ')') + if(convert == 0) { - sym[i] = *(current_command+i+1); - ++i; + /* lookup this symbol in hash table and get it's address */ + i = 0; + while(!isspace(*(current_command+i+1)) && *(current_command+i+1) != ')') + { + sym[i] = *(current_command+i+1); + ++i; + } + sym[i++] = '\0'; + return get_address(sym); + } else { + /* convert numbers into integer and return current symbol as integer */ + i = 0; + while(!isspace(*(current_command+i+1)) && *(current_command+i+1) != ')') + { + sym[i] = *(current_command+i+1); + ++i; + } + sym[i++] = '\0'; + return (int)strtol(sym, (char **) NULL, 10); } - sym[i++] = '\0'; - return 1; } exit_error(8, "Symbol Function Called on Incorrect Command Type."); return 0; } +int symbol_load() +{ + char sym[MAXCOMMAND]; + int i = 0; + while(!isspace(*(current_command+i+1)) && *(current_command+i+1) != ')') + { + sym[i] = *(current_command+i+1); + ++i; + } + sym[i++] = '\0'; + add_entry(sym, get_rom_address()); + return 0; +} + int dest(char dest[]) { int i = 0; @@ -285,64 +342,3 @@ int jump(char jump[]) exit_error(8, "Symbol Function Called on Incorrect Command Type."); return 0; } - -void load_symbols() -{ - int i = 0, j = 0; - char symbol_buff[MAXSYMBOL]; - /* load symbol table with pre-defined symbols */ - add_entry("SP", 0); - add_entry("LCL", 1); - add_entry("ARG", 2); - add_entry("THIS", 3); - add_entry("THAT", 4); - add_entry("SCREEN", 16384); - add_entry("KBD", 24576); - - add_entry("R0", 0); - add_entry("R1", 1); - add_entry("R2", 2); - add_entry("R3", 3); - add_entry("R4", 4); - add_entry("R5", 5); - add_entry("R6", 6); - add_entry("R7", 7); - add_entry("R8", 8); - add_entry("R9", 9); - add_entry("R10", 10); - add_entry("R11", 11); - add_entry("R12", 12); - add_entry("R13", 13); - add_entry("R14", 14); - add_entry("R15", 15); - - /* symbol check: - starts with @ and next char is not a number - starts with ( and next char is not a number - */ - - while(pInBuff != '\0') - { - if(pInBuff == '@' || pInBuff == '(') - { - ++i; - if(!isdigit(pInBuff)) - { - /* printf("SYMBOL_START: %c\n", pInBuff); */ - j = 0; - while(!isspace(pInBuff) && pInBuff != '\0' && pInBuff != ')') - { - symbol_buff[j] = pInBuff; - ++i; - ++j; - } - symbol_buff[j++] = '\0'; - /* printf("Symbol Found: %s\n", symbol_buff); */ - add_entry(symbol_buff, -1); - print_hash(); printf("---------\n"); - } - } - ++i; - } - print_hash(); -} diff --git a/parse.h b/parse.h index 6c1c0cf..054cf5a 100644 --- a/parse.h +++ b/parse.h @@ -1,4 +1,3 @@ - #define MAXCOMMAND 100 #define MAXINBUFF 250000 #define MAXSYMBOL 256 @@ -19,6 +18,12 @@ #define L_COMMAND 2 void dump_buffer(); + +/* +* Resets command pointer to beginning of input buffer. +*/ +void reset_buffer(); + void init_parser(char *FilenameBuff); /* @@ -60,7 +65,12 @@ int command_type(); * Returns symbol or decimal of current command * Should be called only when command_type() is A_COMMAND or L_COMMAND */ -int symbol(char sym[]); +int symbol(); + +/* +* Reads command and finds symbol chars. Loads into hash +*/ +int symbol_load(); /* * Returns the dest mnemonic in the current C_COMMAND @@ -79,9 +89,3 @@ int comp(char comp[]); * Called only when command_type() is C_COMMAND */ int jump(char jump[]); - -/* -* Evaluate full text of input file and find all symbols. -* Load symbols into symbol_hash table. -*/ -void load_symbols(void); diff --git a/symbol.c b/symbol.c index a9826d7..65ec472 100644 --- a/symbol.c +++ b/symbol.c @@ -7,8 +7,25 @@ #include "symbol.h" struct symbol_hash symbol_hash[HASH_SIZE]; + +int ram_address = 17; int rom_address = 0; +void inc_ram_address() +{ + ++ram_address; +} + +void inc_rom_address() +{ + ++rom_address; +} + +int get_rom_address() +{ + return rom_address; +} + void print_hash() { int i = 0; @@ -42,11 +59,11 @@ int add_entry(char symbol[], int address) hash_val = hash(symbol); if(symbol_hash[hash_val].name[0] == '\0') { - printf("NEW SYMBOL %s\n", symbol); + /* printf("NEW SYMBOL %s\n", symbol); */ strcpy(symbol_hash[hash_val].name, symbol); if(address < 0) { - symbol_hash[hash_val].address = rom_address++; + symbol_hash[hash_val].address = ram_address++; } else { symbol_hash[hash_val].address = address; } @@ -54,7 +71,7 @@ int add_entry(char symbol[], int address) } else { /* compare value of symbol here with input of function */ if(strcmp(symbol_hash[hash_val].name, symbol) == 0) { return 1; } - printf("Found Duplicate Hash Value\n"); + /* printf("Found Duplicate Hash Value\n"); */ do{ ++i; } while (symbol_hash[i].name != NULL && i < HASH_SIZE); if( i == HASH_SIZE) { @@ -65,7 +82,7 @@ int add_entry(char symbol[], int address) strcpy(symbol_hash[hash_val].name, symbol); if(address < 0) { - symbol_hash[hash_val].address = rom_address++; + symbol_hash[hash_val].address = ram_address++; } else { symbol_hash[hash_val].address = address; } @@ -80,7 +97,8 @@ int get_address(char symbol[]) hash_val = hash(symbol); if(symbol_hash[hash_val].name != NULL) { - return hash_val; + /* printf("Symbol Passed: %s -> Address Returned %d\n", symbol, symbol_hash[hash_val].address); */ + return symbol_hash[hash_val].address; } else { /* could not find hash -- loop through strings @@ -93,7 +111,8 @@ int get_address(char symbol[]) } if(strcmp(symbol_hash[i].name, symbol) == 0) { - return i; + /* printf("Symbol Passed: %s -> Address Returned %d\n", symbol, symbol_hash[hash_val].address); */ + return symbol_hash[i].address; } } return -1; diff --git a/symbol.h b/symbol.h index 2171934..ef8686a 100644 --- a/symbol.h +++ b/symbol.h @@ -8,6 +8,25 @@ struct symbol_hash }; /* +* Increments RAM Address value. +* RAM Address used to store location of data tied to symbols. +* This number corresponds to the location in RAM of this data value. +*/ +void inc_ram_address(); + +/* +* Increments ROM Address value. +* ROM Address used to store location of instruction tied to symbols. +* This number correponds to the instruction number of the "jump" instruction. +*/ +void inc_rom_address(); + +/* +* Returns current value of ROM address. +*/ +int get_rom_address(); + +/* * Prints out hash. * Must pass hash pointer and length of hash array */ -- 2.11.4.GIT