Skip to content

Commit aa6df7b

Browse files
committed
feat: add unary expression ast
1 parent 25f9dac commit aa6df7b

File tree

6 files changed

+116
-21
lines changed

6 files changed

+116
-21
lines changed

interpreter/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ fn is_truthy(obj: &Object) -> bool {
6161
fn eval_expression(expression: &Expression, env: &Env) -> Result<Rc<Object>, EvalError> {
6262
match expression {
6363
Expression::LITERAL(literal) => eval_literal(literal, env),
64-
Expression::PREFIX(op, expr) => {
64+
Expression::PREFIX(PREFIX { op: op, operand: expr, .. }) => {
6565
let right = eval_expression(expr, &Rc::clone(env))?;
6666
return eval_prefix(op, &right);
6767
}

parser/ast.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,20 +87,27 @@ impl fmt::Display for BlockStatement {
8787
pub enum Expression {
8888
IDENTIFIER(String),
8989
LITERAL(Literal),
90-
PREFIX(Token, Box<Expression>),
90+
PREFIX(PREFIX),
9191
INFIX(Token, Box<Expression>, Box<Expression>),
9292
IF(Box<Expression>, BlockStatement, Option<BlockStatement>),
9393
FUNCTION(Vec<String>, BlockStatement),
9494
FunctionCall(Box<Expression>, Vec<Expression>), // function can be Identifier or FunctionLiteral (think iife)
9595
Index(Box<Expression>, Box<Expression>),
9696
}
9797

98+
#[derive(Clone, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
99+
pub struct PREFIX {
100+
pub op: Token,
101+
pub operand: Box<Expression>,
102+
pub span: Span,
103+
}
104+
98105
impl fmt::Display for Expression {
99106
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
100107
match self {
101108
Expression::IDENTIFIER(id) => write!(f, "{}", id),
102109
Expression::LITERAL(l) => write!(f, "{}",l),
103-
Expression::PREFIX(op, expr) => write!(f, "({}{})", op.kind, expr),
110+
Expression::PREFIX(PREFIX { op: op, operand: expr, .. }) => write!(f, "({}{})", op.kind, expr),
104111
Expression::INFIX(op, left, right) => write!(f, "({} {} {})", left, op.kind, right),
105112
Expression::IF(condition, if_block, else_block) => {
106113
if let Some(else_block) = else_block {

parser/ast_tree_test.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,16 @@ mod tests {
3737
let input = r#"{"a": 1}"#;
3838
test_ast_tree("test_hash", input)
3939
}
40+
41+
#[test]
42+
fn test_return() {
43+
let input = "return 3";
44+
test_ast_tree("test_return", input)
45+
}
46+
47+
#[test]
48+
fn test_unary() {
49+
let input = "-3";
50+
test_ast_tree("test_unary", input)
51+
}
4052
}

parser/lib.rs

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub extern crate lexer;
66

77
use lexer::token::{TokenKind, Token, Span};
88
use lexer::Lexer;
9-
use crate::ast::{Program, Statement, Expression, Node, Literal, BlockStatement, Let, Integer, Boolean, StringType, Array, Hash};
9+
use crate::ast::{Program, Statement, Expression, Node, Literal, BlockStatement, Let, Integer, Boolean, StringType, Array, Hash, PREFIX};
1010
use crate::precedences::{Precedence, get_token_precedence};
1111

1212
type ParseError = String;
@@ -104,7 +104,7 @@ impl<'a> Parser<'a> {
104104
self.expect_peek(&TokenKind::ASSIGN)?;
105105
self.next_token();
106106

107-
let value = self.parse_expression(Precedence::LOWEST)?;
107+
let value = self.parse_expression(Precedence::LOWEST)?.0;
108108

109109
if self.peek_token_is(&TokenKind::SEMICOLON) {
110110
self.next_token();
@@ -125,7 +125,7 @@ impl<'a> Parser<'a> {
125125
fn parse_return_statement(&mut self) -> Result<Statement, ParseError> {
126126
self.next_token();
127127

128-
let value = self.parse_expression(Precedence::LOWEST)?;
128+
let value = self.parse_expression(Precedence::LOWEST)?.0;
129129

130130
if self.peek_token_is(&TokenKind::SEMICOLON) {
131131
self.next_token();
@@ -135,24 +135,33 @@ impl<'a> Parser<'a> {
135135
}
136136

137137
fn parse_expression_statement(&mut self) -> Result<Statement, ParseError> {
138-
let expr = self.parse_expression(Precedence::LOWEST)?;
138+
let expr = self.parse_expression(Precedence::LOWEST)?.0;
139139
if self.peek_token_is(&TokenKind::SEMICOLON) {
140140
self.next_token();
141141
}
142142

143143
Ok(Statement::Expr(expr))
144144
}
145145

146-
fn parse_expression(&mut self, precedence: Precedence) -> Result<Expression, ParseError> {
146+
fn parse_expression(&mut self, precedence: Precedence) -> Result<(Expression, Span), ParseError> {
147+
let start = self.current_token.span.start;
147148
let mut left = self.parse_prefix_expression()?;
148149
while self.peek_token.kind != TokenKind::SEMICOLON && precedence < get_token_precedence(&self.peek_token.kind) {
149150
match self.parse_infix_expression(&left) {
150151
Some(infix) => left = infix?,
151-
None => return Ok(left),
152+
None => return Ok((left, Span {
153+
start,
154+
end: self.current_token.span.end
155+
})),
152156
}
153157
}
154158

155-
Ok(left)
159+
let end = self.current_token.span.end;
160+
161+
Ok((left, Span {
162+
start,
163+
end,
164+
}))
156165
}
157166

158167
fn parse_prefix_expression(&mut self) -> Result<Expression, ParseError> {
@@ -175,16 +184,24 @@ impl<'a> Parser<'a> {
175184
span: self.current_token.clone().span,
176185
}))),
177186
TokenKind::BANG | TokenKind::MINUS => {
187+
let start = self.current_token.span.start;
178188
let prefix_op = self.current_token.clone();
179189
self.next_token();
180-
let expr = self.parse_expression(Precedence::PREFIX)?;
181-
return Ok(Expression::PREFIX(prefix_op, Box::new(expr)));
190+
let (expr, span) = self.parse_expression(Precedence::PREFIX)?;
191+
return Ok(Expression::PREFIX(PREFIX {
192+
op: prefix_op,
193+
operand: Box::new(expr),
194+
span: Span {
195+
start,
196+
end: span.end
197+
}
198+
}));
182199
}
183200
TokenKind::LPAREN => {
184201
self.next_token();
185-
let expr = self.parse_expression(Precedence::LOWEST);
202+
let expr = self.parse_expression(Precedence::LOWEST)?.0;
186203
self.expect_peek(&TokenKind::RPAREN)?;
187-
return expr;
204+
return Ok(expr);
188205
}
189206
TokenKind::IF => self.parse_if_expression(),
190207
TokenKind::FUNCTION => self.parse_fn_expression(),
@@ -217,7 +234,7 @@ impl<'a> Parser<'a> {
217234
let infix_op = self.current_token.clone();
218235
let precedence_value = get_token_precedence(&self.current_token.kind);
219236
self.next_token();
220-
let right: Expression = self.parse_expression(precedence_value).unwrap();
237+
let right: Expression = self.parse_expression(precedence_value).unwrap().0;
221238
return Some(Ok(Expression::INFIX(infix_op, Box::new(left.clone()), Box::new(right))));
222239
}
223240
TokenKind::LPAREN => {
@@ -236,7 +253,7 @@ impl<'a> Parser<'a> {
236253
self.expect_peek(&TokenKind::LPAREN)?;
237254
self.next_token();
238255

239-
let condition = self.parse_expression(Precedence::LOWEST)?;
256+
let condition = self.parse_expression(Precedence::LOWEST)?.0;
240257
self.expect_peek(&TokenKind::RPAREN)?;
241258
self.expect_peek(&TokenKind::LBRACE)?;
242259

@@ -327,12 +344,12 @@ impl<'a> Parser<'a> {
327344

328345
self.next_token();
329346

330-
expr_list.push(self.parse_expression(Precedence::LOWEST)?);
347+
expr_list.push(self.parse_expression(Precedence::LOWEST)?.0);
331348

332349
while self.peek_token_is(&TokenKind::COMMA) {
333350
self.next_token();
334351
self.next_token();
335-
expr_list.push(self.parse_expression(Precedence::LOWEST)?);
352+
expr_list.push(self.parse_expression(Precedence::LOWEST)?.0);
336353
}
337354

338355
self.expect_peek(end)?;
@@ -346,7 +363,7 @@ impl<'a> Parser<'a> {
346363

347364
fn parse_index_expression(&mut self, left: Expression) -> Result<Expression, ParseError> {
348365
self.next_token();
349-
let index = self.parse_expression(Precedence::LOWEST)?;
366+
let index = self.parse_expression(Precedence::LOWEST)?.0;
350367

351368
self.expect_peek(&TokenKind::RBRACKET)?;
352369

@@ -359,12 +376,12 @@ impl<'a> Parser<'a> {
359376
while !self.peek_token_is(&TokenKind::RBRACE) {
360377
self.next_token();
361378

362-
let key = self.parse_expression(Precedence::LOWEST)?;
379+
let key = self.parse_expression(Precedence::LOWEST)?.0;
363380

364381
self.expect_peek(&TokenKind::COLON)?;
365382

366383
self.next_token();
367-
let value = self.parse_expression(Precedence::LOWEST)?;
384+
let value = self.parse_expression(Precedence::LOWEST)?.0;
368385

369386
map.push((key, value));
370387

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
source: parser/ast_tree_test.rs
3+
expression: let_ast
4+
---
5+
{
6+
"Program": {
7+
"body": [
8+
{
9+
"type": "Return",
10+
"LITERAL": {
11+
"type": "Integer",
12+
"raw": 3,
13+
"span": {
14+
"start": 7,
15+
"end": 8
16+
}
17+
}
18+
}
19+
]
20+
}
21+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
source: parser/ast_tree_test.rs
3+
expression: let_ast
4+
---
5+
{
6+
"Program": {
7+
"body": [
8+
{
9+
"type": "Expr",
10+
"PREFIX": {
11+
"op": {
12+
"span": {
13+
"start": 0,
14+
"end": 1
15+
},
16+
"kind": {
17+
"type": "MINUS"
18+
}
19+
},
20+
"operand": {
21+
"LITERAL": {
22+
"type": "Integer",
23+
"raw": 3,
24+
"span": {
25+
"start": 1,
26+
"end": 2
27+
}
28+
}
29+
},
30+
"span": {
31+
"start": 0,
32+
"end": 2
33+
}
34+
}
35+
}
36+
]
37+
}
38+
}

0 commit comments

Comments
 (0)