Add Operator token type
This commit is contained in:
parent
65d2fd3270
commit
4d76023775
81
src/lexer.rs
81
src/lexer.rs
@ -11,11 +11,56 @@ pub enum Token<'src> {
|
||||
Float(f64),
|
||||
String(&'src str),
|
||||
Identifier(&'src str),
|
||||
Operator(&'src str),
|
||||
Operator(Operator),
|
||||
Control(&'src str),
|
||||
Keyword(&'src str),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Operator {
|
||||
Add,
|
||||
AddAssign,
|
||||
And,
|
||||
Assign,
|
||||
Divide,
|
||||
Equal,
|
||||
Greater,
|
||||
GreaterOrEqual,
|
||||
Less,
|
||||
LessOrEqual,
|
||||
Modulo,
|
||||
Multiply,
|
||||
Not,
|
||||
NotEqual,
|
||||
Or,
|
||||
SubAssign,
|
||||
Subtract,
|
||||
}
|
||||
|
||||
impl Display for Operator {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Operator::Add => write!(f, "+"),
|
||||
Operator::AddAssign => write!(f, "+="),
|
||||
Operator::And => write!(f, "&&"),
|
||||
Operator::Assign => write!(f, "="),
|
||||
Operator::Divide => write!(f, "="),
|
||||
Operator::Equal => write!(f, "=="),
|
||||
Operator::Greater => write!(f, ">"),
|
||||
Operator::GreaterOrEqual => write!(f, ">="),
|
||||
Operator::Less => write!(f, "<"),
|
||||
Operator::LessOrEqual => write!(f, "<="),
|
||||
Operator::Modulo => write!(f, "%"),
|
||||
Operator::Multiply => write!(f, "*"),
|
||||
Operator::Not => write!(f, "!"),
|
||||
Operator::NotEqual => write!(f, "!="),
|
||||
Operator::Or => write!(f, "||"),
|
||||
Operator::SubAssign => write!(f, "-="),
|
||||
Operator::Subtract => write!(f, "-"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src> Display for Token<'src> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
match self {
|
||||
@ -24,7 +69,7 @@ impl<'src> Display for Token<'src> {
|
||||
Token::Float(float) => write!(f, "{float}"),
|
||||
Token::String(string) => write!(f, "{string}"),
|
||||
Token::Identifier(string) => write!(f, "{string}"),
|
||||
Token::Operator(string) => write!(f, "{string}"),
|
||||
Token::Operator(operator) => write!(f, "{operator}"),
|
||||
Token::Control(string) => write!(f, "{string}"),
|
||||
Token::Keyword(string) => write!(f, "{string}"),
|
||||
}
|
||||
@ -88,17 +133,27 @@ pub fn lexer<'src>() -> impl Parser<
|
||||
let identifier = text::ident().map(|text: &str| Token::Identifier(text));
|
||||
|
||||
let operator = choice((
|
||||
just("==").padded(),
|
||||
just("!=").padded(),
|
||||
just(">").padded(),
|
||||
just("<").padded(),
|
||||
just(">=").padded(),
|
||||
just("<=").padded(),
|
||||
just("&&").padded(),
|
||||
just("||").padded(),
|
||||
just("=").padded(),
|
||||
just("+=").padded(),
|
||||
just("-=").padded(),
|
||||
// logic
|
||||
just("&&").padded().to(Operator::And),
|
||||
just("==").padded().to(Operator::Equal),
|
||||
just("!=").padded().to(Operator::NotEqual),
|
||||
just(">").padded().to(Operator::Greater),
|
||||
just(">=").padded().to(Operator::GreaterOrEqual),
|
||||
just("<").padded().to(Operator::Less),
|
||||
just("<=").padded().to(Operator::LessOrEqual),
|
||||
just("!").padded().to(Operator::Not),
|
||||
just("!=").padded().to(Operator::NotEqual),
|
||||
just("||").padded().to(Operator::Or),
|
||||
// math
|
||||
just("+").padded().to(Operator::Add),
|
||||
just("-").padded().to(Operator::Subtract),
|
||||
just("*").padded().to(Operator::Multiply),
|
||||
just("/").padded().to(Operator::Divide),
|
||||
just("%").padded().to(Operator::Modulo),
|
||||
// assignment
|
||||
just("=").padded().to(Operator::Assign),
|
||||
just("+=").padded().to(Operator::AddAssign),
|
||||
just("-=").padded().to(Operator::SubAssign),
|
||||
))
|
||||
.map(Token::Operator);
|
||||
|
||||
|
@ -2,7 +2,11 @@ use std::{cell::RefCell, collections::HashMap};
|
||||
|
||||
use chumsky::{input::SpannedInput, pratt::*, prelude::*};
|
||||
|
||||
use crate::{abstract_tree::*, error::Error, lexer::Token};
|
||||
use crate::{
|
||||
abstract_tree::*,
|
||||
error::Error,
|
||||
lexer::{Operator, Token},
|
||||
};
|
||||
|
||||
pub type DustParser<'src> = Boxed<
|
||||
'src,
|
||||
@ -84,33 +88,39 @@ pub fn parser<'src>() -> DustParser<'src> {
|
||||
.delimited_by(just(Token::Control("(")), just(Token::Control(")"))),
|
||||
));
|
||||
|
||||
use Operator::*;
|
||||
|
||||
let logic = atom
|
||||
.pratt((
|
||||
prefix(2, just(Token::Operator("!")), |expression| {
|
||||
prefix(2, just(Token::Operator(Not)), |expression| {
|
||||
Expression::Logic(Box::new(Logic::Not(expression)))
|
||||
}),
|
||||
infix(left(1), just(Token::Operator("==")), |left, right| {
|
||||
infix(left(1), just(Token::Operator(Equal)), |left, right| {
|
||||
Expression::Logic(Box::new(Logic::Equal(left, right)))
|
||||
}),
|
||||
infix(left(1), just(Token::Operator("!=")), |left, right| {
|
||||
infix(left(1), just(Token::Operator(NotEqual)), |left, right| {
|
||||
Expression::Logic(Box::new(Logic::NotEqual(left, right)))
|
||||
}),
|
||||
infix(left(1), just(Token::Operator(">")), |left, right| {
|
||||
infix(left(1), just(Token::Operator(Greater)), |left, right| {
|
||||
Expression::Logic(Box::new(Logic::Greater(left, right)))
|
||||
}),
|
||||
infix(left(1), just(Token::Operator("<")), |left, right| {
|
||||
infix(left(1), just(Token::Operator(Less)), |left, right| {
|
||||
Expression::Logic(Box::new(Logic::Less(left, right)))
|
||||
}),
|
||||
infix(left(1), just(Token::Operator(">=")), |left, right| {
|
||||
Expression::Logic(Box::new(Logic::GreaterOrEqual(left, right)))
|
||||
}),
|
||||
infix(left(1), just(Token::Operator("<=")), |left, right| {
|
||||
Expression::Logic(Box::new(Logic::LessOrEqual(left, right)))
|
||||
}),
|
||||
infix(left(1), just(Token::Operator("&&")), |left, right| {
|
||||
infix(
|
||||
left(1),
|
||||
just(Token::Operator(GreaterOrEqual)),
|
||||
|left, right| Expression::Logic(Box::new(Logic::GreaterOrEqual(left, right))),
|
||||
),
|
||||
infix(
|
||||
left(1),
|
||||
just(Token::Operator(LessOrEqual)),
|
||||
|left, right| Expression::Logic(Box::new(Logic::LessOrEqual(left, right))),
|
||||
),
|
||||
infix(left(1), just(Token::Operator(And)), |left, right| {
|
||||
Expression::Logic(Box::new(Logic::And(left, right)))
|
||||
}),
|
||||
infix(left(1), just(Token::Operator("||")), |left, right| {
|
||||
infix(left(1), just(Token::Operator(Or)), |left, right| {
|
||||
Expression::Logic(Box::new(Logic::Or(left, right)))
|
||||
}),
|
||||
))
|
||||
@ -155,7 +165,7 @@ pub fn parser<'src>() -> DustParser<'src> {
|
||||
|
||||
let assignment = identifier
|
||||
.then(type_specification.clone().or_not())
|
||||
.then_ignore(just(Token::Operator("=")))
|
||||
.then_ignore(just(Token::Operator(Operator::Assign)))
|
||||
.then(statement.clone())
|
||||
.map(|((identifier, r#type), statement)| {
|
||||
Statement::Assignment(Assignment::new(identifier, r#type, statement))
|
||||
|
@ -8,3 +8,9 @@ fn logic() {
|
||||
Ok(Value::boolean(true))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn math() {
|
||||
assert_eq!(interpret("1 + 1"), Ok(Value::integer(2)));
|
||||
assert_eq!(interpret("21 + 19 + 1 * 2"), Ok(Value::integer(42)));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user