[WIP] start to implement types as Objects
This commit is contained in:
parent
148366914e
commit
c89c832b96
2 changed files with 232 additions and 0 deletions
184
lib/rpl/types.rb
Normal file
184
lib/rpl/types.rb
Normal file
|
@ -0,0 +1,184 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# :boolean
|
||||
class RplBoolean
|
||||
attr_accessor :value
|
||||
|
||||
def initialize( value )
|
||||
raise RplTypeError unless self.class.can_parse?( value )
|
||||
|
||||
@value = if value.is_a?( String )
|
||||
value.downcase == 'true'
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
def to_s
|
||||
@value.to_s
|
||||
end
|
||||
|
||||
def self.can_parse?( value )
|
||||
return %w[true false].include?( value.downcase ) if value.is_a?( String )
|
||||
|
||||
%w[TrueClass FalseClass].include?( value.class.to_s )
|
||||
end
|
||||
end
|
||||
|
||||
# :list
|
||||
class RplList
|
||||
attr_accessor :value
|
||||
|
||||
def initialize( value )
|
||||
raise RplTypeError unless self.class.can_parse?( value )
|
||||
|
||||
# we systematicalyl trim enclosing { }
|
||||
@value = value[2..-3] # TODO: parse each element
|
||||
end
|
||||
|
||||
def to_s
|
||||
"{ #{@value.map(&:to_s).join(' ')} }"
|
||||
end
|
||||
|
||||
def self.can_parse?( value )
|
||||
value[0] == '{' && value[-1] == '}'
|
||||
end
|
||||
end
|
||||
|
||||
# :name
|
||||
class RplName
|
||||
attr_accessor :value
|
||||
|
||||
def initialize( value )
|
||||
raise RplTypeError unless self.class.can_parse?( value )
|
||||
|
||||
# we systematicalyl trim enclosing '
|
||||
@value = value[1..-2]
|
||||
end
|
||||
|
||||
def to_s
|
||||
"'#{@value}'"
|
||||
end
|
||||
|
||||
def self.can_parse?( value )
|
||||
value[0] == "'" && value[-1] == "'"
|
||||
end
|
||||
end
|
||||
|
||||
# :numeric
|
||||
class RplNumeric
|
||||
attr_accessor :value
|
||||
|
||||
def initialize( value, base = 10 )
|
||||
raise RplTypeError unless self.class.can_parse?( value )
|
||||
|
||||
@base = base
|
||||
@value = value
|
||||
|
||||
underscore_position = @value.index('_')
|
||||
|
||||
if @value[0] == '0' && ( %w[b o x].include?( @value[1] ) || !underscore_position.nil? )
|
||||
if @value[1] == 'x'
|
||||
@base = 16
|
||||
elsif @value[1] == 'b'
|
||||
@base = 2
|
||||
elsif @value[1] == 'o'
|
||||
@base = 8
|
||||
@value = @value[2..-1]
|
||||
elsif !underscore_position.nil?
|
||||
@base = @value[1..(underscore_position - 1)].to_i
|
||||
@value = @value[(underscore_position + 1)..-1]
|
||||
end
|
||||
end
|
||||
|
||||
@value = @value.to_i( @base ) unless @base == 10
|
||||
@value = BigDecimal( @value, @precision ) # FIXME: how to get @precision?
|
||||
end
|
||||
|
||||
def to_s
|
||||
prefix = case @base
|
||||
when 2
|
||||
'0b'
|
||||
when 8
|
||||
'0o'
|
||||
when 10
|
||||
''
|
||||
when 16
|
||||
'0x'
|
||||
else
|
||||
"0#{@base}_"
|
||||
end
|
||||
|
||||
if @value.infinite?
|
||||
suffix = @value.infinite?.positive? ? '∞' : '-∞'
|
||||
elsif @value.nan?
|
||||
suffix = '<NaN>'
|
||||
else
|
||||
suffix = if @value.to_i == @value
|
||||
@value.to_i
|
||||
else
|
||||
@value.to_s('F')
|
||||
end
|
||||
suffix = @value.to_s( @base ) unless @base == 10
|
||||
end
|
||||
|
||||
"#{prefix}#{suffix}"
|
||||
end
|
||||
|
||||
def self.can_parse?( value )
|
||||
# FIXME
|
||||
!Float( value ).nil?
|
||||
rescue ArgumentError
|
||||
begin
|
||||
!Integer( value ).nil?
|
||||
rescue ArgumentError
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def self.infer_resulting_base( numerics )
|
||||
10 if numerics.length.zero?
|
||||
|
||||
numerics.last.base
|
||||
end
|
||||
end
|
||||
|
||||
# :string
|
||||
class RplString
|
||||
attr_accessor :value
|
||||
|
||||
def initialize( value )
|
||||
raise RplTypeError unless self.class.can_parse?( value )
|
||||
|
||||
# we systematicalyl trim enclosing "
|
||||
@value = value[1..-2]
|
||||
end
|
||||
|
||||
def to_s
|
||||
"\"#{@value}\""
|
||||
end
|
||||
|
||||
def self.can_parse?( value )
|
||||
value[0] == '"' && value[-1] == '"'
|
||||
end
|
||||
end
|
||||
|
||||
# :program
|
||||
class RplProgram
|
||||
attr_accessor :value
|
||||
|
||||
def initialize( value )
|
||||
raise RplTypeError unless self.class.can_parse?( value )
|
||||
|
||||
# we systematicalyl trim enclosing « »
|
||||
@value = value[2..-3]
|
||||
end
|
||||
|
||||
def to_s
|
||||
"« #{@value} »"
|
||||
end
|
||||
|
||||
def self.can_parse?( value )
|
||||
value[0] == '«' && value[-1] == '»'
|
||||
end
|
||||
end
|
48
spec/types_spec.rb
Normal file
48
spec/types_spec.rb
Normal file
|
@ -0,0 +1,48 @@
|
|||
# coding: utf-8
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'minitest/autorun'
|
||||
|
||||
require 'rpl/types'
|
||||
|
||||
class TestTypes < MiniTest::Test
|
||||
def test_boolean
|
||||
assert_equal true, RplBoolean.can_parse?( true )
|
||||
assert_equal true, RplBoolean.can_parse?( false )
|
||||
assert_equal true, RplBoolean.can_parse?( 'true' )
|
||||
assert_equal true, RplBoolean.can_parse?( 'false' )
|
||||
assert_equal true, RplBoolean.can_parse?( 'TRUE' )
|
||||
assert_equal true, RplBoolean.can_parse?( 'FALSE' )
|
||||
assert_equal false, RplBoolean.can_parse?( 'prout' )
|
||||
assert_equal false, RplBoolean.can_parse?( 1 )
|
||||
|
||||
assert_equal RplBoolean, RplBoolean.new( true ).class
|
||||
assert_equal RplBoolean, RplBoolean.new( false ).class
|
||||
assert_equal RplBoolean, RplBoolean.new( 'true' ).class
|
||||
assert_equal RplBoolean, RplBoolean.new( 'false' ).class
|
||||
assert_equal RplBoolean, RplBoolean.new( 'TRUE' ).class
|
||||
assert_equal RplBoolean, RplBoolean.new( 'FALSE' ).class
|
||||
|
||||
assert_equal true, RplBoolean.new( true ).value
|
||||
assert_equal false, RplBoolean.new( false ).value
|
||||
assert_equal true, RplBoolean.new( 'true' ).value
|
||||
assert_equal false, RplBoolean.new( 'false' ).value
|
||||
assert_equal true, RplBoolean.new( 'TRUE' ).value
|
||||
assert_equal false, RplBoolean.new( 'FALSE' ).value
|
||||
end
|
||||
|
||||
def test_name
|
||||
end
|
||||
|
||||
def test_string
|
||||
end
|
||||
|
||||
def test_program
|
||||
end
|
||||
|
||||
def test_list
|
||||
end
|
||||
|
||||
def test_numeric
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue