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),
|
Float(f64),
|
||||||
String(&'src str),
|
String(&'src str),
|
||||||
Identifier(&'src str),
|
Identifier(&'src str),
|
||||||
Operator(&'src str),
|
Operator(Operator),
|
||||||
Control(&'src str),
|
Control(&'src str),
|
||||||
Keyword(&'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> {
|
impl<'src> Display for Token<'src> {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
@ -24,7 +69,7 @@ impl<'src> Display for Token<'src> {
|
|||||||
Token::Float(float) => write!(f, "{float}"),
|
Token::Float(float) => write!(f, "{float}"),
|
||||||
Token::String(string) => write!(f, "{string}"),
|
Token::String(string) => write!(f, "{string}"),
|
||||||
Token::Identifier(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::Control(string) => write!(f, "{string}"),
|
||||||
Token::Keyword(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 identifier = text::ident().map(|text: &str| Token::Identifier(text));
|
||||||
|
|
||||||
let operator = choice((
|
let operator = choice((
|
||||||
just("==").padded(),
|
// logic
|
||||||
just("!=").padded(),
|
just("&&").padded().to(Operator::And),
|
||||||
just(">").padded(),
|
just("==").padded().to(Operator::Equal),
|
||||||
just("<").padded(),
|
just("!=").padded().to(Operator::NotEqual),
|
||||||
just(">=").padded(),
|
just(">").padded().to(Operator::Greater),
|
||||||
just("<=").padded(),
|
just(">=").padded().to(Operator::GreaterOrEqual),
|
||||||
just("&&").padded(),
|
just("<").padded().to(Operator::Less),
|
||||||
just("||").padded(),
|
just("<=").padded().to(Operator::LessOrEqual),
|
||||||
just("=").padded(),
|
just("!").padded().to(Operator::Not),
|
||||||
just("+=").padded(),
|
just("!=").padded().to(Operator::NotEqual),
|
||||||
just("-=").padded(),
|
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);
|
.map(Token::Operator);
|
||||||
|
|
||||||
|
@ -2,7 +2,11 @@ use std::{cell::RefCell, collections::HashMap};
|
|||||||
|
|
||||||
use chumsky::{input::SpannedInput, pratt::*, prelude::*};
|
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<
|
pub type DustParser<'src> = Boxed<
|
||||||
'src,
|
'src,
|
||||||
@ -84,33 +88,39 @@ pub fn parser<'src>() -> DustParser<'src> {
|
|||||||
.delimited_by(just(Token::Control("(")), just(Token::Control(")"))),
|
.delimited_by(just(Token::Control("(")), just(Token::Control(")"))),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
use Operator::*;
|
||||||
|
|
||||||
let logic = atom
|
let logic = atom
|
||||||
.pratt((
|
.pratt((
|
||||||
prefix(2, just(Token::Operator("!")), |expression| {
|
prefix(2, just(Token::Operator(Not)), |expression| {
|
||||||
Expression::Logic(Box::new(Logic::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)))
|
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)))
|
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)))
|
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)))
|
Expression::Logic(Box::new(Logic::Less(left, right)))
|
||||||
}),
|
}),
|
||||||
infix(left(1), just(Token::Operator(">=")), |left, right| {
|
infix(
|
||||||
Expression::Logic(Box::new(Logic::GreaterOrEqual(left, right)))
|
left(1),
|
||||||
}),
|
just(Token::Operator(GreaterOrEqual)),
|
||||||
infix(left(1), just(Token::Operator("<=")), |left, right| {
|
|left, right| Expression::Logic(Box::new(Logic::GreaterOrEqual(left, right))),
|
||||||
Expression::Logic(Box::new(Logic::LessOrEqual(left, right)))
|
),
|
||||||
}),
|
infix(
|
||||||
infix(left(1), just(Token::Operator("&&")), |left, right| {
|
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)))
|
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)))
|
Expression::Logic(Box::new(Logic::Or(left, right)))
|
||||||
}),
|
}),
|
||||||
))
|
))
|
||||||
@ -155,7 +165,7 @@ pub fn parser<'src>() -> DustParser<'src> {
|
|||||||
|
|
||||||
let assignment = identifier
|
let assignment = identifier
|
||||||
.then(type_specification.clone().or_not())
|
.then(type_specification.clone().or_not())
|
||||||
.then_ignore(just(Token::Operator("=")))
|
.then_ignore(just(Token::Operator(Operator::Assign)))
|
||||||
.then(statement.clone())
|
.then(statement.clone())
|
||||||
.map(|((identifier, r#type), statement)| {
|
.map(|((identifier, r#type), statement)| {
|
||||||
Statement::Assignment(Assignment::new(identifier, r#type, statement))
|
Statement::Assignment(Assignment::new(identifier, r#type, statement))
|
||||||
|
@ -8,3 +8,9 @@ fn logic() {
|
|||||||
Ok(Value::boolean(true))
|
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