Implement the negation operator
This commit is contained in:
parent
7d49fc53ae
commit
4fa78336d0
2 changed files with 17 additions and 10 deletions
|
@ -1,6 +1,7 @@
|
||||||
use super::astnode;
|
use super::astnode;
|
||||||
use super::astnode::{ASTNode, BinaryExpr};
|
use super::astnode::{ASTNode, BinaryExpr};
|
||||||
use crate::lexer::{token, token::TokenType};
|
use crate::lexer::{token, token::TokenType};
|
||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::result::Result as StdResult;
|
use std::result::Result as StdResult;
|
||||||
|
|
||||||
|
@ -8,6 +9,7 @@ type Result<T> = StdResult<T, ASTParsingError>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ASTParsingError {
|
pub enum ASTParsingError {
|
||||||
|
IncorrectToken(TokenType),
|
||||||
UnmatchedBrace,
|
UnmatchedBrace,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +17,7 @@ impl std::fmt::Display for ASTParsingError {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
Self::UnmatchedBrace => write!(f, "Unmatched brace"),
|
Self::UnmatchedBrace => write!(f, "Unmatched brace"),
|
||||||
|
Self::IncorrectToken(ref token) => write!(f, "Incorrect token {:?}", token),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,7 +162,7 @@ impl<'a, T: Iterator<Item = token::Token<'a>>> Parser<'a, T> {
|
||||||
None => return Err(ASTParsingError::UnmatchedBrace),
|
None => return Err(ASTParsingError::UnmatchedBrace),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(a) => panic!("{:#?}", a),
|
Some(a) => return Err(ASTParsingError::IncorrectToken(a)),
|
||||||
None => todo!(),
|
None => todo!(),
|
||||||
};
|
};
|
||||||
Ok(node)
|
Ok(node)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use super::types;
|
use super::types::Value;
|
||||||
use crate::ast::astnode::{self, UnaryOperator};
|
use crate::ast::astnode::{self, UnaryOperator};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -14,23 +14,23 @@ impl Display for RuntimeError {
|
||||||
impl std::error::Error for RuntimeError {}
|
impl std::error::Error for RuntimeError {}
|
||||||
|
|
||||||
pub trait Interpret {
|
pub trait Interpret {
|
||||||
fn interpret(&self) -> Result<types::Value, RuntimeError>;
|
fn interpret(&self) -> Result<Value, RuntimeError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpret for astnode::ASTNode {
|
impl Interpret for astnode::ASTNode {
|
||||||
fn interpret(&self) -> Result<types::Value, RuntimeError> {
|
fn interpret(&self) -> Result<Value, RuntimeError> {
|
||||||
astnode::all_variants!(self, n => n.interpret())
|
astnode::all_variants!(self, n => n.interpret())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpret for astnode::Literal {
|
impl Interpret for astnode::Literal {
|
||||||
fn interpret(&self) -> Result<types::Value, RuntimeError> {
|
fn interpret(&self) -> Result<Value, RuntimeError> {
|
||||||
Ok(self.clone().into())
|
Ok(self.clone().into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpret for astnode::BinaryExpr {
|
impl Interpret for astnode::BinaryExpr {
|
||||||
fn interpret(&self) -> Result<types::Value, RuntimeError> {
|
fn interpret(&self) -> Result<Value, RuntimeError> {
|
||||||
let left_val = self.left.interpret().expect("expected lval");
|
let left_val = self.left.interpret().expect("expected lval");
|
||||||
let right_val = self.right.interpret().expect("expected rval");
|
let right_val = self.right.interpret().expect("expected rval");
|
||||||
match self.operator {
|
match self.operator {
|
||||||
|
@ -46,17 +46,21 @@ impl Interpret for astnode::BinaryExpr {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpret for astnode::UnaryExpr {
|
impl Interpret for astnode::UnaryExpr {
|
||||||
fn interpret(&self) -> Result<types::Value, RuntimeError> {
|
fn interpret(&self) -> Result<Value, RuntimeError> {
|
||||||
let val = self.right.interpret()?;
|
let val = self.right.interpret()?;
|
||||||
match self.operator {
|
match self.operator {
|
||||||
UnaryOperator::Bang => Ok(types::Value::Bool(!val.truthy())),
|
UnaryOperator::Bang => Ok(Value::Bool(!val.truthy())),
|
||||||
UnaryOperator::Minus => todo!(),
|
UnaryOperator::Minus => match val {
|
||||||
|
Value::Int(i) => Ok(Value::Int(-i)),
|
||||||
|
Value::Float(f) => Ok(Value::Float(-f)),
|
||||||
|
_ => Err(RuntimeError),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpret for astnode::GroupingExpr {
|
impl Interpret for astnode::GroupingExpr {
|
||||||
fn interpret(&self) -> Result<types::Value, RuntimeError> {
|
fn interpret(&self) -> Result<Value, RuntimeError> {
|
||||||
self.0.interpret()
|
self.0.interpret()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue