use crate::parser::{Token, TokenKind, Value}; use core::convert::TryFrom; #[derive(Debug)] pub struct Program { pub func: Vec, pub globals: Vec, } #[derive(Debug)] pub struct Function { pub name: String, pub arguments: Vec, pub statements: Vec, } #[derive(Debug, Eq, PartialEq)] pub struct Variable { pub name: String, } #[derive(Debug, Eq, PartialEq)] pub enum Statement { Declare(Variable, Option), Return(Option), If(Expression, Box, Option>), While(Expression, Box), Exp(Expression), } #[derive(Debug, Eq, PartialEq)] pub enum Expression { Int(u32), Str(String), Char(u8), FunctionCall(String, Vec), Variable(String), Assign(String, Box), BinOp(Box, BinOp, Box), } impl TryFrom for Expression { type Error = String; fn try_from(token: Token) -> std::result::Result { let kind = token.kind; match kind { TokenKind::Identifier(val) => Ok(Expression::Variable(val)), TokenKind::Literal(Value::Int) => Ok(Expression::Int( token .raw .parse() .map_err(|_| "Int value could not be parsed")?, )), TokenKind::Literal(Value::Str) => Ok(Expression::Str(token.raw)), other => panic!("Value could not be parsed"), } } } #[derive(Debug, Eq, PartialEq)] pub enum BinOp { Addition, Subtraction, Multiplication, Division, Modulus, LessThan, LessThanOrEqual, GreaterThan, GreaterThanOrEqual, Equal, NotEqual, And, Or, } impl TryFrom for BinOp { type Error = String; fn try_from(token: TokenKind) -> Result { match token { TokenKind::Star => Ok(BinOp::Multiplication), TokenKind::Slash => Ok(BinOp::Division), TokenKind::Plus => Ok(BinOp::Addition), TokenKind::Minus => Ok(BinOp::Subtraction), TokenKind::LessThan => Ok(BinOp::LessThan), TokenKind::GreaterThan => Ok(BinOp::GreaterThan), TokenKind::Equals => Ok(BinOp::Equal), // TokenKind::LessThanOrEqual => BinOp::LessThanOrEqual, // TokenKind::GreaterThanOrEqual => BinOp::GreaterThanOrEqual, // TokenKind::NotEquals => BinOp::NotEqual, // TokenKind::And => BinOp::And, // TokenKind::Or => BinOp::Or, other => Err(format!("Token {:?} cannot be converted into a BinOp", other).into()), } } }