2022-01-21 17:43:50 -06:00
|
|
|
use regex::Regex;
|
|
|
|
use std::rc::Rc;
|
|
|
|
|
|
|
|
use crate::{
|
2022-01-22 15:36:13 -06:00
|
|
|
lexer::{Token, here},
|
2022-01-23 05:49:54 -06:00
|
|
|
token::{
|
|
|
|
Type::{self, *}, Return, Error::{self, ErrorString},
|
|
|
|
}, list, vector,
|
2022-01-21 17:43:50 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
const INT_REGEX: &str = r#"^-?[0-9]+$"#;
|
|
|
|
const STRING_REGEX: &str = r#""(?:\\.|[^\\"])*""#;
|
|
|
|
|
2022-01-23 05:49:54 -06:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub enum Expr {
|
|
|
|
Literal(Type),
|
|
|
|
List(Vec<Expr>),
|
|
|
|
Vector(Vec<Expr>),
|
|
|
|
Identifier(String),
|
|
|
|
Assign(String, Box<Expr>),
|
|
|
|
Binary(Box<Expr>, BinaryOp, Box<Expr>),
|
|
|
|
If(Box<Expr>, Vec<Expr>, Vec<Expr>),
|
|
|
|
While(Box<Expr>, Vec<Expr>),
|
|
|
|
Call(String, Vec<Expr>),
|
|
|
|
Function(String, Vec<String>, Vec<Expr>),
|
|
|
|
NoOperation,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub enum BinaryOp {
|
|
|
|
Add, Sub,
|
|
|
|
Mul, Div, Mod,
|
|
|
|
Eq, Ne,
|
|
|
|
Lt, Le, Gt, Ge,
|
|
|
|
}
|
|
|
|
|
2022-01-21 17:43:50 -06:00
|
|
|
struct Reader {
|
2022-01-22 15:36:13 -06:00
|
|
|
src: String,
|
2022-01-21 17:43:50 -06:00
|
|
|
tokens: Vec<Token>,
|
|
|
|
position: usize,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Reader {
|
2022-01-22 15:36:13 -06:00
|
|
|
fn new(tokens: Vec<Token>, src: String) -> Reader {
|
2022-01-21 17:43:50 -06:00
|
|
|
Reader {
|
2022-01-22 15:36:13 -06:00
|
|
|
src,
|
2022-01-21 17:43:50 -06:00
|
|
|
tokens,
|
|
|
|
position: 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn next(&mut self) -> Result<&Token, Error> {
|
|
|
|
self.position += 1;
|
|
|
|
Ok(self.tokens.get(self.position - 1).ok_or(ErrorString("Underflow".to_string()))?)
|
|
|
|
}
|
|
|
|
fn peek(&mut self) -> Result<&Token, Error> {
|
|
|
|
Ok(self.tokens.get(self.position).ok_or(ErrorString("Underflow".to_string()))?)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn read_atom(reader: &mut Reader) -> Return {
|
|
|
|
let int_regex = Regex::new(INT_REGEX).unwrap();
|
|
|
|
let string_regex = Regex::new(STRING_REGEX).unwrap();
|
2022-01-23 05:49:54 -06:00
|
|
|
|
2022-01-21 17:43:50 -06:00
|
|
|
let token = reader.next()?;
|
|
|
|
match &token.value[..] {
|
2022-01-23 05:49:54 -06:00
|
|
|
"null" => Ok(Type::Null),
|
|
|
|
"true" => Ok(Type::Bool(true)),
|
|
|
|
"false" => Ok(Type::Bool(false)),
|
2022-01-21 17:43:50 -06:00
|
|
|
_ => {
|
|
|
|
if int_regex.is_match(&token.value) {
|
2022-01-23 05:49:54 -06:00
|
|
|
Ok(Type::Number(token.value.parse().unwrap()))
|
2022-01-21 17:43:50 -06:00
|
|
|
} else if string_regex.is_match(&token.value) {
|
2022-01-23 05:49:54 -06:00
|
|
|
Ok(Type::Str(token.value[1..token.value.len() - 1].to_string()))
|
2022-01-21 17:43:50 -06:00
|
|
|
} else {
|
2022-01-23 05:49:54 -06:00
|
|
|
Ok(Type::Symbol(token.value.to_string()))
|
2022-01-21 17:43:50 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn read_sequence(reader: &mut Reader, end: &str) -> Return {
|
2022-01-23 05:49:54 -06:00
|
|
|
let mut sequence: Vec<Type> = Vec::new();
|
2022-01-22 15:36:13 -06:00
|
|
|
let _current_token_ = reader.next()?;
|
2022-01-21 17:43:50 -06:00
|
|
|
loop {
|
|
|
|
let token = match reader.peek() {
|
|
|
|
Ok(token) => token,
|
2022-01-22 15:36:13 -06:00
|
|
|
Err(_) => return Err(ErrorString(
|
|
|
|
format!("{} Unexpected end of input, expected '{}'", here(&reader.src, &reader.tokens[reader.position - 1]), end)
|
|
|
|
)),
|
2022-01-21 17:43:50 -06:00
|
|
|
};
|
|
|
|
if token.value == end { break; }
|
|
|
|
sequence.push(read_form(reader)?)
|
|
|
|
}
|
|
|
|
|
2022-01-22 15:36:13 -06:00
|
|
|
let _match_token_ = reader.next()?;
|
2022-01-21 17:43:50 -06:00
|
|
|
match end {
|
|
|
|
")" => Ok(list!(sequence)),
|
|
|
|
"]" => Ok(vector!(sequence)),
|
|
|
|
_ => return Err(ErrorString(format!("Unknown sequence end value: '{}'", end))),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn read_form(reader: &mut Reader) -> Return {
|
|
|
|
let token = reader.peek()?;
|
|
|
|
match &token.value[..] {
|
|
|
|
")" => Err(ErrorString("Unexpected ')'".to_string())),
|
2022-01-22 15:36:13 -06:00
|
|
|
"(" => read_sequence(reader, ")"),
|
2022-01-21 17:43:50 -06:00
|
|
|
"]" => Err(ErrorString("Unexpected ']'".to_string())),
|
2022-01-22 15:36:13 -06:00
|
|
|
"[" => read_sequence(reader, "]"),
|
2022-01-21 17:43:50 -06:00
|
|
|
_ => read_atom(reader),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-22 15:36:13 -06:00
|
|
|
pub fn parse(tokens: Vec<Token>, src: &str) -> Return {
|
2022-01-21 17:43:50 -06:00
|
|
|
if tokens.len() == 0 { return Ok(Null); }
|
2022-01-22 15:36:13 -06:00
|
|
|
read_form(&mut Reader::new(tokens, src.to_string()))
|
2022-01-23 05:49:54 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn translate_expr(ast: Type) -> Result<Expr, String> {
|
|
|
|
let result: Result<Expr, String>;
|
|
|
|
|
|
|
|
result = match ast {
|
|
|
|
Type::Null => Ok(Expr::Literal(Null)),
|
|
|
|
Type::Bool(b) => Ok(Expr::Literal(Bool(b))),
|
|
|
|
Type::Number(n) => Ok(Expr::Literal(Number(n))),
|
|
|
|
Type::Str(s) => Ok(Expr::Literal(Str(s))),
|
|
|
|
Type::Symbol(s) => Ok(Expr::Identifier(s)),
|
|
|
|
Type::List(list, _) => {
|
|
|
|
if list.len() == 0 {
|
|
|
|
Ok(Expr::NoOperation)
|
|
|
|
} else {
|
|
|
|
match &list[0] {
|
|
|
|
Type::Symbol(s) => {
|
|
|
|
match s.as_str() {
|
|
|
|
"def" => {
|
|
|
|
let value = translate_expr(list[1].clone())?;
|
|
|
|
Ok(Expr::Assign(s.clone(), Box::new(value)))
|
|
|
|
}
|
|
|
|
"if" => {
|
|
|
|
let cond = translate_expr(list[1].clone())?;
|
|
|
|
let then = translate_expr(list[2].clone())?;
|
|
|
|
let else_ = translate_expr(list[3].clone())?;
|
|
|
|
Ok(Expr::If(Box::new(cond), vec![then], vec![else_]))
|
|
|
|
}
|
|
|
|
"while" => {
|
|
|
|
let cond = translate_expr(list[1].clone())?;
|
|
|
|
let body = translate_expr(list[2].clone())?;
|
|
|
|
Ok(Expr::While(Box::new(cond), vec![body]))
|
|
|
|
}
|
|
|
|
// (fn [args] body)
|
|
|
|
"fun" => {
|
|
|
|
let function_name = match list[1].clone() {
|
|
|
|
Type::Symbol(s) => s,
|
|
|
|
_ => return Err(format!("Expected symbol as function name, got: {:?}", list[1]))
|
|
|
|
};
|
|
|
|
let args = match list[2].clone() {
|
|
|
|
Type::Vector(v, _) => {
|
|
|
|
let mut args: Vec<String> = Vec::new();
|
|
|
|
for arg in v.iter() {
|
|
|
|
match arg {
|
|
|
|
Type::Symbol(s) => {
|
|
|
|
args.push(s.clone());
|
|
|
|
}
|
|
|
|
_ => return Err(format!("Unexpected type in function arguments")),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
args
|
|
|
|
},
|
|
|
|
_ => return Err(format!("Expected vector of args, got: {:?}", list[1])),
|
|
|
|
};
|
|
|
|
let body = translate_expr(list[3].clone())?;
|
|
|
|
Ok(Expr::Function(function_name, args, vec![body]))
|
|
|
|
}
|
|
|
|
"+" | "-" | "*" | "/" | "%" | "=" | "!=" | "<" | "<=" | ">" | ">=" => {
|
|
|
|
let left = translate_expr(list[1].clone())?;
|
|
|
|
let right = translate_expr(list[2].clone())?;
|
|
|
|
let op = match s.as_str() {
|
|
|
|
"+" => BinaryOp::Add,
|
|
|
|
"-" => BinaryOp::Sub,
|
|
|
|
"*" => BinaryOp::Mul,
|
|
|
|
"/" => BinaryOp::Div,
|
|
|
|
"%" => BinaryOp::Mod,
|
|
|
|
"=" => BinaryOp::Eq,
|
|
|
|
"!=" => BinaryOp::Ne,
|
|
|
|
"<" => BinaryOp::Lt,
|
|
|
|
"<=" => BinaryOp::Le,
|
|
|
|
">" => BinaryOp::Gt,
|
|
|
|
">=" => BinaryOp::Ge,
|
|
|
|
_ => return Err(format!("Unknown binary operator: '{}'", s)),
|
|
|
|
};
|
|
|
|
Ok(Expr::Binary(Box::new(left), op, Box::new(right)))
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
let mut args: Vec<Expr> = Vec::new();
|
|
|
|
for arg in list.iter().skip(1) {
|
|
|
|
args.push(translate_expr(arg.clone())?);
|
|
|
|
}
|
|
|
|
Ok(Expr::Call(s.clone(), args))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
let mut args: Vec<Expr> = Vec::new();
|
|
|
|
for arg in list.iter() {
|
|
|
|
args.push(translate_expr(arg.clone())?);
|
|
|
|
}
|
|
|
|
Ok(Expr::List(args))
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Type::Vector(vector, _) => {
|
|
|
|
let mut vec: Vec<Expr> = Vec::new();
|
|
|
|
for item in vector.iter() {
|
|
|
|
vec.push(translate_expr(item.clone())?);
|
|
|
|
}
|
|
|
|
return Ok(Expr::Vector(vec));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
result
|
2022-01-21 17:43:50 -06:00
|
|
|
}
|