pyper 1.0.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/pyper.rb +83 -1022
- data/lib/pyper/control_characters.rb +22 -0
- data/lib/pyper/control_characters/cadr_like.rb +241 -0
- data/lib/pyper/control_characters/greek_letters.rb +142 -0
- data/lib/pyper/control_characters/other.rb +379 -0
- data/lib/pyper/control_characters/other_latin_letters.rb +228 -0
- data/lib/pyper/default_includes.rb +46 -0
- data/lib/pyper/postfix_machine.rb +442 -0
- data/lib/pyper/postfix_machine/argument_source.rb +205 -0
- data/lib/pyper/version.rb +2 -2
- data/test/pyper_test.rb +45 -47
- metadata +9 -1
@@ -0,0 +1,205 @@
|
|
1
|
+
class Pyper::PostfixMachine
|
2
|
+
# Compile-time argument source stack. To explain, the default source of
|
3
|
+
# arguments in compiled Pyper methods is 'args' local variable, containing
|
4
|
+
# all the arguments supplied to the method (as in +method(*args)+ call).
|
5
|
+
# However, this default argument source can be changed to something else.
|
6
|
+
# For this purpose, compil-time argument source stack is maintained, showing
|
7
|
+
# where the next argument will come from. It is implemented as a struct with
|
8
|
+
# two arrays: +source+ and +grab_method+. The source shows where the argument
|
9
|
+
# comes from, and grab method shows how is it obtained. There are 3 possible
|
10
|
+
# ways to obtain an argument from a source:
|
11
|
+
#
|
12
|
+
# * :ref -- by reference (ie. by simply taking it)
|
13
|
+
# * :dup -- by duplication (calling #dup method on the source)
|
14
|
+
# * :shift -- by shifting (calling #shift method on the source)
|
15
|
+
#
|
16
|
+
# As for the sources, there may be the following ones in a compiled method:
|
17
|
+
#
|
18
|
+
# * :args -- whole argument array
|
19
|
+
# * :args_counted -- args referenced with compile time counter -- default
|
20
|
+
# * :alpha -- primary pipeline
|
21
|
+
# * :beta -- secondary pipeline
|
22
|
+
# * :delta -- in-block pipeline
|
23
|
+
# * :epsilon -- block argument 0
|
24
|
+
# * :zeta -- block argument 1
|
25
|
+
# * :psi -- penultimate element in the args array; penultimate argument
|
26
|
+
# * :omega -- last element in the args array; last argument
|
27
|
+
#
|
28
|
+
# We can se that +:args_counted+ source comes as if with its own special
|
29
|
+
# grabbing method. At compile time, +PostfixMachine+ maintains @args_count
|
30
|
+
# attribute, an index to the +args+ array, and increments it each time
|
31
|
+
# an argument is taken. Other argument sources do not have counters and
|
32
|
+
# if they contain arrays, they can only be grabbed by the standard three
|
33
|
+
# methods.
|
34
|
+
#
|
35
|
+
class ArgumentSource < Struct.new( :source, :grab_method )
|
36
|
+
class << self
|
37
|
+
# Initially, argument stack has a single layer with +:args_counted+ as
|
38
|
+
# the source, and +:ref+ as grab method.
|
39
|
+
#
|
40
|
+
def new
|
41
|
+
self[ [:args_counted], [:ref] ]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Resets the stack back to the initial condition.
|
46
|
+
#
|
47
|
+
def std!
|
48
|
+
self.source = [:args_counted]
|
49
|
+
self.grab_method = [:ref]
|
50
|
+
end
|
51
|
+
|
52
|
+
# Modifies the topmost grab method on the stack to +:shift+.
|
53
|
+
#
|
54
|
+
def shift!
|
55
|
+
grab_method[-1] = :shift
|
56
|
+
end
|
57
|
+
|
58
|
+
# Modifies the topmost grab method on the stack to +:ref+.
|
59
|
+
#
|
60
|
+
def ref!
|
61
|
+
grab_method[-1] = :ref
|
62
|
+
end
|
63
|
+
|
64
|
+
# Modifies the topmost grab method on the stack to +:dup+.
|
65
|
+
#
|
66
|
+
def dup!
|
67
|
+
grab_method[-1] = :dup
|
68
|
+
end
|
69
|
+
|
70
|
+
# Pushes +:args_counted+ source and +:ref+ grab method on the stack.
|
71
|
+
#
|
72
|
+
def args_counted
|
73
|
+
source.push :args_counted
|
74
|
+
grab_method.push :ref
|
75
|
+
end
|
76
|
+
|
77
|
+
# Modifies the topmost source on the stack to +:args_counted+, leaving grab
|
78
|
+
# method unchanged.
|
79
|
+
#
|
80
|
+
def args_counted!
|
81
|
+
source[-1] = :args_counted
|
82
|
+
end
|
83
|
+
|
84
|
+
# Pushes +:args+ source and +:shift+ grab method on the stack.
|
85
|
+
#
|
86
|
+
def args
|
87
|
+
source.push :args
|
88
|
+
grab_method.push :shift
|
89
|
+
end
|
90
|
+
|
91
|
+
# Modifies the topmost source on the stack to +:args+, and grab method to
|
92
|
+
# +:shift+.
|
93
|
+
#
|
94
|
+
def args!
|
95
|
+
source[-1] = :args
|
96
|
+
shift!
|
97
|
+
end
|
98
|
+
|
99
|
+
# Pushes on the stack a given variable name as the source, and +:ref+ as the
|
100
|
+
# grab method.
|
101
|
+
#
|
102
|
+
def var variable
|
103
|
+
source.push variable
|
104
|
+
grab_method.push :ref
|
105
|
+
end
|
106
|
+
|
107
|
+
# Modifies the topmost source on the stack to the given variable name,
|
108
|
+
# leaving the grab method unchanged.
|
109
|
+
#
|
110
|
+
def var! variable
|
111
|
+
source[-1] = variable
|
112
|
+
end
|
113
|
+
|
114
|
+
# Pushes +:alpha+ source and +:ref+ grab method on the stack.
|
115
|
+
#
|
116
|
+
def alpha
|
117
|
+
var :alpha
|
118
|
+
end
|
119
|
+
|
120
|
+
# Modifies the topmost source on the stack to +:alpha+, leaving the grab
|
121
|
+
# method unchanged.
|
122
|
+
#
|
123
|
+
def alpha!
|
124
|
+
var! :alpha
|
125
|
+
end
|
126
|
+
|
127
|
+
# Pushes +:beta+ source and +:ref+ grab method on the stack.
|
128
|
+
#
|
129
|
+
def beta
|
130
|
+
var :beta
|
131
|
+
end
|
132
|
+
|
133
|
+
# Modifies the topmost source on the stack to +:beta+, leaving the grab
|
134
|
+
# method unchanged.
|
135
|
+
#
|
136
|
+
def beta!
|
137
|
+
var! :beta
|
138
|
+
end
|
139
|
+
|
140
|
+
# Pushes +:delta+ source and +:ref+ grab method on the stack.
|
141
|
+
#
|
142
|
+
def delta
|
143
|
+
var :delta
|
144
|
+
end
|
145
|
+
|
146
|
+
# Modifies the topmost source on the stack to +:delta+, leaving the grab
|
147
|
+
# method unchanged.
|
148
|
+
#
|
149
|
+
def delta!
|
150
|
+
var! :delta
|
151
|
+
end
|
152
|
+
|
153
|
+
# Pushes +:epsilon+ source and +:ref+ grab method on the stack.
|
154
|
+
#
|
155
|
+
def epsilon
|
156
|
+
var :epsilon
|
157
|
+
end
|
158
|
+
|
159
|
+
# Modifies the topmost source on the stack to +:epsilon+, leaving the grab
|
160
|
+
# method unchanged.
|
161
|
+
#
|
162
|
+
def epsilon!
|
163
|
+
var! :epsilon
|
164
|
+
end
|
165
|
+
|
166
|
+
# Pushes +:zeta+ source and +:ref+ grab method on the stack.
|
167
|
+
#
|
168
|
+
def zeta
|
169
|
+
var :zeta
|
170
|
+
end
|
171
|
+
|
172
|
+
# Modifies the topmost source on the stack to +:zeta+, leaving the grab
|
173
|
+
# method unchanged.
|
174
|
+
#
|
175
|
+
def zeta!
|
176
|
+
var! :zeta
|
177
|
+
end
|
178
|
+
|
179
|
+
# Pushes +:psi+ source and +:ref+ grab method on the stack.
|
180
|
+
#
|
181
|
+
def psi
|
182
|
+
var :psi
|
183
|
+
end
|
184
|
+
|
185
|
+
# Modifies the topmost source on the stack to +:psi+, leaving the grab
|
186
|
+
# method unchanged.
|
187
|
+
#
|
188
|
+
def psi!
|
189
|
+
var! :psi
|
190
|
+
end
|
191
|
+
|
192
|
+
# Pushes +:omega+ source and +:ref+ grab method on the stack.
|
193
|
+
#
|
194
|
+
def omega
|
195
|
+
var :omega
|
196
|
+
end
|
197
|
+
|
198
|
+
# Modifies the topmost source on the stack to +:omega+, leaving the grab
|
199
|
+
# method unchanged.
|
200
|
+
#
|
201
|
+
def omega!
|
202
|
+
var! :omega
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end # class Pyper::PostfixMachine::ArgumentSource
|
data/lib/pyper/version.rb
CHANGED
data/test/pyper_test.rb
CHANGED
@@ -6,9 +6,7 @@ require 'shoulda'
|
|
6
6
|
require_relative './../lib/pyper'
|
7
7
|
# require 'pyper'
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
class YPiperTest < ::Test::Unit::TestCase
|
9
|
+
class PyperTest < ::Test::Unit::TestCase
|
12
10
|
should "define basic methods" do
|
13
11
|
|
14
12
|
assert_equal 1, [1, 2, 3].car
|
@@ -25,7 +23,7 @@ class YPiperTest < ::Test::Unit::TestCase
|
|
25
23
|
assert_equal [*(4..10)], [*(1..10)].τfτ
|
26
24
|
|
27
25
|
assert_equal [:a, :b, :c], [[:a, 1], [:b, 2], [:c, 3]].τmaτ
|
28
|
-
assert_equal ["a", "b", "c"], [[:a, 1], [:b, 2], [:c, 3]].τ
|
26
|
+
assert_equal ["a", "b", "c"], [[:a, 1], [:b, 2], [:c, 3]].τmatsτ
|
29
27
|
|
30
28
|
assert_equal [*(1..7)], [*(1..10)].τuτ
|
31
29
|
assert_equal [*(1..8)], [*(1..10)].τvτ
|
@@ -35,25 +33,25 @@ class YPiperTest < ::Test::Unit::TestCase
|
|
35
33
|
assert_equal 10, [*(1..10)].τzτ
|
36
34
|
|
37
35
|
|
38
|
-
assert_equal 7, 7
|
39
|
-
assert_equal 7, 7
|
36
|
+
assert_equal 7, 7.π.τCτ
|
37
|
+
assert_equal 7, 7.π.τXτ( 8 )
|
40
38
|
assert_equal 8, [7, 8].χCτ
|
41
|
-
assert_equal 8, 7
|
39
|
+
assert_equal 8, 7.τgτ( 8 )
|
42
40
|
|
43
|
-
assert_equal [0, 1, 6, 9], [:x
|
41
|
+
assert_equal [0, 1, 6, 9], [:x.π.τl0τ, 0.π.τl1τ, Object.new.π.τl6τ, "a".π.τl9τ]
|
44
42
|
|
45
|
-
assert_equal [:hello], :hello
|
43
|
+
assert_equal [:hello], :hello.π.τAτ
|
46
44
|
assert_equal [[:a, 1], [:b, 2]], ( {a: 1, b: 2}.τAτ )
|
47
45
|
assert_equal [1, 2], [1, 2].τAτ
|
48
46
|
|
49
|
-
assert_equal 1, "+1.000000"
|
50
|
-
assert_equal "hello", [:h, ?e, :l, :l, :o].τ
|
47
|
+
assert_equal 1, "+1.000000".τtftiτ
|
48
|
+
assert_equal "hello", [:h, ?e, :l, :l, :o].τijτ
|
51
49
|
|
52
|
-
assert_equal "la", :la
|
50
|
+
assert_equal "la", :la.τtsτ
|
53
51
|
|
54
|
-
assert_equal :hello, "hello"
|
52
|
+
assert_equal :hello, "hello".τtSτ
|
55
53
|
|
56
|
-
assert_equal [[1, 2]], [1, 2]
|
54
|
+
assert_equal [[1, 2]], [1, 2].τtAτ
|
57
55
|
|
58
56
|
assert_equal [1], [*(1..10)].τ0τ
|
59
57
|
assert_equal [1, 2], [*(1..10)].τ1τ
|
@@ -71,52 +69,52 @@ class YPiperTest < ::Test::Unit::TestCase
|
|
71
69
|
|
72
70
|
assert_equal 7, 4.τ₊τ( 3 )
|
73
71
|
assert_equal 15, 3.τ★τ( 5 )
|
74
|
-
assert_equal 2, 17
|
72
|
+
assert_equal 2, 17.τoMτ( 5 )
|
75
73
|
assert_equal 17 / 5, 17.τ÷τ( 5 )
|
76
|
-
assert_equal true, 7
|
74
|
+
assert_equal true, 7.τEτ( 7 )
|
77
75
|
assert_equal [true, false, false], [-1, 0, 1].τm﹤τ( 0, 0, 0 )
|
78
76
|
assert_equal [false, false, true], [-1, 0, 1].τm﹥τ( 0, 0, 0 )
|
79
|
-
assert_equal [true, true, false], [-1, 0, 1].τm
|
80
|
-
assert_equal [false, true, true], [-1, 0, 1].τm
|
81
|
-
assert_equal [5, 10, 15], (1..3).τ
|
82
|
-
assert_equal [1, 4, 9], [*(1..3)]
|
83
|
-
assert_equal [1, 4, 9], (1..3).τ
|
84
|
-
assert_equal [1, 4, 9], (1..3).τ
|
85
|
-
assert_equal [?a, nil, ?a, nil], (1..4).τ
|
86
|
-
assert_equal ["a", nil, "a", nil], (1..4).τ
|
87
|
-
assert_equal [nil, "b", "b", nil], nil
|
77
|
+
assert_equal [true, true, false], [-1, 0, 1].τmιSτ( 0, 0, 0 )
|
78
|
+
assert_equal [false, true, true], [-1, 0, 1].τmιGτ( 0, 0, 0 )
|
79
|
+
assert_equal [5, 10, 15], (1..3).τmomτ( 5 )
|
80
|
+
assert_equal [1, 4, 9], [*(1..3)].τGDσmomτ
|
81
|
+
assert_equal [1, 4, 9], (1..3).τmopτ( 2 )
|
82
|
+
assert_equal [1, 4, 9], (1..3).τMomτ
|
83
|
+
assert_equal [?a, nil, ?a, nil], (1..4).τmoMEτ( 2, 1 ).τmTτ( ?a, nil )
|
84
|
+
assert_equal ["a", nil, "a", nil], (1..4).τmoMETτ( 2, 1, ?a, nil )
|
85
|
+
assert_equal [nil, "b", "b", nil], nil.π.τgmETτ( [0, 1, 1, 0], 1, ?b, nil )
|
88
86
|
assert_equal [["a", nil], [nil, "b"], ["a", "b"], [nil, nil]],
|
89
|
-
(1..4).τ
|
90
|
-
assert_equal true, [:a, :b, :c]
|
91
|
-
assert_equal
|
92
|
-
|
87
|
+
(1..4).τmoMETχ( 2, 1, ?a, nil ).πgmETπ( [0, 1, 1, 0], 1, ?b, nil ).χrZτ
|
88
|
+
assert_equal true, [:a, :b, :c].τoiτ( :b )
|
89
|
+
assert_equal [[:c], [:a]], [[:b, :c, :d], [:a, :b, :d]].πβoIXo8γosmAτ
|
90
|
+
# χGβmgεoiiEεT_iCχmgεoiiEεT_π( nil, nil ) )
|
93
91
|
assert_equal( "d yada yada, a, c blah blah",
|
94
92
|
"%s yada yada, %s blah blah" %
|
95
|
-
[[:d], [:a, :c]].χ
|
96
|
-
assert_equal "
|
93
|
+
[[:d], [:a, :c]].χJXJπ( ", " ) )
|
94
|
+
assert_equal "foobar", (1..100).τmoMETχ( 3, 0, "foo", nil ).πmoMETχ( 5, 0, "bar", nil ).πZmijτ[14]
|
97
95
|
assert_equal ["ax", "bx"], ["a", "b"].τmτ { |o| o + "x" }
|
98
96
|
assert_equal ["ax", "bx"], ["a", "b"].τBmτ { |o| o + "x" }
|
99
|
-
assert_equal [-1, -2], [[1, 1], [2, 3]].π
|
100
|
-
assert_equal [1, 2], [[1, 1], [2, 3]].π
|
97
|
+
assert_equal [-1, -2], [[1, 1], [2, 3]].πMosτ
|
98
|
+
assert_equal [1, 2], [[1, 1], [2, 3]].πWosτ
|
101
99
|
a, b = [Object.new, Object.new].each { |o| o.define_singleton_method :xxx do "xxx" end }
|
102
100
|
hsh = { a => "xxx", b => "xxx" }
|
103
|
-
assert_equal hsh, [a, b].τ
|
101
|
+
assert_equal hsh, [a, b].τBmXthτ( &:xxx )
|
104
102
|
assert_equal [:x], 'x'.τABmτ( &:to_sym )
|
105
|
-
assert_equal ['x'], ['x'].τ
|
106
|
-
assert_equal [[['y']]], [[[:y]]].τ
|
107
|
-
assert_equal [[:x, :y], [:v, :w]], [[?x, ?y], [?v, ?w]].τ
|
103
|
+
assert_equal ['x'], ['x'].τmtS_mtsτ
|
104
|
+
assert_equal [[['y']]], [[[:y]]].τmmmtsτ
|
105
|
+
assert_equal [[:x, :y], [:v, :w]], [[?x, ?y], [?v, ?w]].τmmtSτ
|
108
106
|
|
109
|
-
assert_equal [1, 1, 1], "abc".τ
|
107
|
+
assert_equal [1, 1, 1], "abc".τml1τ
|
110
108
|
require 'y_support/all'
|
111
109
|
@a = ["a", "b", "c"]
|
112
|
-
exp = [[["a"], ["b"], ["c"]],
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
.τ
|
119
|
-
.τ
|
110
|
+
exp = [ [["a"], ["b"], ["c"]],
|
111
|
+
[["a", "b"], ["c"]],
|
112
|
+
[["a"], ["b", "c"]],
|
113
|
+
[["a", "b", "c"]] ]
|
114
|
+
n = @a.size - 1
|
115
|
+
rslt = ( 0 ... 2 ** n ).τmg_MoM_mτ( "%0#{n}b", &[:τmETτ, ?0, ?+, ?,] )
|
116
|
+
.τmpjqJ_moMτ( '', "[@a[%s]]", [ * 0 .. n ] )
|
117
|
+
.τmpq_mτ( '[', ']', & method( :eval ) )
|
120
118
|
assert_equal exp.sort, rslt.sort
|
121
119
|
end
|
122
|
-
end # class
|
120
|
+
end # class PyperTest
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pyper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- boris
|
@@ -37,6 +37,14 @@ files:
|
|
37
37
|
- README.md
|
38
38
|
- Rakefile
|
39
39
|
- lib/pyper.rb
|
40
|
+
- lib/pyper/control_characters.rb
|
41
|
+
- lib/pyper/control_characters/cadr_like.rb
|
42
|
+
- lib/pyper/control_characters/greek_letters.rb
|
43
|
+
- lib/pyper/control_characters/other.rb
|
44
|
+
- lib/pyper/control_characters/other_latin_letters.rb
|
45
|
+
- lib/pyper/default_includes.rb
|
46
|
+
- lib/pyper/postfix_machine.rb
|
47
|
+
- lib/pyper/postfix_machine/argument_source.rb
|
40
48
|
- lib/pyper/version.rb
|
41
49
|
- pyper.gemspec
|
42
50
|
- test/pyper_test.rb
|