rbf 0.0.1
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.
- data/bin/rbf +5 -0
- data/lib/rbf/interpreter.rb +138 -0
- data/lib/rbf/parser.rb +72 -0
- data/lib/rbf/syntax.rb +45 -0
- data/lib/rbf/transform.rb +30 -0
- data/lib/rbf.rb +35 -0
- metadata +69 -0
data/bin/rbf
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
#--
|
2
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
3
|
+
# Version 2, December 2004
|
4
|
+
#
|
5
|
+
# Copyleft meh. [http://meh.paranoid.pk | meh@paranoici.org]
|
6
|
+
#
|
7
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
8
|
+
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
9
|
+
#
|
10
|
+
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
11
|
+
#++
|
12
|
+
|
13
|
+
require 'stringio'
|
14
|
+
|
15
|
+
class IO
|
16
|
+
begin
|
17
|
+
require 'Win32API'
|
18
|
+
|
19
|
+
def read_char
|
20
|
+
Win32API.new('crtdll', '_getch', [], 'L').Call
|
21
|
+
end
|
22
|
+
rescue LoadError
|
23
|
+
def read_char
|
24
|
+
system 'stty raw -echo'
|
25
|
+
|
26
|
+
STDIN.getc
|
27
|
+
ensure
|
28
|
+
system 'stty -raw echo'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module RBF
|
34
|
+
|
35
|
+
class Interpreter
|
36
|
+
class Storage < Array
|
37
|
+
def initialize (*args)
|
38
|
+
super
|
39
|
+
|
40
|
+
@pointer = 0
|
41
|
+
|
42
|
+
check!
|
43
|
+
end
|
44
|
+
|
45
|
+
def check!
|
46
|
+
if self[@pointer].nil?
|
47
|
+
self[@pointer] = 0
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def forward!
|
52
|
+
@pointer += 1
|
53
|
+
|
54
|
+
check!
|
55
|
+
end
|
56
|
+
|
57
|
+
def backward!
|
58
|
+
@pointer -= 1
|
59
|
+
|
60
|
+
check!
|
61
|
+
end
|
62
|
+
|
63
|
+
def increase!
|
64
|
+
self[@pointer] += 1
|
65
|
+
end
|
66
|
+
|
67
|
+
def decrease!
|
68
|
+
self[@pointer] -= 1
|
69
|
+
end
|
70
|
+
|
71
|
+
def set (value)
|
72
|
+
self[@pointer] = value.to_i
|
73
|
+
end
|
74
|
+
|
75
|
+
def get
|
76
|
+
self[@pointer].to_i
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def initialize
|
81
|
+
@storage = Storage.new
|
82
|
+
@input = STDIN
|
83
|
+
end
|
84
|
+
|
85
|
+
def evaluate (tree, options={})
|
86
|
+
if options[:catch]
|
87
|
+
@output = StringIO.new
|
88
|
+
else
|
89
|
+
@output = STDOUT
|
90
|
+
end
|
91
|
+
|
92
|
+
tree.each {|token|
|
93
|
+
if token.is_a?(Array)
|
94
|
+
self.loop(token)
|
95
|
+
else
|
96
|
+
self.send(token)
|
97
|
+
end
|
98
|
+
}
|
99
|
+
|
100
|
+
if options[:catch]
|
101
|
+
@output.rewind
|
102
|
+
@output.read
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
define_method ?> do
|
107
|
+
@storage.forward!
|
108
|
+
end
|
109
|
+
|
110
|
+
define_method ?< do
|
111
|
+
@storage.backward!
|
112
|
+
end
|
113
|
+
|
114
|
+
define_method ?+ do
|
115
|
+
@storage.increase!
|
116
|
+
end
|
117
|
+
|
118
|
+
define_method ?- do
|
119
|
+
@storage.decrease!
|
120
|
+
end
|
121
|
+
|
122
|
+
define_method ?. do
|
123
|
+
@output.print @storage.get.chr
|
124
|
+
@output.flush
|
125
|
+
end
|
126
|
+
|
127
|
+
define_method ?, do
|
128
|
+
@storage.set @input.read_char
|
129
|
+
end
|
130
|
+
|
131
|
+
define_method :loop do |code|
|
132
|
+
while @storage.get != 0
|
133
|
+
evaluate(code)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
data/lib/rbf/parser.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
#--
|
2
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
3
|
+
# Version 2, December 2004
|
4
|
+
#
|
5
|
+
# Copyleft meh. [http://meh.paranoid.pk | meh@paranoici.org]
|
6
|
+
#
|
7
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
8
|
+
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
9
|
+
#
|
10
|
+
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
11
|
+
#++
|
12
|
+
|
13
|
+
require 'parslet'
|
14
|
+
|
15
|
+
module RBF
|
16
|
+
|
17
|
+
class Parser < Parslet::Parser
|
18
|
+
def self.apply (keys)
|
19
|
+
klass = self.clone
|
20
|
+
|
21
|
+
klass.class_eval {
|
22
|
+
rule(:forward) { str(keys[:forward]).as(?>) }
|
23
|
+
rule(:backward) { str(keys[:backward]).as(?<) }
|
24
|
+
|
25
|
+
rule(:increase) { str(keys[:increase]).as(?+) }
|
26
|
+
rule(:decrease) { str(keys[:decrease]).as(?-) }
|
27
|
+
|
28
|
+
rule(:output) { str(keys[:output]).as(?.) }
|
29
|
+
rule(:input) { str(keys[:input]).as(?,) }
|
30
|
+
|
31
|
+
rule(:while_start) { str(keys[:while_start]) }
|
32
|
+
rule(:while_end) { str(keys[:while_end]) }
|
33
|
+
|
34
|
+
rule(:comment) { (
|
35
|
+
str(keys[:forward]) |
|
36
|
+
str(keys[:backward]) |
|
37
|
+
|
38
|
+
str(keys[:increase]) |
|
39
|
+
str(keys[:decrease]) |
|
40
|
+
|
41
|
+
str(keys[:output]) |
|
42
|
+
str(keys[:input]) |
|
43
|
+
|
44
|
+
str(keys[:while_start]) |
|
45
|
+
str(keys[:while_end])
|
46
|
+
).absent? >> any }
|
47
|
+
}
|
48
|
+
|
49
|
+
klass
|
50
|
+
end
|
51
|
+
|
52
|
+
rule(:keyword) {
|
53
|
+
forward |
|
54
|
+
backward |
|
55
|
+
increase |
|
56
|
+
decrease |
|
57
|
+
output |
|
58
|
+
input
|
59
|
+
}
|
60
|
+
|
61
|
+
rule(:while_loop) {
|
62
|
+
while_start >> code.as(:loop) >> while_end
|
63
|
+
}
|
64
|
+
|
65
|
+
rule(:code) {
|
66
|
+
(while_loop | keyword | comment).repeat
|
67
|
+
}
|
68
|
+
|
69
|
+
root :code
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
data/lib/rbf/syntax.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
#--
|
2
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
3
|
+
# Version 2, December 2004
|
4
|
+
#
|
5
|
+
# Copyleft meh. [http://meh.paranoid.pk | meh@paranoici.org]
|
6
|
+
#
|
7
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
8
|
+
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
9
|
+
#
|
10
|
+
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
11
|
+
#++
|
12
|
+
|
13
|
+
module RBF
|
14
|
+
|
15
|
+
module Syntax
|
16
|
+
Default = {
|
17
|
+
:forward => '>',
|
18
|
+
:backward => '<',
|
19
|
+
|
20
|
+
:increase => '+',
|
21
|
+
:decrease => '-',
|
22
|
+
|
23
|
+
:output => '.',
|
24
|
+
:input => ',',
|
25
|
+
|
26
|
+
:while_start => '[',
|
27
|
+
:while_end => ']'
|
28
|
+
}
|
29
|
+
|
30
|
+
Nintendo = {
|
31
|
+
:forward => '!!!!',
|
32
|
+
:backward => 'ASD',
|
33
|
+
|
34
|
+
:increase => 'XD',
|
35
|
+
:decrease => 'LOL',
|
36
|
+
|
37
|
+
:output => 'PLS',
|
38
|
+
:input => 'CMQ',
|
39
|
+
|
40
|
+
:while_start => '[',
|
41
|
+
:while_end => ']'
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#--
|
2
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
3
|
+
# Version 2, December 2004
|
4
|
+
#
|
5
|
+
# Copyleft meh. [http://meh.paranoid.pk | meh@paranoici.org]
|
6
|
+
#
|
7
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
8
|
+
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
9
|
+
#
|
10
|
+
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
11
|
+
#++
|
12
|
+
|
13
|
+
require 'parslet'
|
14
|
+
|
15
|
+
module RBF
|
16
|
+
|
17
|
+
class Transform < Parslet::Transform
|
18
|
+
rule(?> => simple(:x)) { ?> }
|
19
|
+
rule(?< => simple(:x)) { ?< }
|
20
|
+
|
21
|
+
rule(?+ => simple(:x)) { ?+ }
|
22
|
+
rule(?- => simple(:x)) { ?- }
|
23
|
+
|
24
|
+
rule(?. => simple(:x)) { ?. }
|
25
|
+
rule(?, => simple(:x)) { ?, }
|
26
|
+
|
27
|
+
rule(:loop => subtree(:x)) { x }
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/lib/rbf.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#--
|
2
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
3
|
+
# Version 2, December 2004
|
4
|
+
#
|
5
|
+
# Copyleft meh. [http://meh.paranoid.pk | meh@paranoici.org]
|
6
|
+
#
|
7
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
8
|
+
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
9
|
+
#
|
10
|
+
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
11
|
+
#++
|
12
|
+
|
13
|
+
require 'rbf/syntax'
|
14
|
+
require 'rbf/parser'
|
15
|
+
require 'rbf/transform'
|
16
|
+
require 'rbf/interpreter'
|
17
|
+
|
18
|
+
require 'parslet/convenience'
|
19
|
+
|
20
|
+
module RBF
|
21
|
+
def self.parse (text, keys=Syntax::Default)
|
22
|
+
Transform.new.apply(Parser.apply(keys).new.parse_with_debug(text)) or
|
23
|
+
raise SyntaxError, 'There is a syntax error'
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.evaluate (text, keys=Syntax::Default)
|
27
|
+
tree = text.is_a?(Array) ? text : parse(text.to_s, keys)
|
28
|
+
|
29
|
+
Interpreter.new.evaluate(tree)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.execute (file, keys=Syntax::Default)
|
33
|
+
evaluate(File.read(file), keys)
|
34
|
+
end
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rbf
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- meh.
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-06-24 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: parslet
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
type: :runtime
|
25
|
+
version_requirements: *id001
|
26
|
+
description:
|
27
|
+
email: meh@paranoici.org
|
28
|
+
executables:
|
29
|
+
- rbf
|
30
|
+
extensions: []
|
31
|
+
|
32
|
+
extra_rdoc_files: []
|
33
|
+
|
34
|
+
files:
|
35
|
+
- lib/rbf/transform.rb
|
36
|
+
- lib/rbf/interpreter.rb
|
37
|
+
- lib/rbf/syntax.rb
|
38
|
+
- lib/rbf/parser.rb
|
39
|
+
- lib/rbf.rb
|
40
|
+
- bin/rbf
|
41
|
+
homepage: http://github.com/meh/rbf
|
42
|
+
licenses: []
|
43
|
+
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options: []
|
46
|
+
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: "0"
|
61
|
+
requirements: []
|
62
|
+
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 1.8.5
|
65
|
+
signing_key:
|
66
|
+
specification_version: 3
|
67
|
+
summary: A simple Brainfuck interpreter.
|
68
|
+
test_files: []
|
69
|
+
|