use std::rc::Rc; use crate::tokenizing::TokenKind; #[derive(Debug, PartialEq, Clone)] pub struct PrefixOp { sigil: Rc, } impl PrefixOp { pub fn from_sigil(sigil: &str) -> PrefixOp { PrefixOp { sigil: Rc::new(sigil.to_string()) } } pub fn sigil(&self) -> &str { &self.sigil } pub fn is_prefix(op: &str) -> bool { matches!(op, "+" | "-" | "!") } } #[derive(Debug, PartialEq, Clone)] pub struct BinOp { sigil: Rc, } impl BinOp { pub fn from_sigil(sigil: &str) -> BinOp { BinOp { sigil: Rc::new(sigil.to_string()) } } pub fn sigil(&self) -> &str { &self.sigil } pub fn from_sigil_token(tok: &TokenKind) -> Option { let s = token_kind_to_sigil(tok)?; Some(BinOp::from_sigil(s)) } pub fn min_precedence() -> i32 { i32::min_value() } pub fn get_precedence_from_token(op_tok: &TokenKind) -> Option { let s = token_kind_to_sigil(op_tok)?; Some(binop_precedences(s)) } } fn token_kind_to_sigil(tok: & TokenKind) -> Option<&str> { use self::TokenKind::*; Some(match tok { Operator(op) => op.as_str(), Period => ".", Pipe => "|", Slash => "/", LAngleBracket => "<", RAngleBracket => ">", Equals => "=", _ => return None }) } fn binop_precedences(s: &str) -> i32 { let default = 10_000_000; match s { "+" => 10, "-" => 10, "*" => 20, "/" => 20, "%" => 20, "++" => 30, "^" => 30, "&" => 20, "|" => 20, ">" => 20, ">=" => 20, "<" => 20, "<=" => 20, "==" => 40, "<=>" => 30, "=" => 5, // Assignment shoudl have highest precedence _ => default, } }