trac_lang 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,88 @@
1
+
2
+ module TracLang
3
+
4
+ # TRAC octal number. Unlike the TracLang::Decimal, any
5
+ # string prefix is discarded. Bit size is saved so that
6
+ # operations can retain the size.
7
+ class Octal
8
+
9
+ # Number of octal digits in this number.
10
+ attr_accessor :size
11
+
12
+ # Numeric value of this number.
13
+ attr_accessor :value
14
+
15
+ # Creates a TRAC octal. Any leading non-numeric characters are ignored.
16
+ # If there are no octal characters, zero is assumed.
17
+ def initialize(str = '')
18
+ raise ArgumentError unless str.is_a? String
19
+ b = str.partition(/[0-7]*$/)
20
+ @value = b[1].to_i(8)
21
+ @size = b[1].length
22
+ end
23
+
24
+ # Tests for equality. This is different from numeric equality,
25
+ # because size is also tested.
26
+ def ==(o)
27
+ return super unless o.is_a? TracLang::Octal
28
+ o.value == @value && o.size == @size
29
+ end
30
+
31
+ # Converts octal number to string. Returns a string <size> digits long.
32
+ def to_s
33
+ if value < 0
34
+ sprintf("%0*.*o", size + 3, size + 3, value).slice(3..-1)
35
+ else
36
+ sprintf("%0*.*o", size, size, value)
37
+ end
38
+ end
39
+
40
+ # Bit or. Result bit size is maximum of bit size of parameters.
41
+ define_method(:|) do |other|
42
+ result = Octal.new
43
+ result.size = [self.size, other.size].max
44
+ result.value = self.value | other.value
45
+ result
46
+ end
47
+
48
+ # Bitwise and. Result bit size is minimum of bit size of parameters.
49
+ define_method(:&) do |other|
50
+ result = Octal.new
51
+ result.size = [self.size, other.size].min
52
+ result.value = self.value & other.value
53
+ result
54
+ end
55
+
56
+ # Bit complement.
57
+ def ~
58
+ result = Octal.new
59
+ result.size = size
60
+ result.value = ~value
61
+ result
62
+ end
63
+
64
+ # Shifts octal bits by the given amount.
65
+ def shift(n)
66
+ result = Octal.new
67
+ result.size = size
68
+ result.value = n.value < 0 ? value >> -n.value : value << n.value
69
+ result
70
+ end
71
+
72
+ # Rotates octal bits by the given amount.
73
+ def rotate(n)
74
+ result = Octal.new
75
+ result.size = size
76
+ bits = 3 * size
77
+ bit_mask = 2 ** bits - 1
78
+ if n.value < 0
79
+ result.value = ((value >> -n.value) | (value << (bits + n.value))) & bit_mask
80
+ else
81
+ result.value = ((value << n.value) | (value >> (bits - n.value))) & bit_mask
82
+ end
83
+ result
84
+ end
85
+
86
+ end
87
+
88
+ end
@@ -0,0 +1,114 @@
1
+
2
+ module TracLang
3
+
4
+ # Parser for TRAC input. Given the input a character at a time, it
5
+ # creates an active string and then executes it when the string is
6
+ # completed.
7
+ class Parser
8
+
9
+ # Parses the given string and executes it, until the
10
+ # active string is empty.
11
+ def parse(str, &blk)
12
+ @active = str
13
+ @handler = :reading
14
+ @expressions = []
15
+ loop do
16
+ if @active.empty?
17
+ # if handler is parens, we've read a open paren w/o a matching closing one
18
+ throw :reset if @handler == :parens
19
+ # if handler if reading, and expressions is not empty
20
+ # we've read #( without a matching end paren
21
+ throw :reset if @handler == :reading && !@expressions.empty?
22
+ # if hander is :start_proc, we've just read a bunch of #s
23
+ # so we can ignore them without throwing an error
24
+ return
25
+ end
26
+ self.send(@handler, @active.slice!(0), &blk)
27
+ end
28
+ end
29
+
30
+ # Add character to current expression, ignore if no expression exists
31
+ def concat(c)
32
+ unless @expressions.empty?
33
+ @expressions.last.concat(c)
34
+ end
35
+ end
36
+
37
+ # Handler while actively reading the active string. If you start an expression,
38
+ # switch to the start_proc handler. If you see an open parenthesis, switch
39
+ # to the parens handler. Comma marks a new argument in the current expression, and
40
+ # end parenthesis marks the end of an expression. When an expression is ended, execute it
41
+ # and handle the results.
42
+ def reading(c, &blk)
43
+ case c
44
+ when '#'
45
+ @expressions.push Expression.new
46
+ @handler = :start_proc
47
+ when '('
48
+ @nesting = 1
49
+ @handler = :parens
50
+ when ','
51
+ unless @expressions.empty?
52
+ @expressions.last.newarg
53
+ end
54
+ when ')'
55
+ throw :reset if @expressions.empty?
56
+ expression = @expressions.pop
57
+ result = blk.call(expression)
58
+ if result[:force] || expression.active?
59
+ @active.prepend(result[:value])
60
+ else
61
+ concat(result[:value])
62
+ end
63
+ when "\n", "\r"
64
+ # ignore cr and lf
65
+ else
66
+ concat(c)
67
+ end
68
+ end
69
+
70
+ # Handler while reading inside protective parentheses. Copies all
71
+ # characters to current expression while keeping track of current parentheses
72
+ # nesting. When a matching parenthesis is found, go back to reading
73
+ # handler.
74
+ def parens(c)
75
+ case c
76
+ when '('
77
+ @nesting += 1
78
+ when ')'
79
+ @nesting -= 1
80
+ if @nesting == 0
81
+ @handler = :reading
82
+ return
83
+ end
84
+ end
85
+ concat(c)
86
+ end
87
+
88
+ # Handler for the start of an expression. Mark the expression as active or not,
89
+ # depending on whether it starts with #(...) or ##(...).
90
+ def start_proc(c, &blk)
91
+ case c
92
+ when '#'
93
+ throw :reset if @expressions.empty?
94
+ if @expressions.last.active?
95
+ @expressions.last.active = false
96
+ else
97
+ unless @expressions.size == 1
98
+ @expressions[-2].concat(c)
99
+ end
100
+ end
101
+ when '('
102
+ @handler = :reading
103
+ else
104
+ throw :reset if @expressions.empty?
105
+ discard = @expressions.pop
106
+ concat(discard.active? ? '#' : '##')
107
+ @handler = :reading
108
+ reading(c, &blk)
109
+ end
110
+ end
111
+
112
+ end
113
+
114
+ end
@@ -0,0 +1,4 @@
1
+ module TracLang
2
+ # Version number of TRAC Language processor.
3
+ VERSION = '0.1.0'
4
+ end
data/trac_lang.gemspec ADDED
@@ -0,0 +1,42 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'trac_lang/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "trac_lang"
8
+ spec.version = TracLang::VERSION
9
+ spec.authors = ["David Stanley"]
10
+ spec.email = ["dstanley1994@yahoo.com"]
11
+
12
+ spec.summary = %q{Ruby implementation of the TRAC computer language.}
13
+ spec.description = %q{TRAC is a macro language invented in the 1950s.}
14
+ spec.homepage = %q(https://github.com/dstanley1994/trac_lang)
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against " \
23
+ "public gem pushes."
24
+ end
25
+
26
+ spec.require_paths = ["lib"]
27
+ spec.bindir = "exe"
28
+ spec.executables = ['trac_lang']
29
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
30
+ f.match(%r{^(test|spec|features)/})
31
+ end
32
+ spec.has_rdoc = true
33
+ spec.rdoc_options << '--include' << 'lib/trac_lang'
34
+
35
+ spec.add_runtime_dependency "highline", "~> 1.7", ">= 1.7.8"
36
+
37
+ spec.add_development_dependency "bundler", "~> 1.14"
38
+ spec.add_development_dependency "rake", "~> 10.0"
39
+ spec.add_development_dependency "rspec", "~> 3.0"
40
+ spec.add_development_dependency "cucumber", '~> 2.4', '>= 2.4.0'
41
+ spec.add_development_dependency "aruba", "~> 0.14.2"
42
+ end
metadata ADDED
@@ -0,0 +1,177 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: trac_lang
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - David Stanley
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-10-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: highline
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.7.8
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.7'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.7.8
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.14'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.14'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '10.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '10.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: cucumber
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '2.4'
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 2.4.0
85
+ type: :development
86
+ prerelease: false
87
+ version_requirements: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - "~>"
90
+ - !ruby/object:Gem::Version
91
+ version: '2.4'
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: 2.4.0
95
+ - !ruby/object:Gem::Dependency
96
+ name: aruba
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: 0.14.2
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - "~>"
107
+ - !ruby/object:Gem::Version
108
+ version: 0.14.2
109
+ description: TRAC is a macro language invented in the 1950s.
110
+ email:
111
+ - dstanley1994@yahoo.com
112
+ executables:
113
+ - trac_lang
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - ".gitignore"
118
+ - ".rspec"
119
+ - ".travis.yml"
120
+ - CODE_OF_CONDUCT.md
121
+ - Gemfile
122
+ - LICENSE.txt
123
+ - README.md
124
+ - Rakefile
125
+ - bin/console
126
+ - bin/setup
127
+ - examples/README.trl
128
+ - examples/golf.trl
129
+ - examples/list.trl
130
+ - examples/math.trl
131
+ - examples/meta.trl
132
+ - examples/ratio.trl
133
+ - examples/struct.trl
134
+ - examples/term.trl
135
+ - examples/util.trl
136
+ - exe/trac_lang
137
+ - lib/trac_lang.rb
138
+ - lib/trac_lang/bindings.rb
139
+ - lib/trac_lang/block.rb
140
+ - lib/trac_lang/decimal.rb
141
+ - lib/trac_lang/dispatch.rb
142
+ - lib/trac_lang/executor.rb
143
+ - lib/trac_lang/expression.rb
144
+ - lib/trac_lang/form.rb
145
+ - lib/trac_lang/immediate_read.rb
146
+ - lib/trac_lang/octal.rb
147
+ - lib/trac_lang/parser.rb
148
+ - lib/trac_lang/version.rb
149
+ - trac_lang.gemspec
150
+ homepage: https://github.com/dstanley1994/trac_lang
151
+ licenses:
152
+ - MIT
153
+ metadata:
154
+ allowed_push_host: https://rubygems.org
155
+ post_install_message:
156
+ rdoc_options:
157
+ - "--include"
158
+ - lib/trac_lang
159
+ require_paths:
160
+ - lib
161
+ required_ruby_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ required_rubygems_version: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
171
+ requirements: []
172
+ rubyforge_project:
173
+ rubygems_version: 2.6.13
174
+ signing_key:
175
+ specification_version: 4
176
+ summary: Ruby implementation of the TRAC computer language.
177
+ test_files: []