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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '08151903e89f79497698dbbc770c16dd1914a855004bcd1062864573f586df02'
4
- data.tar.gz: 24e27debd03d41327e03ddca31923c1810d9f8137d4913dc4b0fb37c38ffba88
3
+ metadata.gz: a5154444296311ea527d0eddff5821f5de1b2ea798d526ccb7d4374f3a394e09
4
+ data.tar.gz: 5664f22b66f80079a70fae405c888aa61c20bf8af48edceba55dc502558e7de7
5
5
  SHA512:
6
- metadata.gz: c352e0c9014adb1c60bff8312fcb1d8d9cfc5dd79b21329482844bf9d3189f1e4870348553bdd4ac4214ff11a513e991e9e513246425abf4b1e5c97a8163bcc3
7
- data.tar.gz: 739c515d4a24a4db0e379af6f7bf3152f93f5316fa6d52b2d8a884d0fb5dabb3e1fa0682fd6435464d60a70c6f35956362ac8eda2a66c6f73b2af23a31f4a4de
6
+ metadata.gz: f9dcb1e68374a0fc4bb12ff6fd425d2ea66d6c55f9b4610febfc574039dd2857df46f9f0b066a66dc837f7f7867bc4df163a0e525fde162b8cd57e55b3804b57
7
+ data.tar.gz: 3125f3b51655bdcfdbfb40d3f338aee74f11c1ffafd6e74287f4bd9ce199c894316241e6b317162628f4175997869d75293983fbcd4c2d84535cadb7dda6100d
data/bin/brainfunc CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
3
  require_relative "../lib/brainfunc.rb"
4
- Brainfunc::VM.new.exec(ARGF.read)
4
+ Brainfunc::VM::Exec.call(ARGF.read)
data/bin/ibrainfunc ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require_relative "../lib/brainfunc.rb"
4
+ Brainfunc::Repl::Run.()
@@ -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
- class VM
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
- def exec(source)
33
- run({ memory: Hash.new { 0 }, inst_p: 0, data_p: 0, stack: [], program: source.strip.chars })
34
- end
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
- def run(machine)
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
- end
15
+ }
43
16
  end
44
17
  end
data/lib/brainfunc.rb CHANGED
@@ -2,4 +2,5 @@
2
2
 
3
3
  module Brainfunc
4
4
  require_relative "brainfunc/vm"
5
+ require_relative "brainfunc/repl"
5
6
  end
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.1
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: