2018-02-23 19:06:37 -08:00
|
|
|
use std::rc::Rc;
|
2018-02-24 17:37:23 -08:00
|
|
|
use std::collections::HashMap;
|
2018-05-20 20:47:24 -07:00
|
|
|
use std::fmt;
|
2018-02-23 19:06:37 -08:00
|
|
|
|
2018-08-19 20:33:50 -07:00
|
|
|
use tokenizing::TokenType;
|
2018-05-16 01:08:06 -07:00
|
|
|
use self::Type::*; use self::TConstOld::*;
|
2018-02-23 19:06:37 -08:00
|
|
|
|
2018-05-20 20:47:24 -07:00
|
|
|
|
|
|
|
//TODO get rid of these types and replace them with the right MonoType or whatever ones later
|
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
pub enum Type {
|
|
|
|
Const(TConstOld),
|
|
|
|
Func(Box<Type>, Box<Type>),
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
pub enum TConstOld {
|
|
|
|
Nat,
|
|
|
|
Int,
|
|
|
|
Float,
|
|
|
|
StringT,
|
|
|
|
Bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for Type {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "{:?}", self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-23 19:06:37 -08:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2018-02-24 17:37:23 -08:00
|
|
|
pub struct BinOp {
|
2018-02-24 14:39:45 -08:00
|
|
|
sigil: Rc<String>
|
2018-02-23 19:06:37 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl BinOp {
|
2018-02-24 17:50:57 -08:00
|
|
|
pub fn from_sigil(sigil: &str) -> BinOp {
|
|
|
|
BinOp { sigil: Rc::new(sigil.to_string()) }
|
2018-02-23 19:06:37 -08:00
|
|
|
}
|
2018-02-24 14:39:45 -08:00
|
|
|
pub fn sigil(&self) -> &Rc<String> {
|
|
|
|
&self.sigil
|
|
|
|
}
|
2018-08-19 20:33:50 -07:00
|
|
|
pub fn from_sigil_token(tok: &TokenType) -> Option<BinOp> {
|
|
|
|
use self::TokenType::*;
|
|
|
|
let s = match tok {
|
|
|
|
Operator(op) => op,
|
|
|
|
Period => ".",
|
|
|
|
Pipe => "|",
|
|
|
|
Slash => "/",
|
2018-08-19 21:11:43 -07:00
|
|
|
LAngleBracket => "<",
|
|
|
|
RAngleBracket => ">",
|
2018-08-19 20:33:50 -07:00
|
|
|
_ => return None
|
|
|
|
};
|
|
|
|
Some(BinOp::from_sigil(s))
|
|
|
|
}
|
2018-08-19 15:03:41 -07:00
|
|
|
/*
|
2018-05-20 20:47:24 -07:00
|
|
|
pub fn get_type(&self) -> Result<Type, String> {
|
2018-02-24 17:37:23 -08:00
|
|
|
let s = self.sigil.as_str();
|
|
|
|
BINOPS.get(s).map(|x| x.0.clone()).ok_or(format!("Binop {} not found", s))
|
|
|
|
}
|
2018-08-19 15:03:41 -07:00
|
|
|
*/
|
2018-02-23 19:06:37 -08:00
|
|
|
pub fn min_precedence() -> i32 {
|
|
|
|
i32::min_value()
|
|
|
|
}
|
2018-08-19 20:33:50 -07:00
|
|
|
pub fn get_precedence_from_token(op: &TokenType) -> Option<i32> {
|
|
|
|
use self::TokenType::*;
|
|
|
|
let s = match op {
|
|
|
|
Operator(op) => op,
|
|
|
|
Period => ".",
|
|
|
|
Pipe => "|",
|
|
|
|
Slash => "/",
|
2018-08-19 21:11:43 -07:00
|
|
|
LAngleBracket => "<",
|
|
|
|
RAngleBracket => ">",
|
2018-08-19 20:33:50 -07:00
|
|
|
_ => return None
|
|
|
|
};
|
2018-08-19 21:11:43 -07:00
|
|
|
Some(BINOPS.get(s).map(|x| x.2.clone()).expect("Custom operators not handled yet"))
|
2018-02-23 19:06:37 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-24 17:37:23 -08:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
pub struct PrefixOp {
|
|
|
|
sigil: Rc<String>
|
|
|
|
}
|
|
|
|
|
2018-02-23 19:06:37 -08:00
|
|
|
impl PrefixOp {
|
2018-02-24 17:50:57 -08:00
|
|
|
pub fn from_sigil(sigil: &str) -> PrefixOp {
|
|
|
|
PrefixOp { sigil: Rc::new(sigil.to_string()) }
|
2018-02-23 19:06:37 -08:00
|
|
|
}
|
2018-02-24 14:39:45 -08:00
|
|
|
pub fn sigil(&self) -> &Rc<String> {
|
|
|
|
&self.sigil
|
|
|
|
}
|
2018-02-23 19:06:37 -08:00
|
|
|
pub fn is_prefix(op: &str) -> bool {
|
2018-02-24 17:43:26 -08:00
|
|
|
PREFIX_OPS.get(op).is_some()
|
2018-02-23 19:06:37 -08:00
|
|
|
}
|
2018-08-19 15:03:41 -07:00
|
|
|
/*
|
2018-05-20 20:47:24 -07:00
|
|
|
pub fn get_type(&self) -> Result<Type, String> {
|
2018-02-26 02:21:21 -08:00
|
|
|
let s = self.sigil.as_str();
|
|
|
|
PREFIX_OPS.get(s).map(|x| x.0.clone()).ok_or(format!("Prefix op {} not found", s))
|
|
|
|
}
|
2018-08-19 15:03:41 -07:00
|
|
|
*/
|
2018-02-23 19:06:37 -08:00
|
|
|
}
|
2018-02-24 17:43:26 -08:00
|
|
|
lazy_static! {
|
|
|
|
static ref PREFIX_OPS: HashMap<&'static str, (Type, ())> =
|
|
|
|
hashmap! {
|
|
|
|
"+" => (Func(bx!(Const(Int)), bx!(Const(Int))), ()),
|
|
|
|
"-" => (Func(bx!(Const(Int)), bx!(Const(Int))), ()),
|
|
|
|
"!" => (Func(bx!(Const(Bool)), bx!(Const(Bool))), ()),
|
|
|
|
};
|
|
|
|
}
|
2018-02-24 17:37:23 -08:00
|
|
|
|
|
|
|
/* the second tuple member is a placeholder for when I want to make evaluation rules tied to the
|
|
|
|
* binop definition */
|
|
|
|
lazy_static! {
|
|
|
|
static ref BINOPS: HashMap<&'static str, (Type, (), i32)> =
|
|
|
|
hashmap! {
|
2018-05-15 21:47:08 -07:00
|
|
|
"+" => (Func(bx!(Const(Nat)), bx!(Func(bx!(Const(Nat)), bx!(Const(Nat))))), (), 10),
|
|
|
|
"-" => (Func(bx!(Const(Nat)), bx!(Func(bx!(Const(Nat)), bx!(Const(Nat))))), (), 10),
|
|
|
|
"*" => (Func(bx!(Const(Nat)), bx!(Func(bx!(Const(Nat)), bx!(Const(Nat))))), (), 20),
|
|
|
|
"/" => (Func(bx!(Const(Nat)), bx!(Func(bx!(Const(Nat)), bx!(Const(Float))))), (), 20),
|
|
|
|
"//" => (Func(bx!(Const(Nat)), bx!(Func(bx!(Const(Nat)), bx!(Const(Nat))))), (), 20), //TODO change this to `quot`
|
|
|
|
"%" => (Func(bx!(Const(Nat)), bx!(Func(bx!(Const(Nat)), bx!(Const(Nat))))), (), 20),
|
2018-02-24 17:37:23 -08:00
|
|
|
"++" => (Func(bx!(Const(StringT)), bx!(Func(bx!(Const(StringT)), bx!(Const(StringT))))), (), 30),
|
2018-05-15 21:47:08 -07:00
|
|
|
"^" => (Func(bx!(Const(Nat)), bx!(Func(bx!(Const(Nat)), bx!(Const(Nat))))), (), 20),
|
|
|
|
"&" => (Func(bx!(Const(Nat)), bx!(Func(bx!(Const(Nat)), bx!(Const(Nat))))), (), 20),
|
|
|
|
"|" => (Func(bx!(Const(Nat)), bx!(Func(bx!(Const(Nat)), bx!(Const(Nat))))), (), 20),
|
2018-08-19 21:11:43 -07:00
|
|
|
">" => (Func(bx!(Const(Nat)), bx!(Func(bx!(Const(Nat)), bx!(Const(Nat))))), (), 20),
|
|
|
|
">=" => (Func(bx!(Const(Nat)), bx!(Func(bx!(Const(Nat)), bx!(Const(Nat))))), (), 20),
|
|
|
|
"<" => (Func(bx!(Const(Nat)), bx!(Func(bx!(Const(Nat)), bx!(Const(Nat))))), (), 20),
|
|
|
|
"<=" => (Func(bx!(Const(Nat)), bx!(Func(bx!(Const(Nat)), bx!(Const(Nat))))), (), 20),
|
|
|
|
"==" => (Func(bx!(Const(Nat)), bx!(Func(bx!(Const(Nat)), bx!(Const(Nat))))), (), 20),
|
2018-02-24 17:37:23 -08:00
|
|
|
};
|
|
|
|
}
|