#include #include #include #include #include #include "assembler.h" #include "field.h" #include "lc3.h" #include "symbol.h" #include "tokens.h" #include "util.h" /** Global variable containing the head of the linked list of structures */ static line_info_t* infoHead; /** Global variable containing the tail of the linked list of structures */ static line_info_t* infoTail; /** Global variable containing information about the current line */ static line_info_t* currInfo; void asm_init_line_info (line_info_t* info) { if (info) { info->next = NULL; info->lineNum = srcLineNum; info->address = currAddr; info->machineCode = 0; info->opcode = OP_INVALID; info->form = 0; info->reg1 = -1; info->reg2 = -1; info->reg3 = -1; info->immediate = 0; info->reference = NULL; } } void asm_print_line_info (line_info_t* info) { if (info) { printf("%3d: address: x%04x machineCode:%04x op: %s form: %d reg1:%3d, reg2:%3d reg3:%3d imm: %d ref: %s\n", info->lineNum, info->address, info->machineCode, lc3_get_opcode_name(info->opcode), info->form, info->reg1, info->reg2, info->reg3, info->immediate, info->reference); } } /* based on code from http://www.eskimo.com/~scs/cclass/int/sx11c.html */ void asm_error (char* msg, ...) { numErrors++; va_list argp; fprintf(stderr, "ERROR %3d: ", srcLineNum); va_start(argp, msg); vfprintf(stderr, msg, argp); va_end(argp); fprintf(stderr, "\n"); } void asm_init (void) { infoHead = infoTail = currInfo = NULL; tokens_init(); lc3_sym_tab = symbol_init(0); } /** @todo implement this function */ void asm_pass_one (char* asm_file_name, char* sym_file_name) { } /** @todo implement this function */ void asm_pass_two (char* obj_file_name) { } /** @todo implement this function */ void asm_term (void) { } /** @todo implement this function */ char* check_for_label (char* token) { return token; } /** @todo implement this function */ void check_line_syntax (char* token) { printf("check_line_syntax('%s')\n", token); } /** @todo implement this function */ void encode_operand (operand_t operand) { } /** @todo implement this function */ void encode_PC_offset_or_error (int width) { } /** @todo implement this function */ void get_comma_or_error (void) { } /** @todo implement this function */ void get_immediate_or_error (char* token, int width, int isSigned) { } /** @todo implement this function */ void get_PC_offset_or_error (char* token) { } /** @todo implement this function */ int get_reg_or_error (char *token) { return -1; } /** @todo implement this function */ FILE *open_read_or_error (char* file_name) { return NULL; } /** @todo implement this function */ FILE *open_write_or_error (char* file_name) { return NULL; } /** @todo implement this function */ void get_operand (operand_t operand, char* token) { switch (operand) { case FMT_R1: currInfo->reg1 = get_reg_or_error(token); break; default: break; } } // can use ints instead of unsigned ints as long as v is never negative. This // is true for the use in LC3 assembler. // see http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan int count_bits (int v) { return 0; } /** @todo implement this function */ void scan_operands (operands_t operands) { printf("scan_operands() for %s\n", lc3_get_format_name(operands)); int operandCount = 0; int numOperands = count_bits(operands); int errorCount = numErrors; for (operand_t op = FMT_R1; op <= FMT_STR; op <<= 1) { if (errorCount != numErrors) return; // error, so skip processing remainder of line // add code here } } /** @todo implement this function */ void update_address (void) { }