-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdefault.nix
83 lines (75 loc) · 2.32 KB
/
default.nix
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
{pkgs ? import <nixpkgs> {}}: let
inherit (pkgs) lib;
transpileBF = code:
with lib; let
validSymbols = ["[" "]" "+" "-" ">" "<" "." ","];
rawTokens =
builtins.filter
(x: elem x validSymbols)
(splitString "" code);
tokens = let
count = list: c:
if length list == 0
then []
else if length list == 1
then [
{
symbol = head list;
repeat = "1";
}
]
else let
x = elemAt list 0;
y = elemAt list 1;
xs = drop 2 list;
in
if x == y
then count ([y] ++ xs) (c + 1)
else
[
{
symbol = x;
repeat = toString c;
}
]
++ (count ([y] ++ xs) 1);
in
count rawTokens 1;
translateToken = token: let
repeat = string: num: concatStringsSep "" (genList (_: string) (toInt num));
in
if token.symbol == "["
then repeat " while (tape[cell]) {\n" token.repeat
else if token.symbol == "]"
then repeat " }\n" token.repeat
else if token.symbol == "+"
then " tape[cell] += ${token.repeat};\n"
else if token.symbol == "-"
then " tape[cell] -= ${token.repeat};\n"
else if token.symbol == ">"
then " cell += ${token.repeat};\n"
else if token.symbol == "<"
then " cell -= ${token.repeat};\n"
else if token.symbol == "."
then repeat " putchar(tape[cell]);\n" token.repeat
else if token.symbol == ","
then repeat " tape[cell] = getchar();\n" token.repeat
else abort "Invalid character detected";
cSource = ''
extern int putchar(int);
extern char getchar();
char tape[30000];
int cell = 0;
int main() {
${concatStringsSep "\n" (map translateToken tokens)}
}
'';
forwardJumps = count (x: x == "[") rawTokens;
backwardJumps = count (x: x == "]") rawTokens;
in
if (forwardJumps != backwardJumps)
then abort "${fowardJumps} forward jump(s) vs. ${backwardJumps} backward jump(s)"
else cSource;
in {
writeBFBin = name: code: pkgs.writeCBin name (transpileBF code);
}