tisc

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit c2fa47e26498589e4051971fa648478e4595732a
parent b42785d3f3109b72b2f9162b5721fd820985a39c
Author: Paul Longtine <paul@nanner.co>
Date:   Thu, 13 Jun 2019 00:25:48 -0400

Hashing out tiny assembler

Diffstat:
Aexample_assembly.asm | 5+++++
Mtisc.c | 239++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
2 files changed, 151 insertions(+), 93 deletions(-)

diff --git a/example_assembly.asm b/example_assembly.asm @@ -0,0 +1,5 @@ +# we're doing asssembly now + li 0x34 +sc: cin GRA GRB + sp GRA + sb GRB diff --git a/tisc.c b/tisc.c @@ -3,6 +3,7 @@ #include <stdint.h> #include <string.h> +#define TOT_INSTRUCTIONS 15 #define MAX_SYMBOLS 1000 #define MAX_SYMBOL_LEN 100 #define MAX_LINE_LEN 100 @@ -23,92 +24,129 @@ typedef struct InstructionDefintion int arguements; int instructionLength; uint8_t opcode_mask; - uint8_t* (*assemble)(struct InstructionDefintion, int, int, int); + uint8_t** (*assemble)(struct InstructionDefintion, uint8_t*); } InstructionDefinition_t; -uint8_t* assemble_default(InstructionDefinition_t definition, int arg0, int arg1, int arg2) +uint8_t** assemble_default( + InstructionDefinition_t definition, + uint8_t* arg) { - uint8_t return_value[] = { definition.opcode_mask }; + uint8_t** return_value = (uint8_t**)malloc(sizeof(uint8_t*) * 1); + + return_value[0] = &definition.opcode_mask; + return return_value; } -InstructionDefinition_t instruction_definitions[1] = +InstructionDefinition_t definitions[TOT_INSTRUCTIONS] = { - { "push", 0, 1, 0x93, assemble_default } + { "push", 0, 1, 0x93, assemble_default }, + { "pop", 0, 1, 0x53, assemble_default }, + { "pcr", 0, 1, 0xA3, assemble_default }, + { "li", 1, 2, 0x00, assemble_default }, + { "lli", 1, 1, 0x03, assemble_default }, + { "lui", 1, 1, 0x43, assemble_default }, + { "jmp", 1, 2, 0x83, assemble_default }, + { "lb", 1, 1, 0x87, assemble_default }, + { "sb", 1, 1, 0x8B, assemble_default }, + { "sp", 1, 1, 0x8F, assemble_default }, + { "cin", 2, 1, 0x02, assemble_default }, + { "cmp", 2, 1, 0xC3, assemble_default }, + { "or", 2, 1, 0x00, assemble_default }, + { "nand", 2, 1, 0x01, assemble_default }, + { "add", 2, 1, 0x02, assemble_default }, }; int validSymbols = 0; int addresses[MAX_SYMBOLS]; char symbols[MAX_SYMBOLS][MAX_SYMBOL_LEN]; -char *formats[MAX_INSTYPES][8] = -{ - // 0 arg instructions - { - "push", - "pop", - "pcr", - NULL - }, - // 1 arg instructions - { - "lli", - "lui", - "jmp", - "lb", - "sb", - "sp", - ".fill", - NULL - }, - // 2 arg instructions - { - "cmp", - "cin", - NULL - }, - // 3 arg instructions - { - "add", - "nand", - "or", - NULL - } -}; - - /* char *parse -> parses file and sets label, opcode, and args accordingly */ -char *parse(FILE *file, char *line, char **label, char **opcode, - char **arg0, char **arg1, char **arg2) +int parse(FILE *file, char *line, char **label, char **opcode, + char *arg[3]) { + int success = 0; + char *str, *first; str = fgets(line, MAX_LINE_LEN, file); + if (str != NULL) { first = strtok(line, " \t\n"); if (first == NULL || first[0] == '#') { - return parse(file, line, label, opcode, arg0, arg1, arg2); + return parse(file, line, label, opcode, arg); } else if (first[strlen(first) - 1] == ':') { *label = first; *opcode = strtok(NULL, " \t\n"); first[strlen(first) - 1] = '\0'; + + success = 1; } else { *label = NULL; *opcode = first; + + success = 1; + } + + if (success) + { + arg[0] = strtok(NULL, " \t\n"); + arg[1] = strtok(NULL, " \t\n"); + arg[2] = strtok(NULL, " \t\n"); } - *arg0 = strtok(NULL, " \t\n"); - *arg1 = strtok(NULL, " \t\n"); - *arg2 = strtok(NULL, " \t\n"); } - return(str); + return success; +} + +int validins(const char *opcode, char *arg[]) +{ + int status = 0; + + for (int i = 0; i < TOT_INSTRUCTIONS; i++) + { + // does that instruction label match what we're looking for? + if (strcmp(definitions[i].instructionLabel, opcode) == 0) + { + int supp_args; + for (supp_args = 0; supp_args < 3; supp_args++) + { + if (arg[supp_args] == NULL) + { + break; + } + } + + if (definitions[i].arguements > supp_args) + { + status = 2; // Too few args, fail + } + else + if (definitions[i].arguements < supp_args) + { + status = 3; // Too many args, fail + } + else + { + status = 1; // Success! + } + break; + } + } + + return status; +} + +int processins(int op, const char *opcode, char* arg[]) +{ + return 0; } int labelexists(const char *label) @@ -116,25 +154,43 @@ int labelexists(const char *label) int i, status = 0; for (i = 0; i < validSymbols; i++) - if (strcmp(symbols[i], label) == 0) status = 1; + { + if (strcmp(symbols[i], label) == 0) + { + status = 1; + } + } return status; } -int validins(int op, int format, const char *opcode, char *arg[]) +int process_label(char *label, int address) { int status = 0; - if (strcmp(formats[format][op], opcode) == 0) + + if (label != NULL) { - status = 1; - if (!(format == 0 && arg[0] == NULL && arg[1] == NULL && arg[2] == NULL || - format == 1 && arg[0] != NULL && arg[1] == NULL && arg[2] == NULL || - format == 2 && arg[0] != NULL && arg[1] != NULL && arg[2] == NULL || - format == 3 && arg[0] != NULL && arg[1] != NULL && arg[2] != NULL )) + //duplicate label check + if (labelexists(label) == 1) { - status = 2; + printf( + "Error:%i: re-use of existing label '%s'\n", + address, label ); + } + else + { + //add label to table 'o' label + strcpy(symbols[validSymbols], label); + addresses[validSymbols] = address; + validSymbols++; + + status = 1; } } + else + { + status = 1; + } return status; } @@ -142,46 +198,36 @@ int validins(int op, int format, const char *opcode, char *arg[]) /* int preprocess -> 1st pass over file, links symbols to address and reports syntax errors, fails if returns -1 */ int preprocess(int address, char *label, char *opcode, - char *arg0, char *arg1, char *arg2) + char *arg[3]) { + int i,op; int status = 0; - // arguement check - for (i = 0; (i < MAX_INSTYPES) && status == 0; i++) - { - for (op = 0; (formats[i][op] != NULL) && status == 0; op++) - { - char *args[3] = {arg0, arg1, arg2}; - status = validins(op, i, opcode, args); - } - } + status = validins(opcode, arg); switch (status) { case 0: - printf("Error:%i: instruction '%s' does not exist\n",address, opcode); - status = 1; + printf("Error:%i: instruction '%s' does not exist\n", + address, opcode); + status = 0; break; case 2: - printf("Error:%i: not enough arguements for '%s'\n",address, opcode); - status = 1; + printf("Error:%i: too few arguements for '%s'\n", + address, opcode); + status = 0; + break; + case 3: + printf("Error:%i: too many arguements for '%s'\n", + address, opcode); + status = 0; break; } - //duplicate label check - if (label != NULL) + if (status == 1) { - if (labelexists(label) == 1) - { - printf("Error:%i: label exists '%s'\n",address, label); - } - else - { - strcpy(symbols[validSymbols], label); - addresses[validSymbols] = address; - validSymbols++; - } + status = process_label(label, address); } return status; @@ -191,7 +237,7 @@ int preprocess(int address, char *label, char *opcode, machine code with symbols filled in as adresses, fails if returns -1 */ int process(int address, FILE *outfile, char *label, char *opcode, - char *arg0, char *arg1, char *arg2) + char *arg[3]) { return 0; } @@ -201,20 +247,20 @@ int main(int argc, char *argv[]) if (argc != 3) { fprintf(stderr, - "error useage: %s <assembly-code-file> <machine-code-file> \n", argv[0]); + "do: %s <assembly-code-file> <machine-code-file> \n", + argv[0]); + exit(1); } char *input, *output; FILE *inputf, *outputf; - char *labels, *opcodes, *args0, *args1, *args2; - char lines[MAX_LINE_LEN + 1]; + char *labels, *opcodes, *args[3]; + char line[MAX_LINE_LEN + 1]; int address = 0; input = argv[1]; - output = argv[2]; inputf = fopen(input, "r"); - outputf = fopen(output, "w"); if (inputf == NULL) { @@ -222,26 +268,33 @@ int main(int argc, char *argv[]) exit(1); } + output = argv[2]; + outputf = fopen(output, "w"); + if (outputf == NULL) { fprintf(stderr, "Error opening file '%s'", output); exit(1); } - while (parse(inputf, lines, &labels, &opcodes, &args0, &args1, &args2) != NULL) + while (parse(inputf, line, &labels, &opcodes, args) == 1) { - if (preprocess(address, labels, opcodes, args0, args1, args2) == 0) + if (preprocess(address, labels, opcodes, args) == 0) + { exit(1); + } address++; } rewind(inputf); address = 0; - while (parse(inputf, lines, &labels, &opcodes, &args0, &args1, &args2) != NULL) + while (parse(inputf, line, &labels, &opcodes, args) == 1) { - if (process(address, outputf, labels, opcodes, args0, args1, args2) == 0) + if (process(address, outputf, labels, opcodes, args) == 0) + { exit(1); + } address++; }