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-02-23 19:06:37 -08:00
|
|
|
|
2018-02-24 17:37:23 -08:00
|
|
|
use schala_lang::typechecking::{Type, TypeResult, TConst};
|
|
|
|
use self::Type::*; use self::TConst::*;
|
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 {
|
|
|
|
pub fn from_sigil(sigil: Rc<String>) -> BinOp {
|
|
|
|
BinOp { sigil }
|
|
|
|
}
|
2018-02-24 14:39:45 -08:00
|
|
|
pub fn sigil(&self) -> &Rc<String> {
|
|
|
|
&self.sigil
|
|
|
|
}
|
2018-02-24 17:37:23 -08:00
|
|
|
pub fn get_type(&self) -> TypeResult<Type> {
|
|
|
|
let s = self.sigil.as_str();
|
|
|
|
BINOPS.get(s).map(|x| x.0.clone()).ok_or(format!("Binop {} not found", s))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BinOp {
|
2018-02-23 19:06:37 -08:00
|
|
|
pub fn min_precedence() -> i32 {
|
|
|
|
i32::min_value()
|
|
|
|
}
|
|
|
|
pub fn get_precedence(op: &str) -> i32 {
|
|
|
|
match op {
|
|
|
|
"+" | "-" => 10,
|
|
|
|
"*" | "/" | "%" => 20,
|
|
|
|
_ => 30,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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 {
|
|
|
|
pub fn from_sigil(sigil: Rc<String>) -> PrefixOp {
|
|
|
|
PrefixOp { sigil }
|
|
|
|
}
|
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 {
|
|
|
|
match op {
|
|
|
|
"+" | "-" | "!" | "~" => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
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! {
|
|
|
|
"+" => (Func(bx!(Const(Int)), bx!(Func(bx!(Const(Int)), bx!(Const(Int))))), (), 10),
|
|
|
|
"-" => (Func(bx!(Const(Int)), bx!(Func(bx!(Const(Int)), bx!(Const(Int))))), (), 10),
|
|
|
|
"*" => (Func(bx!(Const(Int)), bx!(Func(bx!(Const(Int)), bx!(Const(Int))))), (), 20),
|
|
|
|
"/" => (Func(bx!(Const(Int)), bx!(Func(bx!(Const(Int)), bx!(Const(Int))))), (), 20),
|
|
|
|
"%" => (Func(bx!(Const(Int)), bx!(Func(bx!(Const(Int)), bx!(Const(Int))))), (), 20),
|
|
|
|
"++" => (Func(bx!(Const(StringT)), bx!(Func(bx!(Const(StringT)), bx!(Const(StringT))))), (), 30),
|
|
|
|
};
|
|
|
|
}
|