refactor a couple things

This commit is contained in:
2026-07-16 14:01:36 +10:00
parent 42fab467f1
commit 68b7667725
5 changed files with 201 additions and 63 deletions

View File

@@ -10,7 +10,9 @@ sources = files(
asmSources = files( asmSources = files(
'src/assembler/main.c', 'src/assembler/main.c',
'src/assembler/assemble.c' 'src/assembler/assemble.c',
'src/assembler/program.c',
'src/instruction.c'
) )
args = ['-Wall', '-Wextra'] args = ['-Wall', '-Wextra']

View File

@@ -4,6 +4,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include "../instruction.h" #include "../instruction.h"
@@ -23,12 +24,12 @@ struct _stringToInstructionOpcodeTable {char* str; InstructionOpcode opcode;} st
{"jiz", INST_JIZ}, {"jiz", INST_JIZ},
{"call", INST_CALL}, {"call", INST_CALL},
{"ret", INST_RET}, {"ret", INST_RET},
{"sys", INST_SYS}, {"port", INST_PORT},
{"hlt", INST_HLT}, {"hlt", INST_HLT},
}; };
InstructionOpcode stringToInstructionOpcode(const char* string) { InstructionOpcode stringToInstructionOpcode(const char* string) {
for (size_t i = 0; i < sizeof(stringToInstructionOpcodeTable) / sizeof(struct _stringToInstructionOpcodeTable)); i++) { for (size_t i = 0; i < 16; i++) {
if (strcmp(stringToInstructionOpcodeTable[i].str, string) == 0) { if (strcmp(stringToInstructionOpcodeTable[i].str, string) == 0) {
return stringToInstructionOpcodeTable[i].opcode; return stringToInstructionOpcodeTable[i].opcode;
} }
@@ -38,48 +39,6 @@ InstructionOpcode stringToInstructionOpcode(const char* string) {
exit(1); exit(1);
} }
Program newProgram(void) {
Program program = {
.at = malloc(sizeof(Instruction) * 16),
.len = 0,
.capacity = 16
};
if (program.at == NULL) {
fprintf(stderr, "malloc failed while creating new program\n");
exit(1);
}
return program;
}
void addInstructionToProgram(Program* program, Instruction inst) {
if (program->at == NULL) {
fprintf(stderr, "unexpected NULL value when adding instruction to program\n");
exit(1);
}
if (program->len + 1 >= program->capacity) {
Instruction* tmp = malloc(sizeof(Instruction) * program->capacity * 2);
if (tmp == NULL) {
fprintf(stderr, "malloc failed while expanding program\n");
exit(1);
}
program->at = tmp;
program->capacity *= 2;
}
program->at[program->len] = inst;
program->len++;
}
void freeProgram(Program* program) {
if (program->at != NULL) {
free(program->at);
}
program->capacity = 0;
program->len = 0;
}
/** /**
* Essentially a lexer for the assembly language. * Essentially a lexer for the assembly language.
* @param [input] The text to create a program from. NOT the file name * @param [input] The text to create a program from. NOT the file name
@@ -88,7 +47,7 @@ void freeProgram(Program* program) {
Program createProgramFromText(const char* input) { Program createProgramFromText(const char* input) {
Program program = newProgram(); Program program = newProgram();
char buf[16] = {'\0'}; char buf[32] = {'\0'};
size_t bufSize = 0; size_t bufSize = 0;
size_t programLen = strlen(input); size_t programLen = strlen(input);
size_t current = 0; size_t current = 0;
@@ -96,7 +55,7 @@ Program createProgramFromText(const char* input) {
bool processingInstWord = true; bool processingInstWord = true;
uint8_t processingArgNum = 0; uint8_t processingArgNum = 0;
Instruction currentInst = {}; Instruction instruction = {};
for (;;) { for (;;) {
// scan through until we hit a space, colon or new line // scan through until we hit a space, colon or new line
@@ -109,17 +68,75 @@ Program createProgramFromText(const char* input) {
} }
if (processingInstWord) { if (processingInstWord) {
currentInst.opcode = stringToInstructionOpcode(buf); instruction.opcode = stringToInstructionOpcode(buf);
processingInstWord = false;
} else { } else {
if (processingArgNum >= 3) { if (processingArgNum >= 3) {
fprintf(stderr, "expecting new line after instruction args, got %s\n", buf); fprintf(stderr, "expecting new line after instruction args, got %s\n", buf);
exit(1); exit(1);
} }
OperandType type = INSTRUCTION_OPERAND_TYPES[currentInst.opcode][processingArgNum]; OperandType type = INSTRUCTION_OPERAND_TYPES[instruction.opcode][processingArgNum];
if (type == OP_NONE) { switch (type) {
case OP_NONE: {
fprintf(stderr, "expecting new line after instruction args, got %s\n", buf); fprintf(stderr, "expecting new line after instruction args, got %s\n", buf);
exit(1); exit(1);
} }
case OP_REG: {
if (bufSize > 1) {
fprintf(stderr, "expecting register identifier, got %s\n", buf);
exit(1);
}
switch (buf[0]) {
case 'a':
case 'A':
instruction.operands[processingArgNum] = REG_A;
break;
case 'b':
case 'B':
instruction.operands[processingArgNum] = REG_B;
break;
case 'c':
case 'C':
instruction.operands[processingArgNum] = REG_C;
break;
case 'x':
case 'X':
instruction.operands[processingArgNum] = REG_X;
break;
case 'y':
case 'Y':
instruction.operands[processingArgNum] = REG_Y;
break;
case 'z':
case 'Z':
instruction.operands[processingArgNum] = REG_Z;
break;
case 'r':
case 'R':
instruction.operands[processingArgNum] = REG_R;
break;
case 'f':
case 'F':
instruction.operands[processingArgNum] = REG_F;
break;
default: {
fprintf(stderr, "expecting register identifier, got %s\n", buf);
exit(1);
}
}
break;
}
case OP_IMM16: {
char* endptr;
instruction.immediate = strtol(buf, &endptr, 0);
if (endptr == (char*)buf) {
fprintf(stderr, "couldn't convert %s to a number\n", buf);
exit(1);
}
}
}
processingArgNum++;
} }
buf[0] = '\0'; buf[0] = '\0';
@@ -131,6 +148,10 @@ Program createProgramFromText(const char* input) {
// Ignore extra new lines // Ignore extra new lines
break; break;
} }
processingInstWord = true;
processingArgNum = 0;
buf[0] = '\0';
bufSize = 0;
break; break;
} }
case ':': { case ':': {
@@ -149,6 +170,10 @@ Program createProgramFromText(const char* input) {
break; break;
} }
default: { default: {
if (bufSize + 2 >= sizeof(buf)) {
fprintf(stderr, "text exceeds buffer size\n");
exit(1);
}
buf[bufSize] = c; buf[bufSize] = c;
buf[bufSize + 1] = '\0'; buf[bufSize + 1] = '\0';
bufSize++; bufSize++;

View File

@@ -1,16 +1,6 @@
#pragma once #pragma once
#include "../instruction.h" #include "program.h"
typedef struct {
Instruction* at;
size_t len;
size_t capacity;
} Program;
Program newProgram(void);
void addInstructionToProgram(Program* program, Instruction inst);
void freeProgram(Program* program);
Program createProgramFromText(const char* input); Program createProgramFromText(const char* input);

95
src/assembler/program.c Normal file
View File

@@ -0,0 +1,95 @@
#include "program.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
Program newProgram(void) {
Program program = {
.at = malloc(sizeof(Instruction) * 16),
.len = 0,
.capacity = 16,
.labels = {
.at = malloc(sizeof(Instruction) * 16),
.len = 0,
.capacity = 16,
}
};
if (program.at == NULL || program.labels.at == NULL) {
fprintf(stderr, "malloc failed while creating new program\n");
exit(1);
}
return program;
}
void addInstructionToProgram(Program* program, Instruction inst) {
if (program->at == NULL) {
fprintf(stderr, "unexpected NULL value when adding instruction to program\n");
exit(1);
}
if (program->len + 1 >= program->capacity) {
Instruction* tmp = malloc(sizeof(Instruction) * program->capacity * 2);
if (tmp == NULL) {
fprintf(stderr, "malloc failed while expanding program\n");
exit(1);
}
program->at = tmp;
program->capacity *= 2;
}
program->at[program->len] = inst;
program->len++;
}
void addLabelToProgram(Program* program, const char* name, uint8_t position) {
if (program->labels.at == NULL) {
fprintf(stderr, "unexpected NULL value when adding label to program\n");
exit(1);
}
if (program->labels.len + 1 >= program->labels.capacity) {
Label* tmp = malloc(sizeof(Label) * program->labels.capacity * 2);
if (tmp == NULL) {
fprintf(stderr, "malloc failed while expanding program labels\n");
exit(1);
}
program->labels.at = tmp;
program->labels.capacity *= 2;
}
char* nameCopy = malloc(strlen(name) + 1);
if (nameCopy == NULL) {
fprintf(stderr, "malloc failed while expanding program labels\n");
exit(1);
}
strcpy(nameCopy, name);
program->labels.at[program->labels.len] = (Label) {
.name = nameCopy,
.position = position
};
program->labels.len++;
}
void freeProgram(Program* program) {
if (program->at != NULL) {
free(program->at);
}
program->at = NULL;
program->capacity = 0;
program->len = 0;
if (program->labels.at != NULL) {
for (size_t i = 0; i < program->labels.len; i++) {
free(program->labels.at[i].name);
}
free(program->labels.at);
}
program->labels.at = NULL;
program->labels.capacity = 0;
program->labels.len = 0;
}

26
src/assembler/program.h Normal file
View File

@@ -0,0 +1,26 @@
#pragma once
#include "../instruction.h"
typedef struct {
char* name;
uint8_t position;
} Label;
typedef struct {
Instruction* at;
size_t len;
size_t capacity;
struct {
Label* at;
size_t len;
size_t capacity;
} labels;
} Program;
Program newProgram(void);
void addInstructionToProgram(Program* program, Instruction inst);
void addLabelToProgram(Program* program, const char* name, uint8_t position);
void freeProgram(Program* program);