From 8c5657db42918014ab5fd63078cde9f47bd4a7cb Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Tue, 8 Feb 2022 15:45:36 +0100 Subject: [PATCH] big refactoring --- language.rb | 522 ++++++++++++++++++++----------- lib/core.rb | 71 ++--- lib/core/branch.rb | 11 +- lib/core/filesystem.rb | 9 +- lib/core/list.rb | 6 +- lib/core/mode.rb | 8 +- lib/core/operations.rb | 91 +++--- lib/core/program.rb | 13 +- lib/core/stack.rb | 49 +-- lib/core/store.rb | 48 +-- lib/core/string.rb | 20 +- lib/core/test.rb | 20 +- lib/core/trig.rb | 55 +--- lib/dictionary.rb | 5 +- lib/parser.rb | 146 +++++---- lib/runner.rb | 38 ++- repl.rb | 2 +- spec/core_spec.rb | 4 +- spec/language_filesystem_spec.rb | 4 +- spec/language_store_spec.rb | 3 +- spec/language_trig_spec.rb | 10 +- spec/parser_spec.rb | 48 +-- 22 files changed, 634 insertions(+), 549 deletions(-) diff --git a/language.rb b/language.rb index 6dec1d5..716c8f8 100644 --- a/language.rb +++ b/language.rb @@ -12,224 +12,394 @@ module Rpl def initialize( stack = [] ) @stack = stack @dictionary = Rpl::Lang::Dictionary.new - @parser = Rpl::Lang::Parser.new - @runner = Rpl::Lang::Runner.new load_core end def load_core # GENERAL - @dictionary.add( 'nop', proc { |stack, dictionary| Rpl::Lang::Core.nop( stack, dictionary ) } ) - # @dictionary.add( 'help', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # this help message - # @dictionary.add( 'quit', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # quit software - # @dictionary.add( 'version', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # show rpn version - # @dictionary.add( 'uname', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # show rpn complete identification string - # @dictionary.add( 'history', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # see commands history - @dictionary.add( '__ppstack', proc { |stack, dictionary| Rpl::Lang::Core.__pp_stack( stack, dictionary ) } ) + @dictionary.add( 'nop', + proc { |stack, dictionary| Rpl::Lang::Core.nop( stack, dictionary ) } ) + # @dictionary.add( 'help', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # this help message + # @dictionary.add( 'quit', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # quit software + # @dictionary.add( 'version', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # show rpn version + # @dictionary.add( 'uname', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # show rpn complete identification string + # @dictionary.add( 'history', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # see commands history + @dictionary.add( '__ppstack', + proc { |stack, dictionary| Rpl::Lang.__pp_stack( stack, dictionary ) } ) # STACK - @dictionary.add( 'swap', proc { |stack, dictionary| Rpl::Lang::Core.swap( stack, dictionary ) } ) - @dictionary.add( 'drop', proc { |stack, dictionary| Rpl::Lang::Core.drop( stack, dictionary ) } ) - @dictionary.add( 'drop2', proc { |stack, dictionary| Rpl::Lang::Core.drop2( stack, dictionary ) } ) - @dictionary.add( 'dropn', proc { |stack, dictionary| Rpl::Lang::Core.dropn( stack, dictionary ) } ) - @dictionary.add( 'del', proc { |stack, dictionary| Rpl::Lang::Core.del( stack, dictionary ) } ) - @dictionary.add( 'rot', proc { |stack, dictionary| Rpl::Lang::Core.rot( stack, dictionary ) } ) - @dictionary.add( 'dup', proc { |stack, dictionary| Rpl::Lang::Core.dup( stack, dictionary ) } ) - @dictionary.add( 'dup2', proc { |stack, dictionary| Rpl::Lang::Core.dup2( stack, dictionary ) } ) - @dictionary.add( 'dupn', proc { |stack, dictionary| Rpl::Lang::Core.dupn( stack, dictionary ) } ) - @dictionary.add( 'pick', proc { |stack, dictionary| Rpl::Lang::Core.pick( stack, dictionary ) } ) - @dictionary.add( 'depth', proc { |stack, dictionary| Rpl::Lang::Core.depth( stack, dictionary ) } ) - @dictionary.add( 'roll', proc { |stack, dictionary| Rpl::Lang::Core.roll( stack, dictionary ) } ) - @dictionary.add( 'rolld', proc { |stack, dictionary| Rpl::Lang::Core.rolld( stack, dictionary ) } ) - @dictionary.add( 'over', proc { |stack, dictionary| Rpl::Lang::Core.over( stack, dictionary ) } ) + @dictionary.add( 'swap', + proc { |stack, dictionary| Rpl::Lang::Core.swap( stack, dictionary ) } ) + @dictionary.add( 'drop', + proc { |stack, dictionary| Rpl::Lang::Core.drop( stack, dictionary ) } ) + @dictionary.add( 'drop2', + proc { |stack, dictionary| Rpl::Lang::Core.drop2( stack, dictionary ) } ) + @dictionary.add( 'dropn', + proc { |stack, dictionary| Rpl::Lang::Core.dropn( stack, dictionary ) } ) + @dictionary.add( 'del', + proc { |stack, dictionary| Rpl::Lang::Core.del( stack, dictionary ) } ) + @dictionary.add( 'rot', + proc { |stack, dictionary| Rpl::Lang::Core.rot( stack, dictionary ) } ) + @dictionary.add( 'dup', + proc { |stack, dictionary| Rpl::Lang::Core.dup( stack, dictionary ) } ) + @dictionary.add( 'dup2', + proc { |stack, dictionary| Rpl::Lang::Core.dup2( stack, dictionary ) } ) + @dictionary.add( 'dupn', + proc { |stack, dictionary| Rpl::Lang::Core.dupn( stack, dictionary ) } ) + @dictionary.add( 'pick', + proc { |stack, dictionary| Rpl::Lang::Core.pick( stack, dictionary ) } ) + @dictionary.add( 'depth', + proc { |stack, dictionary| Rpl::Lang::Core.depth( stack, dictionary ) } ) + @dictionary.add( 'roll', + proc { |stack, dictionary| Rpl::Lang::Core.roll( stack, dictionary ) } ) + @dictionary.add( 'rolld', + proc { |stack, dictionary| Rpl::Lang::Core.rolld( stack, dictionary ) } ) + @dictionary.add( 'over', + proc { |stack, dictionary| Rpl::Lang::Core.over( stack, dictionary ) } ) # USUAL OPERATIONS ON REALS AND COMPLEXES - @dictionary.add( '+', proc { |stack, dictionary| Rpl::Lang::Core.add( stack, dictionary ) } ) - @dictionary.add( '-', proc { |stack, dictionary| Rpl::Lang::Core.subtract( stack, dictionary ) } ) - @dictionary.add( 'chs', proc { |stack, dictionary| Rpl::Lang::Core.negate( stack, dictionary ) } ) - @dictionary.add( '*', proc { |stack, dictionary| Rpl::Lang::Core.multiply( stack, dictionary ) } ) # alias - @dictionary.add( '×', proc { |stack, dictionary| Rpl::Lang::Core.multiply( stack, dictionary ) } ) - @dictionary.add( '/', proc { |stack, dictionary| Rpl::Lang::Core.divide( stack, dictionary ) } ) # alias - @dictionary.add( '÷', proc { |stack, dictionary| Rpl::Lang::Core.divide( stack, dictionary ) } ) - @dictionary.add( 'inv', proc { |stack, dictionary| Rpl::Lang::Core.inverse( stack, dictionary ) } ) - @dictionary.add( '^', proc { |stack, dictionary| Rpl::Lang::Core.power( stack, dictionary ) } ) - @dictionary.add( 'sqrt', proc { |stack, dictionary| Rpl::Lang::Core.sqrt( stack, dictionary ) } ) # alias - @dictionary.add( '√', proc { |stack, dictionary| Rpl::Lang::Core.sqrt( stack, dictionary ) } ) - @dictionary.add( 'sq', proc { |stack, dictionary| Rpl::Lang::Core.sq( stack, dictionary ) } ) - @dictionary.add( 'abs', proc { |stack, dictionary| Rpl::Lang::Core.abs( stack, dictionary ) } ) - @dictionary.add( 'dec', proc { |stack, dictionary| Rpl::Lang::Core.dec( stack, dictionary ) } ) - @dictionary.add( 'hex', proc { |stack, dictionary| Rpl::Lang::Core.hex( stack, dictionary ) } ) - @dictionary.add( 'bin', proc { |stack, dictionary| Rpl::Lang::Core.bin( stack, dictionary ) } ) - @dictionary.add( 'base', proc { |stack, dictionary| Rpl::Lang::Core.base( stack, dictionary ) } ) - @dictionary.add( 'sign', proc { |stack, dictionary| Rpl::Lang::Core.sign( stack, dictionary ) } ) + @dictionary.add( '+', + proc { |stack, dictionary| Rpl::Lang::Core.add( stack, dictionary ) } ) + @dictionary.add( '-', + proc { |stack, dictionary| Rpl::Lang::Core.subtract( stack, dictionary ) } ) + @dictionary.add( 'chs', + proc { |stack, dictionary| Rpl::Lang::Core.negate( stack, dictionary ) } ) + @dictionary.add( '*', + proc { |stack, dictionary| Rpl::Lang::Core.multiply( stack, dictionary ) } ) # alias + @dictionary.add( '×', + proc { |stack, dictionary| Rpl::Lang::Core.multiply( stack, dictionary ) } ) + @dictionary.add( '/', + proc { |stack, dictionary| Rpl::Lang::Core.divide( stack, dictionary ) } ) # alias + @dictionary.add( '÷', + proc { |stack, dictionary| Rpl::Lang::Core.divide( stack, dictionary ) } ) + @dictionary.add( 'inv', + proc { |stack, dictionary| Rpl::Lang::Core.inverse( stack, dictionary ) } ) + @dictionary.add( '^', + proc { |stack, dictionary| Rpl::Lang::Core.power( stack, dictionary ) } ) + @dictionary.add( 'sqrt', + proc { |stack, dictionary| Rpl::Lang::Core.sqrt( stack, dictionary ) } ) # alias + @dictionary.add( '√', + proc { |stack, dictionary| Rpl::Lang::Core.sqrt( stack, dictionary ) } ) + @dictionary.add( 'sq', + proc { |stack, dictionary| Rpl::Lang::Core.sq( stack, dictionary ) } ) + @dictionary.add( 'abs', + proc { |stack, dictionary| Rpl::Lang::Core.abs( stack, dictionary ) } ) + @dictionary.add( 'dec', + proc { |stack, dictionary| Rpl::Lang::Core.dec( stack, dictionary ) } ) + @dictionary.add( 'hex', + proc { |stack, dictionary| Rpl::Lang::Core.hex( stack, dictionary ) } ) + @dictionary.add( 'bin', + proc { |stack, dictionary| Rpl::Lang::Core.bin( stack, dictionary ) } ) + @dictionary.add( 'base', + proc { |stack, dictionary| Rpl::Lang::Core.base( stack, dictionary ) } ) + @dictionary.add( 'sign', + proc { |stack, dictionary| Rpl::Lang::Core.sign( stack, dictionary ) } ) # OPERATIONS ON REALS - @dictionary.add( '%', proc { |stack, dictionary| Rpl::Lang::Core.percent( stack, dictionary ) } ) - @dictionary.add( '%CH', proc { |stack, dictionary| Rpl::Lang::Core.inverse_percent( stack, dictionary ) } ) - @dictionary.add( 'mod', proc { |stack, dictionary| Rpl::Lang::Core.mod( stack, dictionary ) } ) - @dictionary.add( 'fact', proc { |stack, dictionary| Rpl::Lang::Core.fact( stack, dictionary ) } ) - @dictionary.add( '!', proc { |stack, dictionary| Rpl::Lang::Core.fact( stack, dictionary ) } ) # alias - @dictionary.add( 'floor', proc { |stack, dictionary| Rpl::Lang::Core.floor( stack, dictionary ) } ) - @dictionary.add( 'ceil', proc { |stack, dictionary| Rpl::Lang::Core.ceil( stack, dictionary ) } ) - @dictionary.add( 'min', proc { |stack, dictionary| Rpl::Lang::Core.min( stack, dictionary ) } ) - @dictionary.add( 'max', proc { |stack, dictionary| Rpl::Lang::Core.max( stack, dictionary ) } ) - # @dictionary.add( 'mant', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # mantissa of a real number - # @dictionary.add( 'xpon', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # exponant of a real number - # @dictionary.add( 'ip', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # integer part - # @dictionary.add( 'fp', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # fractional part + @dictionary.add( '%', + proc { |stack, dictionary| Rpl::Lang::Core.percent( stack, dictionary ) } ) + @dictionary.add( '%CH', + proc { |stack, dictionary| Rpl::Lang::Core.inverse_percent( stack, dictionary ) } ) + @dictionary.add( 'mod', + proc { |stack, dictionary| Rpl::Lang::Core.mod( stack, dictionary ) } ) + @dictionary.add( 'fact', + proc { |stack, dictionary| Rpl::Lang::Core.fact( stack, dictionary ) } ) + @dictionary.add( '!', + proc { |stack, dictionary| Rpl::Lang::Core.fact( stack, dictionary ) } ) # alias + @dictionary.add( 'floor', + proc { |stack, dictionary| Rpl::Lang::Core.floor( stack, dictionary ) } ) + @dictionary.add( 'ceil', + proc { |stack, dictionary| Rpl::Lang::Core.ceil( stack, dictionary ) } ) + @dictionary.add( 'min', + proc { |stack, dictionary| Rpl::Lang::Core.min( stack, dictionary ) } ) + @dictionary.add( 'max', + proc { |stack, dictionary| Rpl::Lang::Core.max( stack, dictionary ) } ) + # @dictionary.add( 'mant', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # mantissa of a real number + # @dictionary.add( 'xpon', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # exponant of a real number + # @dictionary.add( 'ip', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # integer part + # @dictionary.add( 'fp', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # fractional part # OPERATIONS ON COMPLEXES - # @dictionary.add( 're', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # complex real part - # @dictionary.add( 'im', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # complex imaginary part - # @dictionary.add( 'conj', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # complex conjugate - # @dictionary.add( 'arg', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # complex argument in radians - # @dictionary.add( 'c->r', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # transform a complex in 2 reals - # @dictionary.add( 'c→r', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # alias - # @dictionary.add( 'r->c', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # transform 2 reals in a complex - # @dictionary.add( 'r→c', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # alias - # @dictionary.add( 'p->r', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # cartesian to polar - # @dictionary.add( 'p→r', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # alias - # @dictionary.add( 'r->p', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # polar to cartesian - # @dictionary.add( 'r→p', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # alias + # @dictionary.add( 're', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # complex real part + # @dictionary.add( 'im', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # complex imaginary part + # @dictionary.add( 'conj', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # complex conjugate + # @dictionary.add( 'arg', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # complex argument in radians + # @dictionary.add( 'c->r', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # transform a complex in 2 reals + # @dictionary.add( 'c→r', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # alias + # @dictionary.add( 'r->c', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # transform 2 reals in a complex + # @dictionary.add( 'r→c', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # alias + # @dictionary.add( 'p->r', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # cartesian to polar + # @dictionary.add( 'p→r', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # alias + # @dictionary.add( 'r->p', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # polar to cartesian + # @dictionary.add( 'r→p', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # alias # MODE - @dictionary.add( 'prec', proc { |stack, dictionary| Rpl::Lang::Core.prec( stack, dictionary ) } ) - @dictionary.add( 'default', proc { |stack, dictionary| Rpl::Lang::Core.default( stack, dictionary ) } ) - @dictionary.add( 'type', proc { |stack, dictionary| Rpl::Lang::Core.type( stack, dictionary ) } ) - # @dictionary.add( 'std', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # standard floating numbers representation. ex: std - # @dictionary.add( 'fix', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # fixed point representation. ex: 6 fix - # @dictionary.add( 'sci', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # scientific floating point representation. ex: 20 sci - # @dictionary.add( 'round', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # set float rounding mode. ex: ["nearest", "toward zero", "toward +inf", "toward -inf", "away from zero"] round + @dictionary.add( 'prec', + proc { |stack, dictionary| Rpl::Lang::Core.prec( stack, dictionary ) } ) + @dictionary.add( 'default', + proc { |stack, dictionary| Rpl::Lang::Core.default( stack, dictionary ) } ) + @dictionary.add( 'type', + proc { |stack, dictionary| Rpl::Lang::Core.type( stack, dictionary ) } ) + # @dictionary.add( 'std', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # standard floating numbers representation. ex: std + # @dictionary.add( 'fix', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # fixed point representation. ex: 6 fix + # @dictionary.add( 'sci', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # scientific floating point representation. ex: 20 sci + # @dictionary.add( 'round', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # set float rounding mode. ex: ["nearest", "toward zero", "toward +inf", "toward -inf", "away from zero"] round # TEST - @dictionary.add( '>', proc { |stack, dictionary| Rpl::Lang::Core.greater_than( stack, dictionary ) } ) - @dictionary.add( '>=', proc { |stack, dictionary| Rpl::Lang::Core.greater_than_or_equal( stack, dictionary ) } ) # alias - @dictionary.add( '≥', proc { |stack, dictionary| Rpl::Lang::Core.greater_than_or_equal( stack, dictionary ) } ) - @dictionary.add( '<', proc { |stack, dictionary| Rpl::Lang::Core.less_than( stack, dictionary ) } ) - @dictionary.add( '<=', proc { |stack, dictionary| Rpl::Lang::Core.less_than_or_equal( stack, dictionary ) } ) # alias - @dictionary.add( '≤', proc { |stack, dictionary| Rpl::Lang::Core.less_than_or_equal( stack, dictionary ) } ) - @dictionary.add( '!=', proc { |stack, dictionary| Rpl::Lang::Core.different( stack, dictionary ) } ) # alias - @dictionary.add( '≠', proc { |stack, dictionary| Rpl::Lang::Core.different( stack, dictionary ) } ) - @dictionary.add( '==', proc { |stack, dictionary| Rpl::Lang::Core.same( stack, dictionary ) } ) - @dictionary.add( 'and', proc { |stack, dictionary| Rpl::Lang::Core.and( stack, dictionary ) } ) - @dictionary.add( 'or', proc { |stack, dictionary| Rpl::Lang::Core.or( stack, dictionary ) } ) - @dictionary.add( 'xor', proc { |stack, dictionary| Rpl::Lang::Core.xor( stack, dictionary ) } ) - @dictionary.add( 'not', proc { |stack, dictionary| Rpl::Lang::Core.not( stack, dictionary ) } ) - @dictionary.add( 'same', proc { |stack, dictionary| Rpl::Lang::Core.same( stack, dictionary ) } ) # alias - @dictionary.add( 'true', proc { |stack, dictionary| Rpl::Lang::Core.true( stack, dictionary ) } ) # specific - @dictionary.add( 'false', proc { |stack, dictionary| Rpl::Lang::Core.false( stack, dictionary ) } ) # specific + @dictionary.add( '>', + proc { |stack, dictionary| Rpl::Lang::Core.greater_than( stack, dictionary ) } ) + @dictionary.add( '>=', + proc { |stack, dictionary| Rpl::Lang::Core.greater_than_or_equal( stack, dictionary ) } ) # alias + @dictionary.add( '≥', + proc { |stack, dictionary| Rpl::Lang::Core.greater_than_or_equal( stack, dictionary ) } ) + @dictionary.add( '<', + proc { |stack, dictionary| Rpl::Lang::Core.less_than( stack, dictionary ) } ) + @dictionary.add( '<=', + proc { |stack, dictionary| Rpl::Lang::Core.less_than_or_equal( stack, dictionary ) } ) # alias + @dictionary.add( '≤', + proc { |stack, dictionary| Rpl::Lang::Core.less_than_or_equal( stack, dictionary ) } ) + @dictionary.add( '!=', + proc { |stack, dictionary| Rpl::Lang::Core.different( stack, dictionary ) } ) # alias + @dictionary.add( '≠', + proc { |stack, dictionary| Rpl::Lang::Core.different( stack, dictionary ) } ) + @dictionary.add( '==', + proc { |stack, dictionary| Rpl::Lang::Core.same( stack, dictionary ) } ) + @dictionary.add( 'and', + proc { |stack, dictionary| Rpl::Lang::Core.and( stack, dictionary ) } ) + @dictionary.add( 'or', + proc { |stack, dictionary| Rpl::Lang::Core.or( stack, dictionary ) } ) + @dictionary.add( 'xor', + proc { |stack, dictionary| Rpl::Lang::Core.xor( stack, dictionary ) } ) + @dictionary.add( 'not', + proc { |stack, dictionary| Rpl::Lang::Core.not( stack, dictionary ) } ) + @dictionary.add( 'same', + proc { |stack, dictionary| Rpl::Lang::Core.same( stack, dictionary ) } ) # alias + @dictionary.add( 'true', + proc { |stack, dictionary| Rpl::Lang::Core.true( stack, dictionary ) } ) # specific + @dictionary.add( 'false', + proc { |stack, dictionary| Rpl::Lang::Core.false( stack, dictionary ) } ) # specific # STRING - @dictionary.add( '->str', proc { |stack, dictionary| Rpl::Lang::Core.to_string( stack, dictionary ) } ) # alias - @dictionary.add( '→str', proc { |stack, dictionary| Rpl::Lang::Core.to_string( stack, dictionary ) } ) - @dictionary.add( 'str->', proc { |stack, dictionary| Rpl::Lang::Core.from_string( stack, dictionary ) } ) # alias - @dictionary.add( 'str→', proc { |stack, dictionary| Rpl::Lang::Core.from_string( stack, dictionary ) } ) - @dictionary.add( 'chr', proc { |stack, dictionary| Rpl::Lang::Core.chr( stack, dictionary ) } ) - @dictionary.add( 'num', proc { |stack, dictionary| Rpl::Lang::Core.num( stack, dictionary ) } ) - @dictionary.add( 'size', proc { |stack, dictionary| Rpl::Lang::Core.size( stack, dictionary ) } ) - @dictionary.add( 'pos', proc { |stack, dictionary| Rpl::Lang::Core.pos( stack, dictionary ) } ) - @dictionary.add( 'sub', proc { |stack, dictionary| Rpl::Lang::Core.sub( stack, dictionary ) } ) - @dictionary.add( 'rev', proc { |stack, dictionary| Rpl::Lang::Core.rev( stack, dictionary ) } ) # specific - @dictionary.add( 'split', proc { |stack, dictionary| Rpl::Lang::Core.split( stack, dictionary ) } ) # specific + @dictionary.add( '->str', + proc { |stack, dictionary| Rpl::Lang::Core.to_string( stack, dictionary ) } ) # alias + @dictionary.add( '→str', + proc { |stack, dictionary| Rpl::Lang::Core.to_string( stack, dictionary ) } ) + @dictionary.add( 'str->', + proc { |stack, dictionary| Rpl::Lang::Core.from_string( stack, dictionary ) } ) # alias + @dictionary.add( 'str→', + proc { |stack, dictionary| Rpl::Lang::Core.from_string( stack, dictionary ) } ) + @dictionary.add( 'chr', + proc { |stack, dictionary| Rpl::Lang::Core.chr( stack, dictionary ) } ) + @dictionary.add( 'num', + proc { |stack, dictionary| Rpl::Lang::Core.num( stack, dictionary ) } ) + @dictionary.add( 'size', + proc { |stack, dictionary| Rpl::Lang::Core.size( stack, dictionary ) } ) + @dictionary.add( 'pos', + proc { |stack, dictionary| Rpl::Lang::Core.pos( stack, dictionary ) } ) + @dictionary.add( 'sub', + proc { |stack, dictionary| Rpl::Lang::Core.sub( stack, dictionary ) } ) + @dictionary.add( 'rev', + proc { |stack, dictionary| Rpl::Lang::Core.rev( stack, dictionary ) } ) # specific + @dictionary.add( 'split', + proc { |stack, dictionary| Rpl::Lang::Core.split( stack, dictionary ) } ) # specific # BRANCH - @dictionary.add( 'ift', proc { |stack, dictionary| Rpl::Lang::Core.ift( stack, dictionary ) } ) - @dictionary.add( 'ifte', proc { |stack, dictionary| Rpl::Lang::Core.ifte( stack, dictionary ) } ) - @dictionary.add( 'times', proc { |stack, dictionary| Rpl::Lang::Core.times( stack, dictionary ) } ) # specific - @dictionary.add( 'loop', proc { |stack, dictionary| Rpl::Lang::Core.loop( stack, dictionary ) } ) # specific - # @dictionary.add( 'if', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # if then else end - # @dictionary.add( 'then', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # used with if - # @dictionary.add( 'else', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # used with if - # @dictionary.add( 'end', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # used with various branch instructions - # @dictionary.add( 'start', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # start next| step - # @dictionary.add( 'for', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # for next| step - # @dictionary.add( 'next', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # used with start and for - # @dictionary.add( 'step', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # used with start and for - # @dictionary.add( 'do', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # do until end - # @dictionary.add( 'until', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # used with do - # @dictionary.add( 'while', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # while repeat end - # @dictionary.add( 'repeat', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # used with while + @dictionary.add( 'ift', + proc { |stack, dictionary| Rpl::Lang::Core.ift( stack, dictionary ) } ) + @dictionary.add( 'ifte', + proc { |stack, dictionary| Rpl::Lang::Core.ifte( stack, dictionary ) } ) + @dictionary.add( 'times', + proc { |stack, dictionary| Rpl::Lang::Core.times( stack, dictionary ) } ) # specific + @dictionary.add( 'loop', + proc { |stack, dictionary| Rpl::Lang::Core.loop( stack, dictionary ) } ) # specific + # @dictionary.add( 'if', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # if then else end + # @dictionary.add( 'then', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # used with if + # @dictionary.add( 'else', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # used with if + # @dictionary.add( 'end', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # used with various branch instructions + # @dictionary.add( 'start', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # start next| step + # @dictionary.add( 'for', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # for next| step + # @dictionary.add( 'next', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # used with start and for + # @dictionary.add( 'step', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # used with start and for + # @dictionary.add( 'do', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # do until end + # @dictionary.add( 'until', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # used with do + # @dictionary.add( 'while', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # while repeat end + # @dictionary.add( 'repeat', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # used with while # STORE - @dictionary.add( 'sto', proc { |stack, dictionary| Rpl::Lang::Core.sto( stack, dictionary ) } ) - @dictionary.add( '▶', proc { |stack, dictionary| Rpl::Lang::Core.sto( stack, dictionary ) } ) # alias - @dictionary.add( 'rcl', proc { |stack, dictionary| Rpl::Lang::Core.rcl( stack, dictionary ) } ) - @dictionary.add( 'purge', proc { |stack, dictionary| Rpl::Lang::Core.purge( stack, dictionary ) } ) - @dictionary.add( 'vars', proc { |stack, dictionary| Rpl::Lang::Core.vars( stack, dictionary ) } ) - @dictionary.add( 'clusr', proc { |stack, dictionary| Rpl::Lang::Core.clusr( stack, dictionary ) } ) - @dictionary.add( 'sto+', proc { |stack, dictionary| Rpl::Lang::Core.sto_add( stack, dictionary ) } ) - @dictionary.add( 'sto-', proc { |stack, dictionary| Rpl::Lang::Core.sto_subtract( stack, dictionary ) } ) - @dictionary.add( 'sto*', proc { |stack, dictionary| Rpl::Lang::Core.sto_multiply( stack, dictionary ) } ) # alias - @dictionary.add( 'sto×', proc { |stack, dictionary| Rpl::Lang::Core.sto_multiply( stack, dictionary ) } ) - @dictionary.add( 'sto/', proc { |stack, dictionary| Rpl::Lang::Core.sto_divide( stack, dictionary ) } ) # alias - @dictionary.add( 'sto÷', proc { |stack, dictionary| Rpl::Lang::Core.sto_divide( stack, dictionary ) } ) - @dictionary.add( 'sneg', proc { |stack, dictionary| Rpl::Lang::Core.sto_negate( stack, dictionary ) } ) - @dictionary.add( 'sinv', proc { |stack, dictionary| Rpl::Lang::Core.sto_inverse( stack, dictionary ) } ) - # @dictionary.add( 'edit', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # edit a variable content - @dictionary.add( 'lsto', proc { |stack, dictionary| Rpl::Lang::Core.lsto( stack, dictionary ) } ) # store to local variable - @dictionary.add( '↴', proc { |stack, dictionary| Rpl::Lang::Core.lsto( stack, dictionary ) } ) # alias + @dictionary.add( 'sto', + proc { |stack, dictionary| Rpl::Lang::Core.sto( stack, dictionary ) } ) + @dictionary.add( '▶', + proc { |stack, dictionary| Rpl::Lang::Core.sto( stack, dictionary ) } ) # alias + @dictionary.add( 'rcl', + proc { |stack, dictionary| Rpl::Lang::Core.rcl( stack, dictionary ) } ) + @dictionary.add( 'purge', + proc { |stack, dictionary| Rpl::Lang::Core.purge( stack, dictionary ) } ) + @dictionary.add( 'vars', + proc { |stack, dictionary| Rpl::Lang::Core.vars( stack, dictionary ) } ) + @dictionary.add( 'clusr', + proc { |stack, dictionary| Rpl::Lang::Core.clusr( stack, dictionary ) } ) + @dictionary.add( 'sto+', + proc { |stack, dictionary| Rpl::Lang::Core.sto_add( stack, dictionary ) } ) + @dictionary.add( 'sto-', + proc { |stack, dictionary| Rpl::Lang::Core.sto_subtract( stack, dictionary ) } ) + @dictionary.add( 'sto*', + proc { |stack, dictionary| Rpl::Lang::Core.sto_multiply( stack, dictionary ) } ) # alias + @dictionary.add( 'sto×', + proc { |stack, dictionary| Rpl::Lang::Core.sto_multiply( stack, dictionary ) } ) + @dictionary.add( 'sto/', + proc { |stack, dictionary| Rpl::Lang::Core.sto_divide( stack, dictionary ) } ) # alias + @dictionary.add( 'sto÷', + proc { |stack, dictionary| Rpl::Lang::Core.sto_divide( stack, dictionary ) } ) + @dictionary.add( 'sneg', + proc { |stack, dictionary| Rpl::Lang::Core.sto_negate( stack, dictionary ) } ) + @dictionary.add( 'sinv', + proc { |stack, dictionary| Rpl::Lang::Core.sto_inverse( stack, dictionary ) } ) + # @dictionary.add( 'edit', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # edit a variable content + @dictionary.add( 'lsto', + proc { |stack, dictionary| Rpl::Lang::Core.lsto( stack, dictionary ) } ) # store to local variable + @dictionary.add( '↴', + proc { |stack, dictionary| Rpl::Lang::Core.lsto( stack, dictionary ) } ) # alias # PROGRAM - @dictionary.add( 'eval', proc { |stack, dictionary| Rpl::Lang::Core.eval( stack, dictionary ) } ) - # @dictionary.add( '->', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # load program local variables. ex: « → n m « 0 n m for i i + next » » - # @dictionary.add( '→', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # alias + @dictionary.add( 'eval', + proc { |stack, dictionary| Rpl::Lang::Core.eval( stack, dictionary ) } ) + # @dictionary.add( '->', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # load program local variables. ex: « → n m « 0 n m for i i + next » » + # @dictionary.add( '→', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # alias # TRIG ON REALS AND COMPLEXES - @dictionary.add( 'pi', proc { |stack, dictionary| Rpl::Lang::Core.pi( stack, dictionary ) } ) - @dictionary.add( '𝛑', proc { |stack, dictionary| Rpl::Lang::Core.pi( stack, dictionary ) } ) # alias - @dictionary.add( 'sin', proc { |stack, dictionary| Rpl::Lang::Core.sinus( stack, dictionary ) } ) # sinus - @dictionary.add( 'asin', proc { |stack, dictionary| Rpl::Lang::Core.arg_sinus( stack, dictionary ) } ) # arg sinus - @dictionary.add( 'cos', proc { |stack, dictionary| Rpl::Lang::Core.cosinus( stack, dictionary ) } ) # cosinus - @dictionary.add( 'acos', proc { |stack, dictionary| Rpl::Lang::Core.arg_cosinus( stack, dictionary ) } ) # arg cosinus - @dictionary.add( 'tan', proc { |stack, dictionary| Rpl::Lang::Core.tangent( stack, dictionary ) } ) # tangent - @dictionary.add( 'atan', proc { |stack, dictionary| Rpl::Lang::Core.arg_tangent( stack, dictionary ) } ) # arg tangent - @dictionary.add( 'd->r', proc { |stack, dictionary| Rpl::Lang::Core.degrees_to_radians( stack, dictionary ) } ) # convert degrees to radians - @dictionary.add( 'd→r', proc { |stack, dictionary| Rpl::Lang::Core.degrees_to_radians( stack, dictionary ) } ) # alias - @dictionary.add( 'r->d', proc { |stack, dictionary| Rpl::Lang::Core.radians_to_degrees( stack, dictionary ) } ) # convert radians to degrees - @dictionary.add( 'r→d', proc { |stack, dictionary| Rpl::Lang::Core.radians_to_degrees( stack, dictionary ) } ) # alias + @dictionary.add( 'pi', + proc { |stack, dictionary| Rpl::Lang::Core.pi( stack, dictionary ) } ) + @dictionary.add( '𝛑', + proc { |stack, dictionary| Rpl::Lang::Core.pi( stack, dictionary ) } ) # alias + @dictionary.add( 'sin', + proc { |stack, dictionary| Rpl::Lang::Core.sinus( stack, dictionary ) } ) # sinus + @dictionary.add( 'asin', + proc { |stack, dictionary| Rpl::Lang::Core.arg_sinus( stack, dictionary ) } ) # arg sinus + @dictionary.add( 'cos', + proc { |stack, dictionary| Rpl::Lang::Core.cosinus( stack, dictionary ) } ) # cosinus + @dictionary.add( 'acos', + proc { |stack, dictionary| Rpl::Lang::Core.arg_cosinus( stack, dictionary ) } ) # arg cosinus + @dictionary.add( 'tan', + proc { |stack, dictionary| Rpl::Lang::Core.tangent( stack, dictionary ) } ) # tangent + @dictionary.add( 'atan', + proc { |stack, dictionary| Rpl::Lang::Core.arg_tangent( stack, dictionary ) } ) # arg tangent + @dictionary.add( 'd->r', + proc { |stack, dictionary| Rpl::Lang::Core.degrees_to_radians( stack, dictionary ) } ) # convert degrees to radians + @dictionary.add( 'd→r', + proc { |stack, dictionary| Rpl::Lang::Core.degrees_to_radians( stack, dictionary ) } ) # alias + @dictionary.add( 'r->d', + proc { |stack, dictionary| Rpl::Lang::Core.radians_to_degrees( stack, dictionary ) } ) # convert radians to degrees + @dictionary.add( 'r→d', + proc { |stack, dictionary| Rpl::Lang::Core.radians_to_degrees( stack, dictionary ) } ) # alias # LOGS ON REALS AND COMPLEXES - @dictionary.add( 'e', proc { |stack, dictionary| Rpl::Lang::Core.e( stack, dictionary ) } ) # alias - @dictionary.add( 'ℇ', proc { |stack, dictionary| Rpl::Lang::Core.e( stack, dictionary ) } ) - # @dictionary.add( 'ln', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # logarithm base e - # @dictionary.add( 'lnp1', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # ln(1+x) which is useful when x is close to 0 - # @dictionary.add( 'exp', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # exponential - # @dictionary.add( 'expm', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # exp(x)-1 which is useful when x is close to 0 - # @dictionary.add( 'log10', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # logarithm base 10 - # @dictionary.add( 'alog10', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # exponential base 10 - # @dictionary.add( 'log2', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # logarithm base 2 - # @dictionary.add( 'alog2', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # exponential base 2 - # @dictionary.add( 'sinh', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # hyperbolic sine - # @dictionary.add( 'asinh', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # inverse hyperbolic sine - # @dictionary.add( 'cosh', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # hyperbolic cosine - # @dictionary.add( 'acosh', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # inverse hyperbolic cosine - # @dictionary.add( 'tanh', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # hyperbolic tangent - # @dictionary.add( 'atanh', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # inverse hyperbolic tangent + @dictionary.add( 'e', + proc { |stack, dictionary| Rpl::Lang::Core.e( stack, dictionary ) } ) # alias + @dictionary.add( 'ℇ', + proc { |stack, dictionary| Rpl::Lang::Core.e( stack, dictionary ) } ) + # @dictionary.add( 'ln', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # logarithm base e + # @dictionary.add( 'lnp1', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # ln(1+x) which is useful when x is close to 0 + # @dictionary.add( 'exp', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # exponential + # @dictionary.add( 'expm', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # exp(x)-1 which is useful when x is close to 0 + # @dictionary.add( 'log10', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # logarithm base 10 + # @dictionary.add( 'alog10', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # exponential base 10 + # @dictionary.add( 'log2', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # logarithm base 2 + # @dictionary.add( 'alog2', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # exponential base 2 + # @dictionary.add( 'sinh', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # hyperbolic sine + # @dictionary.add( 'asinh', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # inverse hyperbolic sine + # @dictionary.add( 'cosh', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # hyperbolic cosine + # @dictionary.add( 'acosh', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # inverse hyperbolic cosine + # @dictionary.add( 'tanh', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # hyperbolic tangent + # @dictionary.add( 'atanh', + # proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # inverse hyperbolic tangent # TIME AND DATE - @dictionary.add( 'time', proc { |stack, dictionary| Rpl::Lang::Core.time( stack, dictionary ) } ) - @dictionary.add( 'date', proc { |stack, dictionary| Rpl::Lang::Core.date( stack, dictionary ) } ) - @dictionary.add( 'ticks', proc { |stack, dictionary| Rpl::Lang::Core.ticks( stack, dictionary ) } ) + @dictionary.add( 'time', + proc { |stack, dictionary| Rpl::Lang::Core.time( stack, dictionary ) } ) + @dictionary.add( 'date', + proc { |stack, dictionary| Rpl::Lang::Core.date( stack, dictionary ) } ) + @dictionary.add( 'ticks', + proc { |stack, dictionary| Rpl::Lang::Core.ticks( stack, dictionary ) } ) # Rpl.rb specifics # LISTS - @dictionary.add( '->list', proc { |stack, dictionary| Rpl::Lang::Core.to_list( stack, dictionary ) } ) - @dictionary.add( '→list', proc { |stack, dictionary| Rpl::Lang::Core.to_list( stack, dictionary ) } ) # alias - @dictionary.add( 'list->', proc { |stack, dictionary| Rpl::Lang::Core.unpack_list( stack, dictionary ) } ) - @dictionary.add( 'list→', proc { |stack, dictionary| Rpl::Lang::Core.unpack_list( stack, dictionary ) } ) # alias + @dictionary.add( '->list', + proc { |stack, dictionary| Rpl::Lang::Core.to_list( stack, dictionary ) } ) + @dictionary.add( '→list', + proc { |stack, dictionary| Rpl::Lang::Core.to_list( stack, dictionary ) } ) # alias + @dictionary.add( 'list->', + proc { |stack, dictionary| Rpl::Lang::Core.unpack_list( stack, dictionary ) } ) + @dictionary.add( 'list→', + proc { |stack, dictionary| Rpl::Lang::Core.unpack_list( stack, dictionary ) } ) # alias # FILESYSTEM - @dictionary.add( 'fread', proc { |stack, dictionary| Rpl::Lang::Core.fread( stack, dictionary ) } ) - @dictionary.add( 'feval', proc { |stack, dictionary| Rpl::Lang::Core.feval( stack, dictionary ) } ) - @dictionary.add( 'fwrite', proc { |stack, dictionary| Rpl::Lang::Core.fwrite( stack, dictionary ) } ) + @dictionary.add( 'fread', + proc { |stack, dictionary| Rpl::Lang::Core.fread( stack, dictionary ) } ) + @dictionary.add( 'feval', + proc { |stack, dictionary| Rpl::Lang::Core.feval( stack, dictionary ) } ) + @dictionary.add( 'fwrite', + proc { |stack, dictionary| Rpl::Lang::Core.fwrite( stack, dictionary ) } ) # GRAPHICS end def run( input ) - @stack, @dictionary = @runner.run_input( @parser.parse_input( input ), - @stack, @dictionary ) + @stack, @dictionary = Rpl::Lang.run_input( Rpl::Lang.parse_input( input ), + @stack, @dictionary ) end end end diff --git a/lib/core.rb b/lib/core.rb index e8eef34..cc07b27 100644 --- a/lib/core.rb +++ b/lib/core.rb @@ -19,51 +19,52 @@ require_relative './core/list' module Rpl module Lang - module Core - module_function + module_function - include BigMath + include BigMath - def precision - @precision or 12 + def precision + @precision or 12 + end + + def precision=( value ) + @precision = value + end + + def stack_extract( stack, needs ) + raise ArgumentError, 'Not enough elements' if stack.size < needs.size + + args = [] + needs.each do |need| + elt = stack.pop + + raise ArgumentError, "Type Error, needed #{need} got #{elt[:type]}" unless need == :any || need.include?( elt[:type] ) + + args << elt end - def precision=( value ) - @precision = value - end + [stack, args] + end - def stack_extract( stack, needs ) - raise ArgumentError, 'Not enough elements' if stack.size < needs.size + def infer_resulting_base( numerics ) + 10 if numerics.length.zero? - args = [] - needs.each do |need| - elt = stack.pop + numerics.last[:base] + end - raise ArgumentError, "Type Error, needed #{need} got #{elt[:type]}" unless need == :any || need.include?( elt[:type] ) + def eval( stack, dictionary, rplcode ) + preparsed_input = rplcode.gsub( '\n', ' ' ).strip if rplcode.is_a?( String ) + parsed_input = Rpl::Lang.parse_input( preparsed_input.to_s ) - args << elt - end + Rpl::Lang.run_input( parsed_input, + stack, dictionary ) + end - [stack, args] - end + ### DEBUG ### + def __pp_stack( stack, dictionary ) + pp stack - def infer_resulting_base( numerics ) - 10 if numerics.length.zero? - - numerics.last[:base] - end - - def __todo( stack, dictionary ) - puts '__NOT IMPLEMENTED__' - - [stack, dictionary] - end - - def __pp_stack( stack, dictionary ) - pp stack - - [stack, dictionary] - end + [stack, dictionary] end end end diff --git a/lib/core/branch.rb b/lib/core/branch.rb index e0f2d40..2691e6e 100644 --- a/lib/core/branch.rb +++ b/lib/core/branch.rb @@ -7,7 +7,7 @@ module Rpl # ( x prg -- … ) run PRG X times putting i(counter) on the stack before each run def times( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [:any, %i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [:any, %i[numeric]] ) args[1][:value].times do |i| counter = { value: i, type: :numeric, base: 10 } @@ -21,7 +21,7 @@ module Rpl # ( x y prg -- … ) run PRG (Y - X) times putting i(counter) on the stack before each run def loop( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [:any, %i[numeric], %i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [:any, %i[numeric], %i[numeric]] ) (args[2][:value]..args[1][:value]).each do |i| counter = { value: i, type: :numeric, base: 10 } @@ -35,7 +35,7 @@ module Rpl # similar to if-then-else-end, ifte def ifte( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [:any, :any, %i[boolean]] ) + stack, args = Rpl::Lang.stack_extract( stack, [:any, :any, %i[boolean]] ) stack << args[ args[2][:value] ? 1 : 0 ] @@ -45,10 +45,7 @@ module Rpl # Implemented in Rpl # similar to if-then-end, ift def ift( stack, dictionary ) - stack << { value: '« nop » ifte', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, '« nop » ifte' ) end end end diff --git a/lib/core/filesystem.rb b/lib/core/filesystem.rb index 44a4390..bbc6edd 100644 --- a/lib/core/filesystem.rb +++ b/lib/core/filesystem.rb @@ -5,7 +5,7 @@ module Rpl # ( filename -- content ) read file and put content on stack as string def fread( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[string]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[string]] ) path = File.absolute_path( args[0][:value] ) @@ -17,15 +17,12 @@ module Rpl # ( filename -- … ) read and run file def feval( stack, dictionary ) - stack << { value: 'fread eval', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, 'fread eval' ) end # ( content filename -- ) write content into filename def fwrite( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[string], :any] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[string], :any] ) File.write( File.absolute_path( args[0][:value] ), args[1][:value] ) diff --git a/lib/core/list.rb b/lib/core/list.rb index a9d2276..1f5e3f4 100644 --- a/lib/core/list.rb +++ b/lib/core/list.rb @@ -7,8 +7,8 @@ module Rpl # ( … x -- […] ) pack x stacks levels into a list def to_list( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) - stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any] * args[0][:value] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, %i[any] * args[0][:value] ) stack << { type: :list, value: args.reverse } @@ -18,7 +18,7 @@ module Rpl # ( […] -- … ) unpack list on stack def unpack_list( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[list]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[list]] ) args[0][:value].each do |elt| stack << elt diff --git a/lib/core/mode.rb b/lib/core/mode.rb index 96d1629..8bc441a 100644 --- a/lib/core/mode.rb +++ b/lib/core/mode.rb @@ -7,23 +7,23 @@ module Rpl # set float precision in bits. ex: 256 prec def prec( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) - Rpl::Lang::Core.precision = args[0][:value] + Rpl::Lang.precision = args[0][:value] [stack, dictionary] end # set float representation and precision to default def default( stack, dictionary ) - Rpl::Lang::Core.precision = 12 + Rpl::Lang.precision = 12 [stack, dictionary] end # show type of stack first entry def type( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [:any] ) + stack, args = Rpl::Lang.stack_extract( stack, [:any] ) stack << { type: :string, value: args[0][:type].to_s } diff --git a/lib/core/operations.rb b/lib/core/operations.rb index 82d15a4..7ac511d 100644 --- a/lib/core/operations.rb +++ b/lib/core/operations.rb @@ -8,7 +8,7 @@ module Rpl # addition def add( stack, dictionary ) addable = %i[numeric string name list] - stack, args = Rpl::Lang::Core.stack_extract( stack, [addable, addable] ) + stack, args = Rpl::Lang.stack_extract( stack, [addable, addable] ) # | + | 1 numeric | 1 string | 1 name | 1 list | # |-----------+-----------+----------+--------+--------| # | 0 numeric | numeric | string | name | list | @@ -70,9 +70,9 @@ module Rpl # substraction def subtract( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric], %i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric], %i[numeric]] ) - stack << { type: :numeric, base: infer_resulting_base( args ), + stack << { type: :numeric, base: Rpl::Lang.infer_resulting_base( args ), value: args[1][:value] - args[0][:value] } [stack, dictionary] @@ -80,9 +80,9 @@ module Rpl # multiplication def multiply( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric], %i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric], %i[numeric]] ) - stack << { type: :numeric, base: infer_resulting_base( args ), + stack << { type: :numeric, base: Rpl::Lang.infer_resulting_base( args ), value: args[1][:value] * args[0][:value] } [stack, dictionary] @@ -90,9 +90,9 @@ module Rpl # division def divide( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric], %i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric], %i[numeric]] ) - stack << { type: :numeric, base: infer_resulting_base( args ), + stack << { type: :numeric, base: Rpl::Lang.infer_resulting_base( args ), value: args[1][:value] / args[0][:value] } [stack, dictionary] @@ -100,9 +100,9 @@ module Rpl # power def power( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric], %i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric], %i[numeric]] ) - stack << { type: :numeric, base: infer_resulting_base( args ), + stack << { type: :numeric, base: Rpl::Lang.infer_resulting_base( args ), value: args[1][:value]**args[0][:value] } [stack, dictionary] @@ -110,19 +110,19 @@ module Rpl # rpn_square root def sqrt( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) - stack << { type: :numeric, base: infer_resulting_base( args ), - value: BigMath.sqrt( BigDecimal( args[0][:value], Rpl::Lang::Core.precision ), Rpl::Lang::Core.precision ) } + stack << { type: :numeric, base: Rpl::Lang.infer_resulting_base( args ), + value: BigMath.sqrt( BigDecimal( args[0][:value], Rpl::Lang.precision ), Rpl::Lang.precision ) } [stack, dictionary] end # rpn_square def sq( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) - stack << { type: :numeric, base: infer_resulting_base( args ), + stack << { type: :numeric, base: Rpl::Lang.infer_resulting_base( args ), value: args[0][:value] * args[0][:value] } [stack, dictionary] @@ -130,9 +130,9 @@ module Rpl # absolute value def abs( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) - stack << { type: :numeric, base: infer_resulting_base( args ), + stack << { type: :numeric, base: Rpl::Lang.infer_resulting_base( args ), value: args[0][:value].abs } [stack, dictionary] @@ -140,7 +140,7 @@ module Rpl # arbitrary base representation def base( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric], %i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric], %i[numeric]] ) args[1][:base] = args[0][:value] @@ -151,7 +151,7 @@ module Rpl # 1 if number at stack level 1 is > 0, 0 if == 0, -1 if <= 0 def sign( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) value = if args[0][:value].positive? 1 elsif args[0][:value].negative? @@ -160,7 +160,7 @@ module Rpl 0 end - stack << { type: :numeric, base: infer_resulting_base( args ), + stack << { type: :numeric, base: Rpl::Lang.infer_resulting_base( args ), value: value } [stack, dictionary] @@ -170,10 +170,10 @@ module Rpl # percent def percent( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric], %i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric], %i[numeric]] ) stack << { type: :numeric, - base: infer_resulting_base( args ), + base: Rpl::Lang.infer_resulting_base( args ), value: args[0][:value] * ( args[1][:value] / 100.0 ) } [stack, dictionary] @@ -181,10 +181,10 @@ module Rpl # inverse percent def inverse_percent( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric], %i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric], %i[numeric]] ) stack << { type: :numeric, - base: infer_resulting_base( args ), + base: Rpl::Lang.infer_resulting_base( args ), value: 100.0 * ( args[0][:value] / args[1][:value] ) } [stack, dictionary] @@ -192,10 +192,10 @@ module Rpl # modulo def mod( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric], %i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric], %i[numeric]] ) stack << { type: :numeric, - base: infer_resulting_base( args ), + base: Rpl::Lang.infer_resulting_base( args ), value: args[1][:value] % args[0][:value] } [stack, dictionary] @@ -203,10 +203,10 @@ module Rpl # n! for integer n or Gamma(x+1) for fractional x def fact( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) stack << { type: :numeric, - base: infer_resulting_base( args ), + base: Rpl::Lang.infer_resulting_base( args ), value: Math.gamma( args[0][:value] ) } [stack, dictionary] @@ -214,10 +214,10 @@ module Rpl # largest number <= def floor( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) stack << { type: :numeric, - base: infer_resulting_base( args ), + base: Rpl::Lang.infer_resulting_base( args ), value: args[0][:value].floor } [stack, dictionary] @@ -225,10 +225,10 @@ module Rpl # smallest number >= def ceil( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) stack << { type: :numeric, - base: infer_resulting_base( args ), + base: Rpl::Lang.infer_resulting_base( args ), value: args[0][:value].ceil } [stack, dictionary] @@ -236,7 +236,7 @@ module Rpl # min of 2 real numbers def min( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric], %i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric], %i[numeric]] ) stack << ( args[0][:value] < args[1][:value] ? args[0] : args[1] ) @@ -245,7 +245,7 @@ module Rpl # max of 2 real numbers def max( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric], %i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric], %i[numeric]] ) stack << ( args[0][:value] > args[1][:value] ? args[0] : args[1] ) @@ -255,42 +255,27 @@ module Rpl # implemented in Rpl # negation def negate( stack, dictionary ) - stack << { value: '-1 *', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, '-1 *' ) end # inverse def inverse( stack, dictionary ) - stack << { value: '1.0 swap /', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, '1.0 swap /' ) end # decimal representation def dec( stack, dictionary ) - stack << { value: '10 base', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, '10 base' ) end # hexadecimal representation def hex( stack, dictionary ) - stack << { value: '16 base', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, '16 base' ) end # binary representation def bin( stack, dictionary ) - stack << { value: '2 base', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, '2 base' ) end end end diff --git a/lib/core/program.rb b/lib/core/program.rb index b9a6445..f7b53b5 100644 --- a/lib/core/program.rb +++ b/lib/core/program.rb @@ -7,17 +7,10 @@ module Rpl # evaluate (run) a program, or recall a variable. ex: 'my_prog' eval def eval( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [:any] ) + stack, args = Rpl::Lang.stack_extract( stack, [:any] ) - # we trim enclosing characters if necessary - preparsed_input = args[0][:value] - preparsed_input = preparsed_input.gsub( '\n', ' ' ).strip if %i[string program].include?( args[0][:type] ) - parsed_input = Rpl::Lang::Parser.new.parse_input( preparsed_input.to_s ) - - stack, dictionary = Rpl::Lang::Runner.new.run_input( parsed_input, - stack, dictionary ) - - [stack, dictionary] + Rpl::Lang.eval( stack, dictionary, + args[0][:value].to_s ) end end end diff --git a/lib/core/stack.rb b/lib/core/stack.rb index 9c40fa8..b438829 100644 --- a/lib/core/stack.rb +++ b/lib/core/stack.rb @@ -7,7 +7,7 @@ module Rpl # swap 2 first stack entries def swap( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any any] ) + stack, args = Rpl::Lang.stack_extract( stack, %i[any any] ) stack << args[0] << args[1] @@ -16,8 +16,8 @@ module Rpl # drop n first stack entries def dropn( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) - stack, _args = Rpl::Lang::Core.stack_extract( stack, %i[any] * args[0][:value] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) + stack, _args = Rpl::Lang.stack_extract( stack, %i[any] * args[0][:value] ) [stack, dictionary] end @@ -29,7 +29,7 @@ module Rpl # rotate 3 first stack entries def rot( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any any any] ) + stack, args = Rpl::Lang.stack_extract( stack, %i[any any any] ) stack << args[1] << args[0] << args[2] @@ -38,9 +38,9 @@ module Rpl # duplicate n first stack entries def dupn( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) n = args[0][:value].to_i - stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any] * args[0][:value] ) + stack, args = Rpl::Lang.stack_extract( stack, %i[any] * args[0][:value] ) args.reverse! @@ -55,9 +55,9 @@ module Rpl # push a copy of the given stack level onto the stack def pick( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) n = args[0][:value].to_i - stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any] * args[0][:value] ) + stack, args = Rpl::Lang.stack_extract( stack, %i[any] * args[0][:value] ) args.reverse! @@ -78,9 +78,9 @@ module Rpl # move a stack entry to the top of the stack def roll( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) n = args[0][:value] - stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any] * args[0][:value] ) + stack, args = Rpl::Lang.stack_extract( stack, %i[any] * args[0][:value] ) args.reverse! @@ -94,9 +94,9 @@ module Rpl # move the element on top of the stack to a higher stack position def rolld( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) n = args[0][:value] - stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any] * args[0][:value] ) + stack, args = Rpl::Lang.stack_extract( stack, %i[any] * args[0][:value] ) args.reverse! @@ -112,42 +112,27 @@ module Rpl # implemented in Rpl # push a copy of the element in stack level 2 onto the stack def over( stack, dictionary ) - stack << { value: '2 pick', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, '2 pick' ) end # drop first stack entry def drop( stack, dictionary ) - stack << { value: '1 dropn', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, '1 dropn' ) end # drop 2 first stack entries def drop2( stack, dictionary ) - stack << { value: '2 dropn', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, '2 dropn' ) end # duplicate first stack entry def dup( stack, dictionary ) - stack << { value: '1 dupn', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, '1 dupn' ) end # duplicate 2 first stack entries def dup2( stack, dictionary ) - stack << { value: '2 dupn', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, '2 dupn' ) end end end diff --git a/lib/core/store.rb b/lib/core/store.rb index 8fbb988..2e25a06 100644 --- a/lib/core/store.rb +++ b/lib/core/store.rb @@ -7,7 +7,7 @@ module Rpl # store a variable. ex: 1 'name' sto def sto( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[name], :any] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[name], :any] ) dictionary.add_var( args[0][:value], proc { |stk, dict, rcl_only = false| @@ -25,7 +25,7 @@ module Rpl # store a local variable def lsto( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[name], :any] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[name], :any] ) dictionary.add_local_var( args[0][:value], proc { |stk, dict, rcl_only = false| @@ -43,7 +43,7 @@ module Rpl # recall a variable. ex: 'name' rcl def rcl( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[name]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[name]] ) word = dictionary.lookup( args[0][:value] ) @@ -54,7 +54,7 @@ module Rpl # delete a variable. ex: 'name' purge def purge( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[name]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[name]] ) dictionary.remove_var( args[0][:value] ) @@ -64,7 +64,7 @@ module Rpl # list all variables def vars( stack, dictionary ) stack << { type: :list, - value: dictionary.vars.keys + dictionary.local_vars_layers.reduce([]) { |memo, layer| memo + layer.keys } } + value: (dictionary.vars.keys + dictionary.local_vars_layers.reduce([]) { |memo, layer| memo + layer.keys }).map { |name| { type: :name, value: name } } } [stack, dictionary] end @@ -78,66 +78,48 @@ module Rpl # add to a stored variable. ex: 1 'name' sto+ 'name' 2 sto+ def sto_add( stack, dictionary ) - stack << { value: ' + Rpl::Lang.eval( stack, dictionary, ' dup type "name" == « swap » ift - over rcl + swap sto', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + over rcl + swap sto' ) end # substract to a stored variable. ex: 1 'name' sto- 'name' 2 sto- def sto_subtract( stack, dictionary ) - stack << { value: ' + Rpl::Lang.eval( stack, dictionary, ' dup type "name" == « swap » ift - over rcl swap - swap sto', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + over rcl swap - swap sto' ) end # multiply a stored variable. ex: 3 'name' sto* 'name' 2 sto* def sto_multiply( stack, dictionary ) - stack << { value: ' + Rpl::Lang.eval( stack, dictionary, ' dup type "name" == « swap » ift - over rcl * swap sto', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + over rcl * swap sto' ) end # divide a stored variable. ex: 3 'name' sto/ 'name' 2 sto/ def sto_divide( stack, dictionary ) - stack << { value: ' + Rpl::Lang.eval( stack, dictionary, ' dup type "name" == « swap » ift - over rcl swap / swap sto', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + over rcl swap / swap sto' ) end # negate a variable. ex: 'name' sneg def sto_negate( stack, dictionary ) - stack << { value: 'dup rcl chs swap sto', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, 'dup rcl chs swap sto' ) end # inverse a variable. ex: 1 'name' sinv def sto_inverse( stack, dictionary ) - stack << { value: 'dup rcl inv swap sto', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, 'dup rcl inv swap sto' ) end end end diff --git a/lib/core/string.rb b/lib/core/string.rb index 0fad731..57576a9 100644 --- a/lib/core/string.rb +++ b/lib/core/string.rb @@ -7,7 +7,7 @@ module Rpl # convert an object into a string def to_string( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [:any] ) + stack, args = Rpl::Lang.stack_extract( stack, [:any] ) stack << { type: :string, value: args[0][:value].to_s } @@ -17,9 +17,9 @@ module Rpl # convert a string into an object def from_string( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[string]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[string]] ) - parsed_input = Rpl::Lang::Parser.new.parse_input( args[0][:value] ) + parsed_input = Rpl::Lang.parse_input( args[0][:value] ) stack += parsed_input @@ -28,7 +28,7 @@ module Rpl # convert ASCII character code in stack level 1 into a string def chr( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) stack << { type: :string, value: args[0][:value].chr } @@ -38,7 +38,7 @@ module Rpl # return ASCII code of the first character of the string in stack level 1 as a real number def num( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[string]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[string]] ) stack << { type: :numeric, base: 10, @@ -49,7 +49,7 @@ module Rpl # return the length of the string def size( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[string]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[string]] ) stack << { type: :numeric, base: 10, @@ -60,7 +60,7 @@ module Rpl # search for the string in level 1 within the string in level 2 def pos( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[string], %i[string]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[string], %i[string]] ) stack << { type: :numeric, base: 10, @@ -71,7 +71,7 @@ module Rpl # return a substring of the string in level 3 def sub( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric], %i[numeric], %i[string]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric], %i[numeric], %i[string]] ) stack << { type: :string, value: args[2][:value][ (args[1][:value] - 1)..(args[0][:value] - 1) ] } @@ -81,7 +81,7 @@ module Rpl # reverse string or list def rev( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[string list]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[string list]] ) result = args[0] @@ -100,7 +100,7 @@ module Rpl # split string def split( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[string], %i[string]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[string], %i[string]] ) args[1][:value].split( args[0][:value] ).each do |elt| stack << { type: :string, diff --git a/lib/core/test.rb b/lib/core/test.rb index e78428d..120844a 100644 --- a/lib/core/test.rb +++ b/lib/core/test.rb @@ -7,7 +7,7 @@ module Rpl # binary operator > def greater_than( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any any] ) + stack, args = Rpl::Lang.stack_extract( stack, %i[any any] ) stack << { type: :boolean, value: args[1][:value] > args[0][:value] } @@ -17,7 +17,7 @@ module Rpl # binary operator >= def greater_than_or_equal( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any any] ) + stack, args = Rpl::Lang.stack_extract( stack, %i[any any] ) stack << { type: :boolean, value: args[1][:value] >= args[0][:value] } @@ -27,7 +27,7 @@ module Rpl # binary operator < def less_than( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any any] ) + stack, args = Rpl::Lang.stack_extract( stack, %i[any any] ) stack << { type: :boolean, value: args[1][:value] < args[0][:value] } @@ -37,7 +37,7 @@ module Rpl # binary operator <= def less_than_or_equal( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any any] ) + stack, args = Rpl::Lang.stack_extract( stack, %i[any any] ) stack << { type: :boolean, value: args[1][:value] <= args[0][:value] } @@ -47,7 +47,7 @@ module Rpl # boolean operator != (different) def different( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any any] ) + stack, args = Rpl::Lang.stack_extract( stack, %i[any any] ) stack << { type: :boolean, value: args[1][:value] != args[0][:value] } @@ -57,7 +57,7 @@ module Rpl # boolean operator and def and( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[boolean], %i[boolean]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[boolean], %i[boolean]] ) stack << { type: :boolean, value: args[1][:value] && args[0][:value] } @@ -67,7 +67,7 @@ module Rpl # boolean operator or def or( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[boolean], %i[boolean]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[boolean], %i[boolean]] ) stack << { type: :boolean, value: args[1][:value] || args[0][:value] } @@ -77,7 +77,7 @@ module Rpl # boolean operator xor def xor( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[boolean], %i[boolean]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[boolean], %i[boolean]] ) stack << { type: :boolean, value: args[1][:value] ^ args[0][:value] } @@ -87,7 +87,7 @@ module Rpl # boolean operator not def not( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[boolean]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[boolean]] ) stack << { type: :boolean, value: !args[0][:value] } @@ -97,7 +97,7 @@ module Rpl # boolean operator same (equal) def same( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any any] ) + stack, args = Rpl::Lang.stack_extract( stack, %i[any any] ) stack << { type: :boolean, value: args[1][:value] == args[0][:value] } diff --git a/lib/core/trig.rb b/lib/core/trig.rb index 578df4a..613ae11 100644 --- a/lib/core/trig.rb +++ b/lib/core/trig.rb @@ -7,18 +7,18 @@ module Rpl def pi( stack, dictionary ) stack << { type: :numeric, base: 10, - value: BigMath.PI( Rpl::Lang::Core.precision ) } + value: BigMath.PI( Rpl::Lang.precision ) } [stack, dictionary] end # sinus def sinus( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) stack << { type: :numeric, - base: infer_resulting_base( args ), - value: BigMath.sin( BigDecimal( args[0][:value], Rpl::Lang::Core.precision ), Rpl::Lang::Core.precision ) } + base: Rpl::Lang.infer_resulting_base( args ), + value: BigMath.sin( BigDecimal( args[0][:value], Rpl::Lang.precision ), Rpl::Lang.precision ) } [stack, dictionary] end @@ -26,36 +26,27 @@ module Rpl # https://rosettacode.org/wiki/Trigonometric_functions#Ruby # arg sinus def arg_sinus( stack, dictionary ) - # # Handle angles with no tangent. - # return -PI / 2 if y == -1 - # return PI / 2 if y == 1 - - # # Tangent of angle is y / x, where x^2 + y^2 = 1. - # atan(y / sqrt(1 - y * y, prec), prec) - stack << { value: ' + Rpl::Lang.eval( stack, dictionary, ' dup abs 1 == « 𝛑 2 / * » « dup sq 1 swap - sqrt / atan » - ifte', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + ifte' ) end # cosinus def cosinus( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) stack << { type: :numeric, - base: infer_resulting_base( args ), - value: BigMath.cos( BigDecimal( args[0][:value], Rpl::Lang::Core.precision ), Rpl::Lang::Core.precision ) } + base: Rpl::Lang.infer_resulting_base( args ), + value: BigMath.cos( BigDecimal( args[0][:value], Rpl::Lang.precision ), Rpl::Lang.precision ) } [stack, dictionary] end # arg cosinus def arg_cosinus( stack, dictionary ) - stack << { value: ' + Rpl::Lang.eval( stack, dictionary, ' dup 0 == « drop 𝛑 2 / » « @@ -64,45 +55,33 @@ module Rpl « 𝛑 + » ift » - ifte', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + ifte' ) end # tangent def tangent( stack, dictionary ) - stack << { value: 'dup sin swap cos /', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, 'dup sin swap cos /' ) end # arg tangent def arg_tangent( stack, dictionary ) - stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] ) + stack, args = Rpl::Lang.stack_extract( stack, [%i[numeric]] ) stack << { type: :numeric, - base: infer_resulting_base( args ), - value: BigMath.atan( BigDecimal( args[0][:value], Rpl::Lang::Core.precision ), Rpl::Lang::Core.precision ) } + base: Rpl::Lang.infer_resulting_base( args ), + value: BigMath.atan( BigDecimal( args[0][:value], Rpl::Lang.precision ), Rpl::Lang.precision ) } [stack, dictionary] end # convert degrees to radians def degrees_to_radians( stack, dictionary ) - stack << { value: '𝛑 180 / *', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, '𝛑 180 / *' ) end # convert radians to degrees def radians_to_degrees( stack, dictionary ) - stack << { value: '𝛑 180 / /', - type: :program } - - Rpl::Lang::Core.eval( stack, dictionary ) + Rpl::Lang.eval( stack, dictionary, '𝛑 180 / /' ) end end end diff --git a/lib/dictionary.rb b/lib/dictionary.rb index d337240..c245383 100644 --- a/lib/dictionary.rb +++ b/lib/dictionary.rb @@ -7,7 +7,6 @@ module Rpl :local_vars_layers def initialize - @parser = Parser.new @words = {} @vars = {} @local_vars_layers = [] @@ -54,8 +53,8 @@ module Rpl end def lookup( name ) - local_var = @local_vars_layers.reverse.find { |layer| layer[ name ] } - word = local_var.nil? ? nil : local_var[name] + local_vars_layer = @local_vars_layers.reverse.find { |layer| layer[ name ] } + word = local_vars_layer.nil? ? nil : local_vars_layer[ name ] word ||= @vars[ name ] word ||= @words[ name ] diff --git a/lib/parser.rb b/lib/parser.rb index 3ebc854..db69be9 100644 --- a/lib/parser.rb +++ b/lib/parser.rb @@ -2,94 +2,92 @@ module Rpl module Lang - class Parser - def initialize; end + module_function - def numeric?( elt ) - !Float(elt).nil? + def numeric?( elt ) + !Float(elt).nil? + rescue ArgumentError + begin + !Integer(elt).nil? rescue ArgumentError - begin - !Integer(elt).nil? - rescue ArgumentError - false + false + end + end + + def parse_input( input ) + splitted_input = input.split(' ') + + # 2-passes: + # 1. regroup strings and programs + opened_programs = 0 + closed_programs = 0 + string_delimiters = 0 + name_delimiters = 0 + regrouping = false + + regrouped_input = [] + splitted_input.each do |elt| + if elt[0] == '«' + opened_programs += 1 + elt.gsub!( '«', '« ') if elt.length > 1 && elt[1] != ' ' end + string_delimiters += 1 if elt[0] == '"' && elt.length > 1 + name_delimiters += 1 if elt[0] == "'" && elt.length > 1 + + elt = "#{regrouped_input.pop} #{elt}".strip if regrouping + + regrouped_input << elt + + if elt[-1] == '»' + closed_programs += 1 + elt.gsub!( '»', ' »') if elt.length > 1 && elt[-2] != ' ' + end + string_delimiters += 1 if elt[-1] == '"' + name_delimiters += 1 if elt[-1] == "'" + + regrouping = string_delimiters.odd? || name_delimiters.odd? || (opened_programs > closed_programs ) end - def parse_input( input ) - splitted_input = input.split(' ') + # 2. parse + parsed_tree = [] + regrouped_input.each do |elt| + parsed_entry = { value: elt } - # 2-passes: - # 1. regroup strings and programs - opened_programs = 0 - closed_programs = 0 - string_delimiters = 0 - name_delimiters = 0 - regrouping = false - - regrouped_input = [] - splitted_input.each do |elt| - if elt[0] == '«' - opened_programs += 1 - elt.gsub!( '«', '« ') if elt.length > 1 && elt[1] != ' ' - end - string_delimiters += 1 if elt[0] == '"' && elt.length > 1 - name_delimiters += 1 if elt[0] == "'" && elt.length > 1 - - elt = "#{regrouped_input.pop} #{elt}".strip if regrouping - - regrouped_input << elt - - if elt[-1] == '»' - closed_programs += 1 - elt.gsub!( '»', ' »') if elt.length > 1 && elt[-2] != ' ' - end - string_delimiters += 1 if elt[-1] == '"' - name_delimiters += 1 if elt[-1] == "'" - - regrouping = string_delimiters.odd? || name_delimiters.odd? || (opened_programs > closed_programs ) - end - - # 2. parse - parsed_tree = [] - regrouped_input.each do |elt| - parsed_entry = { value: elt } - - parsed_entry[:type] = case elt[0] - when '«' - :program - when '"' - :string - when "'" - :name # TODO: check for forbidden space + parsed_entry[:type] = case elt[0] + when '«' + :program + when '"' + :string + when "'" + :name # TODO: check for forbidden space + else + if numeric?( elt ) + :numeric else - if numeric?( elt ) - :numeric - else - :word - end + :word end + end - if %I[string name].include?( parsed_entry[:type] ) - parsed_entry[:value] = parsed_entry[:value][1..-2] - elsif parsed_entry[:type] == :program - parsed_entry[:value] = parsed_entry[:value][2..-3] - elsif parsed_entry[:type] == :numeric - parsed_entry[:base] = 10 # TODO: parse others possible bases 0x... + if %I[string name].include?( parsed_entry[:type] ) + parsed_entry[:value] = parsed_entry[:value][1..-2] + elsif parsed_entry[:type] == :program + parsed_entry[:value] = parsed_entry[:value][2..-3] + elsif parsed_entry[:type] == :numeric + parsed_entry[:base] = 10 # TODO: parse others possible bases 0x... - # TODO: store value as BigDecimal - begin - parsed_entry[:value] = Float( parsed_entry[:value] ) - parsed_entry[:value] = parsed_entry[:value].to_i if (parsed_entry[:value] % 1).zero? && elt.index('.').nil? - rescue ArgumentError - parsed_entry[:value] = Integer( parsed_entry[:value] ) - end + # TODO: store value as BigDecimal + begin + parsed_entry[:value] = Float( parsed_entry[:value] ) + parsed_entry[:value] = parsed_entry[:value].to_i if (parsed_entry[:value] % 1).zero? && elt.index('.').nil? + rescue ArgumentError + parsed_entry[:value] = Integer( parsed_entry[:value] ) end - - parsed_tree << parsed_entry end - parsed_tree + parsed_tree << parsed_entry end + + parsed_tree end end end diff --git a/lib/runner.rb b/lib/runner.rb index 331caab..3ed387f 100644 --- a/lib/runner.rb +++ b/lib/runner.rb @@ -2,34 +2,32 @@ module Rpl module Lang - class Runner - def initialize; end + module_function - def run_input( input, stack, dictionary ) - dictionary.add_local_vars_layer + def run_input( input, stack, dictionary ) + dictionary.add_local_vars_layer - input.each do |elt| - case elt[:type] - when :word - command = dictionary.lookup( elt[:value] ) + input.each do |elt| + case elt[:type] + when :word + command = dictionary.lookup( elt[:value] ) - if command.nil? - # if there's command by that name then it's a name - elt[:type] = :name + if command.nil? + # if there's command by that name then it's a name + elt[:type] = :name - stack << elt - else - stack, dictionary = command.call( stack, dictionary ) - end - else stack << elt + else + stack, dictionary = command.call( stack, dictionary ) end + else + stack << elt end - - dictionary.remove_local_vars_layer - - [stack, dictionary] end + + dictionary.remove_local_vars_layer + + [stack, dictionary] end end end diff --git a/repl.rb b/repl.rb index 14237a7..fed552f 100644 --- a/repl.rb +++ b/repl.rb @@ -53,7 +53,7 @@ class RplRepl end "#{prefix}#{elt[:value].to_s( elt[:base] )}" when :list - "[#{elt[:value].map { |e| e[:value] }.join(', ')}]" + "[#{elt[:value].map { |e| format_element( e ) }.join(', ')}]" when :program "« #{elt[:value]} »" when :string diff --git a/spec/core_spec.rb b/spec/core_spec.rb index 2107a6f..53b4bbf 100644 --- a/spec/core_spec.rb +++ b/spec/core_spec.rb @@ -7,7 +7,7 @@ require_relative '../lib/core' class TestParser < Test::Unit::TestCase def test_stack_extract - stack, args = Rpl::Lang::Core.stack_extract [{ value: 1, type: :numeric }, + stack, args = Rpl::Lang.stack_extract [{ value: 1, type: :numeric }, { value: 2, type: :numeric }], [:any] assert_equal [{ value: 1, type: :numeric }], @@ -15,7 +15,7 @@ class TestParser < Test::Unit::TestCase assert_equal [{ value: 2, type: :numeric }], args - stack, args = Rpl::Lang::Core.stack_extract [{ value: 'test', type: :string }, + stack, args = Rpl::Lang.stack_extract [{ value: 'test', type: :string }, { value: 2, type: :numeric }], [[:numeric], :any] assert_equal [], diff --git a/spec/language_filesystem_spec.rb b/spec/language_filesystem_spec.rb index be2cdbb..ea044c9 100644 --- a/spec/language_filesystem_spec.rb +++ b/spec/language_filesystem_spec.rb @@ -21,7 +21,7 @@ trrr lang.run 'eval vars' assert_equal [{ value: 27, base: 10, type: :numeric }, - { value: ['trrr'], type: :list }], + { value: [{ type: :name, value: 'trrr' }], type: :list }], lang.stack end @@ -29,7 +29,7 @@ trrr lang = Rpl::Language.new lang.run '"spec/test.rpl" feval vars' assert_equal [{ value: 27, base: 10, type: :numeric }, - { value: ['trrr'], type: :list }], + { value: [{ type: :name, value: 'trrr' }], type: :list }], lang.stack end diff --git a/spec/language_store_spec.rb b/spec/language_store_spec.rb index 42d40e7..d258ec8 100644 --- a/spec/language_store_spec.rb +++ b/spec/language_store_spec.rb @@ -47,7 +47,8 @@ class TestLanguageProgram < Test::Unit::TestCase def test_vars lang = Rpl::Language.new lang.run '« 2 dup * » \'quatre\' sto 1 \'un\' sto vars' - assert_equal [{ value: %w[quatre un], type: :list }], + assert_equal [{ value: [{ type: :name, value: 'quatre' }, + { type: :name, value: 'un' }], type: :list }], lang.stack end diff --git a/spec/language_trig_spec.rb b/spec/language_trig_spec.rb index 3893ce9..4eafd65 100644 --- a/spec/language_trig_spec.rb +++ b/spec/language_trig_spec.rb @@ -9,14 +9,14 @@ class TesttLanguageOperations < Test::Unit::TestCase def test_pi lang = Rpl::Language.new lang.run 'pi' - assert_equal [{ value: BigMath.PI( Rpl::Lang::Core.precision ), type: :numeric, base: 10 }], + assert_equal [{ value: BigMath.PI( Rpl::Lang.precision ), type: :numeric, base: 10 }], lang.stack end def test_sin lang = Rpl::Language.new lang.run '3 sin' - assert_equal [{ value: BigMath.sin( BigDecimal( 3 ), Rpl::Lang::Core.precision ), type: :numeric, base: 10 }], + assert_equal [{ value: BigMath.sin( BigDecimal( 3 ), Rpl::Lang.precision ), type: :numeric, base: 10 }], lang.stack end @@ -30,7 +30,7 @@ class TesttLanguageOperations < Test::Unit::TestCase def test_cos lang = Rpl::Language.new lang.run '3 cos' - assert_equal [{ value: BigMath.cos( BigDecimal( 3 ), Rpl::Lang::Core.precision ), type: :numeric, base: 10 }], + assert_equal [{ value: BigMath.cos( BigDecimal( 3 ), Rpl::Lang.precision ), type: :numeric, base: 10 }], lang.stack end @@ -51,14 +51,14 @@ class TesttLanguageOperations < Test::Unit::TestCase def test_atan lang = Rpl::Language.new lang.run '1 atan' - assert_equal [{ value: BigMath.atan( BigDecimal( 1 ), Rpl::Lang::Core.precision ), type: :numeric, base: 10 }], + assert_equal [{ value: BigMath.atan( BigDecimal( 1 ), Rpl::Lang.precision ), type: :numeric, base: 10 }], lang.stack end def test_d→r lang = Rpl::Language.new lang.run '90 d→r' - assert_equal [{ value: BigDecimal( 1.57079632679489661923132169168272243847381663981000003, Rpl::Lang::Core.precision ), + assert_equal [{ value: BigDecimal( 1.57079632679489661923132169168272243847381663981000003, Rpl::Lang.precision ), type: :numeric, base: 10 }], lang.stack end diff --git a/spec/parser_spec.rb b/spec/parser_spec.rb index d51ec1e..f53f596 100644 --- a/spec/parser_spec.rb +++ b/spec/parser_spec.rb @@ -7,112 +7,112 @@ require_relative '../lib/parser' class TestParser < Test::Unit::TestCase def test_number - result = Rpl::Lang::Parser.new.parse_input( '1' ) + result = Rpl::Lang.parse_input( '1' ) assert_equal [{ value: 1, type: :numeric, base: 10 }], result end def test_word - result = Rpl::Lang::Parser.new.parse_input( 'dup' ) + result = Rpl::Lang.parse_input( 'dup' ) assert_equal [{ value: 'dup', type: :word }], result end def test_string - result = Rpl::Lang::Parser.new.parse_input( '"test"' ) + result = Rpl::Lang.parse_input( '"test"' ) assert_equal [{ value: 'test', type: :string }], result - result = Rpl::Lang::Parser.new.parse_input( '" test"' ) + result = Rpl::Lang.parse_input( '" test"' ) assert_equal [{ value: ' test', type: :string }], result - result = Rpl::Lang::Parser.new.parse_input( '"test "' ) + result = Rpl::Lang.parse_input( '"test "' ) assert_equal [{ value: 'test ', type: :string }], result - result = Rpl::Lang::Parser.new.parse_input( '" test "' ) + result = Rpl::Lang.parse_input( '" test "' ) assert_equal [{ value: ' test ', type: :string }], result - result = Rpl::Lang::Parser.new.parse_input( '" « test » "' ) + result = Rpl::Lang.parse_input( '" « test » "' ) assert_equal [{ value: ' « test » ', type: :string }], result end def test_name - result = Rpl::Lang::Parser.new.parse_input( "'test'" ) + result = Rpl::Lang.parse_input( "'test'" ) assert_equal [{ value: 'test', type: :name }], result end def test_program - result = Rpl::Lang::Parser.new.parse_input( '« test »' ) + result = Rpl::Lang.parse_input( '« test »' ) assert_equal [{ value: 'test', type: :program }], result - result = Rpl::Lang::Parser.new.parse_input( '«test »' ) + result = Rpl::Lang.parse_input( '«test »' ) assert_equal [{ value: 'test', type: :program }], result - result = Rpl::Lang::Parser.new.parse_input( '« test»' ) + result = Rpl::Lang.parse_input( '« test»' ) assert_equal [{ value: 'test', type: :program }], result - result = Rpl::Lang::Parser.new.parse_input( '«test»' ) + result = Rpl::Lang.parse_input( '«test»' ) assert_equal [{ value: 'test', type: :program }], result - result = Rpl::Lang::Parser.new.parse_input( '« test test »' ) + result = Rpl::Lang.parse_input( '« test test »' ) assert_equal [{ value: 'test test', type: :program }], result - result = Rpl::Lang::Parser.new.parse_input( '« test « test » »' ) + result = Rpl::Lang.parse_input( '« test « test » »' ) assert_equal [{ value: 'test « test »', type: :program }], result - result = Rpl::Lang::Parser.new.parse_input( '« test "test" test »' ) + result = Rpl::Lang.parse_input( '« test "test" test »' ) assert_equal [{ value: 'test "test" test', type: :program }], result end def test_number_number - result = Rpl::Lang::Parser.new.parse_input( '2 3' ) + result = Rpl::Lang.parse_input( '2 3' ) assert_equal [{ value: 2, type: :numeric, base: 10 }, { value: 3, type: :numeric, base: 10 }], result end def test_number_number_word - result = Rpl::Lang::Parser.new.parse_input( '2 3 +' ) + result = Rpl::Lang.parse_input( '2 3 +' ) assert_equal [{ value: 2, type: :numeric, base: 10 }, { value: 3, type: :numeric, base: 10 }, { value: '+', type: :word }], result end def test_number_string - result = Rpl::Lang::Parser.new.parse_input( '4 "test"' ) + result = Rpl::Lang.parse_input( '4 "test"' ) assert_equal [{ value: 4, type: :numeric, base: 10 }, { value: 'test', type: :string }], result end def test_emptystring - result = Rpl::Lang::Parser.new.parse_input( '""' ) + result = Rpl::Lang.parse_input( '""' ) assert_equal [{ value: '', type: :string }], result end def test_spacestring - result = Rpl::Lang::Parser.new.parse_input( '" "' ) + result = Rpl::Lang.parse_input( '" "' ) assert_equal [{ value: ' ', type: :string }], result end def test_string_spacestring - result = Rpl::Lang::Parser.new.parse_input( '"test string" " "' ) + result = Rpl::Lang.parse_input( '"test string" " "' ) assert_equal [{ value: 'test string', type: :string }, { value: ' ', type: :string }], result end def test_string_word - result = Rpl::Lang::Parser.new.parse_input( '"test string" split' ) + result = Rpl::Lang.parse_input( '"test string" split' ) assert_equal [{ value: 'test string', type: :string }, { value: 'split', type: :word }], result end def test_spacestring_word - result = Rpl::Lang::Parser.new.parse_input( '" " split' ) + result = Rpl::Lang.parse_input( '" " split' ) assert_equal [{ value: ' ', type: :string }, { value: 'split', type: :word }], result end def test_program_name - result = Rpl::Lang::Parser.new.parse_input( "« 2 dup * » 'carré' sto" ) + result = Rpl::Lang.parse_input( "« 2 dup * » 'carré' sto" ) assert_equal [{ value: '2 dup *', type: :program }, { value: 'carré', type: :name },