aboutsummaryrefslogtreecommitdiff
path: root/bfc.c
diff options
context:
space:
mode:
authorCharles Cabergs <me@cacharle.xyz>2021-11-16 18:42:30 +0100
committerCharles Cabergs <me@cacharle.xyz>2021-11-16 18:42:30 +0100
commit2f6a51855571ee12bad247ac026aa02a061800f0 (patch)
tree82fb10f7f697ec2c1cd24aa39c517a67c401857b /bfc.c
parent2d3d9d3a5fd436735b912d1fe0ad731a81eca036 (diff)
downloadbfc-2f6a51855571ee12bad247ac026aa02a061800f0.tar.gz
bfc-2f6a51855571ee12bad247ac026aa02a061800f0.tar.bz2
bfc-2f6a51855571ee12bad247ac026aa02a061800f0.zip
Updated to generate correct assembly (segfaults)
Diffstat (limited to 'bfc.c')
-rw-r--r--bfc.c71
1 files changed, 53 insertions, 18 deletions
diff --git a/bfc.c b/bfc.c
index cb1b0f9..2d4c8f9 100644
--- a/bfc.c
+++ b/bfc.c
@@ -2,52 +2,87 @@
#include <stdlib.h>
#include <stdio.h>
-const size_t buffer_size = 256;
-const char* asm_filename = "out.asm";
+static const size_t buffer_size = 256;
+static const char* asm_filename = "out.asm";
+
+static const char *write_syscall = "0x2000004";
+static const char *read_syscall = "0x2000003";
+
+#define LABEL_COUNT_STACK_SIZE 256
+static size_t label_stack[LABEL_COUNT_STACK_SIZE + 1] = {0};
+static size_t label_stack_frame = 0;
int main(int argc, char *argv[])
{
- FILE* file = fopen(asm_filename, "w");
+ FILE *input_file = NULL;
+ if (argc == 2)
+ input_file = fopen(argv[1], "r");
+ else
+ input_file = stdin;
+
+ /* FILE* output_file = fopen(asm_filename, "w"); */
+ FILE *output_file = stdout;
fprintf(
- file,
+ output_file,
+ "global _start\n"
"section .bss\n"
- "buffer: resb %zu\n"
- "section .text\n",
- "mov rax buffer\n",
+ "\tbuffer: resb %zu\n\n"
+ "section .text\n"
+ "_start:\n"
+ "\tmov rbx, buffer\n",
buffer_size
);
+ size_t label_frame_id;
char c;
- while ((c = fgetc(file)) != EOF)
+ while ((c = fgetc(input_file)) != EOF)
{
switch (c)
{
case '>':
- fputs("inc rax");
+ fprintf(output_file, " inc rbx ; >\n");
break;
case '<':
- fputs("dec rax");
+ fprintf(output_file, " dec rbx ; <\n");
break;
case '+':
- fputs("inc [rax]");
+ fprintf(output_file, " inc byte [rbx] ; +\n");
break;
case '-':
- fputs("dec [rax]");
+ fprintf(output_file, " dec byte [rbx] ; -\n");
break;
case '.':
- // putchar
+ fprintf(output_file, " mov rdi, 1 ; .\n");
+ fprintf(output_file, " mov rsi, rbx ; .\n");
+ fprintf(output_file, " mov rdx, 1 ; .\n");
+ fprintf(output_file, " mov rax, %-10s ; .\n", write_syscall);
+ fprintf(output_file, " syscall ; .\n");
break;
case ',':
- // getchar
+ fprintf(output_file, " mov rdi, 0 ; ,\n");
+ fprintf(output_file, " mov rsi, rbx ; ,\n");
+ fprintf(output_file, " mov rdx, 1 ; ,\n");
+ fprintf(output_file, " mov rax, %-10s ; ,\n", read_syscall);
+ fprintf(output_file, " syscall ; ,\n");
break;
case '[':
- // jump to next ] if byte at data ptr is 0
+ label_frame_id = label_stack[label_stack_frame];
+ fprintf(output_file, "label_open_%03d_%03d: ; [\n", label_stack_frame, label_frame_id);
+ fprintf(output_file, " cmp byte [rbx], 0 ; [\n");
+ fprintf(output_file, " je label_close_%03d_%03d ; [\n", label_stack_frame, label_frame_id);
+ label_stack_frame++;
break;
- case '[':
- // jump to prev [ if byte at data ptr is not 0
+ case ']':
+ label_stack_frame--;
+ label_frame_id = label_stack[label_stack_frame];
+ fprintf(output_file, "label_close_%03d_%03d: ; ]\n", label_stack_frame, label_frame_id);
+ fprintf(output_file, " cmp byte [rbx], 0 ; ]\n");
+ fprintf(output_file, " jne label_open_%03d_%03d ; ]\n", label_stack_frame, label_frame_id);
+ label_stack[label_stack_frame]++;
break;
case ';':
- // comment
+ while (c != EOF && c != '\n')
+ c = fgetc(input_file);
break;
default:
// error