big refactoring

This commit is contained in:
Gwenhael Le Moine 2022-02-08 15:45:36 +01:00
parent 217a4e98ee
commit 8c5657db42
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
22 changed files with 634 additions and 549 deletions

View file

@ -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 <test-instruction> then <true-instructions> else <false-instructions> 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> <end> start <instructions> next|<step> step
# @dictionary.add( 'for', proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # <start> <end> for <variable> <instructions> next|<step> 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 <instructions> until <condition> 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 <test-instruction> repeat <loop-instructions> 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 <test-instruction> then <true-instructions> else <false-instructions> 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> <end> start <instructions> next|<step> step
# @dictionary.add( 'for',
# proc { |stack, dictionary| Rpl::Lang::Core.__todo( stack, dictionary ) } ) # <start> <end> for <variable> <instructions> next|<step> 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 <instructions> until <condition> 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 <test-instruction> repeat <loop-instructions> 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

View file

@ -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

View file

@ -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, <test-instruction> <true-instruction> <false-instruction> 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, <test-instruction> <true-instruction> 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

View file

@ -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] )

View file

@ -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

View file

@ -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 }

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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] }

View file

@ -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

View file

@ -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 ]

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 [],

View file

@ -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

View file

@ -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

View file

@ -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_dr
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

View file

@ -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 },