rpl.rb/lib/rpl/words/operations.rb

402 lines
17 KiB
Ruby
Raw Normal View History

2021-12-07 16:09:17 +01:00
# frozen_string_literal: true
module RplLang
module Words
module Operations
2022-02-26 18:53:39 +01:00
include Types
def populate_dictionary
super
# Usual operations on reals and complexes
@dictionary.add_word( ['+'],
'Usual operations on reals and complexes',
'( a b -- c ) addition',
proc do
2022-02-26 18:53:39 +01:00
addable = [RplNumeric, RplString, RplName, RplList]
args = stack_extract( [addable, addable] )
2022-02-26 18:53:39 +01:00
# | + | 1 numeric | 1 string | 1 name |v1 list |
# |-----------+-----------+----------+--------+--------|
2022-02-26 18:53:39 +01:00
# | 0 numeric | numeric | string | name |vlist |
# |v0 string |vstring |vstring |vstring |vlist |
# |v0 name |vstring |vstring |vname |vlist |
# |v0 list |vlist |vlist |vlist |vlist |
args.reverse!
result = if args[0].instance_of?( RplList )
if args[1].instance_of?( RplList )
args[0].value.concat( args[1].value )
else
args[0].value << args[1]
end
args[0]
elsif args[1].instance_of?( RplList )
if args[0].instance_of?( RplList )
args[0].value.concat( args[1].value )
args[0]
else
args[1].value.unshift( args[0] )
args[1]
end
elsif args[0].instance_of?( RplString )
args[0].value = if args[1].instance_of?( RplString ) ||
args[1].instance_of?( RplName )
"#{args[0].value}#{args[1].value}"
else
"#{args[0].value}#{args[1]}"
end
args[0]
elsif args[0].instance_of?( RplName )
if args[1].instance_of?( RplName )
args[0].value = "#{args[0].value}#{args[1].value}"
args[0]
else
if args[1].instance_of?( RplString )
2022-02-28 11:40:47 +01:00
Types.new_object( RplString, "\"#{args[0].value}#{args[1].value}\"" )
2022-02-26 18:53:39 +01:00
elsif args[1].instance_of?( RplNumeric )
args[0].value = "#{args[0].value}#{args[1]}"
args[0]
else
2022-02-28 11:40:47 +01:00
Types.new_object( RplString, "\"#{args[0]}#{args[1]}\"" )
2022-02-26 18:53:39 +01:00
end
end
elsif args[0].instance_of?( RplNumeric )
if args[1].instance_of?( RplNumeric )
args[0].value += args[1].value
args[0]
elsif args[1].instance_of?( RplString ) ||
args[1].instance_of?( RplName )
args[1].value = "#{args[0]}#{args[1].value}"
args[1]
end
end
@stack << result
end )
@dictionary.add_word( ['-'],
'Usual operations on reals and complexes',
'( a b -- c ) subtraction',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric], [RplNumeric]] )
args[1].value = args[1].value - args[0].value
2022-02-26 18:53:39 +01:00
@stack << args[1]
end )
@dictionary.add_word( ['chs'],
'Usual operations on reals and complexes',
'( a -- b ) negate',
proc do
run( '-1 *' )
end )
@dictionary.add_word( ['×', '*'],
'Usual operations on reals and complexes',
'( a b -- c ) multiplication',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric], [RplNumeric]] )
2022-02-26 18:53:39 +01:00
args[1].value = args[1].value * args[0].value
@stack << args[1]
end )
@dictionary.add_word( ['÷', '/'],
'Usual operations on reals and complexes',
'( a b -- c ) division',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric], [RplNumeric]] )
args[1].value = args[1].value / args[0].value
2022-02-26 18:53:39 +01:00
@stack << args[1]
end )
@dictionary.add_word( ['inv'],
'Usual operations on reals and complexes',
'( a -- b ) invert numeric',
proc do
run( '1.0 swap /' )
end )
@dictionary.add_word( ['^'],
'Usual operations on reals and complexes',
'( a b -- c ) a to the power of b',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric], [RplNumeric]] )
args[1].value = args[1].value**args[0].value
2022-02-26 18:53:39 +01:00
@stack << args[1]
end )
@dictionary.add_word( ['√', 'sqrt'],
'Usual operations on reals and complexes',
'( a -- b ) square root',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric]] )
2022-02-26 18:53:39 +01:00
args[0].value = BigMath.sqrt( args[0].value, RplNumeric.precision )
@stack << args[0]
end )
@dictionary.add_word( ['²', 'sq'],
'Usual operations on reals and complexes',
'( a -- b ) square',
proc do
run( 'dup ×')
end )
@dictionary.add_word( ['abs'],
'Usual operations on reals and complexes',
'( a -- b ) absolute value',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric]] )
args[0].value = args[0].value.abs
2022-02-26 18:53:39 +01:00
@stack << args[0]
end )
@dictionary.add_word( ['dec'],
'Usual operations on reals and complexes',
'( a -- a ) set numeric\'s base to 10',
proc do
run( '10 base' )
end )
@dictionary.add_word( ['hex'],
'Usual operations on reals and complexes',
'( a -- a ) set numeric\'s base to 16',
proc do
run( '16 base' )
end )
@dictionary.add_word( ['bin'],
'Usual operations on reals and complexes',
'( a -- a ) set numeric\'s base to 2',
proc do
run( '2 base' )
end )
@dictionary.add_word( ['base'],
'Usual operations on reals and complexes',
'( a b -- a ) set numeric\'s base to b',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric], [RplNumeric]] )
2022-02-26 18:53:39 +01:00
args[1].base = args[0].value
@stack << args[1]
end )
@dictionary.add_word( ['sign'],
'Usual operations on reals and complexes',
'( a -- b ) sign of element',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric]] )
args[0].value = if args[0].value.positive?
1
elsif args[0].value.negative?
-1
else
0
end
@stack << args[0]
end )
# Operations on reals
@dictionary.add_word( ['%'],
'Operations on reals',
'( a b -- c ) b% of a',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric], [RplNumeric]] )
2022-02-26 18:53:39 +01:00
args[1].value = args[0].value * ( args[1].value / 100.0 )
@stack << args[1]
end )
@dictionary.add_word( ['%CH'],
'Operations on reals',
'( a b -- c ) b is c% of a',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric], [RplNumeric]] )
args[1].value = 100.0 * ( args[0].value / args[1].value )
2022-02-26 18:53:39 +01:00
@stack << args[1]
end )
@dictionary.add_word( ['mod'],
'Operations on reals',
'( a b -- c ) modulo',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric], [RplNumeric]] )
args[1].value = args[1].value % args[0].value
2022-02-26 18:53:39 +01:00
@stack << args[1]
end )
@dictionary.add_word( ['!', 'fact'],
'Operations on reals',
'( a -- b ) factorial',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric]] )
2022-02-26 18:53:39 +01:00
args[0].value = Math.gamma( args[0].value )
@stack << args[0]
end )
@dictionary.add_word( ['floor'],
'Operations on reals',
'( a -- b ) highest integer under a',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric]] )
args[0].value = args[0].value.floor
2022-02-26 18:53:39 +01:00
@stack << args[0]
end )
@dictionary.add_word( ['ceil'],
'Operations on reals',
'( a -- b ) highest integer over a',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric]] )
args[0].value = args[0].value.ceil
2022-02-26 18:53:39 +01:00
@stack << args[0]
end )
@dictionary.add_word( ['min'],
'Operations on reals',
'( a b -- a/b ) leave lowest of a or b',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric], [RplNumeric]] )
2022-02-26 18:53:39 +01:00
@stack << ( args[0].value < args[1].value ? args[0] : args[1] )
end )
@dictionary.add_word( ['max'],
'Operations on reals',
'( a b -- a/b ) leave highest of a or b',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric], [RplNumeric]] )
2022-02-26 18:53:39 +01:00
@stack << ( args[0].value > args[1].value ? args[0] : args[1] )
end )
2022-02-22 16:38:42 +01:00
@dictionary.add_word( ['mant'],
'Operations on reals',
'mantissa of a real number',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric]] )
2022-02-11 16:30:49 +01:00
2022-02-28 11:40:47 +01:00
@stack << Types.new_object( RplNumeric, args[0].value.to_s.split('e').first.to_f.abs )
2022-02-22 16:38:42 +01:00
end )
2022-02-15 18:48:19 +01:00
@dictionary.add_word( ['xpon'],
'Operations on reals',
'exponant of a real number',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric]] )
2022-02-11 16:30:49 +01:00
2022-02-26 18:53:39 +01:00
args[0].value = args[0].value.exponent
@stack << args[0]
2022-02-15 18:48:19 +01:00
end )
@dictionary.add_word( ['ip'],
'Operations on reals',
'( n -- i ) integer part',
proc do
run( 'dup fp -' )
end )
@dictionary.add_word( ['fp'],
'Operations on reals',
'( n -- f ) fractional part',
proc do
2022-02-26 18:53:39 +01:00
args = stack_extract( [[RplNumeric]] )
args[0].value = args[0].value.frac
2022-02-26 18:53:39 +01:00
@stack << args[0]
end )
2022-02-11 16:30:49 +01:00
# Operations on complexes
# @dictionary.add_word( ['re'],
2022-02-11 16:30:49 +01:00
# 'Operations on complexes',
# 'complex real part',
# proc do
# end )
# @dictionary.add_word( 'im',
2022-02-11 16:30:49 +01:00
# 'Operations on complexes',
# 'complex imaginary part',
# proc do
# end )
# @dictionary.add_word( ['conj'],
2022-02-11 16:30:49 +01:00
# 'Operations on complexes',
# 'complex conjugate',
# proc do
# end )
# @dictionary.add_word( 'arg',
2022-02-11 16:30:49 +01:00
# 'Operations on complexes',
# 'complex argument in radians',
# proc do
# end )
# @dictionary.add_word( ['c→r', 'c->r'],
# 'Operations on complexes',
# 'transform a complex in 2 reals',
# proc do
# end )
# @dictionary.add_word( ['r→c', 'r->c'],
# 'Operations on complexes',
# 'transform 2 reals in a complex',
# proc do
# end )
# @dictionary.add_word( ['p→r', 'p->r'],
# 'Operations on complexes',
# 'cartesian to polar',
# proc do
# end )
# @dictionary.add_word( ['r→p', 'r->p'],
# 'Operations on complexes',
# 'polar to cartesian',
# proc do
# end )
2022-02-10 14:50:59 +01:00
end
end
end
end