use crate::parser::Datum; use crate::parser::Datum::*; use std::io; use std::io::prelude::*; use std::mem; pub fn add(mut args: Vec) -> Datum { let mut r = 0; for i in 1..args.len() { let datum = mem::take(&mut args[i]); if let Number(n) = datum { r += n; } else { panic!("ADD -- not-all-args-are-numbers {:?}", args) } } Number(r) } pub fn mul(mut args: Vec) -> Datum { let mut r = 1; for i in 1..args.len() { let datum = mem::take(&mut args[i]); if let Number(n) = datum { r *= n; } else { panic!("MUL -- not-all-args-are-numbers {:?}", args) } } Number(r) } pub fn sub(mut args: Vec) -> Datum { if args.len() == 2 { let datum = mem::take(&mut args[1]); if let Number(n) = datum { return Number(-n); } else { panic!("SUB -- not-all-args-are-numbers {:?}", args) } } let mut r; let datum = mem::take(&mut args[1]); if let Number(n) = datum { r = n; } else { panic!("SUB -- not-all-args-are-numbers {:?}", args) } for i in 2..args.len() { let datum = mem::take(&mut args[i]); if let Number(n) = datum { r -= n; } else { panic!("SUB -- not-all-args-are-numbers {:?}", args) } } Number(r) } pub fn eq(args: Vec) -> Datum { if args.len() == 1 { Boolean(true) } else { let first = &args[1]; for i in 2..args.len() { let current = &args[i]; if first != current { return Boolean(false); } } Boolean(true) } } pub fn lt(args: Vec) -> Datum { if args.len() == 1 { Boolean(true) } else { for i in 1..(args.len() - 1) { if &args[i] >= &args[i + 1] { return Boolean(false); } } Boolean(true) } } pub fn display(args: Vec) -> Datum { for i in 1..args.len() { match &args[i] { Boolean(b) => print!("{}", b), Number(n) => print!("{}", n), String(s) => print!("{}", s), List(v) => print!("{:?}", v), _ => panic!("DISPLAY -- cannot-print {:?}", args[i]), }; } io::stdout().flush().ok().expect("Could not flush stdout"); Unspecified }