sbyc 0.1.3 → 0.1.4

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.
@@ -1,6 +1,8 @@
1
- module TypeSystem
2
- class Error < StandardError; end
3
- class InvalidValueLiteralError < Error; end
4
- class NoSuchLiteralError < Error; end
5
- class CoercionError < Error; end
6
- end # module TypeSystem
1
+ module SByC
2
+ module TypeSystem
3
+ class Error < StandardError; end
4
+ class InvalidValueLiteralError < Error; end
5
+ class NoSuchLiteralError < Error; end
6
+ class CoercionError < Error; end
7
+ end # module TypeSystem
8
+ end # module SByC
@@ -1,135 +1,151 @@
1
1
  require 'date'
2
2
  require 'time'
3
- module TypeSystem
4
- #
5
- # Implements a basic TypeSystem that mimics Ruby's type system.
6
- #
7
- module Ruby
3
+ module SByC
4
+ module TypeSystem
5
+ #
6
+ # Implements a basic TypeSystem that mimics Ruby's type system.
7
+ #
8
+ module Ruby
8
9
 
9
- # Methods
10
- module Methods
10
+ # Marker module for ruby Boolean values
11
+ module Boolean
12
+
13
+ # Returns true if value is a boolean
14
+ def self.===(value)
15
+ (value == true) or (value == false)
16
+ end
11
17
 
12
- # Ruby classes for which value.inspect will work for returning
13
- # a valid literal
14
- SAFE_LITERAL_CLASSES = {}
15
- [NilClass, TrueClass, FalseClass,
16
- Fixnum, Bignum,
17
- Float,
18
- String,
19
- Symbol,
20
- Class,
21
- Module,
22
- Regexp].each{|c| SAFE_LITERAL_CLASSES[c] = true}
23
-
24
- #
25
- # Returns value.class
26
- #
27
- # @see TypeSystem::Contract#type_of
28
- #
29
- def type_of(value)
30
- value.class
31
18
  end
19
+
20
+ # Methods
21
+ module Methods
22
+
23
+ # Ruby classes for which value.inspect will work for returning
24
+ # a valid literal
25
+ SAFE_LITERAL_CLASSES = {}
26
+ [NilClass, TrueClass, FalseClass,
27
+ Fixnum, Bignum,
28
+ Float,
29
+ String,
30
+ Symbol,
31
+ Class,
32
+ Module,
33
+ Regexp].each{|c| SAFE_LITERAL_CLASSES[c] = true}
34
+
35
+ #
36
+ # Returns value.class
37
+ #
38
+ # @see TypeSystem::Contract#type_of
39
+ #
40
+ def type_of(value)
41
+ value.class
42
+ end
32
43
 
33
- #
34
- # Converts _value_ to a ruby literal and returns it.
35
- #
36
- # Behavior of the algorithm when th value cannot be recognized depends
37
- # on the :fallback option:
38
- # * when set to :fail, it raises a NoSuchLiteralError
39
- # * when set to :inspect, it returns <code>value.inspect</code>
40
- # * when set to :marshal it uses <code>Marshal::dump(value)</code>
41
- # * when set to :json it uses <code>JSON::generate(value)</code>
42
- #
43
- # @see TypeSystem::Contract#to_literal(value)
44
- #
45
- def to_literal(value, options = {:fallback => :fail})
46
- if value.respond_to?(:to_ruby_literal)
47
- value.to_ruby_literal
48
- elsif value == (1.0/0)
49
- return '(1.0/0)'
50
- elsif value == -(1.0/0)
51
- return '(-1.0/0)'
52
- elsif SAFE_LITERAL_CLASSES.key?(type_of(value))
53
- value.inspect
54
- elsif value.kind_of?(Array)
55
- "[" + value.collect{|v| to_literal(v, options)}.join(', ') + "]"
56
- elsif value.kind_of?(Hash)
57
- "{" + value.collect{|pair| "#{to_literal(pair[0], options)} => #{to_literal(pair[1], options)}"}.join(', ') + "}"
58
- elsif value.kind_of?(Date)
59
- "Date::parse(#{value.to_s.inspect})"
60
- elsif value.kind_of?(Time)
61
- "Time::parse(#{value.inspect.inspect})"
62
- else
63
- case options[:fallback]
64
- when :inspect
65
- value.inspect
66
- when :marshal
67
- "Marshal::load(#{Marshal::dump(value).inspect})"
68
- when :json
69
- require 'json'
70
- JSON::generate(value)
71
- when :fail, nil
72
- raise NoSuchLiteralError, "Unable to convert #{value.inspect} to a ruby literal"
73
- else
74
- raise ArgumentError, "Invalid fallback option #{options[:fallback]}"
44
+ #
45
+ # Converts _value_ to a ruby literal and returns it.
46
+ #
47
+ # Behavior of the algorithm when th value cannot be recognized depends
48
+ # on the :fallback option:
49
+ # * when set to :fail, it raises a NoSuchLiteralError
50
+ # * when set to :inspect, it returns <code>value.inspect</code>
51
+ # * when set to :marshal it uses <code>Marshal::dump(value)</code>
52
+ # * when set to :json it uses <code>JSON::generate(value)</code>
53
+ #
54
+ # @see TypeSystem::Contract#to_literal(value)
55
+ #
56
+ def to_literal(value, options = {:fallback => :fail})
57
+ if value.respond_to?(:to_ruby_literal)
58
+ value.to_ruby_literal
59
+ elsif value == (1.0/0)
60
+ return '(1.0/0)'
61
+ elsif value == -(1.0/0)
62
+ return '(-1.0/0)'
63
+ elsif SAFE_LITERAL_CLASSES.key?(type_of(value))
64
+ value.inspect
65
+ elsif value.kind_of?(Array)
66
+ "[" + value.collect{|v| to_literal(v, options)}.join(', ') + "]"
67
+ elsif value.kind_of?(Hash)
68
+ "{" + value.collect{|pair| "#{to_literal(pair[0], options)} => #{to_literal(pair[1], options)}"}.join(', ') + "}"
69
+ elsif value.kind_of?(Date)
70
+ "Date::parse(#{value.to_s.inspect})"
71
+ elsif value.kind_of?(Time)
72
+ "Time::parse(#{value.inspect.inspect})"
73
+ else
74
+ case options[:fallback]
75
+ when :inspect
76
+ value.inspect
77
+ when :marshal
78
+ "Marshal::load(#{Marshal::dump(value).inspect})"
79
+ when :json
80
+ require 'json'
81
+ JSON::generate(value)
82
+ when :fail, nil
83
+ raise NoSuchLiteralError, "Unable to convert #{value.inspect} to a ruby literal"
84
+ else
85
+ raise ArgumentError, "Invalid fallback option #{options[:fallback]}"
86
+ end
75
87
  end
