summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Phillips <david@sighup.nz>2019-08-03 13:58:10 +1200
committerDavid Phillips <david@sighup.nz>2019-08-03 14:01:46 +1200
commit085145a1f49ffcae235fa559df254919366fe497 (patch)
treee9cb9f4e0c92b7de0b28ee36ec439863155eb52b
parent5940828912aaee614f40c258e88dc58941971317 (diff)
downloadtoy-cpu-assembler-085145a1f49ffcae235fa559df254919366fe497.tar.xz
Add asmcat, bincat
These tools are currently fairly useless for real-world programming. Each of them takes in either asm or binary, translates this to the internal intermediate representation of a list of instruction structs, and then translates and outputs in the same format that they took it in. These are mostly oly useful for testing purposes, but may one day be useful if e.g. an optimiser stage is put in between the input and output stages.
-rw-r--r--.gitignore2
-rw-r--r--Makefile14
-rw-r--r--asmcat.c77
-rw-r--r--bincat.c70
4 files changed, 159 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore
index 7c146f7..1e1fca8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@
*.bin
assembler
disassembler
+asmcat
+bincat
diff --git a/Makefile b/Makefile
index 54f76f7..d361fc5 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,11 @@
CFLAGS = -Wall -Wextra -Wpedantic
-EXECUTABLES = assembler disassembler
+EXECUTABLES = assembler disassembler asmcat bincat
-ASM_OBJECTS = lex.o parse.o output.o assembler.o util.o
-DISASM_OBJECTS = disassembler.o util.o input_bin.o output_asm.o
+ASM_OBJECTS = assembler.o lex.o parse.o output.o util.o
+DISASM_OBJECTS = disassembler.o input_bin.o output_asm.o util.o
+ASMCAT_OBJECTS = asmcat.o lex.o parse.o output_asm.o util.o
+BINCAT_OBJECTS = bincat.o input_bin.o output.o util.o
all: $(EXECUTABLES)
@@ -11,6 +13,10 @@ assembler: $(ASM_OBJECTS)
disassembler: $(DISASM_OBJECTS)
+asmcat: $(ASMCAT_OBJECTS)
+
+bincat: $(BINCAT_OBJECTS)
+
lex.o: lex.h
parse.o: lex.h parse.h instruction.h util.h
@@ -21,7 +27,7 @@ util.o: lex.h instruction.h
.PHONY: clean test
clean:
- - rm -f $(EXECUTABLES) $(ASM_OBJECTS) $(DISASM_OBJECTS)
+ - rm -f $(EXECUTABLES) $(ASM_OBJECTS) $(DISASM_OBJECTS) $(ASMCAT_OBJECTS) $(BINCAT_OBJECTS)
test: all
make -C test test
diff --git a/asmcat.c b/asmcat.c
new file mode 100644
index 0000000..2791443
--- /dev/null
+++ b/asmcat.c
@@ -0,0 +1,77 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "lex.h"
+#include "parse.h"
+#include "instruction.h"
+#include "output_asm.h"
+
+void print_help(const char *argv0)
+{
+ fprintf(stderr, "Syntax: %s <in.asm> <out.asm>\n", argv0);
+}
+
+int main(int argc, char **argv)
+{
+ int error_ret = 1;
+ int ret = 0;
+ const char *path_in = NULL;
+ const char *path_out = NULL;
+ FILE *fin = NULL;
+ FILE *fout = NULL;
+
+ if (argc < 3) {
+ print_help(argv[0]);
+ return 1;
+ }
+
+ if (strcmp(argv[1], "-q") == 0) {
+ if (argc != 4) {
+ print_help(argv[0]);
+ return 0;
+ }
+ error_ret = 0;
+ path_in = argv[2];
+ path_out = argv[3];
+ } else {
+ path_in = argv[1];
+ path_out = argv[2];
+ }
+
+
+ if ((fin = fopen(path_in, "r")) == NULL) {
+ fprintf(stderr, "Error opening %s: ", path_in);
+ perror("fopen");
+ return error_ret;
+ }
+
+ if ((fout = fopen(path_out, "wb")) == NULL) {
+ fprintf(stderr, "Error opening %s: ", path_out);
+ perror("fopen");
+ return error_ret;
+ }
+/****/
+ struct token *tokens = NULL;
+ size_t tok_count = 0;
+
+ if ((tokens = lex(path_in, fin, &tok_count)) == NULL)
+ return error_ret;
+
+ /* FIXME package these things into `tok_result`, `parse_result` etc */
+ struct instruction *insts;
+ size_t insts_count;
+ struct label *labels;
+ size_t labels_count;
+ if ((ret = parse(path_in, fin, &labels, &labels_count, tokens, tok_count, &insts, &insts_count)))
+ return error_ret && ret;
+
+ /* FIXME insert pass for sanity checking identifiers, sizes of values */
+
+ /* FIXME insert optional pass for optimisation */
+
+ if ((ret = output_asm(fout, labels, labels_count, insts, insts_count)))
+ return error_ret && ret;
+
+ return 0;
+}
diff --git a/bincat.c b/bincat.c
new file mode 100644
index 0000000..fcda22e
--- /dev/null
+++ b/bincat.c
@@ -0,0 +1,70 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "instruction.h"
+#include "parse.h"
+#include "input_bin.h"
+#include "output.h"
+
+void print_help(const char *argv0)
+{
+ fprintf(stderr, "Syntax: %s <in.bin> <out.bin>\n", argv0);
+}
+
+int main(int argc, char **argv)
+{
+ int error_ret = 1;
+ int ret = 0;
+ const char *path_in = NULL;
+ const char *path_out = NULL;
+ FILE *fin = NULL;
+ FILE *fout = NULL;
+
+ if (argc < 3) {
+ print_help(argv[0]);
+ return 1;
+ }
+
+ if (strcmp(argv[1], "-q") == 0) {
+ if (argc != 4) {
+ print_help(argv[0]);
+ return 0;
+ }
+ error_ret = 0;
+ path_in = argv[2];
+ path_out = argv[3];
+ } else {
+ path_in = argv[1];
+ path_out = argv[2];
+ }
+
+
+ if ((fin = fopen(path_in, "r")) == NULL) {
+ fprintf(stderr, "Error opening %s: ", path_in);
+ perror("fopen");
+ return error_ret;
+ }
+
+ if ((fout = fopen(path_out, "w")) == NULL) {
+ fprintf(stderr, "Error opening %s: ", path_out);
+ perror("fopen");
+ return error_ret;
+ }
+
+ /* FIXME package these things into `tok_result`, parse_result` etc */
+ struct instruction *insts;
+ size_t insts_count;
+ struct label *labels;
+ size_t labels_count;
+ labels = NULL;
+ labels_count = 0;
+
+ if ((ret = disasm(fin, &insts, &insts_count)))
+ return error_ret && ret;
+
+ if ((ret = output(fout, labels, labels_count, insts, insts_count)))
+ return error_ret && ret;
+
+ return 0;
+}