lisp-8bit/src/parser.rs

135 lines
4.2 KiB
Rust
Raw Normal View History

2025-09-08 16:04:31 +02:00
use std::fmt::Display;
2024-08-08 21:53:27 +02:00
2025-09-08 16:04:31 +02:00
use color_eyre::eyre::Error;
use crate::lexer::{Keyword, Macro, Token, TokenString, TokenType};
pub static NIL: SExpression = SExpression::Atom(LispAtom::Keyword(Keyword::Nil));
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SExpression {
Pair(Box<SExpression>, Box<SExpression>),
Atom(LispAtom),
2024-08-08 21:53:27 +02:00
}
2025-09-08 16:04:31 +02:00
#[derive(Debug, Clone, PartialEq, Eq)]
struct State {
expression: Vec<Token>,
index: usize,
_functions: Vec<String>,
2024-08-08 21:53:27 +02:00
}
2025-09-08 16:04:31 +02:00
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum LispAtom {
Integer(isize),
String(String),
2024-08-08 21:53:27 +02:00
Identifier(String),
2025-09-08 16:04:31 +02:00
Keyword(Keyword),
Macro(Macro),
2024-08-08 21:53:27 +02:00
}
2025-09-08 16:04:31 +02:00
impl TryFrom<TokenString> for Vec<SExpression> {
fn try_from(value: TokenString) -> Result<Self, Self::Error> {
let list = value.tokens;
2024-08-08 21:53:27 +02:00
2025-09-08 16:04:31 +02:00
let mut expressions = vec![];
2024-08-08 21:53:27 +02:00
2025-09-08 16:04:31 +02:00
let mut state = State {
expression: list,
index: 0,
_functions: Vec::new(),
};
2024-08-08 21:53:27 +02:00
2025-09-08 16:04:31 +02:00
while state.index != state.expression.len() {
expressions.push(SExpression::parse_sexpression(&mut state)?);
state.index += 1;
2024-08-08 21:53:27 +02:00
}
2025-09-08 16:04:31 +02:00
Ok(expressions)
2024-08-08 21:53:27 +02:00
}
2025-09-08 16:04:31 +02:00
type Error = Error;
}
2024-08-08 21:53:27 +02:00
2025-09-08 16:04:31 +02:00
impl SExpression {
fn parse_sexpression(state: &mut State) -> Result<Self, Error> {
let expr = match &state.expression[state.index].token_type {
TokenType::OpenParantheses => Self::parse_expression(state),
TokenType::Integer(val) => Ok(Self::Atom(LispAtom::Integer(val.to_owned()))),
TokenType::String(val) => Ok(Self::Atom(LispAtom::String(val.to_owned()))),
TokenType::Identifier(val) => Ok(Self::Atom(LispAtom::Identifier(val.to_owned()))),
TokenType::Keyword(val) => Ok(Self::Atom(LispAtom::Keyword(val.to_owned()))),
TokenType::Macro(val) => Ok(Self::Atom(LispAtom::Macro(val.to_owned()))),
_other => Err(Error::msg(format!(
"Did not expect symbol at row {} col {}",
state.expression[state.index].row, state.expression[state.index].col
))),
};
2024-08-08 21:53:27 +02:00
2025-09-08 16:04:31 +02:00
dbg!(expr)
2024-08-08 21:53:27 +02:00
}
2025-09-08 16:04:31 +02:00
fn parse_expression(state: &mut State) -> Result<Self, Error> {
if state.expression[state.index].token_type != TokenType::OpenParantheses {
return Err(Error::msg(format!(
"Error: Expected ( at row {} col {}",
state.expression[state.index].row, state.expression[state.index].col
)));
2024-08-08 21:53:27 +02:00
}
2025-09-08 16:04:31 +02:00
state.index += 1;
let expression_1 = dbg!(Self::parse_sexpression(state)?);
state.index += 1;
// Is pair
if state.expression[state.index].token_type == TokenType::Dot {
state.index += 1;
let expression_2 = Self::parse_sexpression(state)?;
return Ok(Self::Pair(Box::new(expression_1), Box::new(expression_2)));
} else {
// Is list
let mut elements = vec![expression_1];
while state.expression[state.index].token_type != TokenType::ClosedParantheses {
elements.push(Self::parse_sexpression(state)?);
state.index += 1;
}
2024-08-08 21:53:27 +02:00
2025-09-08 16:04:31 +02:00
elements.reverse();
2024-08-08 21:53:27 +02:00
2025-09-08 16:04:31 +02:00
let pair = Self::make_pair_list(elements);
return Ok(pair);
2024-08-08 21:53:27 +02:00
}
}
2025-09-08 16:04:31 +02:00
fn make_pair_list(mut expressions: Vec<SExpression>) -> SExpression {
if expressions.len() == 1 {
return SExpression::Pair(Box::new(expressions[0].clone()), Box::new(NIL.clone()));
2024-08-08 21:53:27 +02:00
}
2025-09-08 16:04:31 +02:00
return SExpression::Pair(
Box::new(
expressions
.pop()
.expect("The length should be more than one"),
),
Box::new(Self::make_pair_list(expressions)),
);
}
}
2024-08-08 21:53:27 +02:00
2025-09-08 16:04:31 +02:00
impl Display for SExpression {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Pair(a, b) => write!(f, "({a} . {b})"),
Self::Atom(a) => match a {
LispAtom::String(a) => write!(f, "\"{a}\""),
LispAtom::Integer(a) => write!(f, "{a}"),
LispAtom::Keyword(a) => write!(f, "{a}"),
LispAtom::Identifier(a) => write!(f, "{a}"),
LispAtom::Macro(a) => write!(f, "{a}"),
},
}
2024-08-08 21:53:27 +02:00
}
}