Skip to content

Commit 00790f5

Browse files
committed
refactor: refactor more expressions and statements
1 parent 5d94fc5 commit 00790f5

File tree

19 files changed

+418
-414
lines changed

19 files changed

+418
-414
lines changed

packages/engine/src/lexer/mod.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::{iter::Peekable, str::Chars};
22

33
use error::LexerResult;
4-
use tokens::{LexerLiteral, LexerToken, LexerTokenKind, LexerTokenList};
4+
use tokens::{LexerTokenValue, LexerToken, LexerTokenKind, LexerTokenList};
55

66
use crate::{
77
component::{ComponentErrors, ComponentIter}, constants::{MAX_I32_LEN, MAX_I64_LEN}, cursor::Cursor, error::{EngineErrorKind, ErrorList}, parser::expr::ShellCommand
@@ -93,7 +93,7 @@ impl<'a> Lexer<'a> {
9393
fn scan_char(
9494
&mut self,
9595
char: &char,
96-
) -> LexerResult<Option<(LexerTokenKind, Option<Box<LexerLiteral>>)>> {
96+
) -> LexerResult<Option<(LexerTokenKind, Option<Box<LexerTokenValue>>)>> {
9797
macro_rules! check_double {
9898
($single_type:expr, $double:tt, $double_type:expr) => {
9999
if self.next_if_eq(&$double).is_some() {
@@ -142,7 +142,7 @@ impl<'a> Lexer<'a> {
142142
return Ok(None);
143143
};
144144

145-
return Ok(Some((Integer, Some(Box::from(LexerLiteral::Integer(-self.eat_number(char)?))))));
145+
return Ok(Some((Integer, Some(Box::from(LexerTokenValue::Integer(-self.eat_number(char)?))))));
146146
}
147147
_ => Minus,
148148
},
@@ -187,7 +187,7 @@ impl<'a> Lexer<'a> {
187187
'0'..='9' => {
188188
return Ok(Some((
189189
Integer,
190-
Some(Box::from(LexerLiteral::Integer(self.eat_number(*char)?))),
190+
Some(Box::from(LexerTokenValue::Integer(self.eat_number(*char)?))),
191191
)))
192192
}
193193
'"' => return Ok(Some(self.consume_string()?)),
@@ -219,10 +219,10 @@ impl<'a> Lexer<'a> {
219219
"and" => And,
220220
"or" => Or,
221221

222-
"true" => return Ok(Some((Boolean, Some(Box::from(LexerLiteral::Boolean(true)))))),
223-
"false" => return Ok(Some((Boolean, Some(Box::from(LexerLiteral::Boolean(false)))))),
222+
"true" => return Ok(Some((Boolean, Some(Box::from(LexerTokenValue::Boolean(true)))))),
223+
"false" => return Ok(Some((Boolean, Some(Box::from(LexerTokenValue::Boolean(false)))))),
224224

225-
_ if Self::is_valid_identifier(char) => return Ok(Some((Identifier, Some(Box::from(LexerLiteral::Identifier(Box::from(word))))))),
225+
_ if Self::is_valid_identifier(char) => return Ok(Some((Identifier, Some(Box::from(LexerTokenValue::Identifier(Box::from(word))))))),
226226
_ => return Err(LexerErrorKind::UnknownToken),
227227
}
228228
}
@@ -234,7 +234,7 @@ impl<'a> Lexer<'a> {
234234
fn add_token(
235235
&mut self,
236236
token_type: LexerTokenKind,
237-
value: Option<Box<LexerLiteral>>,
237+
value: Option<Box<LexerTokenValue>>,
238238
start: Cursor,
239239
) {
240240
self.tokens.push(LexerToken {
@@ -279,7 +279,7 @@ impl<'a> Lexer<'a> {
279279
}
280280

281281
/// Attempts to return a [`TokenType::String`]
282-
fn consume_string(&mut self) -> LexerResult<(LexerTokenKind, Option<Box<LexerLiteral>>)> {
282+
fn consume_string(&mut self) -> LexerResult<(LexerTokenKind, Option<Box<LexerTokenValue>>)> {
283283
let string = self.eat_until(&['"', '\n'], true).unwrap_or_default();
284284

285285
if let Err(err) = self.expect_char(&'"') {
@@ -292,14 +292,14 @@ impl<'a> Lexer<'a> {
292292

293293
Ok((
294294
LexerTokenKind::String,
295-
Some(Box::from(LexerLiteral::String(Box::from(string)))),
295+
Some(Box::from(LexerTokenValue::String(Box::from(string)))),
296296
))
297297
}
298298

299299
/// Attempts to return a [`TokenType::ShellCommand`]
300300
fn consume_shell_command(
301301
&mut self,
302-
) -> LexerResult<(LexerTokenKind, Option<Box<LexerLiteral>>)> {
302+
) -> LexerResult<(LexerTokenKind, Option<Box<LexerTokenValue>>)> {
303303
let cmd_name = self
304304
.eat_until(&[' ', '\t', '\n', '('], false)
305305
.ok_or(LexerErrorKind::UnexpectedEnd)?;
@@ -323,7 +323,7 @@ impl<'a> Lexer<'a> {
323323

324324
Ok((
325325
LexerTokenKind::ShellCommand,
326-
Some(Box::from(LexerLiteral::ShellCommand(Box::from(ShellCommand(cmd_name, cmd_args))))),
326+
Some(Box::from(LexerTokenValue::ShellCommand(Box::from(ShellCommand(cmd_name, cmd_args))))),
327327
))
328328
}
329329

packages/engine/src/lexer/tokens.rs

Lines changed: 25 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ impl Display for LexerTokenKind {
121121
}
122122

123123
#[derive(Debug, PartialEq, Eq, Clone)]
124-
pub enum LexerLiteral {
124+
pub enum LexerTokenValue {
125125
Identifier(Box<String>),
126126
/// `"..."`
127127
String(Box<String>),
@@ -133,40 +133,25 @@ pub enum LexerLiteral {
133133
ShellCommand(Box<ShellCommand>),
134134
}
135135

136-
impl LexerLiteral {
136+
impl LexerTokenValue {
137137
pub fn as_identifier(&self) -> Option<&String> {
138-
match self {
139-
Self::Identifier(identifier) => Some(identifier),
140-
_ => None,
141-
}
138+
self.try_into().ok()
142139
}
143140

144141
pub fn as_string(&self) -> Option<&String> {
145-
match self {
146-
Self::String(string) => Some(string),
147-
_ => None,
148-
}
142+
self.try_into().ok()
149143
}
150144

151145
pub fn as_integer(&self) -> Option<&isize> {
152-
match self {
153-
Self::Integer(int) => Some(int),
154-
_ => None,
155-
}
146+
self.try_into().ok()
156147
}
157148

158149
pub fn as_boolean(&self) -> Option<&bool> {
159-
match self {
160-
Self::Boolean(bool) => Some(bool),
161-
_ => None,
162-
}
150+
self.try_into().ok()
163151
}
164152

165153
pub fn as_shell_command(&self) -> Option<&ShellCommand> {
166-
match self {
167-
Self::ShellCommand(cmd) => Some(cmd),
168-
_ => None,
169-
}
154+
self.try_into().ok()
170155
}
171156
}
172157

@@ -175,58 +160,41 @@ pub struct LexerToken {
175160
pub kind: LexerTokenKind,
176161
pub start: Cursor,
177162
pub end: Cursor,
178-
pub value: Option<Box<LexerLiteral>>,
163+
pub value: Option<Box<LexerTokenValue>>,
179164
}
180165

181-
impl LexerToken {
182-
pub fn as_identifier(&self) -> EngineResult<&String> {
183-
self.value
166+
macro_rules! as_value {
167+
($self:expr, $token:expr, |$v:ident| => $exp:expr) => {
168+
$self.value
184169
.as_ref()
185-
.and_then(|v| v.as_identifier())
170+
.and_then(|$v| $exp)
186171
.ok_or(EngineErrorKind::LiteralExtractionError(
187-
LexerTokenKind::Identifier,
188-
self.kind.clone(),
172+
$token,
173+
$self.kind.clone(),
189174
))
175+
};
176+
}
177+
178+
impl LexerToken {
179+
180+
pub fn as_identifier(&self) -> EngineResult<&String> {
181+
as_value!(self, LexerTokenKind::Identifier, |v| => v.as_identifier())
190182
}
191183

192184
pub fn as_string(&self) -> EngineResult<&String> {
193-
self.value
194-
.as_ref()
195-
.and_then(|v| v.as_string())
196-
.ok_or(EngineErrorKind::LiteralExtractionError(
197-
LexerTokenKind::String,
198-
self.kind.clone(),
199-
))
185+
as_value!(self, LexerTokenKind::String, |v| => v.as_string())
200186
}
201187

202188
pub fn as_integer(&self) -> EngineResult<&isize> {
203-
self.value
204-
.as_ref()
205-
.and_then(|v| v.as_integer())
206-
.ok_or(EngineErrorKind::LiteralExtractionError(
207-
LexerTokenKind::Integer,
208-
self.kind.clone(),
209-
))
189+
as_value!(self, LexerTokenKind::Identifier, |v| => v.as_identifier())
210190
}
211191

212192
pub fn as_boolean(&self) -> EngineResult<&bool> {
213-
self.value
214-
.as_ref()
215-
.and_then(|v| v.as_boolean())
216-
.ok_or(EngineErrorKind::LiteralExtractionError(
217-
LexerTokenKind::Boolean,
218-
self.kind.clone(),
219-
))
193+
as_value!(self, LexerTokenKind::Boolean, |v| => v.as_boolean())
220194
}
221195

222196
pub fn as_shell_command(&self) -> EngineResult<&ShellCommand> {
223-
self.value
224-
.as_ref()
225-
.and_then(|v| v.as_shell_command())
226-
.ok_or(EngineErrorKind::LiteralExtractionError(
227-
LexerTokenKind::ShellCommand,
228-
self.kind.clone(),
229-
))
197+
as_value!(self, LexerTokenKind::ShellCommand, |v| => v.as_shell_command())
230198
}
231199
}
232200

packages/engine/src/parser/expr/assignment_expr.rs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,41 @@
1-
use crate::{lexer::tokens::LexerTokenKind, parser::ParserErrorKind};
1+
use crate::{component::ComponentIter, lexer::tokens::LexerTokenKind, parser::{ast::Parse, expr::Literal, ParserErrorKind}};
22

3-
use super::Expression;
3+
use super::{Expression, ExpressionKind};
44

55
#[derive(Debug, Clone, PartialEq, Eq)]
66
pub struct Assignment(pub Expression, pub AssignmentOperator, pub Expression);
77

8+
impl Parse<ExpressionKind> for Assignment {
9+
fn parse(parser: &mut crate::parser::Parser) -> crate::parser::ParserResult<ExpressionKind> {
10+
let lhs = parser.expr_logic_or()?;
11+
12+
if let Some(op_token) = parser.next_if_eq_mul(&[
13+
&LexerTokenKind::Equal,
14+
&LexerTokenKind::PlusEqual,
15+
&LexerTokenKind::MinusEqual,
16+
&LexerTokenKind::MultiplyEqual,
17+
&LexerTokenKind::DivideEqual,
18+
]) {
19+
let rhs = parser.expr_logic_or()?;
20+
21+
if let ExpressionKind::Literal(Literal::Identifier(identifier)) = lhs
22+
{
23+
let operator: AssignmentOperator = op_token.kind.clone().try_into()?;
24+
25+
return Ok(
26+
ExpressionKind::Assignment(Assignment(
27+
lhs,
28+
operator,
29+
rhs,
30+
)),
31+
);
32+
}
33+
}
34+
35+
Ok(lhs)
36+
}
37+
}
38+
839
#[derive(lang_macro::EnumVariants, Debug, Clone, Copy, PartialEq, Eq)]
940
pub enum AssignmentOperator {
1041
PlusAssign,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
use super::Expression;
2+
3+
pub trait BinaryOp {
4+
fn set_left()
5+
}
Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
1-
use crate::parser::stmt::Statement;
1+
use crate::{component::ComponentIter, lexer::tokens::LexerTokenKind, parser::{ast::Parse, stmt::Statement}};
2+
3+
use super::ExpressionKind;
24

35
#[derive(Debug, Clone, PartialEq, Eq)]
4-
pub struct Block(pub Vec<Statement>);
6+
pub struct Block(pub Vec<Statement>);
7+
8+
impl Parse<ExpressionKind> for Block {
9+
fn parse(parser: &mut crate::parser::Parser) -> crate::parser::ParserResult<ExpressionKind> {
10+
parser.expect_terminator()?;
11+
12+
let mut statements = vec![];
13+
14+
while let Some(token) = parser.peek().cloned() {
15+
if token.kind == LexerTokenKind::RBracket {
16+
parser.next();
17+
break;
18+
}
19+
20+
let statement = parser.parse_statement(token)?;
21+
statements.push(statement);
22+
23+
parser.next();
24+
}
25+
26+
Ok(ExpressionKind::Block(Block(statements)))
27+
}
28+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{literal::identifier::IdentifierLiteral, Expression};
1+
use super::{Expression, Identifier};
22

33
#[derive(Debug, Clone, PartialEq, Eq)]
4-
pub struct FunctionCall(pub IdentifierLiteral, pub Vec<Expression>);
4+
pub struct FunctionCall(pub Identifier, pub Vec<Expression>);

packages/engine/src/parser/expr/literal/identifier.rs renamed to packages/engine/src/parser/expr/identifier.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::{lexer::tokens::LexerToken, parser::ParserErrorKind};
22

3-
#[derive(Debug, Clone, PartialEq, Eq)]
4-
pub struct IdentifierLiteral(String);
3+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4+
pub struct Identifier(String);
55

6-
impl TryFrom<LexerToken> for IdentifierLiteral {
6+
impl TryFrom<LexerToken> for Identifier {
77
type Error = ParserErrorKind;
88

99
fn try_from(value: LexerToken) -> Result<Self, Self::Error> {
Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,48 @@
1-
use super::{Block, else_expr::ElseExpr, Expression};
1+
use crate::{component::ComponentIter, lexer::tokens::LexerTokenKind, parser::{ast::Parse, ParserErrorKind}};
2+
3+
use super::{else_expr::ElseExpr, Block, Expression, ExpressionKind};
24

35
#[derive(Debug, Clone, PartialEq, Eq)]
4-
pub struct IfExpr(pub Expression, pub Block, pub Option<ElseExpr>);
6+
pub struct IfExpr(pub Expression, pub Block, pub Option<ElseExpr>);
7+
8+
impl Parse<ExpressionKind> for IfExpr {
9+
fn parse(parser: &mut crate::parser::Parser) -> crate::parser::ParserResult<ExpressionKind> {
10+
let condition = parser.expression()?;
11+
12+
let start = parser.cursor;
13+
14+
let truthy_block = if parser.next_if_eq(&&LexerTokenKind::LBracket).is_some() {
15+
parser.stmt_block()?
16+
}
17+
// TODO:
18+
// else if parser.next_if_eq(&&LexerTokenKind::Colon).is_some() {
19+
// parser.parse_inline_block()?
20+
// }
21+
else {
22+
return Err(ParserErrorKind::ExpectedExpression);
23+
};
24+
25+
let else_condition = if parser.next_if_eq(&&LexerTokenKind::Else).is_some() {
26+
let start = parser.cursor;
27+
28+
Some(match parser.peek().map(|t| t.kind.clone()) {
29+
Some(LexerTokenKind::LBracket) => {
30+
parser.next();
31+
parser.stmt_block()?
32+
}
33+
// Some(LexerTokenKind::Colon) => {
34+
// parser.next();
35+
// parser.parse_inline_block()?
36+
// }
37+
_ => {
38+
let stmt = parser.stmt_if()?;
39+
vec![stmt]
40+
}
41+
})
42+
} else {
43+
None
44+
};
45+
46+
Ok(ExpressionKind::If((condition, truthy_block, else_condition)))
47+
}
48+
}

0 commit comments

Comments
 (0)