dslkit 0.2.0
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/CHANGES +2 -0
- data/GPL +340 -0
- data/Rakefile +83 -0
- data/TODO +0 -0
- data/VERSION +1 -0
- data/examples/mail.rb +76 -0
- data/examples/mm.rb +148 -0
- data/examples/multiply.reg +42 -0
- data/examples/null_pattern.rb +52 -0
- data/examples/recipe.rb +81 -0
- data/examples/recipe2.rb +82 -0
- data/examples/recipe_common.rb +99 -0
- data/examples/subtract.reg +9 -0
- data/install.rb +17 -0
- data/lib/dslkit/polite.rb +538 -0
- data/lib/dslkit/rude.rb +23 -0
- data/lib/dslkit.rb +2 -0
- data/tests/runner.rb +12 -0
- data/tests/test_common.rb +180 -0
- data/tests/test_polite.rb +91 -0
- data/tests/test_rude.rb +70 -0
- metadata +69 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'dslkit/polite'
|
2
|
+
$:.unshift 'examples'
|
3
|
+
|
4
|
+
include DSLKit::Deflect
|
5
|
+
|
6
|
+
puts "Example 1"
|
7
|
+
deflect(NilClass, :method_missing, Deflector.new { nil }) do
|
8
|
+
begin
|
9
|
+
p "foo".bar.baz
|
10
|
+
rescue NoMethodError
|
11
|
+
p "caught 1"
|
12
|
+
end
|
13
|
+
p nil.bar.baz
|
14
|
+
t = Thread.new do
|
15
|
+
begin
|
16
|
+
p nil.bar.baz
|
17
|
+
rescue NoMethodError
|
18
|
+
p "caught 2"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
t.join if t.alive?
|
22
|
+
p nil.bar.baz
|
23
|
+
end
|
24
|
+
begin
|
25
|
+
p nil.bar.baz
|
26
|
+
rescue NoMethodError
|
27
|
+
p "caught 3"
|
28
|
+
end
|
29
|
+
|
30
|
+
puts "-" * 70, "Example 2"
|
31
|
+
deflect_start(NilClass, :method_missing, Deflector.new { nil })
|
32
|
+
begin
|
33
|
+
p "foo".bar.baz
|
34
|
+
rescue NoMethodError
|
35
|
+
p "caught 1"
|
36
|
+
end
|
37
|
+
p nil.bar.baz
|
38
|
+
t = Thread.new do
|
39
|
+
begin
|
40
|
+
p nil.bar.baz
|
41
|
+
rescue NoMethodError
|
42
|
+
p "caught 2"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
t.join if t.alive?
|
46
|
+
p nil.bar.baz
|
47
|
+
deflect_stop(NilClass, :method_missing)
|
48
|
+
begin
|
49
|
+
p nil.bar.baz
|
50
|
+
rescue NoMethodError
|
51
|
+
p "caught 3"
|
52
|
+
end
|
data/examples/recipe.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'dslkit/rude'
|
4
|
+
$:.unshift 'examples'
|
5
|
+
require 'recipe_common'
|
6
|
+
|
7
|
+
class Cup < Unit; end
|
8
|
+
class Teaspoon < Unit; end
|
9
|
+
class Tablespoon < Unit; end
|
10
|
+
|
11
|
+
class Flour < Ingredient; end
|
12
|
+
class Bakingpowder < Ingredient; end
|
13
|
+
class Salt < Ingredient; end
|
14
|
+
class Egg < Ingredient; end
|
15
|
+
class Milk < Ingredient; end
|
16
|
+
class Butter < Ingredient; end
|
17
|
+
|
18
|
+
class Recipe < DSLKit::BlankSlate.with(:respond_to?, :instance_exec, :inspect, /^deflect/)
|
19
|
+
include DSLKit::Deflect
|
20
|
+
|
21
|
+
def initialize(&block)
|
22
|
+
@ingredients = []
|
23
|
+
deflector = Deflector.new do |number, id, name|
|
24
|
+
if unit = Unit.unit(name, number)
|
25
|
+
unit
|
26
|
+
else
|
27
|
+
ingredient = Ingredient.ingredient(name, number)
|
28
|
+
@ingredients << ingredient
|
29
|
+
end
|
30
|
+
end
|
31
|
+
deflect(Numeric, :method_missing, deflector) do
|
32
|
+
instance_exec(&block)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
attr_reader :ingredients
|
37
|
+
|
38
|
+
def to_a
|
39
|
+
@ingredients
|
40
|
+
end
|
41
|
+
alias to_ary to_a
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
to_a * "\n"
|
45
|
+
end
|
46
|
+
alias inspect to_s
|
47
|
+
|
48
|
+
def method_missing(name, *args)
|
49
|
+
name = name.to_s.gsub(/_/, '').capitalize
|
50
|
+
@ingredients << Object.const_get(name).new(*args)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class RecipeInterpreter
|
55
|
+
def recipe(&block)
|
56
|
+
Recipe.new(&block)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
recipe_source = <<EOT
|
61
|
+
pancakes = recipe do
|
62
|
+
flour 2.cups
|
63
|
+
baking_powder 2.5.teaspoons
|
64
|
+
salt 0.5.teaspoon
|
65
|
+
egg 1
|
66
|
+
milk 1.5.cups
|
67
|
+
butter 2.tablespoons
|
68
|
+
end
|
69
|
+
EOT
|
70
|
+
|
71
|
+
pancakes = RecipeInterpreter.new.interpret(recipe_source)
|
72
|
+
puts pancakes
|
73
|
+
|
74
|
+
puts
|
75
|
+
|
76
|
+
def recipe(&block)
|
77
|
+
Recipe.new(&block)
|
78
|
+
end
|
79
|
+
|
80
|
+
pancakes = eval recipe_source
|
81
|
+
puts pancakes
|
data/examples/recipe2.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'dslkit/rude'
|
4
|
+
$:.unshift 'examples'
|
5
|
+
require 'recipe_common'
|
6
|
+
|
7
|
+
class Cup < Unit; end
|
8
|
+
class Teaspoon < Unit; end
|
9
|
+
class Tablespoon < Unit; end
|
10
|
+
|
11
|
+
class Flour < Ingredient; end
|
12
|
+
class Bakingpowder < Ingredient; end
|
13
|
+
class Salt < Ingredient; end
|
14
|
+
class Egg < Ingredient; end
|
15
|
+
class Milk < Ingredient; end
|
16
|
+
class Butter < Ingredient; end
|
17
|
+
|
18
|
+
class Recipe < DSLKit::BlankSlate.with(:respond_to?, :instance_exec, :inspect, /^deflect/)
|
19
|
+
include DSLKit::Deflect
|
20
|
+
|
21
|
+
def initialize(&block)
|
22
|
+
@ingredients = []
|
23
|
+
deflector = Deflector.new do |number, id, name|
|
24
|
+
if unit = Unit.unit(name, number)
|
25
|
+
unit
|
26
|
+
else
|
27
|
+
ingredient = Ingredient.ingredient(name, number)
|
28
|
+
@ingredients << ingredient
|
29
|
+
end
|
30
|
+
end
|
31
|
+
deflect_start(Numeric, :method_missing, deflector)
|
32
|
+
deflector2 = Deflector.new do |unit, id, name|
|
33
|
+
ingredient = Ingredient.ingredient(name, unit)
|
34
|
+
@ingredients << ingredient
|
35
|
+
end
|
36
|
+
deflect_start(Unit, :method_missing, deflector2)
|
37
|
+
instance_exec(&block)
|
38
|
+
ensure
|
39
|
+
deflect_stop(Numeric, :method_missing) if deflect?(Numeric, :method_missing)
|
40
|
+
deflect_stop(Unit, :method_missing) if deflect?(Unit, :method_missing)
|
41
|
+
end
|
42
|
+
|
43
|
+
attr_reader :ingredients
|
44
|
+
|
45
|
+
def to_a
|
46
|
+
@ingredients
|
47
|
+
end
|
48
|
+
alias to_ary to_a
|
49
|
+
|
50
|
+
def to_s
|
51
|
+
to_a * "\n"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class RecipeInterpreter
|
56
|
+
def recipe(&block)
|
57
|
+
Recipe.new(&block)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
recipe_source = <<EOT
|
62
|
+
pancakes = recipe do
|
63
|
+
2.cups. flour
|
64
|
+
2.5.teaspoons. baking_powder
|
65
|
+
0.5.teaspoon. salt
|
66
|
+
1. egg
|
67
|
+
1.5.cups. milk
|
68
|
+
2.tablespoons. butter
|
69
|
+
end
|
70
|
+
EOT
|
71
|
+
|
72
|
+
pancakes = RecipeInterpreter.new.interpret(recipe_source)
|
73
|
+
puts pancakes
|
74
|
+
|
75
|
+
puts
|
76
|
+
|
77
|
+
def recipe(&block)
|
78
|
+
Recipe.new(&block)
|
79
|
+
end
|
80
|
+
|
81
|
+
pancakes = eval recipe_source
|
82
|
+
puts pancakes
|
@@ -0,0 +1,99 @@
|
|
1
|
+
class Ingredient
|
2
|
+
class << self
|
3
|
+
def inherited(klass)
|
4
|
+
ingredients << klass
|
5
|
+
end
|
6
|
+
|
7
|
+
attr_accessor :ingredients
|
8
|
+
|
9
|
+
def ingredient(name, amount)
|
10
|
+
name = name.to_s.gsub(/_/, '').capitalize
|
11
|
+
if klass = ingredients.find { |n| n.to_s == name }
|
12
|
+
klass.new(amount)
|
13
|
+
else
|
14
|
+
raise "unknown ingredient #{name}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
self.ingredients = []
|
19
|
+
|
20
|
+
def initialize(amount = 1)
|
21
|
+
@amount = amount
|
22
|
+
end
|
23
|
+
|
24
|
+
def name
|
25
|
+
self.class.name.downcase
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :amount
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
"#@amount #{name}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Unit
|
36
|
+
class << self
|
37
|
+
def inherited(klass)
|
38
|
+
units << klass
|
39
|
+
end
|
40
|
+
|
41
|
+
attr_accessor :units
|
42
|
+
|
43
|
+
def unit(name, amount)
|
44
|
+
name = name.to_s.gsub(/s$/, '').capitalize
|
45
|
+
if klass = units.find { |n| n.to_s == name }
|
46
|
+
klass.new(amount)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
self.units = []
|
51
|
+
|
52
|
+
def initialize(n = 1)
|
53
|
+
@n = n
|
54
|
+
end
|
55
|
+
|
56
|
+
def name
|
57
|
+
self.class.name.downcase
|
58
|
+
end
|
59
|
+
|
60
|
+
attr_reader :n
|
61
|
+
|
62
|
+
def to_s
|
63
|
+
"#@n #{name}#{@n > 1 ? 's' : ''}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class Unit
|
68
|
+
class << self
|
69
|
+
def inherited(klass)
|
70
|
+
units << klass
|
71
|
+
end
|
72
|
+
|
73
|
+
attr_accessor :units
|
74
|
+
|
75
|
+
def unit(name, amount)
|
76
|
+
name = name.to_s.gsub(/s$/, '').capitalize
|
77
|
+
if klass = units.find { |n| n.to_s == name }
|
78
|
+
klass.new(amount)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
self.units = []
|
83
|
+
|
84
|
+
def initialize(n = 1)
|
85
|
+
@n = n
|
86
|
+
end
|
87
|
+
|
88
|
+
def name
|
89
|
+
self.class.name.downcase
|
90
|
+
end
|
91
|
+
|
92
|
+
attr_reader :n
|
93
|
+
|
94
|
+
def to_s
|
95
|
+
"#@n #{name}#{@n > 1 ? 's' : ''}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# vim: set filetype=ruby:
|
2
|
+
|
3
|
+
# Subtraction A = A - B, A >= 0 and A >= B
|
4
|
+
register.A = 10 # register names have to be uppercase
|
5
|
+
register.B = 3
|
6
|
+
|
7
|
+
label(Sub_B) { decrement B, Stop, Sub_A } # labels have to be uppercase as well
|
8
|
+
label(Sub_A) { decrement A, Stop, Sub_B }
|
9
|
+
label(Stop) { halt }
|
data/install.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rbconfig'
|
4
|
+
require 'fileutils'
|
5
|
+
include FileUtils::Verbose
|
6
|
+
|
7
|
+
include Config
|
8
|
+
|
9
|
+
src = File.join(*%w[lib dslkit])
|
10
|
+
dst = File.join(CONFIG["sitelibdir"], 'dslkit')
|
11
|
+
mkdir_p dst
|
12
|
+
for file in %w[polite.rb rude.rb]
|
13
|
+
install File.join(src, file), File.join(dst, file)
|
14
|
+
end
|
15
|
+
install File.join('lib', 'dslkit.rb'), File.join(CONFIG["sitelibdir"], file)
|
16
|
+
|
17
|
+
# vim: set et sw=4 ts=4:
|