Compare commits

...

2 commits

Author SHA1 Message Date
Gwenhael Le Moine
09c44b684d
implement string words 2021-11-24 15:04:56 +01:00
Gwenhael Le Moine
ac7cab6490
fix parsing error on program-closer » 2021-11-24 15:04:27 +01:00
5 changed files with 103 additions and 9 deletions

View file

@ -95,11 +95,11 @@ module Rpl
# STRING
add( '->str', proc { |stack| Rpl::Core.to_string( stack ) } )
add( 'str->', proc { |stack| Rpl::Core.__todo( stack ) } ) # convert a string into an object
add( 'chr', proc { |stack| Rpl::Core.__todo( stack ) } ) # convert ASCII character code in stack level 1 into a string
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( 'str->', proc { |stack| Rpl::Core.from_string( stack ) } )
add( 'chr', proc { |stack| Rpl::Core.chr( stack ) } )
add( 'num', proc { |stack| Rpl::Core.num( 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 ) } )
# BRANCH

View file

@ -4,26 +4,60 @@ module Rpl
# convert an object into a string
def to_string( stack )
stack, args = Rpl::Core.stack_extract( stack, :any )
stack, args = Rpl::Core.stack_extract( stack, [:any] )
stack << { type: :string,
value: args[0][:value].to_s }
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
def size( stack )
stack, args = Rpl::Core.stack_extract( stack, %i[string] )
stack, args = Rpl::Core.stack_extract( stack, [%i[string]] )
stack << { type: :numeric,
base: 10,
value: args[0][:value].length }
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
def sub( stack )
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,
value: args[2][:value][args[1][:value]..args[0][:value]] }
end

View file

@ -37,13 +37,13 @@ module Rpl
regrouped_input << elt
regrouping = string_delimiters.odd? || (opened_programs > closed_programs )
if elt[-1] == '»'
closed_programs += 1
elt.gsub!( '»', ' »') if elt.length > 1 && elt[-2] != ' '
end
string_delimiters += 1 if elt.length > 1 && elt[-1] == '"'
regrouping = string_delimiters.odd? || (opened_programs > closed_programs )
end
# 2. parse

View file

@ -4,8 +4,59 @@
require 'test/unit'
require_relative '../lib/core'
require_relative '../lib/parser'
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
stack = Rpl::Core.sub( [{ value: 'test', type: :string },
{ value: 1, type: :numeric, base: 10 },

View file

@ -74,4 +74,13 @@ class TestParser < Test::Unit::TestCase
result = Rpl::Parser.new.parse_input( '4 "test"' )
assert_equal [{ value: 4, type: :numeric, base: 10 }, { value: '"test"', type: :string }], result
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