rbf 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/bin/rbf ADDED
@@ -0,0 +1,5 @@
1
+ #! /usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'rbf'
4
+
5
+ RBF.execute(ARGV.first)
@@ -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
+