summaryrefslogtreecommitdiff
path: root/asmcat.c
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 /asmcat.c
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.
Diffstat (limited to 'asmcat.c')
-rw-r--r--asmcat.c77
1 files changed, 77 insertions, 0 deletions
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;
+}