i made things faster
This commit is contained in:
parent
ccf63424af
commit
cb76bcf7d2
8 changed files with 242 additions and 211 deletions
|
@ -1,71 +1,22 @@
|
|||
#include "interpreter.h"
|
||||
#include "program.h"
|
||||
#include "types.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void loop_end(Program* program) {
|
||||
uint32_t count = 1;
|
||||
void interpret(Program* program) {
|
||||
Stack tape_stack;
|
||||
stack_init(&tape_stack, sizeof(void*));
|
||||
|
||||
Tape* tape = malloc(sizeof(Tape));
|
||||
tape_init(tape, sizeof(void*));
|
||||
|
||||
stack_push(&tape_stack, tape);
|
||||
|
||||
Symbol s;
|
||||
|
||||
while (true) {
|
||||
program_next(program, &s);
|
||||
if (s == StartLoop) {
|
||||
count++;
|
||||
} else if (s == EndLoop) {
|
||||
count--;
|
||||
} else if (s == Eof) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (count == 0) return;
|
||||
}
|
||||
}
|
||||
|
||||
static void loop_start(Program* program) {
|
||||
uint32_t count = 1;
|
||||
Symbol s;
|
||||
|
||||
program_last(program, &s);
|
||||
while (true) {
|
||||
program_last(program, &s);
|
||||
if (s == StartLoop) {
|
||||
count--;
|
||||
} else if (s == EndLoop) {
|
||||
count++;
|
||||
} else if (s == Eof) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
return;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static void recurse_program(Program* program, Tape* tape) {
|
||||
Symbol s;
|
||||
|
||||
next:
|
||||
program_next(program, &s);
|
||||
|
||||
// printf("[");
|
||||
// for(uint32_t i = 0; i < tape->len; i++) {
|
||||
// printf("0x%02x ", tape->data[i]);
|
||||
// }
|
||||
// printf("\b]\n ");
|
||||
// for(uint32_t i = 0; i < tape->len; i++) {
|
||||
// if (i == tape->index) {
|
||||
// printf(" ^ ");
|
||||
// } else {
|
||||
// printf(" ");
|
||||
// }
|
||||
// }
|
||||
// printf(" \ + tape->indexn");
|
||||
|
||||
program_get(program, &s);
|
||||
|
||||
switch (s) {
|
||||
case MoveLeft:
|
||||
tape_left(tape);
|
||||
|
@ -74,77 +25,72 @@ next:
|
|||
tape_right(tape);
|
||||
break;
|
||||
case Increment:
|
||||
tape_set(tape, tape_get(tape) + 1);
|
||||
tape_increment(tape);
|
||||
break;
|
||||
case Decrement:
|
||||
tape_set(tape, tape_get(tape) - 1);
|
||||
tape_decrement(tape);
|
||||
break;
|
||||
case StartLoop:
|
||||
if (tape_get(tape) == 0)
|
||||
loop_end(program);
|
||||
if (tape_get(tape) == 0) {
|
||||
program_seek(program, program_get_jump(program));
|
||||
}
|
||||
break;
|
||||
case EndLoop:
|
||||
if (tape_get(tape) != 0)
|
||||
loop_start(program);
|
||||
if (tape_get(tape) != 0) {
|
||||
program_seek(program, program_get_jump(program));
|
||||
}
|
||||
break;
|
||||
case PutChar: {
|
||||
printf("%c", tape_get(tape));
|
||||
break;
|
||||
}
|
||||
case GetChar: {
|
||||
uint8_t c = (uint8_t) getchar();
|
||||
tape_set(tape, c);
|
||||
tape_set(tape, getchar());
|
||||
break;
|
||||
}
|
||||
case Allocate: {
|
||||
uint8_t len = tape_get(tape);
|
||||
Tape* new = malloc(sizeof(Tape));
|
||||
tape_init(len, new);
|
||||
void* ptr = (void*) tape_ptr(tape);
|
||||
memcpy(ptr, &new, sizeof(Tape*));
|
||||
tape_init(new, tape_get(tape));
|
||||
memcpy(tape_ptr(tape), &new, sizeof(Tape*));
|
||||
break;
|
||||
}
|
||||
case Free: {
|
||||
Tape* old;
|
||||
void* ptr = (void*) tape_ptr(tape);
|
||||
memcpy(&old, ptr, sizeof(Tape*));
|
||||
memset(ptr, 0, sizeof(Tape*));
|
||||
memcpy(&old, tape_ptr(tape), sizeof(Tape*));
|
||||
tape_free(old);
|
||||
free(old);
|
||||
break;
|
||||
}
|
||||
case EnterTape: {
|
||||
Tape* cur;
|
||||
void* ptr = (void*) tape_ptr(tape);
|
||||
memcpy(&cur, ptr, sizeof(Tape*));
|
||||
recurse_program(program, cur);
|
||||
memcpy(&tape, tape_ptr(tape), sizeof(Tape*));
|
||||
stack_push(&tape_stack, tape);
|
||||
break;
|
||||
}
|
||||
case LeaveTape: {
|
||||
tape = stack_pop(&tape_stack);
|
||||
if (tape == NULL) goto end;
|
||||
break;
|
||||
}
|
||||
case GetString: {
|
||||
uint8_t len = tape_get(tape);
|
||||
void* ptr = (void*) tape_ptr(tape);
|
||||
fgets(ptr, len, stdin);
|
||||
fgets((char*) tape_ptr(tape), tape_get(tape), stdin);
|
||||
break;
|
||||
}
|
||||
case PutString: {
|
||||
char* ptr = (char*) tape_ptr(tape);
|
||||
printf("%s", ptr);
|
||||
printf("%s", (char*) tape_ptr(tape));
|
||||
break;
|
||||
}
|
||||
case Clear:
|
||||
printf("\033c");
|
||||
break;
|
||||
case LeaveTape:
|
||||
case Eof:
|
||||
return;
|
||||
goto end;
|
||||
}
|
||||
|
||||
program_next(program);
|
||||
goto next;
|
||||
}
|
||||
end:
|
||||
tape_free(tape);
|
||||
free(tape);
|
||||
|
||||
void run_program(Program* program) {
|
||||
Tape tape;
|
||||
tape_init(sizeof(void*), &tape);
|
||||
recurse_program(program, &tape);
|
||||
tape_free(&tape);
|
||||
stack_free(&tape_stack);
|
||||
}
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "program.h"
|
||||
|
||||
void run_program(Program* program);
|
|
@ -1,10 +1,7 @@
|
|||
#include "program.h"
|
||||
#include "interpreter.h"
|
||||
#include "types.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -42,8 +39,8 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
|
||||
Program program;
|
||||
program_init(file, &program);
|
||||
run_program(&program);
|
||||
program_init(&program, file);
|
||||
interpret(&program);
|
||||
program_free(&program);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
#include "program.h"
|
||||
#include "types.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
static char next_char(FILE* file) {
|
||||
char c;
|
||||
|
@ -65,89 +64,69 @@ retest:
|
|||
}
|
||||
}
|
||||
|
||||
void program_init(FILE* file, Program* program) {
|
||||
void program_init(Program* program, FILE* file) {
|
||||
uint32_t capacity = 8;
|
||||
|
||||
program->data = malloc(capacity * sizeof(Symbol));
|
||||
program->data = malloc(capacity * sizeof(struct instruction));
|
||||
program->len = 0;
|
||||
program->index = 0;
|
||||
|
||||
Stack stack;
|
||||
stack_init(&stack, 8);
|
||||
|
||||
Symbol s;
|
||||
while(true) {
|
||||
s = next_symbol(file);
|
||||
|
||||
if (program->len == capacity) {
|
||||
capacity *= 2;
|
||||
program->data = realloc(program->data, capacity * sizeof(Symbol));
|
||||
program->data = realloc(program->data, capacity * sizeof(struct instruction));
|
||||
}
|
||||
|
||||
program->data[program->len].s = s;
|
||||
program->data[program->len].j = 0;
|
||||
|
||||
if (s == StartLoop) {
|
||||
stack_pushi(&stack, program->len);
|
||||
} else if (s == EndLoop) {
|
||||
uint32_t i = stack_popi(&stack);
|
||||
program->data[program->len].j = i;
|
||||
if (i != 0 || program->data[i].j == 0) {
|
||||
program->data[i].j = program->len;
|
||||
}
|
||||
}
|
||||
|
||||
program->data[program->len] = s;
|
||||
program->len++;
|
||||
|
||||
if (s == Eof) break;
|
||||
}
|
||||
|
||||
stack_free(&stack);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
void program_peek(Program* program, Symbol* symbol) {
|
||||
*symbol = program->data[program->index];
|
||||
}
|
||||
|
||||
void program_next(Program* program, Symbol* symbol) {
|
||||
void program_get(Program* program, Symbol* symbol) {
|
||||
if (program->index >= program->len) {
|
||||
*symbol = Eof;
|
||||
return;
|
||||
}
|
||||
program_peek(program, symbol);
|
||||
*symbol = program->data[program->index].s;
|
||||
}
|
||||
|
||||
uint32_t program_get_jump(Program* program) {
|
||||
if (program->index >= program->len) {
|
||||
return 0;
|
||||
}
|
||||
return program->data[program->index].j;
|
||||
}
|
||||
|
||||
void program_next(Program* program) {
|
||||
program->index++;
|
||||
}
|
||||
|
||||
void program_last(Program* program, Symbol* symbol) {
|
||||
if (program->index < 1) {
|
||||
*symbol = Eof;
|
||||
return;
|
||||
}
|
||||
program->index--;
|
||||
program_peek(program, symbol);
|
||||
void program_seek(Program* program, uint32_t index) {
|
||||
program->index = index;
|
||||
}
|
||||
|
||||
void program_free(Program* program) {
|
||||
free(program->data);
|
||||
}
|
||||
|
||||
void tape_init(uint32_t len, Tape* tape) {
|
||||
tape->len = len;
|
||||
tape->data = malloc(len);
|
||||
tape->index = 0;
|
||||
memset(tape->data, 0, len);
|
||||
}
|
||||
|
||||
void tape_left(Tape* tape) {
|
||||
if (tape->index == 0) {
|
||||
tape->index = tape->len - 1;
|
||||
} else {
|
||||
tape->index--;
|
||||
}
|
||||
}
|
||||
|
||||
void tape_right(Tape* tape) {
|
||||
tape->index++;
|
||||
tape->index %= tape->len;
|
||||
}
|
||||
|
||||
uint8_t tape_get(Tape* tape) {
|
||||
return tape->data[tape->index];
|
||||
}
|
||||
|
||||
void tape_set(Tape* tape, uint8_t value) {
|
||||
tape->data[tape->index] = value;
|
||||
}
|
||||
|
||||
uint8_t* tape_ptr(Tape* tape) {
|
||||
return tape->data + tape->index;
|
||||
}
|
||||
|
||||
void tape_free(Tape* tape) {
|
||||
free(tape->data);
|
||||
}
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef enum {
|
||||
MoveLeft,
|
||||
MoveRight,
|
||||
Increment,
|
||||
Decrement,
|
||||
StartLoop,
|
||||
EndLoop,
|
||||
PutChar,
|
||||
GetChar,
|
||||
Allocate,
|
||||
Free,
|
||||
EnterTape,
|
||||
LeaveTape,
|
||||
PutString,
|
||||
GetString,
|
||||
Clear,
|
||||
Eof
|
||||
} Symbol;
|
||||
|
||||
typedef struct {
|
||||
uint32_t len;
|
||||
uint32_t index;
|
||||
Symbol* data;
|
||||
} Program;
|
||||
|
||||
void program_init(FILE* file, Program* program);
|
||||
void program_peek(Program* program, Symbol* symbol);
|
||||
void program_next(Program* program, Symbol* symbol);
|
||||
void program_last(Program* program, Symbol* symbol);
|
||||
void program_free(Program* program);
|
||||
|
||||
typedef struct {
|
||||
uint32_t len;
|
||||
uint32_t index;
|
||||
uint8_t* data;
|
||||
} Tape;
|
||||
|
||||
void tape_init(uint32_t len, Tape* tape);
|
||||
void tape_left(Tape* tape);
|
||||
void tape_right(Tape* tape);
|
||||
uint8_t tape_get(Tape* tape);
|
||||
void tape_set(Tape* tape, uint8_t value);
|
||||
uint8_t* tape_ptr(Tape* tape);
|
||||
void tape_free(Tape* tape);
|
47
src/stack.c
Normal file
47
src/stack.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
#include "types.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void stack_init(Stack* stack, uint32_t len) {
|
||||
stack->index = 0;
|
||||
stack->len = len;
|
||||
stack->data = malloc(stack->len * sizeof(union stored));
|
||||
}
|
||||
|
||||
void stack_push(Stack* stack, void* value) {
|
||||
if (stack->index == stack->len) {
|
||||
stack->len *= 2;
|
||||
stack->data = realloc(stack->data, stack->len * sizeof(union stored));
|
||||
}
|
||||
stack->data[stack->index].p = value;
|
||||
stack->index++;
|
||||
}
|
||||
|
||||
void* stack_pop(Stack* stack) {
|
||||
if (stack->index == 0) {
|
||||
return NULL;
|
||||
}
|
||||
stack->index--;
|
||||
return stack->data[stack->index].p;
|
||||
}
|
||||
|
||||
void stack_pushi(Stack* stack, uint32_t value) {
|
||||
if (stack->index == stack->len) {
|
||||
stack->len *= 2;
|
||||
stack->data = realloc(stack->data, stack->len * sizeof(union stored));
|
||||
}
|
||||
stack->data[stack->index].i = value;
|
||||
stack->index++;
|
||||
}
|
||||
|
||||
uint32_t stack_popi(Stack* stack) {
|
||||
if (stack->index == 0) {
|
||||
return 0;
|
||||
}
|
||||
stack->index--;
|
||||
return stack->data[stack->index].i;
|
||||
}
|
||||
|
||||
void stack_free(Stack* stack) {
|
||||
free(stack->data);
|
||||
}
|
44
src/tape.c
Normal file
44
src/tape.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
#include "types.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void tape_init(Tape* tape, uint8_t len) {
|
||||
tape->index = 0;
|
||||
tape->len = len;
|
||||
tape->data = malloc(tape->len);
|
||||
memset(tape->data, 0, len);
|
||||
}
|
||||
|
||||
void tape_free(Tape* tape) {
|
||||
free(tape->data);
|
||||
}
|
||||
|
||||
void tape_left(Tape* tape) {
|
||||
tape->index--;
|
||||
}
|
||||
|
||||
void tape_right(Tape* tape) {
|
||||
tape->index++;
|
||||
}
|
||||
|
||||
void tape_increment(Tape* tape) {
|
||||
tape->data[tape->index]++;
|
||||
}
|
||||
|
||||
void tape_decrement(Tape* tape) {
|
||||
tape->data[tape->index]--;
|
||||
}
|
||||
|
||||
uint8_t tape_get(Tape* tape) {
|
||||
return tape->data[tape->index];
|
||||
}
|
||||
|
||||
void tape_set(Tape* tape, uint8_t value) {
|
||||
tape->data[tape->index] = value;
|
||||
}
|
||||
|
||||
void* tape_ptr(Tape* tape) {
|
||||
return tape->data + tape->index;
|
||||
}
|
73
src/types.h
Normal file
73
src/types.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef enum {
|
||||
MoveLeft,
|
||||
MoveRight,
|
||||
Increment,
|
||||
Decrement,
|
||||
StartLoop,
|
||||
EndLoop,
|
||||
PutChar,
|
||||
GetChar,
|
||||
Allocate,
|
||||
Free,
|
||||
EnterTape,
|
||||
LeaveTape,
|
||||
PutString,
|
||||
GetString,
|
||||
Clear,
|
||||
Eof
|
||||
} Symbol;
|
||||
|
||||
typedef struct {
|
||||
uint32_t len;
|
||||
uint32_t index;
|
||||
struct instruction {
|
||||
Symbol s;
|
||||
uint32_t j;
|
||||
} * data;
|
||||
} Program;
|
||||
|
||||
void program_init(Program* program, FILE* file);
|
||||
void program_get(Program* program, Symbol* symbol);
|
||||
uint32_t program_get_jump(Program* program);
|
||||
void program_next(Program* program);
|
||||
void program_seek(Program* program, uint32_t index);
|
||||
void program_free(Program* program);
|
||||
|
||||
typedef struct {
|
||||
uint32_t len;
|
||||
uint32_t index;
|
||||
union stored {
|
||||
void* p;
|
||||
uint32_t i;
|
||||
} * data;
|
||||
} Stack;
|
||||
|
||||
void stack_init(Stack* stack, uint32_t len);
|
||||
void stack_push(Stack* stack, void* value);
|
||||
void* stack_pop(Stack* stack);
|
||||
void stack_pushi(Stack* stack, uint32_t value);
|
||||
uint32_t stack_popi(Stack* stack);
|
||||
void stack_free(Stack* stack);
|
||||
|
||||
typedef struct {
|
||||
uint8_t len;
|
||||
uint8_t index;
|
||||
uint8_t* data;
|
||||
} Tape;
|
||||
|
||||
void tape_init(Tape* tape, uint8_t len);
|
||||
void tape_free(Tape* tape);
|
||||
void tape_left(Tape* tape);
|
||||
void tape_right(Tape* tape);
|
||||
void tape_increment(Tape* tape);
|
||||
void tape_decrement(Tape* tape);
|
||||
uint8_t tape_get(Tape* tape);
|
||||
void tape_set(Tape* tape, uint8_t value);
|
||||
void* tape_ptr(Tape* tape);
|
||||
|
||||
void interpret(Program* program);
|
Loading…
Reference in a new issue