more assembler stuff

This commit is contained in:
2026-07-16 13:29:53 +10:00
parent a2d90f620a
commit 42fab467f1
4 changed files with 180 additions and 2 deletions

View File

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

View File

@@ -1,9 +1,170 @@
#include "assemble.h" #include "assemble.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "../instruction.h" #include "../instruction.h"
void assemble(const char* input, const char* outputFileName) { // Table of strings to instructions
struct _stringToInstructionOpcodeTable {char* str; InstructionOpcode opcode;} stringToInstructionOpcodeTable[] = {
{"mov", INST_MOV},
{"mvi", INST_MVI},
{"add", INST_ADD},
{"sub", INST_SUB},
{"load", INST_LOAD},
{"store", INST_STORE},
{"and", INST_AND},
{"or", INST_OR},
{"xor", INST_XOR},
{"shf", INST_SHF},
{"jmp", INST_JMP},
{"jiz", INST_JIZ},
{"call", INST_CALL},
{"ret", INST_RET},
{"sys", INST_SYS},
{"hlt", INST_HLT},
};
InstructionOpcode stringToInstructionOpcode(const char* string) {
for (size_t i = 0; i < sizeof(stringToInstructionOpcodeTable) / sizeof(struct _stringToInstructionOpcodeTable)); i++) {
if (strcmp(stringToInstructionOpcodeTable[i].str, string) == 0) {
return stringToInstructionOpcodeTable[i].opcode;
}
}
fprintf(stderr, "Invalid instruction string %s\n", string);
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.
* @param [input] The text to create a program from. NOT the file name
* @return A new program, with all instructions from the input
*/
Program createProgramFromText(const char* input) {
Program program = newProgram();
char buf[16] = {'\0'};
size_t bufSize = 0;
size_t programLen = strlen(input);
size_t current = 0;
bool processingInstWord = true;
uint8_t processingArgNum = 0;
Instruction currentInst = {};
for (;;) {
// scan through until we hit a space, colon or new line
char c = input[current];
switch (c) {
case ' ': {
if (bufSize == 0) {
// Ignore extra spaces
break;
}
if (processingInstWord) {
currentInst.opcode = stringToInstructionOpcode(buf);
} else {
if (processingArgNum >= 3) {
fprintf(stderr, "expecting new line after instruction args, got %s\n", buf);
exit(1);
}
OperandType type = INSTRUCTION_OPERAND_TYPES[currentInst.opcode][processingArgNum];
if (type == OP_NONE) {
fprintf(stderr, "expecting new line after instruction args, got %s\n", buf);
exit(1);
}
}
buf[0] = '\0';
bufSize = 0;
break;
}
case '\n': {
if (processingInstWord && bufSize == 0) {
// Ignore extra new lines
break;
}
break;
}
case ':': {
if (!processingInstWord) {
fprintf(stderr, "label must be first word on a new line");
exit(1);
}
break;
}
case '\t': {
// Ignore tabs
break;
}
case '\r': {
// Ignore Windows specific formatting
break;
}
default: {
buf[bufSize] = c;
buf[bufSize + 1] = '\0';
bufSize++;
break;
}
}
current++;
if (current >= programLen) {
break;
}
}
return program;
}
void assemble(const char* input, const char* outputFileName) {
Program program = createProgramFromText(input);
} }

View File

@@ -1,3 +1,17 @@
#pragma once #pragma once
#include "../instruction.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);
void assemble(const char* input, const char* outputFileName); void assemble(const char* input, const char* outputFileName);

View File

@@ -1,3 +1,5 @@
dingus:
mvi a 2 mvi a 2
mvi b 2 mvi b 2