Compare commits
2 commits
395406d516
...
09c44b684d
Author | SHA1 | Date | |
---|---|---|---|
|
09c44b684d | ||
|
ac7cab6490 |
5 changed files with 103 additions and 9 deletions
|
@ -95,11 +95,11 @@ module Rpl
|
||||||
|
|
||||||
# STRING
|
# STRING
|
||||||
add( '->str', proc { |stack| Rpl::Core.to_string( stack ) } )
|
add( '->str', proc { |stack| Rpl::Core.to_string( stack ) } )
|
||||||
add( 'str->', proc { |stack| Rpl::Core.__todo( stack ) } ) # convert a string into an object
|
add( 'str->', proc { |stack| Rpl::Core.from_string( stack ) } )
|
||||||
add( 'chr', proc { |stack| Rpl::Core.__todo( stack ) } ) # convert ASCII character code in stack level 1 into a string
|
add( 'chr', proc { |stack| Rpl::Core.chr( stack ) } )
|
||||||
add( 'num', proc { |stack| Rpl::Core.__todo( stack ) } ) # return ASCII code of the first character of the string in stack level 1 as a real number
|
add( 'num', proc { |stack| Rpl::Core.num( stack ) } )
|
||||||
add( 'size', proc { |stack| Rpl::Core.size( stack ) } )
|
add( 'size', proc { |stack| Rpl::Core.size( stack ) } )
|
||||||
add( 'pos', proc { |stack| Rpl::Core.__todo( stack ) } ) # seach for the string in level 1 within the string in level 2
|
add( 'pos', proc { |stack| Rpl::Core.pos( stack ) } )
|
||||||
add( 'sub', proc { |stack| Rpl::Core.sub( stack ) } )
|
add( 'sub', proc { |stack| Rpl::Core.sub( stack ) } )
|
||||||
|
|
||||||
# BRANCH
|
# BRANCH
|
||||||
|
|
|
@ -4,26 +4,60 @@ module Rpl
|
||||||
|
|
||||||
# convert an object into a string
|
# convert an object into a string
|
||||||
def to_string( stack )
|
def to_string( stack )
|
||||||
stack, args = Rpl::Core.stack_extract( stack, :any )
|
stack, args = Rpl::Core.stack_extract( stack, [:any] )
|
||||||
|
|
||||||
stack << { type: :string,
|
stack << { type: :string,
|
||||||
value: args[0][:value].to_s }
|
value: args[0][:value].to_s }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# convert a string into an object
|
||||||
|
def from_string( stack )
|
||||||
|
stack, args = Rpl::Core.stack_extract( stack, [%i[string]] )
|
||||||
|
|
||||||
|
parsed_input = Rpl::Parser.new.parse_input( args[0][:value] )
|
||||||
|
|
||||||
|
stack + parsed_input
|
||||||
|
end
|
||||||
|
|
||||||
|
# convert ASCII character code in stack level 1 into a string
|
||||||
|
def chr( stack )
|
||||||
|
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric]] )
|
||||||
|
|
||||||
|
stack << { type: :string,
|
||||||
|
value: args[0][:value].chr }
|
||||||
|
end
|
||||||
|
|
||||||
|
# return ASCII code of the first character of the string in stack level 1 as a real number
|
||||||
|
def num( stack )
|
||||||
|
stack, args = Rpl::Core.stack_extract( stack, [%i[string]] )
|
||||||
|
|
||||||
|
stack << { type: :numeric,
|
||||||
|
base: 10,
|
||||||
|
value: args[0][:value].ord }
|
||||||
|
end
|
||||||
|
|
||||||
# return the length of the string
|
# return the length of the string
|
||||||
def size( stack )
|
def size( stack )
|
||||||
stack, args = Rpl::Core.stack_extract( stack, %i[string] )
|
stack, args = Rpl::Core.stack_extract( stack, [%i[string]] )
|
||||||
|
|
||||||
stack << { type: :numeric,
|
stack << { type: :numeric,
|
||||||
base: 10,
|
base: 10,
|
||||||
value: args[0][:value].length }
|
value: args[0][:value].length }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# search for the string in level 1 within the string in level 2
|
||||||
|
def pos( stack )
|
||||||
|
stack, args = Rpl::Core.stack_extract( stack, [%i[string], %i[string]] )
|
||||||
|
|
||||||
|
stack << { type: :numeric,
|
||||||
|
base: 10,
|
||||||
|
value: args[1][:value].index( args[0][:value] ) }
|
||||||
|
end
|
||||||
|
|
||||||
# return a substring of the string in level 3
|
# return a substring of the string in level 3
|
||||||
def sub( stack )
|
def sub( stack )
|
||||||
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric], %i[string]] )
|
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric], %i[string]] )
|
||||||
|
|
||||||
puts "#{args[0][:value]}[#{args[1][:value]}..#{args[2][:value]}]"
|
|
||||||
stack << { type: :string,
|
stack << { type: :string,
|
||||||
value: args[2][:value][args[1][:value]..args[0][:value]] }
|
value: args[2][:value][args[1][:value]..args[0][:value]] }
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,13 +37,13 @@ module Rpl
|
||||||
|
|
||||||
regrouped_input << elt
|
regrouped_input << elt
|
||||||
|
|
||||||
regrouping = string_delimiters.odd? || (opened_programs > closed_programs )
|
|
||||||
|
|
||||||
if elt[-1] == '»'
|
if elt[-1] == '»'
|
||||||
closed_programs += 1
|
closed_programs += 1
|
||||||
elt.gsub!( '»', ' »') if elt.length > 1 && elt[-2] != ' '
|
elt.gsub!( '»', ' »') if elt.length > 1 && elt[-2] != ' '
|
||||||
end
|
end
|
||||||
string_delimiters += 1 if elt.length > 1 && elt[-1] == '"'
|
string_delimiters += 1 if elt.length > 1 && elt[-1] == '"'
|
||||||
|
|
||||||
|
regrouping = string_delimiters.odd? || (opened_programs > closed_programs )
|
||||||
end
|
end
|
||||||
|
|
||||||
# 2. parse
|
# 2. parse
|
||||||
|
|
|
@ -4,8 +4,59 @@
|
||||||
require 'test/unit'
|
require 'test/unit'
|
||||||
|
|
||||||
require_relative '../lib/core'
|
require_relative '../lib/core'
|
||||||
|
require_relative '../lib/parser'
|
||||||
|
|
||||||
class TestLanguageString < Test::Unit::TestCase
|
class TestLanguageString < Test::Unit::TestCase
|
||||||
|
def test_to_string
|
||||||
|
stack = Rpl::Core.to_string( [{ value: 2, type: :numeric, base: 10 }] )
|
||||||
|
|
||||||
|
assert_equal [{ value: '2', type: :string }],
|
||||||
|
stack
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_from_string
|
||||||
|
stack = Rpl::Core.from_string( [{ value: '2', type: :string }] )
|
||||||
|
|
||||||
|
assert_equal [{ value: 2, type: :numeric, base: 10 }],
|
||||||
|
stack
|
||||||
|
|
||||||
|
stack = Rpl::Core.from_string( [{ value: "« 2 dup * » 'carré' sto", type: :string }] )
|
||||||
|
|
||||||
|
assert_equal [{ value: '« 2 dup * »', type: :program },
|
||||||
|
{ value: "'carré'", type: :name },
|
||||||
|
{ value: 'sto', type: :word }],
|
||||||
|
stack
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_chr
|
||||||
|
stack = Rpl::Core.chr( [{ value: 71, type: :numeric, base: 10 }] )
|
||||||
|
|
||||||
|
assert_equal [{ value: 'G', type: :string }],
|
||||||
|
stack
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_num
|
||||||
|
stack = Rpl::Core.num( [{ value: 'G', type: :string }] )
|
||||||
|
|
||||||
|
assert_equal [{ value: 71, type: :numeric, base: 10 }],
|
||||||
|
stack
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_size
|
||||||
|
stack = Rpl::Core.size( [{ value: 'test', type: :string }] )
|
||||||
|
|
||||||
|
assert_equal [{ value: 4, type: :numeric, base: 10 }],
|
||||||
|
stack
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_pos
|
||||||
|
stack = Rpl::Core.pos( [{ value: 'test of POS', type: :string },
|
||||||
|
{ value: 'of', type: :string }] )
|
||||||
|
|
||||||
|
assert_equal [{ value: 5, type: :numeric, base: 10 }],
|
||||||
|
stack
|
||||||
|
end
|
||||||
|
|
||||||
def test_sub
|
def test_sub
|
||||||
stack = Rpl::Core.sub( [{ value: 'test', type: :string },
|
stack = Rpl::Core.sub( [{ value: 'test', type: :string },
|
||||||
{ value: 1, type: :numeric, base: 10 },
|
{ value: 1, type: :numeric, base: 10 },
|
||||||
|
|
|
@ -74,4 +74,13 @@ class TestParser < Test::Unit::TestCase
|
||||||
result = Rpl::Parser.new.parse_input( '4 "test"' )
|
result = Rpl::Parser.new.parse_input( '4 "test"' )
|
||||||
assert_equal [{ value: 4, type: :numeric, base: 10 }, { value: '"test"', type: :string }], result
|
assert_equal [{ value: 4, type: :numeric, base: 10 }, { value: '"test"', type: :string }], result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_program_name
|
||||||
|
result = Rpl::Parser.new.parse_input( "« 2 dup * » 'carré' sto" )
|
||||||
|
|
||||||
|
assert_equal [{ value: '« 2 dup * »', type: :program },
|
||||||
|
{ value: "'carré'", type: :name },
|
||||||
|
{ value: 'sto', type: :word }],
|
||||||
|
result
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue