mirror of
https://github.com/SimonFJ20/bfjit
synced 2026-01-16 05:27:30 +01:00
140 lines
4.0 KiB
C
140 lines
4.0 KiB
C
#include "emitter.h"
|
|
#include "expr.h"
|
|
#include "optimizer.h"
|
|
#include "parser.h"
|
|
#include "print.h"
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/mman.h>
|
|
|
|
#define ADD_OPTIMIZATION_WO_FREE_AST(NAME) \
|
|
previous_ast = ast; \
|
|
ast = optimize_##NAME(&ast); \
|
|
printf("%s" #NAME ":%s\n", color_bold, color_reset); \
|
|
if (!expr_vec_equal(&ast, &previous_ast)) { \
|
|
ast_string[0] = '\0'; \
|
|
expr_vec_stringify(&ast, ast_string, 0); \
|
|
puts(ast_string); \
|
|
}
|
|
|
|
#define ADD_OPTIMIZATION(NAME) \
|
|
expr_vec_free(&previous_ast); \
|
|
ADD_OPTIMIZATION_WO_FREE_AST(NAME)
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
// const char* text = "++++++++++[>+<-]";
|
|
// printf("\ntext:%s\n\"%s\"%s\n", color_bright_green, text, color_reset);
|
|
// Parser parser = parser_create(lexer_from_string(text, strlen(text)));
|
|
|
|
Parser parser = parser_create(lexer_from_args_or_stdin(argc, argv));
|
|
|
|
char* ast_string = malloc(sizeof(char) * 33768);
|
|
ast_string[0] = '\0';
|
|
|
|
ExprVec ast = parser_parse(&parser);
|
|
{
|
|
expr_vec_stringify(&ast, ast_string, 0);
|
|
printf("\nparsed:\n%s\n", ast_string);
|
|
}
|
|
|
|
ExprVec previous_ast;
|
|
bool first = true;
|
|
int pass_counter = 1;
|
|
while (first || !expr_vec_equal(&ast, &previous_ast)) {
|
|
printf(
|
|
"\n%soptimization pass %d:%s\n",
|
|
color_bold,
|
|
pass_counter,
|
|
color_reset
|
|
);
|
|
pass_counter += 1;
|
|
|
|
if (!first) {
|
|
expr_vec_free(&previous_ast);
|
|
}
|
|
ADD_OPTIMIZATION_WO_FREE_AST(fold_adjecent);
|
|
ADD_OPTIMIZATION(eliminate_negation);
|
|
ADD_OPTIMIZATION(eliminate_overflow);
|
|
ADD_OPTIMIZATION(replace_zeroing_loops);
|
|
ADD_OPTIMIZATION(replace_copying_loops);
|
|
|
|
if (first) {
|
|
first = false;
|
|
}
|
|
}
|
|
|
|
ast_string[0] = '\0';
|
|
expr_vec_stringify(&ast, ast_string, 0);
|
|
printf("\n%sfinal:%s\n%s\n", color_bold, color_reset, ast_string);
|
|
|
|
size_t code_size = 33678;
|
|
void* code = mmap(
|
|
NULL,
|
|
code_size,
|
|
PROT_READ | PROT_WRITE | PROT_EXEC,
|
|
MAP_PRIVATE | MAP_ANONYMOUS,
|
|
-1,
|
|
0
|
|
);
|
|
if (code == NULL) {
|
|
fprintf(stderr, "panic: could not mmap\n");
|
|
exit(1);
|
|
}
|
|
|
|
Emitter emitter = emitter_create(code);
|
|
emitter_emit_program(&emitter, &ast);
|
|
|
|
uint8_t* memory = malloc(30000);
|
|
memset(memory, 0, 30000);
|
|
|
|
printf("\n%scode:%s\n", color_bold, color_reset);
|
|
|
|
for (size_t y = 0; y < 40; ++y) {
|
|
for (size_t x = 0; x < 16; ++x) {
|
|
uint8_t v = ((uint8_t*)code)[y * 8 + x];
|
|
if (v == 0) {
|
|
fputs(color_gray, stdout);
|
|
}
|
|
if (x == 8) {
|
|
fputc(' ', stdout);
|
|
}
|
|
printf("%02x ", v);
|
|
fputs(color_reset, stdout);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
printf("\n%sresult:%s\n", color_bold, color_reset);
|
|
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wpedantic"
|
|
void (*runnable)(uint8_t* memory) = (void (*)(uint8_t* memory))code;
|
|
#pragma GCC diagnostic pop
|
|
|
|
runnable(memory);
|
|
|
|
printf("\n%smemory:%s\n", color_bold, color_reset);
|
|
|
|
for (size_t y = 0; y < 4; ++y) {
|
|
for (size_t x = 0; x < 8; ++x) {
|
|
uint8_t v = memory[y * 8 + x];
|
|
if (v == 0) {
|
|
fputs(color_gray, stdout);
|
|
}
|
|
printf("%02x ", v);
|
|
fputs(color_reset, stdout);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
free(memory);
|
|
munmap(code, code_size);
|
|
expr_vec_free(&previous_ast);
|
|
expr_vec_free(&ast);
|
|
free(ast_string);
|
|
}
|