Moved AST node enums and functions into their own file.

This commit is contained in:
PaddiM8 2020-05-30 15:27:58 +02:00
parent 41a41629a5
commit 036fadb041
6 changed files with 56 additions and 65 deletions

47
src/ast.rs Normal file
View File

@ -0,0 +1,47 @@
use crate::lexer::TokenKind;
use std::mem;
#[derive(Debug, Clone)]
pub enum Stmt {
VarDecl(String, Box<Expr>),
FnDecl(String, Vec<String>, Box<Expr>),
Expr(Box<Expr>),
}
#[derive(Debug, Clone)]
pub enum Expr {
Binary(Box<Expr>, TokenKind, Box<Expr>),
Unary(TokenKind, Box<Expr>),
Unit(Box<Expr>, TokenKind),
Var(String),
Group(Box<Expr>),
FnCall(String, Vec<Expr>),
Literal(String),
}
#[derive(Debug, Clone)]
pub enum Unit {
Radians,
Degrees,
}
impl TokenKind {
pub fn is_unit(&self) -> bool {
match self {
TokenKind::Deg | TokenKind::Rad => true,
_ => false,
}
}
pub fn to_unit(&self) -> Result<Unit, String> {
match self {
TokenKind::Deg => Ok(Unit::Degrees),
TokenKind::Rad => Ok(Unit::Radians),
_ => Err(String::from("Invalid unit.")),
}
}
}
pub fn compare_enums<T>(first: &T, second: &T) -> bool {
mem::discriminant(first) == mem::discriminant(second)
}

View File

@ -1,7 +1,5 @@
use std::mem; use crate::ast::{compare_enums, Expr, Stmt, Unit};
use crate::lexer::TokenKind; use crate::lexer::TokenKind;
use crate::parser::{Expr, Stmt, Unit};
use crate::prelude; use crate::prelude;
use crate::symbol_table::SymbolTable; use crate::symbol_table::SymbolTable;
@ -43,23 +41,6 @@ impl<'a> Context<'a> {
} }
} }
impl TokenKind {
fn to_unit(&self) -> Result<Unit, String> {
match self {
TokenKind::Deg => Ok(Unit::Degrees),
TokenKind::Rad => Ok(Unit::Radians),
_ => Err(String::from("Invalid unit.")),
}
}
}
impl Unit {
// TODO: Something more generic
fn compare(&self, second_token: &Unit) -> bool {
mem::discriminant(self) == mem::discriminant(second_token)
}
}
fn eval_stmt(context: &mut Context, stmt: &Stmt) -> Result<f64, String> { fn eval_stmt(context: &mut Context, stmt: &Stmt) -> Result<f64, String> {
match stmt { match stmt {
Stmt::VarDecl(identifier, _) => eval_var_decl_stmt(context, stmt, identifier), Stmt::VarDecl(identifier, _) => eval_var_decl_stmt(context, stmt, identifier),
@ -125,7 +106,7 @@ fn eval_unit_expr(context: &mut Context, expr: &Expr, kind: &TokenKind) -> Resul
// Don't do any angle conversions if the defauly angle unit is the same as the unit kind // Don't do any angle conversions if the defauly angle unit is the same as the unit kind
match unit { match unit {
Unit::Degrees | Unit::Radians => { Unit::Degrees | Unit::Radians => {
if context.angle_unit.compare(&unit) { if compare_enums(&context.angle_unit, &unit) {
return x; return x;
} }
} }

View File

@ -1,14 +1,15 @@
use std::{env, process}; use std::{env, process};
mod ast;
mod interpreter; mod interpreter;
mod lexer; mod lexer;
mod parser; mod parser;
mod prelude; mod prelude;
mod symbol_table; mod symbol_table;
use parser::Unit;
use rustyline::error::ReadlineError; use rustyline::error::ReadlineError;
use rustyline::Editor; use rustyline::Editor;
use ast::Unit;
fn main() { fn main() {
let mut parser = parser::Context::new(); let mut parser = parser::Context::new();

View File

@ -1,35 +1,10 @@
use std::mem;
use crate::{ use crate::{
ast::{compare_enums, Expr, Stmt, Unit},
interpreter, interpreter,
lexer::{Lexer, Token, TokenKind}, lexer::{Lexer, Token, TokenKind},
symbol_table::SymbolTable, symbol_table::SymbolTable,
}; };
#[derive(Debug, Clone)]
pub enum Stmt {
VarDecl(String, Box<Expr>),
FnDecl(String, Vec<String>, Box<Expr>),
Expr(Box<Expr>),
}
#[derive(Debug, Clone)]
pub enum Expr {
Binary(Box<Expr>, TokenKind, Box<Expr>),
Unary(TokenKind, Box<Expr>),
Unit(Box<Expr>, TokenKind),
Var(String),
Group(Box<Expr>),
FnCall(String, Vec<Expr>),
Literal(String),
}
#[derive(Debug, Clone)]
pub enum Unit {
Radians,
Degrees,
}
pub struct Context { pub struct Context {
//angle_unit: Unit, //angle_unit: Unit,
tokens: Vec<Token>, tokens: Vec<Token>,
@ -37,19 +12,6 @@ pub struct Context {
symbol_table: SymbolTable, symbol_table: SymbolTable,
} }
impl TokenKind {
pub fn is_unit(&self) -> bool {
match self {
TokenKind::Deg | TokenKind::Rad => true,
_ => false,
}
}
pub fn compare(&self, second_token: &TokenKind) -> bool {
mem::discriminant(self) == mem::discriminant(second_token)
}
}
impl Context { impl Context {
pub fn new() -> Self { pub fn new() -> Self {
Context { Context {
@ -279,7 +241,7 @@ fn match_token(context: &mut Context, kind: TokenKind) -> bool {
return false; return false;
} }
peek(context).kind.compare(&kind) compare_enums(&peek(context).kind, &kind)
} }
fn advance<'a>(context: &'a mut Context) -> &'a Token { fn advance<'a>(context: &'a mut Context) -> &'a Token {
@ -296,5 +258,5 @@ fn consume<'a>(context: &'a mut Context, kind: TokenKind) -> Result<&'a Token, S
} }
fn is_at_end(context: &mut Context) -> bool { fn is_at_end(context: &mut Context) -> bool {
context.pos >= context.tokens.len() || peek(context).kind.compare(&TokenKind::EOF) context.pos >= context.tokens.len() || compare_enums(&peek(context).kind, &TokenKind::EOF)
} }

View File

@ -1,4 +1,3 @@
use crate::parser::Unit;
use FuncType::*; use FuncType::*;
pub const CONSTANTS: &[(&str, &str)] = &[ pub const CONSTANTS: &[(&str, &str)] = &[
@ -11,6 +10,7 @@ pub const CONSTANTS: &[(&str, &str)] = &[
("ϕ", "1.61803398"), ("ϕ", "1.61803398"),
]; ];
use crate::ast::Unit;
use funcs::*; use funcs::*;
pub const UNARY_FUNCS: phf::Map<&'static str, UnaryFuncInfo> = phf::phf_map! { pub const UNARY_FUNCS: phf::Map<&'static str, UnaryFuncInfo> = phf::phf_map! {
"cos" => UnaryFuncInfo(cos, Trig), "cos" => UnaryFuncInfo(cos, Trig),

View File

@ -1,4 +1,4 @@
use crate::{parser::Stmt, prelude}; use crate::{ast::Stmt, prelude};
use std::collections::HashMap; use std::collections::HashMap;
pub struct SymbolTable { pub struct SymbolTable {