Match Brainfuck compiler output in C89 port
This commit is contained in:
+81
-17
@@ -1170,51 +1170,115 @@ static int pm_command_list(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pm_bf_append_text(char **buffer, size_t *used, size_t *capacity,
|
||||
const char *part)
|
||||
{
|
||||
size_t length;
|
||||
size_t needed;
|
||||
size_t next_capacity;
|
||||
char *next;
|
||||
length = strlen(part);
|
||||
needed = *used + length + 1U;
|
||||
if (needed > *capacity) {
|
||||
next_capacity = *capacity;
|
||||
while (next_capacity < needed) {
|
||||
if (next_capacity > ((size_t)-1) / 2U) return 0;
|
||||
next_capacity *= 2U;
|
||||
}
|
||||
next = (char *)realloc(*buffer, next_capacity);
|
||||
if (next == NULL) return 0;
|
||||
*buffer = next;
|
||||
*capacity = next_capacity;
|
||||
}
|
||||
memcpy(*buffer + *used, part, length + 1U);
|
||||
*used += length;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pm_bf_ensure_compile_cell(int **cells, long index, long *capacity)
|
||||
{
|
||||
long next_capacity;
|
||||
int *next;
|
||||
long i;
|
||||
if (index < *capacity) return 1;
|
||||
next_capacity = *capacity;
|
||||
while (next_capacity <= index) {
|
||||
if (next_capacity > 1073741823L) return 0;
|
||||
next_capacity *= 2L;
|
||||
}
|
||||
next = (int *)realloc(*cells, (size_t)next_capacity * sizeof(int));
|
||||
if (next == NULL) return 0;
|
||||
for (i = *capacity; i < next_capacity; i++) next[i] = 0;
|
||||
*cells = next;
|
||||
*capacity = next_capacity;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pm_bf_compile(const char *source)
|
||||
{
|
||||
int cells[PM_BF_CELLS];
|
||||
int pointer;
|
||||
int *cells;
|
||||
long capacity;
|
||||
long pointer;
|
||||
const char *p;
|
||||
int value;
|
||||
char compiled[PM_TEXT_MAX];
|
||||
char *compiled;
|
||||
char part[64];
|
||||
char *dir;
|
||||
char *out;
|
||||
size_t used;
|
||||
int i;
|
||||
for (i = 0; i < PM_BF_CELLS; i++) cells[i] = 0;
|
||||
pointer = 0;
|
||||
size_t compiled_capacity;
|
||||
int ok;
|
||||
cells = (int *)calloc(1U, sizeof(int));
|
||||
compiled_capacity = 128U;
|
||||
compiled = (char *)malloc(compiled_capacity);
|
||||
if (cells == NULL || compiled == NULL) {
|
||||
free(cells);
|
||||
free(compiled);
|
||||
return 0;
|
||||
}
|
||||
capacity = 1L;
|
||||
pointer = 0L;
|
||||
value = 0;
|
||||
compiled[0] = '\0';
|
||||
used = 0U;
|
||||
compiled[0] = '\0';
|
||||
p = source;
|
||||
while (*p != '\0') {
|
||||
if (*p == '+') cells[pointer]++;
|
||||
else if (*p == '-') cells[pointer]--;
|
||||
else if (*p == '>' && pointer < PM_BF_CELLS - 1) pointer++;
|
||||
else if (*p == '<' && pointer > 0) pointer--;
|
||||
else if (*p == '.') {
|
||||
else if (*p == '>') {
|
||||
pointer++;
|
||||
if (!pm_bf_ensure_compile_cell(&cells, pointer, &capacity)) {
|
||||
free(cells);
|
||||
free(compiled);
|
||||
return 0;
|
||||
}
|
||||
} else if (*p == '<') {
|
||||
if (pointer != 0L) pointer--;
|
||||
} else if (*p == '.') {
|
||||
int diff;
|
||||
diff = cells[pointer] - value;
|
||||
value = cells[pointer];
|
||||
if (diff < 0) sprintf(part, "%d-", -diff);
|
||||
else sprintf(part, "%d+", diff);
|
||||
if (used + strlen(part) < sizeof(compiled)) {
|
||||
strcat(compiled, part);
|
||||
used += strlen(part);
|
||||
if (!pm_bf_append_text(&compiled, &used, &compiled_capacity, part)) {
|
||||
free(cells);
|
||||
free(compiled);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
dir = pm_join_path(".", "dist");
|
||||
if (dir == NULL) return 0;
|
||||
if (dir == NULL) { free(cells); free(compiled); return 0; }
|
||||
pm_make_dir(dir);
|
||||
out = pm_join_path(dir, "test.long");
|
||||
free(dir);
|
||||
if (out == NULL) return 0;
|
||||
i = pm_write_file(out, compiled);
|
||||
if (out == NULL) { free(cells); free(compiled); return 0; }
|
||||
ok = pm_write_file(out, compiled);
|
||||
free(out);
|
||||
return i;
|
||||
free(cells);
|
||||
free(compiled);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int pm_bf_execute(const char *source)
|
||||
|
||||
Reference in New Issue
Block a user