brainfunc 0.0.1 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/brainfunc +1 -1
- data/bin/ibrainfunc +4 -0
- data/lib/brainfunc/functions.rb +31 -0
- data/lib/brainfunc/repl.rb +19 -0
- data/lib/brainfunc/vm.rb +9 -36
- data/lib/brainfunc.rb +1 -0
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5154444296311ea527d0eddff5821f5de1b2ea798d526ccb7d4374f3a394e09
|
4
|
+
data.tar.gz: 5664f22b66f80079a70fae405c888aa61c20bf8af48edceba55dc502558e7de7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9dcb1e68374a0fc4bb12ff6fd425d2ea66d6c55f9b4610febfc574039dd2857df46f9f0b066a66dc837f7f7867bc4df163a0e525fde162b8cd57e55b3804b57
|
7
|
+
data.tar.gz: 3125f3b51655bdcfdbfb40d3f338aee74f11c1ffafd6e74287f4bd9ce199c894316241e6b317162628f4175997869d75293983fbcd4c2d84535cadb7dda6100d
|
data/bin/brainfunc
CHANGED
data/bin/ibrainfunc
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Brainfunc
|
4
|
+
Functions = (Hash.new { ->(state) { state.merge({inst_p: state[:inst_p] + 1}) } })
|
5
|
+
.merge(
|
6
|
+
{
|
7
|
+
?> => ->(state) { state.merge({data_p: state[:data_p]+1, inst_p: state[:inst_p] + 1}) },
|
8
|
+
?< => ->(state) { state.merge({data_p: state[:data_p]-1, inst_p: state[:inst_p] + 1}) },
|
9
|
+
?+ => ->(state) { state.merge({memory: state[:memory].merge(state[:data_p] => (state[:memory][state[:data_p]]+1 % 127).abs), inst_p: state[:inst_p] + 1}) },
|
10
|
+
?- => ->(state) { state.merge({memory: state[:memory].merge(state[:data_p] => (state[:memory][state[:data_p]]-1 % 127).abs), inst_p: state[:inst_p] + 1}) },
|
11
|
+
?. => ->(state) { print(state[:memory][state[:data_p]].chr); state.merge({inst_p: state[:inst_p] + 1}) },
|
12
|
+
?, => ->(state) { state.merge({memory: state[:memory].merge({ state[:data_p] => STDIN.getch.bytes[0] }), inst_p: state[:inst_p] + 1}) },
|
13
|
+
?[ => ->(state) {
|
14
|
+
state[:stack].push(state[:inst_p]) && ((
|
15
|
+
state[:memory][state[:data_p]].zero? && state.merge(
|
16
|
+
inst_p: state[:program]
|
17
|
+
.slice(state[:inst_p]..-1)
|
18
|
+
.filter_map.with_index { |el, index| index + 1 if el == "]" }[state[:stack].size]
|
19
|
+
)
|
20
|
+
) || state.merge({inst_p: state[:inst_p] + 1}))
|
21
|
+
},
|
22
|
+
?] => ->(state) {
|
23
|
+
(matching_paren=state[:stack].pop) && ((
|
24
|
+
!state[:memory][state[:data_p]].zero? &&
|
25
|
+
state.merge({inst_p: matching_paren})
|
26
|
+
) || state.merge({inst_p: state[:inst_p] + 1}))
|
27
|
+
},
|
28
|
+
?# => ->(state) { puts(state.inspect) || state.merge({inst_p: state[:inst_p] + 1}) }
|
29
|
+
}
|
30
|
+
)
|
31
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Brainfunc
|
2
|
+
module Repl
|
3
|
+
Run = ->() {
|
4
|
+
puts("Brainfunc - Functional Brainfuck Interpreter")
|
5
|
+
loop do
|
6
|
+
print("-> ")
|
7
|
+
case (instruction = gets.strip.chomp)
|
8
|
+
when "quit"
|
9
|
+
break
|
10
|
+
when "exit"
|
11
|
+
break
|
12
|
+
else
|
13
|
+
state = Brainfunc::VM::Exec.call(instruction, (state || {}))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
exit(0)
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
data/lib/brainfunc/vm.rb
CHANGED
@@ -1,44 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Brainfunc
|
4
|
-
|
5
|
-
def ops
|
6
|
-
@ops ||= (Hash.new { ->(state) { state.merge({inst_p: state[:inst_p] + 1}) } }).merge({
|
7
|
-
?> => ->(state) { state.merge({data_p: state[:data_p]+1, inst_p: state[:inst_p] + 1}) },
|
8
|
-
?< => ->(state) { state.merge({data_p: state[:data_p]-1, inst_p: state[:inst_p] + 1}) },
|
9
|
-
?+ => ->(state) { state.merge({memory: state[:memory].merge(state[:data_p] => (state[:memory][state[:data_p]]+1 % 127).abs), inst_p: state[:inst_p] + 1}) },
|
10
|
-
?- => ->(state) { state.merge({memory: state[:memory].merge(state[:data_p] => (state[:memory][state[:data_p]]-1 % 127).abs), inst_p: state[:inst_p] + 1}) },
|
11
|
-
?. => ->(state) { print(state[:memory][state[:data_p]].chr); state.merge({inst_p: state[:inst_p] + 1}) },
|
12
|
-
?, => ->(state) { state.merge({memory: state[:memory].merge({ state[:data_p] => STDIN.getch.bytes[0] }), inst_p: state[:inst_p] + 1}) },
|
13
|
-
?[ => ->(state) {
|
14
|
-
state[:stack].push(state[:inst_p]) && ((
|
15
|
-
state[:memory][state[:data_p]].zero? && state.merge(
|
16
|
-
inst_p: state[:program]
|
17
|
-
.slice(state[:inst_p]..-1)
|
18
|
-
.filter_map.with_index { |el, index| index + 1 if el == "]" }[state[:stack].size]
|
19
|
-
)
|
20
|
-
) || state.merge({inst_p: state[:inst_p] + 1}))
|
21
|
-
},
|
22
|
-
?] => ->(state) {
|
23
|
-
(matching_paren=state[:stack].pop) && ((
|
24
|
-
!state[:memory][state[:data_p]].zero? &&
|
25
|
-
state.merge({inst_p: matching_paren})
|
26
|
-
) || state.merge({inst_p: state[:inst_p] + 1}))
|
27
|
-
},
|
28
|
-
?# => ->(state) { puts(debug(state)) || state.merge({inst_p: state[:inst_p] + 1}) }
|
29
|
-
})
|
30
|
-
end
|
4
|
+
require_relative "functions"
|
31
5
|
|
32
|
-
|
33
|
-
|
34
|
-
|
6
|
+
module VM
|
7
|
+
Exec = ->(source, vm_state = {}) {
|
8
|
+
vm_state = { memory: Hash.new { 0 }, inst_p: 0, data_p: 0, stack: [], program: (vm_state[:program] || []) + source.strip.chars }
|
9
|
+
loop { (vm_state=Brainfunc::Functions[vm_state[:program][vm_state[:inst_p]]].(vm_state)) && (vm_state[:inst_p] >= vm_state[:program].length && break) }
|
10
|
+
vm_state
|
11
|
+
}
|
35
12
|
|
36
|
-
|
37
|
-
loop { (machine=ops[machine[:program][machine[:inst_p]]].(machine)) && (machine[:inst_p] >= machine[:program].length && break) }
|
38
|
-
end
|
39
|
-
|
40
|
-
def debug(machine)
|
13
|
+
Debug = ->(machine) {
|
41
14
|
{ m: machine.slice(:memory, :data_p, :inst_p), in: machine[:program][machine[:inst_p]], stack: machine[:stack] }
|
42
|
-
|
15
|
+
}
|
43
16
|
end
|
44
17
|
end
|
data/lib/brainfunc.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brainfunc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sreedev Kodichath
|
@@ -13,12 +13,16 @@ dependencies: []
|
|
13
13
|
description: Tiny, Performant, Functional Brainfuck interpreter
|
14
14
|
email: sreedevpadmakumar@gmail.com
|
15
15
|
executables:
|
16
|
+
- ibrainfunc
|
16
17
|
- brainfunc
|
17
18
|
extensions: []
|
18
19
|
extra_rdoc_files: []
|
19
20
|
files:
|
20
21
|
- bin/brainfunc
|
22
|
+
- bin/ibrainfunc
|
21
23
|
- lib/brainfunc.rb
|
24
|
+
- lib/brainfunc/functions.rb
|
25
|
+
- lib/brainfunc/repl.rb
|
22
26
|
- lib/brainfunc/vm.rb
|
23
27
|
homepage: https://www.sree.dev
|
24
28
|
licenses:
|