-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtape.c
85 lines (61 loc) · 1.77 KB
/
tape.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include "tape.h"
#include <stdio.h>
#include <string.h>
static void set_default(Symbol* const start, const size_t length, const Symbol def) {
for(size_t i = 0; i < length; i++){
((Symbol*)start)[i] = def;
}
}
inline struct Tape init_tape_full(const Symbol def, Symbol* content, const size_t size) {
return (struct Tape){
.content = content,
.size = size,
.def = def,
.cursor = 0
};
}
struct Tape init_tape(const Symbol def) {
const size_t size = 16;
Symbol* const content = malloc(sizeof(Symbol) * size);
set_default(content, size, def);
struct Tape tape = init_tape_full(def, content, size);
tape.cursor = size / 2;
return tape;
}
void left(struct Tape* const tape) {
if(tape->cursor > 0) {
--tape->cursor;
return;
}
Symbol* new = malloc(sizeof(Symbol) * tape->size * 2);
if(!new) {
fprintf(stderr, "Not enough memory\n");
exit(EXIT_FAILURE);
}
memcpy(new + tape->size, tape->content, sizeof(Symbol) * tape->size);
set_default(new, tape->size, tape->def);
free(tape->content);
tape->content = new;
tape->cursor += tape->size - 1;
tape->size *= 2;
}
void right(struct Tape* const tape) {
if(!(tape->size <= ++(tape->cursor))) {
return;
}
Symbol* new = realloc(tape->content, sizeof(Symbol) * tape->size * 2);
if(!new) {
fprintf(stderr, "Not enough memory\n");
exit(EXIT_FAILURE);
}
tape->content = new;
set_default(tape->content + tape->size, tape->size, tape->def);
tape->size *= 2;
}
void write(struct Tape* const tape, const Symbol symbol) {
tape->content[tape->cursor] = symbol;
}
void free_tape(struct Tape* const tape) {
free(tape->content);
free(tape);
}