use crate::lexer::*;
use std::collections::HashMap;
#[derive(Debug, Clone, PartialEq)]
pub enum AstNode {
Integer(IntegerExpr),
Float(FloatExpr),
String(StringExpr),
Identifier(IdentifierExpr),
Binary(BinaryExpr)
}
type Node = Box<AstNode>;
trait IntoNode {
fn into_node(self) -> Node;
}
use node_macro::IntoNode;
macro_rules! new_node {
($struct_name:ident { $($field:ident : $value:expr),* $(,)? }) => {
$struct_name { $($field: $value),* }.into_node()
};
}
#[derive(Debug, Clone, PartialEq)]
pub struct Value<T> {
pub value: T,
pub token: Token
}
impl<T> Value<T> {
pub fn new(value: T, token: Token) -> Self {
Value {
value: value,
token: token
}
}
}
#[derive(Debug, Clone, PartialEq, IntoNode)]
#[node_variant("Integer")]
pub struct IntegerExpr {
pub value: Value<isize>
}
#[derive(Debug, Clone, PartialEq, IntoNode)]
#[node_variant("Float")]
pub struct FloatExpr {
pub value: Value<f64>
}
#[derive(Debug, Clone, PartialEq, IntoNode)]
#[node_variant("String")]
pub struct StringExpr {
pub value: Value<String>
}
#[derive(Debug, Clone, PartialEq, IntoNode)]
#[node_variant("Identifier")]
pub struct IdentifierExpr {
pub name: Value<String>
}
#[derive(Debug, Clone, PartialEq, IntoNode)]
#[node_variant("Binary")]
pub struct BinaryExpr {
pub op: Value<String>,
pub left: Node,
pub right: Node
}
pub struct Parser {
idx: usize,
idx_list: HashMap<String, usize>,
tokens: Vec<Token>,
ast: Vec<Node>
}
impl Parser {
pub fn new(tokens: Vec<Token>) -> Self {
let parser = Parser {
idx: 0,
idx_list: HashMap::new(),
tokens: tokens,
ast: Vec::new()
};
return parser
}
pub fn start(&mut self) -> Option<Vec<Node>> {
return self.loop_parser();
}
fn integer(&mut self) -> Option<Node> {
let idx = self.idx;
if let Some(token) = self.token_get() {
if token.kind == Tkn::Integer {
return Some(new_node!(IntegerExpr {
value: Value::new(
token.value.parse::<isize>().unwrap(),
token
)
}));
}
self.idx = idx;
return None;
}
self.idx = idx;
return None;
}
fn float(&mut self) -> Option<Node> {
let idx = self.idx;
if let Some(token) = self.token_get() {
if token.kind == Tkn::Float {
return Some(new_node!(FloatExpr {
value: Value::new(
token.value.parse::<f64>().unwrap(),
token
)
}));
}
self.idx = idx;
return None;
}
self.idx = idx;
return None;
}
fn string(&mut self) -> Option<Node> {
let idx = self.idx;
if let Some(token) = self.token_get() {
if token.kind == Tkn::String {
return Some(new_node!(StringExpr {
value: Value::new(
token.value.clone(),
token
)
}));
}
self.idx = idx;
return None;
}
self.idx = idx;
return None;
}
fn identifier(&mut self) -> Option<Node> {
let idx = self.idx;
if let Some(token) = self.token_get() {
if token.kind == Tkn::Identifier {
return Some(new_node!(IdentifierExpr {
name: Value::new(
token.value.clone(),
token
)
}));
}
self.idx = idx;
return None;
}
self.idx = idx;
return None;
}
fn value(&mut self) -> Option<Node> {
if let Some(node) = self.integer() {
return Some(node);
}
if let Some(node) = self.float() {
return Some(node);
}
if let Some(node) = self.string() {
return Some(node);
}
if let Some(node) = self.identifier() {
return Some(node);
}
return None;
}
fn expr0(&mut self) -> Option<Node> {
return self.value();
}
fn expr1(&mut self) -> Option<Node> {
let expr1 = self.expr0();
if expr1 == None {
return None;
}
let idx = self.idx;
let op = self.token_get();
if op == None {
self.idx = idx;
return None;
}
let expr2 = self.expr1();
if let Some(op2) = op {
if (op2.kind == Tkn::Multiply || op2.kind == Tkn::Slash || op2.kind == Tkn::Remainder) && expr2.is_some() {
return Some(new_node!(BinaryExpr {
op: Value::new(op2.value.clone(), op2),
left: expr1?,
right: expr2?
}));
}
}
self.idx = idx;
return expr1;
}
fn expr2(&mut self) -> Option<Node> {
let expr1 = self.expr1();
if expr1 == None {
return None;
}
let idx = self.idx;
let op = self.token_get();
if op == None {
self.idx = idx;
return None;
}
let expr2 = self.expr2();
if let Some(op2) = op {
if (op2.kind == Tkn::Plus || op2.kind == Tkn::Minus) && expr2.is_some() {
return Some(new_node!(BinaryExpr {
op: Value::new(op2.value.clone(), op2),
left: expr1?,
right: expr2?
}));
}
}
self.idx = idx;
return expr1;
}
fn loop_parser(&mut self) -> Option<Vec<Node>> {
let mut result = Vec::new();
loop {
if let Some(node) = self.parser() {
result.push(node);
} else {
break;
}
}
return Some(result);
}
fn parser(&mut self) -> Option<Node> {
if let Some(node) = self.expr2() {
return Some(node);
}
return None;
}
fn record_idx(&mut self, name: &str) {
self.idx_list.insert(name.to_string(), self.idx);
}
fn recover_idx(&mut self, name: &str) {
if let Some(idx) = self.idx_list.get(&name.to_string()) {
self.idx = *idx;
}
}
fn token(&mut self) -> Option<Token> {
let token = self.tokens.get(self.idx);
self.idx += 1;
token.cloned()
}
fn token_get(&mut self) -> Option<Token> {
loop {
if let Some(token) = self.token() {
if token.kind != Tkn::Space && token.kind != Tkn::Tab && token.kind != Tkn::Line {
return Some(token);
}
} else {
return None;
}
}
}
}