Advertisement
lilo_booter

rrpn v2

Mar 29th, 2022
1,458
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.98 KB | None | 0 0
  1. use std::env;
  2. use num_traits::Float;
  3. use std::str::FromStr;
  4. use std::fmt::Debug;
  5. use std::collections::HashMap;
  6.  
  7. // Basic Stack is just a vector
  8. struct Stack< T >
  9. {
  10.     stack: Vec< T >,
  11. }
  12.  
  13. // Implementation provides push, pop, pick etc
  14. impl< T : Copy > Stack< T >
  15. {
  16.     fn new( ) -> Self
  17.     {
  18.         Stack { stack: Vec::new( ) }
  19.     }
  20.  
  21.     fn depth( &self ) -> usize
  22.     {
  23.         self.stack.len( )
  24.     }
  25.  
  26.     fn pop( &mut self ) -> Option< T >
  27.     {
  28.         self.stack.pop( )
  29.     }
  30.  
  31.     fn push( &mut self, item: T )
  32.     {
  33.         self.stack.push( item );
  34.     }
  35.  
  36.     fn pick( &self, index: usize ) -> T
  37.     {
  38.         let depth = self.depth( );
  39.         self.stack[ depth - index - 1 ]
  40.     }
  41. }
  42.  
  43. // For now, only Floats types are supported
  44. trait StackEntry : Float + FromStr + Debug
  45. {
  46. }
  47.  
  48. // This ensures the f32 and f64 are identified as StackEntry
  49. impl< T : Float + FromStr + Debug > StackEntry for T
  50. {
  51. }
  52.  
  53. // Vocab implementation
  54. fn add< T : StackEntry >( stack: &mut Stack< T > )
  55. {
  56.     let tos = stack.pop( );
  57.     let bos = stack.pop( );
  58.     stack.push( bos.unwrap( ) + tos.unwrap( ) );
  59. }
  60.  
  61. fn sub< T : StackEntry >( stack: &mut Stack< T > )
  62. {
  63.     let tos = stack.pop( );
  64.     let bos = stack.pop( );
  65.     stack.push( bos.unwrap( ) - tos.unwrap( ) );
  66. }
  67.  
  68. fn mul< T : StackEntry >( stack: &mut Stack< T > )
  69. {
  70.     let tos = stack.pop( );
  71.     let bos = stack.pop( );
  72.     stack.push( bos.unwrap( ) * tos.unwrap( ) );
  73. }
  74.  
  75. fn div< T : StackEntry >( stack: &mut Stack< T > )
  76. {
  77.     let tos = stack.pop( );
  78.     let bos = stack.pop( );
  79.     stack.push( bos.unwrap( ) / tos.unwrap( ) );
  80. }
  81.  
  82. fn dup< T : StackEntry >( stack: &mut Stack< T > )
  83. {
  84.     let value = stack.pick( 0 );
  85.     stack.push( value );
  86. }
  87.  
  88. fn drop< T : StackEntry >( stack: &mut Stack< T > )
  89. {
  90.     stack.pop( );
  91. }
  92.  
  93. fn dot< T : StackEntry >( stack: &mut Stack< T > )
  94. {
  95.     let result = stack.pop( );
  96.     match result
  97.     {
  98.         Some( x ) => println!( "{:?}", x ),
  99.         None      => println!( "ERR: Underflow" ),
  100.     };
  101. }
  102.  
  103. struct Vocabulary< T >
  104. {
  105.     list : HashMap< String, fn( stack: &mut Stack< T > ) >,
  106. }
  107.  
  108. impl< T : StackEntry > Vocabulary< T >
  109. {
  110.     fn new( ) -> Self
  111.     {
  112.         Vocabulary { list: HashMap::new( ) }
  113.     }
  114.  
  115.     fn add( &mut self, name: &str, func: fn( stack: &mut Stack< T > ) )
  116.     {
  117.         self.list.insert( name.to_string( ), func );
  118.     }
  119.  
  120.     fn eval( &self, stack: &mut Stack< T >, token: String )
  121.     {
  122.         match self.list.get( token.as_str( ) )
  123.         {
  124.             Some( word ) => word( stack ),
  125.             _ => stack.push( token.as_str( ).parse::< T >( ).unwrap_or( T::nan( ) ) ),
  126.         }
  127.     }
  128. }
  129.  
  130. fn run< T : StackEntry >( )
  131. {
  132.     let mut stack: Stack< T > = Stack::new( );
  133.  
  134.     let mut vocab: Vocabulary< T > = Vocabulary::new( );
  135.     vocab.add( "+", add );
  136.     vocab.add( "-", sub );
  137.     vocab.add( "*", mul );
  138.     vocab.add( "/", div );
  139.     vocab.add( ".", dot );
  140.     vocab.add( "drop", drop );
  141.     vocab.add( "dup", dup );
  142.  
  143.     let args: Vec< String > = env::args( ).collect( );
  144.     for arg in args.iter( ).skip( 1 )
  145.     {
  146.         vocab.eval( &mut stack, arg.to_string( ) );
  147.     }
  148.  
  149.     if stack.depth( ) > 0
  150.     {
  151.         dot( &mut stack );
  152.     }
  153. }
  154.  
  155. fn main( )
  156. {
  157.     run::< f32 >( );
  158. }
  159.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement