aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfc.c71
-rw-r--r--examples/add_2_5.bf20
-rw-r--r--examples/getchar_putchar.bf1
3 files changed, 74 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
diff --git a/examples/add_2_5.bf b/examples/add_2_5.bf
new file mode 100644
index 0000000..a6425d7
--- /dev/null
+++ b/examples/add_2_5.bf
@@ -0,0 +1,20 @@
+++ ; Cell c0 = 2
+> +++++ ; Cell c1 = 5
+
+[ ; Start your loops with your cell pointer on the loop counter (c1 in our case)
+< + ; Add 1 to c0
+> - ; Subtract 1 from c1
+] ; End your loops with the cell pointer on the loop counter
+
+; At this point our program has added 5 to 2 leaving 7 in c0 and 0 in c1
+; but we cannot output this value to the terminal since it is not ASCII encoded.
+
+; To display the ASCII character "7" we must add 48 to the value 7.
+; We use a loop to compute 48 = 6 * 8.
+
+++++ ++++ ; c1 = 8 and this will be our loop counter again
+[
+< +++ +++ ; Add 6 to c0
+> - ; Subtract 1 from c1
+]
+< . ; Print out c0 which has the value 55 which translates to "7"!
diff --git a/examples/getchar_putchar.bf b/examples/getchar_putchar.bf
new file mode 100644
index 0000000..f36f02a
--- /dev/null
+++ b/examples/getchar_putchar.bf
@@ -0,0 +1 @@
+,.