From 36e1bf722a3d366cea20ab7315d63d588d23dc48 Mon Sep 17 00:00:00 2001 From: Dominick Allen Date: Sat, 20 Jun 2020 13:38:03 -0500 Subject: Working on a simple LISP/scheme interpreter. --- src/lib/types.rs | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/lib/types.rs (limited to 'src/lib/types.rs') diff --git a/src/lib/types.rs b/src/lib/types.rs new file mode 100644 index 0000000..4c2900a --- /dev/null +++ b/src/lib/types.rs @@ -0,0 +1,97 @@ +use std::str::FromStr; + +#[derive(PartialEq, Debug, Clone, Copy)] +pub enum Op { + Add, + Sub, + Mul, + Div, + Modulo, + Equals, + Greater, + GrEqTo, + Less, + LsEqTo, + Define, +} + +impl FromStr for Op { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "+" => Ok(Op::Add), + "-" => Ok(Op::Sub), + "*" => Ok(Op::Mul), + "/" => Ok(Op::Div), + "%" => Ok(Op::Modulo), + "=" => Ok(Op::Equals), + ">" => Ok(Op::Greater), + ">=" => Ok(Op::GrEqTo), + "<" => Ok(Op::Less), + "<=" => Ok(Op::LsEqTo), + "define" => Ok(Op::Define), + x => Err(format!("{} is not an operator", x)) + } + } +} + +#[derive(PartialEq, Debug, Clone)] +pub enum Number { + Int(isize), + Float(f32) +} + +#[derive(PartialEq, Debug, Clone)] +pub enum Type { + Bool(bool), + Number(Number), + Str(String), + Symbol(String), + Operator(Op), +} + +#[derive(PartialEq, Debug)] +pub enum SEXP { + Atom(Type), + Sexpr(Vec) +} + +#[test] +fn construct() { + let atom1 = SEXP::Atom(Type::Number(Number::Int(1))); + let atom2 = SEXP::Atom(Type::Number(Number::Int(2))); + let atom3 = SEXP::Atom(Type::Number(Number::Int(3))); + let atom4 = SEXP::Atom(Type::Number(Number::Int(4))); + let sexp = SEXP::Sexpr(vec!(atom1, atom2, atom3, atom4)); + match sexp { + SEXP::Sexpr(ref x) => { + assert_eq!(x[0], SEXP::Atom(Type::Number(Number::Int(1)))); + }, + _ => panic!("What") + } +} + +#[test] +fn mutability() { + let atom1 = SEXP::Atom(Type::Number(Number::Int(1))); + let atom2 = SEXP::Atom(Type::Number(Number::Int(2))); + let atom3 = SEXP::Atom(Type::Number(Number::Int(3))); + let atom4 = SEXP::Atom(Type::Number(Number::Int(4))); + let mut sexp = SEXP::Sexpr(vec!(atom1, atom2, atom3, atom4)); + match sexp { + SEXP::Sexpr(ref mut x) => match x[0] { + SEXP::Atom(Type::Number(Number::Int(ref mut x))) => *x += 7, + _ => panic!("What") + }, + _ => panic!("What") + } + + match sexp { + SEXP::Sexpr(ref x) => { + assert_eq!(x[0], SEXP::Atom(Type::Number(Number::Int(8)))); + }, + _ => panic!("What") + } +} + -- cgit v1.2.3