76
88
  end
77
- end
78
89
 
79
- #
80
- # Returns result of Kernel.eval(str)
81
- #
82
- # @see TypeSystem::Contract#parse_literal(str)
83
- #
84
- def parse_literal(str)
85
- Kernel.eval(str)
86
- rescue Exception => ex
87
- raise TypeSystem::InvalidValueLiteralError, "Invalid ruby value literal #{str.inspect}", ex.backtrace
88
- end
90
+ #
91
+ # Returns result of Kernel.eval(str)
92
+ #
93
+ # @see TypeSystem::Contract#parse_literal(str)
94
+ #
95
+ def parse_literal(str)
96
+ Kernel.eval(str)
97
+ rescue Exception => ex
98
+ raise TypeSystem::InvalidValueLiteralError, "Invalid ruby value literal #{str.inspect}", ex.backtrace
99
+ end
89
100
 
90
- #
91
- # Coerces a string to a given class.
92
- #
93
- # @see TypeSystem::Contract#coerce(str)
94
- #
95
- def coerce(str, clazz)
96
- if clazz == NilClass
97
- return nil if str.empty? or str == "nil"
98
- elsif clazz == TrueClass
99
- return true if str == "true"
100
- elsif clazz == FalseClass
101
- return false if str == "false"
102
- elsif [Fixnum, Bignum, Integer].include?(clazz)
103
- if str =~ /^[-+]?[0-9]+$/
104
- i = str.to_i
105
- return i if i.kind_of?(clazz)
101
+ #
102
+ # Coerces a string to a given class.
103
+ #
104
+ # @see TypeSystem::Contract#coerce(str)
105
+ #
106
+ def coerce(str, clazz)
107
+ return str if str.kind_of?(clazz)
108
+ if clazz == NilClass
109
+ return nil if str.empty? or str == "nil"
110
+ elsif clazz == Ruby::Boolean
111
+ return true if str.to_s == "true"
112
+ return false if str.to_s == "false"
113
+ elsif clazz == TrueClass
114
+ return true if str == "true"
115
+ elsif clazz == FalseClass
116
+ return false if str == "false"
117
+ elsif [Fixnum, Bignum, Integer].include?(clazz)
118
+ if str =~ /^[-+]?[0-9]+$/
119
+ i = str.to_i
120
+ return i if i.kind_of?(clazz)
121
+ end
122
+ elsif clazz == Float
123
+ if str =~ /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/
124
+ return str.to_f
125
+ end
126
+ elsif clazz == String
127
+ return str
128
+ elsif clazz == Symbol
129
+ return str.to_sym
130
+ elsif clazz == Class or clazz == Module
131
+ parts, current = str.split("::"), Kernel
132
+ parts.each{|part| current = current.const_get(part.to_sym)}
133
+ return current if current.kind_of?(clazz)
134
+ elsif clazz == Regexp
135
+ return Regexp::compile(str)
136
+ elsif clazz.respond_to?(:parse)
137
+ return clazz.parse(str)
106
138
  end
