feat: add monkey-rs
This commit is contained in:
151
__lang/monkey-rs/src/ast.rs
Normal file
151
__lang/monkey-rs/src/ast.rs
Normal file
@@ -0,0 +1,151 @@
|
||||
use std::fmt;
|
||||
use std::fmt::Formatter;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Program {
|
||||
pub stmts: Vec<Statement>,
|
||||
}
|
||||
|
||||
impl fmt::Display for Program {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for stmt in &self.stmts {
|
||||
write!(f, "{}", stmt)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct BlockStatement {
|
||||
pub stmts: Vec<Statement>,
|
||||
}
|
||||
|
||||
impl fmt::Display for BlockStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{{");
|
||||
for stmt in &self.stmts {
|
||||
write!(f, "{}", stmt)?;
|
||||
}
|
||||
write!(f, "}}");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Prefix {
|
||||
Minus,
|
||||
Bang
|
||||
}
|
||||
|
||||
impl fmt::Display for Prefix {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Prefix::Minus => write!(f, "-"),
|
||||
Prefix::Bang => write!(f, "!"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Infix {
|
||||
Eq,
|
||||
NotEq,
|
||||
Lt,
|
||||
Gt,
|
||||
Plus,
|
||||
Minus,
|
||||
Asterisk,
|
||||
Slash,
|
||||
LBracket,
|
||||
}
|
||||
|
||||
impl fmt::Display for Infix {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Infix::Eq => write!(f, "=="),
|
||||
Infix::NotEq => write!(f, "!="),
|
||||
Infix::Lt => write!(f, "<"),
|
||||
Infix::Gt => write!(f, ">"),
|
||||
Infix::Plus => write!(f, "+"),
|
||||
Infix::Minus => write!(f, "-"),
|
||||
Infix::Asterisk => write!(f, "*"),
|
||||
Infix::Slash => write!(f, "/"),
|
||||
Infix::LBracket => write!(f, "["),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Expression {
|
||||
Identifier(String),
|
||||
IntegerLiteral(i64),
|
||||
String(String),
|
||||
Boolean(bool),
|
||||
Prefix(Prefix, Box<Expression>),
|
||||
Infix(Infix, Box<Expression>, Box<Expression>),
|
||||
If(Box<Expression>, Box<BlockStatement>, Option<Box<BlockStatement>>),
|
||||
FunctionLiteral(Vec<String>, Box<BlockStatement>),
|
||||
DictionaryLiteral(Vec<(Expression, Expression)>),
|
||||
ArrayLiteral(Vec<Expression>),
|
||||
Index(Box<Expression>, Box<Expression>),
|
||||
Call(Box<Expression>, Vec<Expression>),
|
||||
}
|
||||
|
||||
impl fmt::Display for Expression {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Expression::Identifier(s) => write!(f, "{}", s),
|
||||
Expression::IntegerLiteral(i) => write!(f, "{}", i),
|
||||
Expression::String(s) => write!(f, "\"{}\"", s),
|
||||
Expression::Boolean(b) => write!(f, "{}", b),
|
||||
Expression::Prefix(p, exp) => write!(f, "({}{})", p, exp),
|
||||
Expression::Infix(op, left, right) =>
|
||||
write!(f, "({} {} {})", left, op, right),
|
||||
Expression::If(exp, true_blk, Some(false_blk)) =>
|
||||
write!(f,"if ({}) {} else {}", exp, true_blk, false_blk),
|
||||
Expression::If(exp, true_blk, None) =>
|
||||
write!(f,"if ({}) {}", exp, true_blk),
|
||||
Expression::DictionaryLiteral(key_values) => {
|
||||
let mut str = String::new();
|
||||
str.push_str("{");
|
||||
for (k, v) in key_values{
|
||||
str.push_str(format!("{}:{},", k, v).as_str());
|
||||
}
|
||||
|
||||
if str.ends_with(',') {
|
||||
str.pop();
|
||||
}
|
||||
str.push_str("}");
|
||||
write!(f, "{}", str)
|
||||
},
|
||||
Expression::ArrayLiteral(members) => write!(f, "[{}]",
|
||||
members.iter().map(|a| a.to_string()).collect::<Vec<String>>().join(",")),
|
||||
Expression::Index(arr, idx) => write!(f, "{}[{}]", arr.to_string(), idx.to_string()),
|
||||
Expression::FunctionLiteral(params, block) => write!(f, "fn({}){}", params.join(","), block),
|
||||
Expression::Call(exp, params) => write!(f, "{}({})", exp,
|
||||
params.iter().map(|a| a.to_string()).collect::<Vec<String>>().join(",")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Statement {
|
||||
Let(String, Box<Expression>),
|
||||
Return(Option<Box<Expression>>),
|
||||
Expression(Box<Expression>),
|
||||
}
|
||||
|
||||
impl fmt::Display for Statement {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Statement::Let(s, exp) => write!(f, "let {} = {};", s, exp),
|
||||
Statement::Return(None) => write!(f, "return;"),
|
||||
Statement::Return(Some(val)) => write!(f, "return {};", val),
|
||||
Statement::Expression(exp) => write!(f, "{};", exp),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user