dslkit 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|