107
- elsif clazz == Float
108
- if str =~ /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/
109
- return str.to_f
110
- end
111
- elsif clazz == String
112
- return str
113
- elsif clazz == Symbol
114
- return str.to_sym
115
- elsif clazz == Class or clazz == Module
116
- parts, current = str.split("::"), Kernel
117
- parts.each{|part| current = current.const_get(part.to_sym)}
118
- return current if current.kind_of?(clazz)
119
- elsif clazz == Regexp
120
- return Regexp::compile(str)
121
- elsif clazz.respond_to?(:parse)
122
- return clazz.parse(str)
139
+ raise TypeSystem::CoercionError, "Unable to coerce #{str} to a #{clazz}"
140
+ rescue TypeSystem::CoercionError
141
+ raise
142
+ rescue StandardError => ex
143
+ raise TypeSystem::CoercionError, "Unable to coerce #{str} to a #{clazz}: #{ex.message}"
123
144
  end
124
- raise TypeSystem::CoercionError, "Unable to coerce #{str} to a #{clazz}"
125
- rescue TypeSystem::CoercionError
126
- raise
127
- rescue StandardError => ex
128
- raise TypeSystem::CoercionError, "Unable to coerce #{str} to a #{clazz}: #{ex.message}"
129
- end
130
145
 
131
- end # module Methods
132
- extend(Methods)
146
+ end # module Methods
147
+ extend(Methods)
133
148
 
134
- end # class Ruby
135
- end # module TypeSystem
149
+ end # class Ruby
150
+ end # module TypeSystem
151
+ end # module SByC
@@ -2,7 +2,7 @@ $LOAD_PATH.unshift(File.expand_path('../', __FILE__))
2
2
  $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
3
3
 
4
4
  require 'rubygems'
5
- require 'sbyc'
5
+ require 'sbyc/shortspaces'
6
6
  require 'spec'
7
7
  require 'spec/autorun'
8
8
 
@@ -0,0 +1,14 @@
1
+ require File.expand_path('../../../../../spec_helper', __FILE__)
2
+ require 'sbyc/type_system/ruby'
3
+
4
+ describe "TypeSystem::Ruby::Boolean" do
5
+
6
+ subject{ TypeSystem::Ruby::Boolean }
7
+
8
+ it { should === true }
9
+
10
+ it { should === false }
11
+
12
+ it { should_not === nil }
13
+
14
+ end
@@ -9,6 +9,7 @@ describe "TypeSystem::Ruby#coerce" do
9
9
 
10
10
  safe_representors = {
11
11
  NilClass => [ nil ],
12
+ ::SByC::TypeSystem::Ruby::Boolean => [ true, false ],
12
13
  TrueClass => [ true ],
13
14
  FalseClass => [ false ],
14
15
  Fixnum => [ -(2**(0.size * 8 - 2)), -1, 0, 1, 10, (2**(0.size * 8 - 2) - 1)],
@@ -23,12 +24,20 @@ describe "TypeSystem::Ruby#coerce" do
23
24
 
24
25
  safe_representors.each_pair do |clazz, values|
25
26
  values.each do |value|
26
- describe "When coercing #{value} to a #{clazz}" do
27
+
28
+ describe "When coercing '#{value} to a #{clazz}" do
29
+
27
30
  it "should return #{value}" do
28
31
  str = value.kind_of?(Regexp) ? value.inspect[1..-2] : value.to_s
29
32
  TypeSystem::Ruby::coerce(str, clazz).should == value
30
33
  end
34
+
35
+ it "should be friendly" do
36
+ TypeSystem::Ruby::coerce(value, clazz).should == value
37
+ end
38
+
31
39
  end
40
+
32
41
  end
33
42
  end
34
43
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sbyc
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 3
10
- version: 0.1.3
9
+ - 4
10
+ version: 0.1.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Bernard Lambeau
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-07-19 00:00:00 +02:00
18
+ date: 2010-09-08 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -51,6 +51,7 @@ files:
51
51
  - lib/sbyc/codetree/rewriting/match.rb
52
52
  - lib/sbyc/codetree/rewriting.rb
53
53
  - lib/sbyc/codetree.rb
54
+ - lib/sbyc/shortspaces.rb
54
55
  - lib/sbyc/type_system/contract.rb
55
56
  - lib/sbyc/type_system/errors.rb
56
57
  - lib/sbyc/type_system/ruby.rb
@@ -113,6 +114,7 @@ files:
113
114
  - test/spec/unit/sbyc/codetree/rewriting/match/apply.spec
114
115
  - test/spec/unit/sbyc/codetree/rewriting/match/coerce.spec
115
116
  - test/spec/unit/sbyc/codetree/rewriting/match/matches.spec
117
+ - test/spec/unit/sbyc/type_system/ruby/boolean.spec
116
118
  - test/spec/unit/sbyc/type_system/ruby/coerce.spec
117
119
  - test/spec/unit/sbyc/type_system/ruby/parse_literal.spec
118
120
  - test/spec/unit/sbyc/type_system/ruby/to_literal.spec