aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/nasm.c48
-rw-r--r--src/codegen/nasm.h7
2 files changed, 55 insertions, 0 deletions
diff --git a/src/codegen/nasm.c b/src/codegen/nasm.c
new file mode 100644
index 0000000..0782ee1
--- /dev/null
+++ b/src/codegen/nasm.c
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <stddef.h>
+
+#include "codegen/nasm.h"
+
+static void emit_consts(struct Program* program, FILE* out)
+{
+ for (size_t i = 0; i < program->const_count; i += 1)
+ {
+ struct ConstDecl decl = program->consts[i];
+ fprintf(out, "%.*s equ %.*s\n",
+ (int)decl.name.length, decl.name.start,
+ (int)decl.value.length, decl.value.start);
+ }
+}
+
+static void emit_data(struct Program* program, FILE* out)
+{
+ fprintf(out, "section .data\n");
+
+ for (size_t i = 0; i < program->data_count; i += 1)
+ {
+ struct DataDecl decl = program->data_decls[i];
+
+ // the value lexeme keeps its surrounding double quotes; NASM backtick
+ // strings interpret the same escapes, so re-wrap the inner content
+ fprintf(out, "%.*s: db `%.*s`\n",
+ (int)decl.name.length, decl.name.start,
+ (int)(decl.value.length - 2), decl.value.start + 1);
+ fprintf(out, ".len equ $ - %.*s\n",
+ (int)decl.name.length, decl.name.start);
+ }
+}
+
+void generate_nasm(struct Program* program, FILE* out)
+{
+ if (program->const_count > 0)
+ {
+ emit_consts(program, out);
+ fprintf(out, "\n");
+ }
+
+ emit_data(program, out);
+ fprintf(out, "\n");
+
+ fprintf(out, "section .text\n");
+ fprintf(out, "global _start\n");
+}
diff --git a/src/codegen/nasm.h b/src/codegen/nasm.h
new file mode 100644
index 0000000..b9c2c90
--- /dev/null
+++ b/src/codegen/nasm.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include <stdio.h>
+
+#include "parser/ast.h"
+
+void generate_nasm(struct Program* program, FILE* out);