You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
2.7 KiB

use crate::parser::{Token, TokenKind, Value};
use core::convert::TryFrom;
3 years ago
#[derive(Debug)]
pub struct Program {
pub func: Vec<Function>,
pub globals: Vec<String>,
}
#[derive(Debug)]
pub struct Function {
pub name: String,
pub arguments: Vec<Variable>,
pub statements: Vec<Statement>,
}
#[derive(Debug, Eq, PartialEq)]
pub struct Variable {
pub name: String,
}
#[derive(Debug, Eq, PartialEq)]
pub enum Statement {
Declare(Variable, Option<Expression>),
Return(Option<Expression>),
3 years ago
If(Expression, Box<Statement>, Option<Box<Statement>>),
While(Expression, Box<Statement>),
Exp(Expression),
}
#[derive(Debug, Eq, PartialEq)]
pub enum Expression {
Int(u32),
3 years ago
Str(String),
3 years ago
Char(u8),
FunctionCall(String, Vec<Expression>),
Variable(String),
Assign(String, Box<Expression>),
BinOp(Box<Expression>, BinOp, Box<Expression>),
}
impl TryFrom<Token> for Expression {
type Error = String;
fn try_from(token: Token) -> std::result::Result<Self, String> {
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<TokenKind> for BinOp {
type Error = String;
fn try_from(token: TokenKind) -> Result<BinOp, String> {
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()),
}
}
3 years ago
}