-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbrainfuck.csp
126 lines (106 loc) · 2.7 KB
/
brainfuck.csp
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import "std.csp";
type Op: enum {
END,
INC_DP,
DEC_DP,
INC_VAL,
DEC_VAL,
OUT,
IN,
JMP_FWD,
JMP_BCK
};
type Status: enum {
OK,
ERR
};
type Instruction: struct {
operator: u16,
operand: u16
};
const PROG_SIZE: i32 = 4096;
const STACK_SIZE: i32 = 512;
const DATA_SIZE: i32 = 65535;
let program: Instruction[PROG_SIZE];
let stack: u16[STACK_SIZE];
let sp: u32;
fn compile(f: &std::File): Status
{
let pc: u16 = 0;
let jmp_pc: u16;
let c: i32;
while (c = std::file::readc(f)) != '\0' && pc < PROG_SIZE
{
match c
{
'>' => program[pc].operator = Op::INC_DP;
'<' => program[pc].operator = Op::DEC_DP;
'+' => program[pc].operator = Op::INC_VAL;
'-' => program[pc].operator = Op::DEC_VAL;
'.' => program[pc].operator = Op::OUT;
',' => program[pc].operator = Op::IN;
'[' => {
program[pc].operator = Op::JMP_FWD;
if sp == STACK_SIZE ret Status::ERR;
stack[sp++] = pc;
}
']' => {
if sp == 0 ret Status::ERR;
jmp_pc = stack[sp -= 1];
program[pc].operator = Op::JMP_BCK;
program[pc].operand = jmp_pc;
program[jmp_pc].operand = pc;
}
_ => pc--;
}
pc++;
}
if sp != 0 || pc == PROG_SIZE ret Status::ERR;
program[pc].operator = Op::END;
<- Status::OK;
}
fn execute(): Status
{
using std;
let data: u16[DATA_SIZE];
let pc: u16 = 0;
let ptr = 0;
while program[pc].operator != Op::END && ptr < DATA_SIZE
{
match program[pc].operator
{
Op::INC_DP => ptr++;
Op::DEC_DP => ptr--;
Op::INC_VAL => data[ptr]++;
Op::DEC_VAL => data[ptr]--;
Op::OUT => io::putc(data[ptr]);
Op::IN => data[ptr] = io::getc(): u16;
Op::JMP_FWD => if !data[ptr] pc = program[pc].operand;
Op::JMP_BCK => if data[ptr] pc = program[pc].operand;
_ => ret Status::ERR;
}
pc++;
}
<- Status::OK;
}
fn main(argc: i32, argv: &&char): i32
{
using std;
do {
io::eprintf("Usage: %s filename\n", argv[0]);
<- Status::ERR;
} unless argc == 2;
let status = Status::OK;
with f = file::open(argv[1], file::READ) {
status = compile(f);
match status {
Status::OK => status = execute();
Status::ERR => io::eputs("Error Compiling!\n");
}
}
else {
io::eprintf("Could not read file `%s'\n", argv[1]);
status = Status::ERR;
}
<- status;
}