Решение на Forth от Даяна Веселинова

Обратно към всички решения

Към профила на Даяна Веселинова

Резултати

  • 0 точки от тестове
  • 0 бонус точки
  • 0 точки общо
  • 0 успешни тест(а)
  • 0 неуспешни тест(а)

Код

use std::collections::HashMap;
use std::iter::Iterator;
use std::str;
/// Грешки, които могат да се срещнат по време на изпълнение на програмата
///
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum RuntimeError {
DivideByZero,
StackUnderflow,
UnknownWord,
}
//type Callback =Fn(i32) -> i32 + 'static;
pub struct Interpreter {
stack:Vec<i32>,
variables:HashMap<String,String>,
// functions:HashMap<String, Callback>,
}
impl Interpreter {
/// Създава нов интерпретатор
///
pub fn new() -> Self {
Interpreter{stack:Vec::new(), variables:HashMap::new()}
}
/// Дефинира нова дума за променлива.
///
/// При срещане на думата `name` се добавя стойността `val`
/// на върха на стека.
///
pub fn def_var(&mut self, name: &str, val: i32) {
self.variables.insert(name.to_string(), val.to_string());
}
/// Дефинира нова дума за едноместен оператор
///
/// При срещане на думата `name` се изважда най-горният елемент
/// от стека, изпълнява се `op` и резултатът се добавя в стека.
///
pub fn def_unary_op<F>(&mut self, name: &str, op: F)
where
F: Fn(i32) -> i32 + 'static,
{
let first_number=self.stack.pop().unwrap();
let changed_variable=op(first_number);
self.stack.push(changed_variable)
}
/// Дефинира нова дума за едноместен оператор
///
/// При срещане на думата `name` се изваждат най-горните два елемента
/// от стека, изпълнява се `op` и резултатът се добавя в стека.
///
pub fn def_binary_op<F>(&mut self, name: &str, op: F)
where
F: Fn(i32, i32) -> i32 + 'static,
{
let first_number=self.stack.pop().unwrap();
let second_number=self.stack.pop().unwrap();
let changed_variable=op(first_number, second_number);
self.stack.push(changed_variable);
}
/// Изпълнява програмата `input` в този интерпретатор.
///
/// Ако програмата се изпълни успрешно се връща `Ok(top)`, където
/// `top` е елемента на върха на стека, или `None` ако стекът е празен.
///
/// Ако по време на изпълнението се срещне грешка се връща `Err`.
///
pub fn run(&mut self, input: &str) -> Result<Option<i32>, RuntimeError> {
let v:Vec<&str> = input.split(' ').collect();
let mut _trimmed:Vec<String>=Vec::new();
for element in v.iter() {
if !element.is_empty() {
if element.parse::<i32>().is_ok() {
_trimmed.push(element.to_string());
}
else if !element.parse::<i32>().is_ok() {
for (key,value) in self.variables.iter() {
if key == &element.to_string(){
_trimmed.push(value.to_string())
}
}}
if element==&"ADD"{
let first_number=_trimmed.pop().unwrap().parse::<i32>().unwrap();
let second_number=_trimmed.pop().unwrap().parse::<i32>().unwrap();
_trimmed.push((first_number + second_number).to_string());
} else if element==&"SUB"{
let first_number=_trimmed.pop().unwrap().parse::<i32>().unwrap();
let second_number=_trimmed.pop().unwrap().parse::<i32>().unwrap();
_trimmed.push((first_number-second_number).to_string());
} else if element==&"MUL"{
let first_number=_trimmed.pop().unwrap().parse::<i32>().unwrap();
let second_number=_trimmed.pop().unwrap().parse::<i32>().unwrap();
_trimmed.push((first_number*second_number).to_string());
} else if element==&"DIV" {
let first_number=_trimmed.pop().unwrap().parse::<i32>().unwrap();
let second_number=_trimmed.pop().unwrap().parse::<i32>().unwrap();
if second_number==0 {
return Err(RuntimeError::DivideByZero);
} else {
_trimmed.push((first_number/second_number).to_string());
}
} else if element==&"DUP" {
let get_number=_trimmed.pop().unwrap();
let dup_num:String=String::clone(&get_number);
_trimmed.push(get_number);
_trimmed.push(dup_num);
} else if element==&"POP"{
if _trimmed.is_empty(){
return Err(RuntimeError::StackUnderflow);
}else{
if _trimmed.len()==1{
_trimmed.pop();
return Ok(None);
}
_trimmed.pop();
}
} else if element==&"SWAP" {
let first_number=_trimmed.pop().unwrap();
let second_number=_trimmed.pop().unwrap();
_trimmed.push(first_number);
_trimmed.push(second_number);
}
}
}
for elem in _trimmed.iter(){
self.stack.push(elem.parse::<i32>().unwrap())
}
if _trimmed.len()==0{
return Ok(None);
}
Ok(Some(_trimmed.pop().unwrap().parse::<i32>().unwrap()))
}
}

Лог от изпълнението

Compiling solution v0.1.0 (/tmp/d20190128-22631-bc85yn/solution)
warning: unused variable: `name`
  --> src/lib.rs:43:39
   |
43 |     pub fn def_unary_op<F>(&mut self, name: &str, op: F)
   |                                       ^^^^ help: consider using `_name` instead
   |
   = note: #[warn(unused_variables)] on by default

warning: unused variable: `name`
  --> src/lib.rs:57:40
   |
57 |     pub fn def_binary_op<F>(&mut self, name: &str, op: F)
   |                                        ^^^^ help: consider using `_name` instead

warning: unused variable: `name`
  --> src/lib.rs:43:39
   |
43 |     pub fn def_unary_op<F>(&mut self, name: &str, op: F)
   |                                       ^^^^ help: consider using `_name` instead
   |
   = note: #[warn(unused_variables)] on by default

warning: unused variable: `name`
  --> src/lib.rs:57:40
   |
57 |     pub fn def_binary_op<F>(&mut self, name: &str, op: F)
   |                                        ^^^^ help: consider using `_name` instead

error[E0599]: no method named `stack` found for type `solution::Interpreter` in the current scope
  --> tests/solution_test.rs:41:32
   |
41 |         assert_eq!(interpreter.stack().collect::<Vec<_>>(), vec![2, 1]);
   |                                ^^^^^ private field, not a method

error[E0599]: no method named `stack` found for type `solution::Interpreter` in the current scope
  --> tests/solution_test.rs:52:32
   |
52 |         assert_eq!(interpreter.stack().collect::<Vec<_>>(), vec![2, 2, 1]);
   |                                ^^^^^ private field, not a method

error[E0599]: no method named `stack` found for type `solution::Interpreter` in the current scope
  --> tests/solution_test.rs:63:32
   |
63 |         assert_eq!(interpreter.stack().collect::<Vec<_>>(), vec![2, 3, 1]);
   |                                ^^^^^ private field, not a method

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0599`.
error: Could not compile `solution`.

To learn more, run the command again with --verbose.

История (1 версия и 1 коментар)

Даяна качи първо решение на 27.01.2019 16:56 (преди над 4 години)

Нямаш метод stack(), но дори да го имаше имплементиран правилно, има и други проблеми. Предполагам, че покрай сесията, няма време да седне човек да го напише внимателно. Oh, well :).

Можеш да видиш моето (което всъщност е предимно на Никола) решение като нещо работещо. Ще опитам да намеря време идващите дни за някакво по-обстойно review на твоя код.