brainfuck  0.1
A full fledged brainfuck compiler
compiler.c
Go to the documentation of this file.
1 
10 #include <stdlib.h>
11 
12 #include "common.h"
13 
17 #define BUF_SIZE 256
18 
28 int compile(FILE *in, FILE *out, int stack_size, int array_size)
29 {
30  int c, ret = 0;
31  unsigned long label_num = 0L;
32  int stack_ptr = 0;
33  unsigned long *stack = malloc(stack_size * sizeof *stack);
34  if (stack == NULL) {
35  fprintf(stderr, "error: couldn't allocate stack (%lu bytes)\n", stack_size * sizeof *stack);
36  ret = -1;
37  goto cleanup;
38  }
39  char buf[BUF_SIZE];
40  snprintf(buf, BUF_SIZE, "\t.lcomm buffer %d\n", array_size);
41  fputs("\t.section .bss\n", out);
42  fputs(buf, out);
43  fputs("\n", out);
44  fputs("\t.section .text\n", out);
45  fputs("\t.globl _start\n", out);
46  fputs("_start:\n", out);
47  fputs("\tmovl $buffer, %edi\n", out);
48  fputs("\n", out);
49  while ((c = fgetc(in)) != EOF) {
50  switch (c) {
51  case '>':
52  fputs("\tinc %edi\n", out);
53  fputs("\n", out);
54  break;
55  case '<':
56  fputs("\tdec %edi\n", out);
57  fputs("\n", out);
58  break;
59  case '+':
60  fputs("\tincb (%edi)\n", out);
61  fputs("\n", out);
62  break;
63  case '-':
64  fputs("\tdecb (%edi)\n", out);
65  fputs("\n", out);
66  break;
67  case '.':
68  fputs("\tmovl $4, %eax\n", out);
69  fputs("\tmovl $1, %ebx\n", out);
70  fputs("\tmovl %edi, %ecx\n", out);
71  fputs("\tmovl $1, %edx\n", out);
72  fputs("\tint $0x80\n", out);
73  fputs("\n", out);
74  break;
75  case ',':
76  fputs("\tmovl $3, %eax\n", out);
77  fputs("\tmovl $0, %ebx\n", out);
78  fputs("\tmovl %edi, %ecx\n", out);
79  fputs("\tmovl $1, %edx\n", out);
80  fputs("\tint $0x80\n", out);
81  fputs("\n", out);
82  break;
83  case '[':
84  if (stack_ptr == stack_size) {
85  stack_size *= 2;
86  unsigned long *temp = realloc(stack, stack_size * sizeof *stack);
87  if (temp == NULL) {
88  fprintf(stderr, "error: couldn't reallocate stack (%lu bytes)\n", stack_size * sizeof *stack);
89  ret = -1;
90  goto cleanup;
91  }
92  stack = temp;
93  }
94  stack[stack_ptr++] = ++label_num;
95  fputs("\tcmpb $0, (%edi)\n", out);
96  snprintf(buf, BUF_SIZE, "\tjz .LE%lu\n", label_num);
97  fputs(buf, out);
98  snprintf(buf, BUF_SIZE, ".LB%lu:\n", label_num);
99  fputs(buf, out);
100  break;
101  case ']':
102  fputs("\tcmpb $0, (%edi)\n", out);
103  snprintf(buf, BUF_SIZE, "\tjnz .LB%lu\n", stack[--stack_ptr]);
104  fputs(buf, out);
105  snprintf(buf, BUF_SIZE, ".LE%lu:\n", stack[stack_ptr]);
106  fputs(buf, out);
107  break;
108  default:
109  break;
110  }
111  }
112  fputs("\n", out);
113  fputs("\tmovl $1, %eax\n", out);
114  fputs("\tmovl $0, %ebx\n", out);
115  fputs("\tint $0x80\n", out);
116  fputs("\n", out);
117 cleanup:
118  if (stack)
119  free(stack);
120  return ret;
121 }
#define BUF_SIZE
The size of the stack buffer.
Definition: compiler.c:17
int compile(FILE *in, FILE *out, int stack_size, int array_size)
compiler function
Definition: compiler.c:28
Header for extern functions.