Cleaned up redundant code and replaced compare_enums() with PartialEq.

This commit is contained in:
PaddiM8 2020-06-05 13:47:39 +02:00
parent 4360f3f4ee
commit 98d4a16195
4 changed files with 26 additions and 26 deletions

View File

@ -1,6 +1,5 @@
use crate::lexer::TokenKind; use crate::lexer::TokenKind;
use crate::parser::Unit; use crate::parser::Unit;
use std::mem;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum Stmt { pub enum Stmt {
@ -36,7 +35,3 @@ impl TokenKind {
} }
} }
} }
pub fn compare_enums<T>(first: &T, second: &T) -> bool {
mem::discriminant(first) == mem::discriminant(second)
}

View File

@ -1,4 +1,4 @@
use crate::ast::{compare_enums, Expr, Stmt}; use crate::ast::{Expr, Stmt};
use crate::lexer::TokenKind; use crate::lexer::TokenKind;
use crate::parser::Unit; use crate::parser::Unit;
use crate::prelude; use crate::prelude;
@ -95,7 +95,7 @@ fn eval_binary_expr(
} }
fn eval_unary_expr(context: &mut Context, op: &TokenKind, expr: &Expr) -> Result<Float, String> { fn eval_unary_expr(context: &mut Context, op: &TokenKind, expr: &Expr) -> Result<Float, String> {
let expr_value = eval_expr(context, &expr)?.clone(); let expr_value = eval_expr(context, &expr)?;
match op { match op {
TokenKind::Minus => Ok(-expr_value), TokenKind::Minus => Ok(-expr_value),
@ -114,7 +114,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 compare_enums(&context.angle_unit, &unit) { if context.angle_unit == unit {
return x; return x;
} }
} }
@ -129,7 +129,7 @@ fn eval_unit_expr(context: &mut Context, expr: &Expr, kind: &TokenKind) -> Resul
fn eval_var_expr(context: &mut Context, identifier: &str) -> Result<Float, String> { fn eval_var_expr(context: &mut Context, identifier: &str) -> Result<Float, String> {
// If there is a constant with this name, return a literal expression with its value // If there is a constant with this name, return a literal expression with its value
if let Some(value) = prelude::CONSTANTS.get(identifier) { if let Some(value) = prelude::CONSTANTS.get(identifier) {
return eval_expr(context, &Expr::Literal(value.to_string())); return eval_expr(context, &Expr::Literal((*value).to_string()));
} }
// Look for the variable in the symbol table // Look for the variable in the symbol table
@ -154,7 +154,7 @@ fn eval_group_expr(context: &mut Context, expr: &Expr) -> Result<Float, String>
fn eval_fn_call_expr( fn eval_fn_call_expr(
context: &mut Context, context: &mut Context,
identifier: &str, identifier: &str,
expressions: &Vec<Expr>, expressions: &[Expr],
) -> Result<Float, String> { ) -> Result<Float, String> {
// Prelude // Prelude
let prelude_func = match expressions.len() { let prelude_func = match expressions.len() {
@ -190,7 +190,7 @@ fn eval_fn_call_expr(
let mut sum = Float::with_val(context.precision, 0); let mut sum = Float::with_val(context.precision, 0);
for n in start..=end { for n in start..=end {
let n_expr = Expr::Literal(String::from(n.to_string())); let n_expr = Expr::Literal(n.to_string());
// Update the variable "n" in the symbol table on every iteration, // Update the variable "n" in the symbol table on every iteration,
// then calculate the expression and add it to the total sum. // then calculate the expression and add it to the total sum.
@ -230,7 +230,7 @@ fn eval_fn_call_expr(
)?; )?;
} }
return eval_expr(context, &*fn_body); eval_expr(context, &*fn_body)
} }
_ => Err(format!("Undefined function: '{}'.", identifier)), _ => Err(format!("Undefined function: '{}'.", identifier)),
} }

View File

@ -141,7 +141,7 @@ impl<'a> Lexer<'a> {
} }
fn advance(&mut self) { fn advance(&mut self) {
self.index = self.index + 1; self.index += 1;
} }
fn is_at_end(&self) -> bool { fn is_at_end(&self) -> bool {
@ -163,14 +163,13 @@ fn is_valid_identifier(c: char) -> bool {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::ast::compare_enums;
use test_case::test_case; use test_case::test_case;
fn match_tokens(tokens: Vec<Token>, expected: Vec<TokenKind>) { fn match_tokens(tokens: Vec<Token>, expected: Vec<TokenKind>) {
let mut expected_iter = expected.iter(); let mut expected_iter = expected.iter();
for token in tokens { for token in tokens {
assert!(compare_enums(&token.kind, &expected_iter.next().unwrap())); assert_eq!(token.kind, *expected_iter.next().unwrap());
} }
} }

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
ast::{compare_enums, Expr, Stmt}, ast::{Expr, Stmt},
interpreter, interpreter,
lexer::{Lexer, Token, TokenKind}, lexer::{Lexer, Token, TokenKind},
symbol_table::SymbolTable, symbol_table::SymbolTable,
@ -12,7 +12,7 @@ pub struct Context {
symbol_table: SymbolTable, symbol_table: SymbolTable,
angle_unit: Unit, angle_unit: Unit,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq)]
pub enum Unit { pub enum Unit {
Radians, Radians,
Degrees, Degrees,
@ -35,6 +35,12 @@ impl Context {
} }
} }
impl Default for Context {
fn default() -> Self {
Self::new()
}
}
pub fn parse(context: &mut Context, input: &str, precision: u32) -> Result<Option<Float>, String> { pub fn parse(context: &mut Context, input: &str, precision: u32) -> Result<Option<Float>, String> {
context.tokens = Lexer::lex(input); context.tokens = Lexer::lex(input);
context.pos = 0; context.pos = 0;
@ -244,7 +250,7 @@ fn parse_identifier(context: &mut Context) -> Result<Expr, String> {
// Eg. x // Eg. x
if context.symbol_table.contains_var(&identifier.value) { if context.symbol_table.contains_var(&identifier.value) {
return Ok(Expr::Var(identifier.value)); Ok(Expr::Var(identifier.value))
} else { } else {
let mut chars = identifier.value.chars(); let mut chars = identifier.value.chars();
let mut left = Expr::Var(chars.next().unwrap().to_string()); let mut left = Expr::Var(chars.next().unwrap().to_string());
@ -259,19 +265,19 @@ fn parse_identifier(context: &mut Context) -> Result<Expr, String> {
); );
} }
return Ok(left); Ok(left)
} }
} }
fn peek<'a>(context: &'a mut Context) -> &'a Token { fn peek(context: &mut Context) -> &Token {
&context.tokens[context.pos] &context.tokens[context.pos]
} }
fn peek_next<'a>(context: &'a mut Context) -> &'a Token { fn peek_next(context: &mut Context) -> &Token {
&context.tokens[context.pos + 1] &context.tokens[context.pos + 1]
} }
fn previous<'a>(context: &'a mut Context) -> &'a Token { fn previous(context: &mut Context) -> &Token {
&context.tokens[context.pos - 1] &context.tokens[context.pos - 1]
} }
@ -280,15 +286,15 @@ fn match_token(context: &mut Context, kind: TokenKind) -> bool {
return false; return false;
} }
compare_enums(&peek(context).kind, &kind) peek(context).kind == kind
} }
fn advance<'a>(context: &'a mut Context) -> &'a Token { fn advance(context: &mut Context) -> &Token {
context.pos += 1; context.pos += 1;
previous(context) previous(context)
} }
fn consume<'a>(context: &'a mut Context, kind: TokenKind) -> Result<&'a Token, String> { fn consume(context: &mut Context, kind: TokenKind) -> Result<&Token, String> {
if match_token(context, kind) { if match_token(context, kind) {
return Ok(advance(context)); return Ok(advance(context));
} }
@ -297,7 +303,7 @@ 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() || compare_enums(&peek(context).kind, &TokenKind::EOF) context.pos >= context.tokens.len() || peek(context).kind == TokenKind::EOF
} }
#[cfg(test)] #[cfg(test)]