├── .gitignore ├── Cargo.toml ├── README.md └── src ├── ast.rs ├── evaluator.rs ├── lexer.rs ├── lib.rs ├── main.rs ├── object.rs ├── parser.rs ├── repl.rs ├── token.rs └── utils.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | waiig_code_1.4 5 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "waiir" 3 | version = "0.1.0" 4 | authors = ["kei-s "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Writing An Interpreter In Rust 2 | 3 | [Writing An Interpreter In Go](https://interpreterbook.com/) in Rust. 4 | 5 | ## Version 6 | 7 | - Rust 1.36.0 8 | 9 | # Repl 10 | 11 | ``` 12 | $ cargo run 13 | ``` 14 | 15 | # Test 16 | 17 | ``` 18 | $ cargo test 19 | ``` 20 | 21 | # References 22 | 23 | ## Waiir Precedessors 24 | 25 | - [kogai/monkey](https://github.com/kogai/monkey) 26 | - [tsuyoshiwada/rs-monkey-lang](https://github.com/tsuyoshiwada/rs-monkey-lang) 27 | - [avocado-shrimp/Monkey](https://github.com/avocado-shrimp/Monkey) 28 | 29 | ## Rust 30 | 31 | - [The Rust Programming Language, Second Edition / the book (JA)](https://doc.rust-jp.rs/book/second-edition/) 32 | - [Rust by Example (JA)](https://doc.rust-jp.rs/rust-by-example-ja/) 33 | - [The standard library guide](https://doc.rust-lang.org/std/index.html) 34 | -------------------------------------------------------------------------------- /src/ast.rs: -------------------------------------------------------------------------------- 1 | use super::enum_with_fmt; 2 | use std::cell::RefCell; 3 | use std::collections::BTreeMap; 4 | use std::fmt; 5 | use std::rc::Rc; 6 | 7 | #[derive(Debug, PartialEq)] 8 | pub struct Program { 9 | pub statements: Vec, 10 | } 11 | 12 | impl fmt::Display for Program { 13 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 14 | let str_iter = self.statements.iter().map(|stmt| format!("{}", stmt)); 15 | write!(f, "{}", str_iter.collect::>().join("")) 16 | } 17 | } 18 | 19 | // Statement 20 | enum_with_fmt!( 21 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 22 | pub enum Statement { 23 | LetStatement(LetStatement), 24 | ReturnStatement(ReturnStatement), 25 | ExpressionStatement(ExpressionStatement), 26 | } 27 | ); 28 | 29 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 30 | pub struct LetStatement { 31 | pub name: Identifier, 32 | pub value: Expression, 33 | } 34 | 35 | impl fmt::Display for LetStatement { 36 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 37 | write!(f, "let {} = {};", self.name, self.value) 38 | } 39 | } 40 | 41 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 42 | pub struct ReturnStatement { 43 | pub return_value: Expression, 44 | } 45 | 46 | impl fmt::Display for ReturnStatement { 47 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 48 | write!(f, "return {};", self.return_value) 49 | } 50 | } 51 | 52 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 53 | pub struct ExpressionStatement { 54 | pub expression: Expression, 55 | } 56 | 57 | impl fmt::Display for ExpressionStatement { 58 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 59 | write!(f, "{}", self.expression) 60 | } 61 | } 62 | 63 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 64 | pub struct BlockStatement { 65 | pub statements: Vec, 66 | } 67 | 68 | impl fmt::Display for BlockStatement { 69 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 70 | self.statements.iter().map(|s| write!(f, "{}", s)).collect() 71 | } 72 | } 73 | 74 | // Expression 75 | enum_with_fmt!( 76 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 77 | pub enum Expression { 78 | Identifier(Identifier), 79 | IntegerLiteral(IntegerLiteral), 80 | PrefixExpression(PrefixExpression), 81 | InfixExpression(InfixExpression), 82 | Boolean(Boolean), 83 | IfExpression(IfExpression), 84 | FunctionLiteral(FunctionLiteral), 85 | CallExpression(CallExpression), 86 | StringLiteral(StringLiteral), 87 | ArrayLiteral(ArrayLiteral), 88 | IndexExpression(IndexExpression), 89 | HashLiteral(HashLiteral), 90 | MacroLiteral(MacroLiteral), 91 | } 92 | ); 93 | 94 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 95 | pub struct Identifier { 96 | pub value: String, 97 | } 98 | 99 | impl fmt::Display for Identifier { 100 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 101 | write!(f, "{}", self.value) 102 | } 103 | } 104 | 105 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 106 | pub struct IntegerLiteral { 107 | pub value: i64, 108 | } 109 | 110 | impl fmt::Display for IntegerLiteral { 111 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 112 | write!(f, "{}", self.value) 113 | } 114 | } 115 | 116 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 117 | pub struct PrefixExpression { 118 | pub operator: String, 119 | pub right: Box, 120 | } 121 | 122 | impl fmt::Display for PrefixExpression { 123 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 124 | write!(f, "({}{})", self.operator, self.right) 125 | } 126 | } 127 | 128 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 129 | pub struct InfixExpression { 130 | pub left: Box, 131 | pub operator: String, 132 | pub right: Box, 133 | } 134 | 135 | impl fmt::Display for InfixExpression { 136 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 137 | write!(f, "({} {} {})", self.left, self.operator, self.right) 138 | } 139 | } 140 | 141 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 142 | pub struct Boolean { 143 | pub value: bool, 144 | } 145 | 146 | impl fmt::Display for Boolean { 147 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 148 | write!(f, "{}", self.value) 149 | } 150 | } 151 | 152 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 153 | pub struct IfExpression { 154 | pub condition: Box, 155 | pub consequence: Box, 156 | pub alternative: Option>, 157 | } 158 | 159 | impl fmt::Display for IfExpression { 160 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 161 | if let Some(alternative) = &self.alternative { 162 | write!( 163 | f, 164 | "if{} {}else {}", 165 | self.condition, self.consequence, alternative 166 | ) 167 | } else { 168 | write!(f, "if{} {}", self.condition, self.consequence) 169 | } 170 | } 171 | } 172 | 173 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 174 | pub struct FunctionLiteral { 175 | pub parameters: Vec, 176 | pub body: Box, 177 | } 178 | 179 | impl fmt::Display for FunctionLiteral { 180 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 181 | write!( 182 | f, 183 | "fn({}) {}", 184 | self.parameters 185 | .iter() 186 | .map(|p| format!("{}", p)) 187 | .collect::>() 188 | .join(", "), 189 | self.body 190 | ) 191 | } 192 | } 193 | 194 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 195 | pub struct CallExpression { 196 | pub function: Box, 197 | pub arguments: Vec, 198 | } 199 | 200 | impl fmt::Display for CallExpression { 201 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 202 | write!( 203 | f, 204 | "{}({})", 205 | self.function, 206 | self.arguments 207 | .iter() 208 | .map(|p| format!("{}", p)) 209 | .collect::>() 210 | .join(", ") 211 | ) 212 | } 213 | } 214 | 215 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 216 | pub struct StringLiteral { 217 | pub value: String, 218 | } 219 | 220 | impl fmt::Display for StringLiteral { 221 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 222 | write!(f, r#""{}""#, self.value) 223 | } 224 | } 225 | 226 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 227 | pub struct ArrayLiteral { 228 | pub elements: Vec, 229 | } 230 | 231 | impl fmt::Display for ArrayLiteral { 232 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 233 | write!( 234 | f, 235 | "[{}]", 236 | self.elements 237 | .iter() 238 | .map(|p| format!("{}", p)) 239 | .collect::>() 240 | .join(", ") 241 | ) 242 | } 243 | } 244 | 245 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 246 | pub struct IndexExpression { 247 | pub left: Box, 248 | pub index: Box, 249 | } 250 | 251 | impl fmt::Display for IndexExpression { 252 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 253 | write!(f, "({}[{}])", self.left, self.index) 254 | } 255 | } 256 | 257 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 258 | pub struct HashLiteral { 259 | pub pairs: BTreeMap, 260 | } 261 | 262 | impl fmt::Display for HashLiteral { 263 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 264 | write!( 265 | f, 266 | "{{{}}}", 267 | self.pairs 268 | .iter() 269 | .map(|(k, v)| format!("{}: {}", k, v)) 270 | .collect::>() 271 | .join(", ") 272 | ) 273 | } 274 | } 275 | 276 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 277 | pub struct MacroLiteral { 278 | pub parameters: Vec, 279 | pub body: Box, 280 | } 281 | 282 | impl fmt::Display for MacroLiteral { 283 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 284 | write!( 285 | f, 286 | "macro({}) {}", 287 | self.parameters 288 | .iter() 289 | .map(|p| format!("{}", p)) 290 | .collect::>() 291 | .join(", "), 292 | self.body 293 | ) 294 | } 295 | } 296 | 297 | #[derive(Debug, PartialEq)] 298 | pub enum Node { 299 | Program(Program), 300 | Statement(Statement), 301 | BlockStatement(BlockStatement), 302 | Expression(Expression), 303 | } 304 | 305 | pub fn modify Node>(target: Node, modifier: Rc>) -> Node { 306 | match target { 307 | Node::Program(mut program) => { 308 | for i in 0..program.statements.len() { 309 | let statement = program.statements.swap_remove(i); 310 | if let Node::Statement(stmt) = 311 | modify(Node::Statement(statement), Rc::clone(&modifier)) 312 | { 313 | program.statements.insert(i, stmt); 314 | } 315 | } 316 | (&mut *modifier.borrow_mut())(Node::Program(program)) 317 | } 318 | Node::BlockStatement(mut node) => { 319 | for i in 0..node.statements.len() { 320 | let statement = node.statements.swap_remove(i); 321 | if let Node::Statement(stmt) = 322 | modify(Node::Statement(statement), Rc::clone(&modifier)) 323 | { 324 | node.statements.insert(i, stmt) 325 | } 326 | } 327 | (&mut *modifier.borrow_mut())(Node::BlockStatement(node)) 328 | } 329 | Node::Statement(Statement::ExpressionStatement(node)) => { 330 | if let Node::Expression(expression) = 331 | modify(Node::Expression(node.expression), Rc::clone(&modifier)) 332 | { 333 | (&mut *modifier.borrow_mut())(Node::Statement(Statement::ExpressionStatement( 334 | ExpressionStatement { expression }, 335 | ))) 336 | } else { 337 | unreachable!() 338 | } 339 | } 340 | Node::Expression(Expression::InfixExpression(node)) => { 341 | if let Node::Expression(left) = 342 | modify(Node::Expression(*node.left), Rc::clone(&modifier)) 343 | { 344 | if let Node::Expression(right) = 345 | modify(Node::Expression(*node.right), Rc::clone(&modifier)) 346 | { 347 | (&mut *modifier.borrow_mut())(Node::Expression(Expression::InfixExpression( 348 | InfixExpression { 349 | left: Box::new(left), 350 | right: Box::new(right), 351 | operator: node.operator, 352 | }, 353 | ))) 354 | } else { 355 | unreachable!() 356 | } 357 | } else { 358 | unreachable!() 359 | } 360 | } 361 | Node::Expression(Expression::PrefixExpression(node)) => { 362 | if let Node::Expression(right) = 363 | modify(Node::Expression(*node.right), Rc::clone(&modifier)) 364 | { 365 | (&mut *modifier.borrow_mut())(Node::Expression(Expression::PrefixExpression( 366 | PrefixExpression { 367 | right: Box::new(right), 368 | operator: node.operator, 369 | }, 370 | ))) 371 | } else { 372 | unreachable!() 373 | } 374 | } 375 | Node::Expression(Expression::IndexExpression(node)) => { 376 | if let Node::Expression(left) = 377 | modify(Node::Expression(*node.left), Rc::clone(&modifier)) 378 | { 379 | if let Node::Expression(index) = 380 | modify(Node::Expression(*node.index), Rc::clone(&modifier)) 381 | { 382 | (&mut *modifier.borrow_mut())(Node::Expression(Expression::IndexExpression( 383 | IndexExpression { 384 | left: Box::new(left), 385 | index: Box::new(index), 386 | }, 387 | ))) 388 | } else { 389 | unreachable!() 390 | } 391 | } else { 392 | unreachable!() 393 | } 394 | } 395 | Node::Expression(Expression::IfExpression(node)) => { 396 | if let Node::Expression(condition) = 397 | modify(Node::Expression(*node.condition), Rc::clone(&modifier)) 398 | { 399 | if let Node::BlockStatement(consequence) = modify( 400 | Node::BlockStatement(*node.consequence), 401 | Rc::clone(&modifier), 402 | ) { 403 | if node.alternative.is_some() { 404 | if let Node::BlockStatement(alternative) = modify( 405 | Node::BlockStatement(*node.alternative.unwrap()), 406 | Rc::clone(&modifier), 407 | ) { 408 | (&mut *modifier.borrow_mut())(Node::Expression( 409 | Expression::IfExpression(IfExpression { 410 | condition: Box::new(condition), 411 | consequence: Box::new(consequence), 412 | alternative: Some(Box::new(alternative)), 413 | }), 414 | )) 415 | } else { 416 | unreachable!() 417 | } 418 | } else { 419 | (&mut *modifier.borrow_mut())(Node::Expression(Expression::IfExpression( 420 | IfExpression { 421 | condition: Box::new(condition), 422 | consequence: Box::new(consequence), 423 | alternative: None, 424 | }, 425 | ))) 426 | } 427 | } else { 428 | unreachable!() 429 | } 430 | } else { 431 | unreachable!() 432 | } 433 | } 434 | Node::Expression(Expression::FunctionLiteral(mut node)) => { 435 | for i in 0..node.parameters.len() { 436 | let identifier = node.parameters.swap_remove(i); 437 | if let Node::Expression(Expression::Identifier(ident)) = modify( 438 | Node::Expression(Expression::Identifier(identifier)), 439 | Rc::clone(&modifier), 440 | ) { 441 | node.parameters.insert(i, ident); 442 | } 443 | } 444 | if let Node::BlockStatement(body) = 445 | modify(Node::BlockStatement(*node.body), Rc::clone(&modifier)) 446 | { 447 | (&mut *modifier.borrow_mut())(Node::Expression(Expression::FunctionLiteral( 448 | FunctionLiteral { 449 | parameters: node.parameters, 450 | body: Box::new(body), 451 | }, 452 | ))) 453 | } else { 454 | unreachable!() 455 | } 456 | } 457 | Node::Expression(Expression::ArrayLiteral(mut node)) => { 458 | for i in 0..node.elements.len() { 459 | let element = node.elements.swap_remove(i); 460 | if let Node::Expression(elem) = 461 | modify(Node::Expression(element), Rc::clone(&modifier)) 462 | { 463 | node.elements.insert(i, elem); 464 | } 465 | } 466 | (&mut *modifier.borrow_mut())(Node::Expression(Expression::ArrayLiteral(node))) 467 | } 468 | Node::Expression(Expression::HashLiteral(node)) => { 469 | let mut new_pairs = BTreeMap::new(); 470 | for (key, value) in node.pairs { 471 | if let Node::Expression(k) = modify(Node::Expression(key), Rc::clone(&modifier)) { 472 | if let Node::Expression(v) = 473 | modify(Node::Expression(value), Rc::clone(&modifier)) 474 | { 475 | new_pairs.insert(k, v); 476 | } 477 | } 478 | } 479 | (&mut *modifier.borrow_mut())(Node::Expression(Expression::HashLiteral(HashLiteral { 480 | pairs: new_pairs, 481 | }))) 482 | } 483 | Node::Statement(Statement::ReturnStatement(node)) => { 484 | if let Node::Expression(return_value) = 485 | modify(Node::Expression(node.return_value), Rc::clone(&modifier)) 486 | { 487 | (&mut *modifier.borrow_mut())(Node::Statement(Statement::ReturnStatement( 488 | ReturnStatement { return_value }, 489 | ))) 490 | } else { 491 | unreachable!() 492 | } 493 | } 494 | Node::Statement(Statement::LetStatement(node)) => { 495 | if let Node::Expression(value) = 496 | modify(Node::Expression(node.value), Rc::clone(&modifier)) 497 | { 498 | (&mut *modifier.borrow_mut())(Node::Statement(Statement::LetStatement( 499 | LetStatement { 500 | name: node.name, 501 | value, 502 | }, 503 | ))) 504 | } else { 505 | unreachable!() 506 | } 507 | } 508 | _ => (&mut *modifier.borrow_mut())(target), 509 | } 510 | } 511 | 512 | #[cfg(test)] 513 | mod tests { 514 | use super::{ 515 | modify, ArrayLiteral, BTreeMap, BlockStatement, Expression, ExpressionStatement, 516 | FunctionLiteral, HashLiteral, Identifier, IfExpression, IndexExpression, InfixExpression, 517 | IntegerLiteral, LetStatement, Node, PrefixExpression, Program, ReturnStatement, Statement, 518 | }; 519 | use std::cell::RefCell; 520 | use std::rc::Rc; 521 | 522 | #[test] 523 | fn test_string() { 524 | let program = Program { 525 | statements: vec![ 526 | Statement::LetStatement(LetStatement { 527 | name: Identifier { 528 | value: "myVar".to_string(), 529 | }, 530 | value: Expression::Identifier(Identifier { 531 | value: "anotherVar".to_string(), 532 | }), 533 | }), 534 | Statement::ReturnStatement(ReturnStatement { 535 | return_value: Expression::Identifier(Identifier { 536 | value: "returnVar".to_string(), 537 | }), 538 | }), 539 | ], 540 | }; 541 | 542 | assert_eq!( 543 | format!("{}", program), 544 | "let myVar = anotherVar;return returnVar;" 545 | ); 546 | } 547 | 548 | #[test] 549 | fn test_modify() { 550 | fn one() -> Expression { 551 | Expression::IntegerLiteral(IntegerLiteral { value: 1 }) 552 | } 553 | fn two() -> Expression { 554 | Expression::IntegerLiteral(IntegerLiteral { value: 2 }) 555 | } 556 | let turn_one_into_two = |node: Node| -> Node { 557 | if let Node::Expression(Expression::IntegerLiteral(integer)) = &node { 558 | if integer.value != 1 { 559 | return node; 560 | } 561 | Node::Expression(Expression::IntegerLiteral(IntegerLiteral { value: 2 })) 562 | } else { 563 | node 564 | } 565 | }; 566 | 567 | let mut input_map = BTreeMap::new(); 568 | input_map.insert(one(), one()); 569 | input_map.insert(one(), one()); 570 | let mut expected_map = BTreeMap::new(); 571 | expected_map.insert(two(), two()); 572 | expected_map.insert(two(), two()); 573 | 574 | let mut tests = vec![ 575 | (Node::Expression(one()), Node::Expression(two())), 576 | ( 577 | Node::Program(Program { 578 | statements: vec![Statement::ExpressionStatement(ExpressionStatement { 579 | expression: one(), 580 | })], 581 | }), 582 | Node::Program(Program { 583 | statements: vec![Statement::ExpressionStatement(ExpressionStatement { 584 | expression: two(), 585 | })], 586 | }), 587 | ), 588 | ( 589 | Node::Expression(Expression::InfixExpression(InfixExpression { 590 | left: Box::new(one()), 591 | operator: "+".to_string(), 592 | right: Box::new(two()), 593 | })), 594 | Node::Expression(Expression::InfixExpression(InfixExpression { 595 | left: Box::new(two()), 596 | operator: "+".to_string(), 597 | right: Box::new(two()), 598 | })), 599 | ), 600 | ( 601 | Node::Expression(Expression::InfixExpression(InfixExpression { 602 | left: Box::new(two()), 603 | operator: "+".to_string(), 604 | right: Box::new(one()), 605 | })), 606 | Node::Expression(Expression::InfixExpression(InfixExpression { 607 | left: Box::new(two()), 608 | operator: "+".to_string(), 609 | right: Box::new(two()), 610 | })), 611 | ), 612 | ( 613 | Node::Expression(Expression::PrefixExpression(PrefixExpression { 614 | operator: "-".to_string(), 615 | right: Box::new(one()), 616 | })), 617 | Node::Expression(Expression::PrefixExpression(PrefixExpression { 618 | operator: "-".to_string(), 619 | right: Box::new(two()), 620 | })), 621 | ), 622 | ( 623 | Node::Expression(Expression::IndexExpression(IndexExpression { 624 | left: Box::new(one()), 625 | index: Box::new(one()), 626 | })), 627 | Node::Expression(Expression::IndexExpression(IndexExpression { 628 | left: Box::new(two()), 629 | index: Box::new(two()), 630 | })), 631 | ), 632 | ( 633 | Node::Expression(Expression::IfExpression(IfExpression { 634 | condition: Box::new(one()), 635 | consequence: Box::new(BlockStatement { 636 | statements: vec![Statement::ExpressionStatement(ExpressionStatement { 637 | expression: one(), 638 | })], 639 | }), 640 | alternative: Some(Box::new(BlockStatement { 641 | statements: vec![Statement::ExpressionStatement(ExpressionStatement { 642 | expression: one(), 643 | })], 644 | })), 645 | })), 646 | Node::Expression(Expression::IfExpression(IfExpression { 647 | condition: Box::new(two()), 648 | consequence: Box::new(BlockStatement { 649 | statements: vec![Statement::ExpressionStatement(ExpressionStatement { 650 | expression: two(), 651 | })], 652 | }), 653 | alternative: Some(Box::new(BlockStatement { 654 | statements: vec![Statement::ExpressionStatement(ExpressionStatement { 655 | expression: two(), 656 | })], 657 | })), 658 | })), 659 | ), 660 | ( 661 | Node::Statement(Statement::ReturnStatement(ReturnStatement { 662 | return_value: one(), 663 | })), 664 | Node::Statement(Statement::ReturnStatement(ReturnStatement { 665 | return_value: two(), 666 | })), 667 | ), 668 | ( 669 | Node::Statement(Statement::LetStatement(LetStatement { 670 | name: Identifier { 671 | value: "value".to_string(), 672 | }, 673 | value: one(), 674 | })), 675 | Node::Statement(Statement::LetStatement(LetStatement { 676 | name: Identifier { 677 | value: "value".to_string(), 678 | }, 679 | value: two(), 680 | })), 681 | ), 682 | ( 683 | Node::Expression(Expression::FunctionLiteral(FunctionLiteral { 684 | parameters: vec![], 685 | body: Box::new(BlockStatement { 686 | statements: vec![Statement::ExpressionStatement(ExpressionStatement { 687 | expression: one(), 688 | })], 689 | }), 690 | })), 691 | Node::Expression(Expression::FunctionLiteral(FunctionLiteral { 692 | parameters: vec![], 693 | body: Box::new(BlockStatement { 694 | statements: vec![Statement::ExpressionStatement(ExpressionStatement { 695 | expression: two(), 696 | })], 697 | }), 698 | })), 699 | ), 700 | ( 701 | Node::Expression(Expression::ArrayLiteral(ArrayLiteral { 702 | elements: vec![one(), one()], 703 | })), 704 | Node::Expression(Expression::ArrayLiteral(ArrayLiteral { 705 | elements: vec![two(), two()], 706 | })), 707 | ), 708 | ( 709 | Node::Expression(Expression::HashLiteral(HashLiteral { pairs: input_map })), 710 | Node::Expression(Expression::HashLiteral(HashLiteral { 711 | pairs: expected_map, 712 | })), 713 | ), 714 | ]; 715 | 716 | while !tests.is_empty() { 717 | let (input, expected) = tests.pop().unwrap(); 718 | let modified = modify(input, Rc::new(RefCell::new(turn_one_into_two))); 719 | assert_eq!(modified, expected); 720 | } 721 | } 722 | } 723 | -------------------------------------------------------------------------------- /src/evaluator.rs: -------------------------------------------------------------------------------- 1 | use super::ast::{ 2 | modify, ArrayLiteral, BlockStatement, Boolean, CallExpression, Expression, FunctionLiteral, 3 | HashLiteral, Identifier, IfExpression, IndexExpression, InfixExpression, IntegerLiteral, Node, 4 | PrefixExpression, Program, Statement, StringLiteral, 5 | }; 6 | use super::object::hash::hash_key_of; 7 | use super::object::{Array, Builtin, Function, Hash, HashPair, Macro, Object, Quote}; 8 | use std::cell::RefCell; 9 | use std::collections::HashMap; 10 | use std::rc::Rc; 11 | 12 | const TRUE: Object = Object::Boolean(true); 13 | const FALSE: Object = Object::Boolean(false); 14 | const NULL: Object = Object::Null; 15 | 16 | #[derive(Debug, Clone, PartialEq, Eq)] 17 | pub struct Environment { 18 | store: HashMap, 19 | outer: Option>>, 20 | } 21 | 22 | impl Environment { 23 | pub fn new() -> Rc> { 24 | let store = HashMap::new(); 25 | let env = Environment { store, outer: None }; 26 | Rc::new(RefCell::new(env)) 27 | } 28 | 29 | pub fn new_enclosed(outer: Rc>) -> Rc> { 30 | let store = HashMap::new(); 31 | let env = Environment { 32 | store, 33 | outer: Some(outer), 34 | }; 35 | Rc::new(RefCell::new(env)) 36 | } 37 | 38 | fn get(&self, name: &str) -> Option { 39 | if let Some(o) = self.store.get(name) { 40 | Some(o.clone()) 41 | } else { 42 | self.outer 43 | .as_ref() 44 | .and_then(|outer| outer.borrow().get(name)) 45 | } 46 | } 47 | 48 | fn set(&mut self, name: &str, val: &Object) { 49 | self.store.insert(name.to_string(), val.clone()); 50 | } 51 | } 52 | 53 | pub trait Eval { 54 | fn eval(&self, env: &mut Rc>) -> Object; 55 | } 56 | 57 | macro_rules! impl_eval { 58 | ($ty:ty => ($self:ident, $env:ident) $block:block) => { 59 | impl Eval for $ty { 60 | fn eval(&$self, $env: &mut Rc>) -> Object { 61 | $block 62 | } 63 | } 64 | }; 65 | } 66 | 67 | impl_eval!(Program => (self, env) { 68 | let mut result = NULL; 69 | for statement in &self.statements { 70 | result = statement.eval(env); 71 | 72 | match result { 73 | Object::ReturnValue(return_value) => return *return_value, 74 | Object::Error(_) => return result, 75 | _ => (), 76 | } 77 | } 78 | result 79 | }); 80 | 81 | impl_eval!(Vec => (self, env) { 82 | let mut result = NULL; 83 | for stmt in self { 84 | result = stmt.eval(env); 85 | 86 | if let Object::ReturnValue(return_value) = result { 87 | return *return_value; 88 | } 89 | } 90 | result 91 | }); 92 | 93 | impl_eval!(Statement => (self, env) { 94 | match self { 95 | Statement::ExpressionStatement(stmt) => stmt.expression.eval(env), 96 | Statement::ReturnStatement(stmt) => { 97 | let val = stmt.return_value.eval(env); 98 | if is_error(&val) { 99 | return val; 100 | } 101 | Object::ReturnValue(Box::new(val)) 102 | } 103 | Statement::LetStatement(stmt) => { 104 | let val = stmt.value.eval(env); 105 | if is_error(&val) { 106 | return val; 107 | } 108 | env.borrow_mut().set(&stmt.name.value, &val); 109 | val 110 | } 111 | } 112 | }); 113 | 114 | impl_eval!(Expression => (self, env) { 115 | match self { 116 | Expression::IntegerLiteral(exp) => exp.eval(env), 117 | Expression::Boolean(exp) => exp.eval(env), 118 | Expression::PrefixExpression(exp) => exp.eval(env), 119 | Expression::InfixExpression(exp) => exp.eval(env), 120 | Expression::IfExpression(exp) => exp.eval(env), 121 | Expression::Identifier(exp) => exp.eval(env), 122 | Expression::FunctionLiteral(exp) => exp.eval(env), 123 | Expression::CallExpression(exp) => exp.eval(env), 124 | Expression::StringLiteral(exp) => exp.eval(env), 125 | Expression::ArrayLiteral(exp) => exp.eval(env), 126 | Expression::IndexExpression(exp) => exp.eval(env), 127 | Expression::HashLiteral(exp) => exp.eval(env), 128 | _ => unimplemented!() 129 | } 130 | }); 131 | 132 | impl_eval!(IntegerLiteral => (self, _env) { Object::Integer(self.value) }); 133 | 134 | impl_eval!(Boolean => (self, _env) { 135 | native_bool_to_boolean_object(self.value) 136 | }); 137 | 138 | fn native_bool_to_boolean_object(input: bool) -> Object { 139 | if input { 140 | TRUE 141 | } else { 142 | FALSE 143 | } 144 | } 145 | 146 | impl_eval!(PrefixExpression => (self, env) { 147 | let right = self.right.eval(env); 148 | if is_error(&right) { 149 | return right; 150 | } 151 | eval_prefix_expression(&self.operator, right) 152 | }); 153 | 154 | fn eval_prefix_expression(operator: &str, right: Object) -> Object { 155 | match operator { 156 | "!" => eval_bang_operator_expression(right), 157 | "-" => eval_minus_prefix_operator_expression(right), 158 | _ => new_error(format!("unknown operator: {}{:?}", operator, right)), 159 | } 160 | } 161 | 162 | fn eval_bang_operator_expression(right: Object) -> Object { 163 | match right { 164 | TRUE => FALSE, 165 | FALSE => TRUE, 166 | NULL => TRUE, 167 | _ => FALSE, 168 | } 169 | } 170 | 171 | fn eval_minus_prefix_operator_expression(right: Object) -> Object { 172 | if let Object::Integer(value) = right { 173 | Object::Integer(-value) 174 | } else { 175 | new_error(format!("unknown operator: -{:?}", right)) 176 | } 177 | } 178 | 179 | impl_eval!(InfixExpression => (self, env) { 180 | let left = self.left.eval(env); 181 | if is_error(&left) { 182 | return left; 183 | } 184 | let right = self.right.eval(env); 185 | if is_error(&right) { 186 | return right; 187 | } 188 | eval_infix_expression(&self.operator, left, right) 189 | }); 190 | 191 | fn eval_infix_expression(operator: &str, left: Object, right: Object) -> Object { 192 | if operator == "==" { 193 | return native_bool_to_boolean_object(left == right); 194 | } 195 | if operator == "!=" { 196 | return native_bool_to_boolean_object(left != right); 197 | } 198 | if let Object::Integer(l) = left { 199 | if let Object::Integer(r) = right { 200 | return eval_integer_infix_expression(operator, l, r); 201 | } 202 | return new_error(format!( 203 | "type mismatch: {:?} {} {:?}", 204 | left, operator, right 205 | )); 206 | } 207 | if let Object::String(l) = &left { 208 | if let Object::String(r) = &right { 209 | return eval_string_infix_expression(operator, l, r); 210 | } 211 | return new_error(format!( 212 | "type mismatch: {:?} {} {:?}", 213 | left, operator, right 214 | )); 215 | } 216 | new_error(format!( 217 | "unknown operator: {:?} {} {:?}", 218 | left, operator, right 219 | )) 220 | } 221 | 222 | fn eval_integer_infix_expression(operator: &str, left_val: i64, right_val: i64) -> Object { 223 | match operator { 224 | "+" => Object::Integer(left_val + right_val), 225 | "-" => Object::Integer(left_val - right_val), 226 | "*" => Object::Integer(left_val * right_val), 227 | "/" => Object::Integer(left_val / right_val), 228 | "<" => native_bool_to_boolean_object(left_val < right_val), 229 | ">" => native_bool_to_boolean_object(left_val > right_val), 230 | "==" => native_bool_to_boolean_object(left_val == right_val), 231 | "!=" => native_bool_to_boolean_object(left_val != right_val), 232 | _ => new_error(format!( 233 | "unknown operator: {:?} {} {:?}", 234 | left_val, operator, right_val 235 | )), 236 | } 237 | } 238 | 239 | impl_eval!(IfExpression => (self, env) { 240 | let condition = self.condition.eval(env); 241 | if is_error(&condition) { 242 | return condition; 243 | } 244 | 245 | if is_truthy(condition) { 246 | self.consequence.eval(env) 247 | } else if let Some(alternative) = &self.alternative { 248 | alternative.eval(env) 249 | } else { 250 | NULL 251 | } 252 | }); 253 | 254 | impl_eval!(BlockStatement => (self, env) { 255 | let mut result = NULL; 256 | for statement in &self.statements { 257 | result = statement.eval(env); 258 | 259 | match result { 260 | Object::ReturnValue(_) => return result, 261 | Object::Error(_) => return result, 262 | _ => (), 263 | } 264 | } 265 | result 266 | }); 267 | 268 | impl_eval!(Identifier => (self, env) { 269 | if let Some(val) = env.borrow().get(&self.value) { 270 | return val; 271 | } 272 | match self.value.as_str() { 273 | "len" => Object::Builtin(Builtin{func: builtin::len}), 274 | "first" => Object::Builtin(Builtin{func: builtin::first}), 275 | "last" => Object::Builtin(Builtin{func: builtin::last}), 276 | "rest" => Object::Builtin(Builtin{func: builtin::rest}), 277 | "push" => Object::Builtin(Builtin{func: builtin::push}), 278 | "puts" => Object::Builtin(Builtin{func: builtin::puts}), 279 | _ => new_error(format!("identifier not found: {}", self.value)) 280 | } 281 | }); 282 | 283 | impl_eval!(FunctionLiteral => (self, env) { 284 | Object::Function(Function { 285 | parameters: self.parameters.clone(), 286 | body: *self.body.clone(), 287 | env: Rc::clone(&env), 288 | }) 289 | }); 290 | 291 | impl_eval!(CallExpression => (self, env) { 292 | if let Expression::Identifier(identifier) = &*self.function { 293 | if identifier.value == "quote" { 294 | return quote(&self.arguments[0], env) 295 | } 296 | } 297 | let function = self.function.eval(env); 298 | if is_error(&function) { 299 | return function; 300 | } 301 | let mut args: Vec = vec![]; 302 | for argument in &self.arguments { 303 | let evaluated = argument.eval(env); 304 | if is_error(&evaluated) { 305 | return evaluated; 306 | } 307 | args.push(evaluated); 308 | } 309 | apply_function(function, args) 310 | }); 311 | 312 | fn apply_function(func: Object, args: Vec) -> Object { 313 | match func { 314 | Object::Function(function) => { 315 | let mut extended_env = Environment::new_enclosed(function.env); 316 | for (i, param) in function.parameters.iter().enumerate() { 317 | extended_env.borrow_mut().set(¶m.value, &args[i]); 318 | } 319 | let evaluated = function.body.eval(&mut extended_env); 320 | unwrap_return_value(evaluated) 321 | } 322 | Object::Builtin(builtin) => { 323 | let builtin_function = builtin.func; 324 | builtin_function(args) 325 | } 326 | _ => new_error(format!("not a function: {:?}", func)), 327 | } 328 | } 329 | 330 | fn unwrap_return_value(obj: Object) -> Object { 331 | if let Object::ReturnValue(return_value) = obj { 332 | return *return_value; 333 | } 334 | obj 335 | } 336 | 337 | impl_eval!(StringLiteral => (self, _env) { 338 | Object::String(self.value.clone()) 339 | }); 340 | 341 | fn eval_string_infix_expression(operator: &str, left: &str, right: &str) -> Object { 342 | if operator != "+" { 343 | return new_error(format!( 344 | "unknown operator: {:?} {} {:?}", 345 | left, operator, right 346 | )); 347 | } 348 | Object::String([left, right].join("")) 349 | } 350 | 351 | impl_eval!(ArrayLiteral => (self, env) { 352 | let mut elements: Vec = vec![]; 353 | for element in &self.elements { 354 | let evaluated = element.eval(env); 355 | if is_error(&evaluated) { 356 | return evaluated; 357 | } 358 | elements.push(evaluated); 359 | } 360 | Object::Array(Array{ elements }) 361 | }); 362 | 363 | impl_eval!(IndexExpression => (self, env) { 364 | let left = self.left.eval(env); 365 | if is_error(&left) { 366 | return left 367 | } 368 | let index = self.index.eval(env); 369 | if is_error(&index) { 370 | return index 371 | } 372 | eval_index_expression(left, index) 373 | }); 374 | 375 | fn eval_index_expression(left: Object, index: Object) -> Object { 376 | if let Object::Array(array) = &left { 377 | if let Object::Integer(idx) = index { 378 | return eval_array_index_expression(&array.elements, idx); 379 | } 380 | } 381 | if let Object::Hash(hash) = &left { 382 | return eval_hash_index_expression(hash, index); 383 | } 384 | new_error(format!("index operator not supported: {:?}", left)) 385 | } 386 | 387 | fn eval_array_index_expression(elements: &[Object], idx: i64) -> Object { 388 | let max = elements.len() - 1; 389 | 390 | if idx < 0 || idx as usize > max { 391 | return NULL; 392 | } 393 | elements[idx as usize].clone() 394 | } 395 | 396 | impl_eval!(HashLiteral => (self, env) { 397 | let mut pairs = HashMap::new(); 398 | 399 | for (key_node, value_node) in &self.pairs { 400 | let key = key_node.eval(env); 401 | if is_error(&key) { 402 | return key; 403 | } 404 | 405 | let hashed = match hash_key_of(&key) { 406 | Ok(k) => k, 407 | Err(message) => return new_error(message), 408 | }; 409 | 410 | let value = value_node.eval(env); 411 | 412 | pairs.insert(hashed, HashPair{key, value}); 413 | } 414 | 415 | Object::Hash(Hash{pairs}) 416 | }); 417 | 418 | fn eval_hash_index_expression(hash_object: &Hash, index: Object) -> Object { 419 | let key = match hash_key_of(&index) { 420 | Ok(k) => k, 421 | Err(message) => return new_error(message), 422 | }; 423 | 424 | if let Some(pair) = hash_object.pairs.get(&key) { 425 | pair.value.clone() 426 | } else { 427 | NULL 428 | } 429 | } 430 | 431 | fn is_truthy(obj: Object) -> bool { 432 | match obj { 433 | NULL => false, 434 | TRUE => true, 435 | FALSE => false, 436 | _ => true, 437 | } 438 | } 439 | 440 | fn new_error(message: String) -> Object { 441 | Object::Error(message) 442 | } 443 | 444 | fn is_error(obj: &Object) -> bool { 445 | if let Object::Error(_) = obj { 446 | true 447 | } else { 448 | false 449 | } 450 | } 451 | 452 | fn quote(node: &Expression, env: &mut Rc>) -> Object { 453 | let n = eval_unquote_calls(node, env); 454 | Object::Quote(Quote { node: n }) 455 | } 456 | 457 | fn eval_unquote_calls(quoted: &Expression, env: &mut Rc>) -> Expression { 458 | if let Node::Expression(exp) = modify( 459 | Node::Expression(quoted.clone()), 460 | Rc::new(RefCell::new(|node: Node| -> Node { 461 | if !is_unquote_call(&node) { 462 | return node; 463 | } 464 | 465 | if let Node::Expression(Expression::CallExpression(call)) = &node { 466 | if call.arguments.len() != 1 { 467 | return node; 468 | } 469 | let unquoted = call.arguments[0].eval(env); 470 | Node::Expression(convert_object_to_ast_node(unquoted)) 471 | } else { 472 | node 473 | } 474 | })), 475 | ) { 476 | exp 477 | } else { 478 | unreachable!() 479 | } 480 | } 481 | 482 | fn convert_object_to_ast_node(obj: Object) -> Expression { 483 | match obj { 484 | Object::Integer(int) => Expression::IntegerLiteral(IntegerLiteral { value: int }), 485 | Object::Boolean(boolean) => Expression::Boolean(Boolean { value: boolean }), 486 | Object::Quote(quote) => quote.node, 487 | _ => unimplemented!(), 488 | } 489 | } 490 | 491 | fn is_unquote_call(node: &Node) -> bool { 492 | if let Node::Expression(Expression::CallExpression(call_expression)) = node { 493 | if let Expression::Identifier(identifier) = &*call_expression.function { 494 | return identifier.value == "unquote"; 495 | } 496 | false 497 | } else { 498 | false 499 | } 500 | } 501 | 502 | pub fn define_macros(program: &mut Program, env: Rc>) { 503 | let mut definition = vec![]; 504 | for (i, statement) in program.statements.iter().enumerate() { 505 | if is_macro_definition(statement) { 506 | add_macro(statement, Rc::clone(&env)); 507 | definition.push(i); 508 | } 509 | } 510 | 511 | definition.reverse(); 512 | for definition_index in definition.iter() { 513 | program.statements.remove(*definition_index); 514 | } 515 | } 516 | 517 | fn is_macro_definition(node: &Statement) -> bool { 518 | if let Statement::LetStatement(let_statement) = node { 519 | if let Expression::MacroLiteral(_) = let_statement.value { 520 | true 521 | } else { 522 | false 523 | } 524 | } else { 525 | false 526 | } 527 | } 528 | 529 | fn add_macro(stmt: &Statement, env: Rc>) { 530 | if let Statement::LetStatement(let_statement) = stmt { 531 | if let Expression::MacroLiteral(macro_literal) = &let_statement.value { 532 | let macro_o = Object::Macro(Macro { 533 | parameters: macro_literal.parameters.clone(), 534 | env: Rc::clone(&env), 535 | body: *macro_literal.body.clone(), 536 | }); 537 | env.borrow_mut().set(&let_statement.name.value, ¯o_o); 538 | } else { 539 | unreachable!() 540 | } 541 | } else { 542 | unreachable!() 543 | } 544 | } 545 | 546 | pub fn expand_macros(program: Program, env: &mut Rc>) -> Program { 547 | if let Node::Program(p) = modify( 548 | Node::Program(program), 549 | Rc::new(RefCell::new(|node: Node| -> Node { 550 | if let Node::Expression(Expression::CallExpression(call_expression)) = &node { 551 | if let Some(macro_o) = is_macro_call(call_expression, env) { 552 | let args = quote_args(call_expression); 553 | let mut eval_env = Environment::new_enclosed(macro_o.env); 554 | for (i, param) in macro_o.parameters.iter().enumerate() { 555 | eval_env.borrow_mut().set(¶m.value, &args[i]); 556 | } 557 | let evaluated = macro_o.body.eval(&mut eval_env); 558 | if let Object::Quote(quote) = evaluated { 559 | Node::Expression(quote.node) 560 | } else { 561 | panic!("we only support returning AST-nodes from macros"); 562 | } 563 | } else { 564 | node 565 | } 566 | } else { 567 | node 568 | } 569 | })), 570 | ) { 571 | p 572 | } else { 573 | unreachable!() 574 | } 575 | } 576 | 577 | fn is_macro_call(exp: &CallExpression, env: &Rc>) -> Option { 578 | if let Expression::Identifier(identifier) = &*exp.function { 579 | if let Some(obj) = env.borrow().get(&identifier.value) { 580 | if let Object::Macro(macro_o) = obj { 581 | Some(macro_o) 582 | } else { 583 | None 584 | } 585 | } else { 586 | None 587 | } 588 | } else { 589 | None 590 | } 591 | } 592 | 593 | fn quote_args(exp: &CallExpression) -> Vec { 594 | let mut args = vec![]; 595 | 596 | for a in &exp.arguments { 597 | args.push(Object::Quote(Quote { node: a.clone() })); 598 | } 599 | args 600 | } 601 | 602 | mod builtin { 603 | use super::new_error; 604 | use super::{Array, Object, NULL}; 605 | 606 | pub fn len(args: Vec) -> Object { 607 | if args.len() != 1 { 608 | return new_error(format!( 609 | "wrong number of arguments. got={}, want=1", 610 | args.len() 611 | )); 612 | } 613 | match &args[0] { 614 | Object::String(string) => Object::Integer(string.len() as i64), 615 | Object::Array(array) => Object::Integer(array.elements.len() as i64), 616 | _ => new_error(format!( 617 | "argument to `len` not supported, got {:?}", 618 | args[0] 619 | )), 620 | } 621 | } 622 | 623 | pub fn first(args: Vec) -> Object { 624 | if args.len() != 1 { 625 | return new_error(format!( 626 | "wrong number of arguments. got={}, want=1", 627 | args.len() 628 | )); 629 | } 630 | if let Object::Array(array) = &args[0] { 631 | if !array.elements.is_empty() { 632 | array.elements.first().unwrap().clone() 633 | } else { 634 | NULL 635 | } 636 | } else { 637 | new_error(format!( 638 | "argument to `first` must be ARRAY, got {:?}", 639 | args[0] 640 | )) 641 | } 642 | } 643 | 644 | pub fn last(args: Vec) -> Object { 645 | if args.len() != 1 { 646 | return new_error(format!( 647 | "wrong number of arguments. got={}, want=1", 648 | args.len() 649 | )); 650 | } 651 | if let Object::Array(array) = &args[0] { 652 | if !array.elements.is_empty() { 653 | array.elements.last().unwrap().clone() 654 | } else { 655 | NULL 656 | } 657 | } else { 658 | new_error(format!( 659 | "argument to `last` must be ARRAY, got {:?}", 660 | args[0] 661 | )) 662 | } 663 | } 664 | 665 | pub fn rest(args: Vec) -> Object { 666 | if args.len() != 1 { 667 | return new_error(format!( 668 | "wrong number of arguments. got={}, want=1", 669 | args.len() 670 | )); 671 | } 672 | if let Object::Array(array) = &args[0] { 673 | if !array.elements.is_empty() { 674 | Object::Array(Array { 675 | elements: array.elements[1..].to_vec(), 676 | }) 677 | } else { 678 | NULL 679 | } 680 | } else { 681 | new_error(format!( 682 | "argument to `rest` must be ARRAY, got {:?}", 683 | args[0] 684 | )) 685 | } 686 | } 687 | 688 | pub fn push(args: Vec) -> Object { 689 | if args.len() != 2 { 690 | return new_error(format!( 691 | "wrong number of arguments. got={}, want=2", 692 | args.len() 693 | )); 694 | } 695 | if let Object::Array(array) = &args[0] { 696 | let mut elements = array.elements[..].to_vec(); 697 | elements.push(args[1].clone()); 698 | Object::Array(Array { elements }) 699 | } else { 700 | new_error(format!( 701 | "argument to `push` must be ARRAY, got {:?}", 702 | args[0] 703 | )) 704 | } 705 | } 706 | 707 | pub fn puts(args: Vec) -> Object { 708 | for arg in args { 709 | println!("{}", arg); 710 | } 711 | NULL 712 | } 713 | } 714 | 715 | #[cfg(test)] 716 | mod tests { 717 | use super::super::ast::Program; 718 | use super::super::lexer::Lexer; 719 | use super::super::object::hash::Hashable; 720 | use super::super::object::Object; 721 | use super::super::parser::Parser; 722 | use super::{define_macros, expand_macros, Environment, Eval, NULL}; 723 | use std::collections::HashMap; 724 | use std::rc::Rc; 725 | 726 | #[test] 727 | fn test_eval_integer_expression() { 728 | let tests = [ 729 | ("5", 5), 730 | ("10", 10), 731 | ("-5", -5), 732 | ("-10", -10), 733 | ("5 + 5 + 5 + 5 - 10", 10), 734 | ("2 * 2 * 2 * 2 * 2", 32), 735 | ("-50 + 100 + -50", 0), 736 | ("5 * 2 + 10", 20), 737 | ("5 + 2 * 10", 25), 738 | ("20 + 2 * -10", 0), 739 | ("50 / 2 * 2 + 10", 60), 740 | ("2 * (5 + 10)", 30), 741 | ("3 * 3 * 3 + 10", 37), 742 | ("3 * (3 * 3) + 10", 37), 743 | ("(5 + 10 * 2 + 15 / 3) * 2 + -10", 50), 744 | ]; 745 | 746 | for (input, expected) in tests.iter() { 747 | let evaluated = test_eval(input); 748 | assert_integer_object(&evaluated, *expected); 749 | } 750 | } 751 | 752 | #[test] 753 | fn test_eval_boolean_expression() { 754 | let tests = [ 755 | ("true", true), 756 | ("false", false), 757 | ("1 < 2", true), 758 | ("1 > 2", false), 759 | ("1 < 1", false), 760 | ("1 > 1", false), 761 | ("1 == 1", true), 762 | ("1 != 1", false), 763 | ("1 == 2", false), 764 | ("1 != 2", true), 765 | ]; 766 | 767 | for (input, expected) in tests.iter() { 768 | let evaluated = test_eval(input); 769 | assert_boolean_object(evaluated, *expected); 770 | } 771 | } 772 | 773 | #[test] 774 | fn test_bang_operator() { 775 | let tests = [ 776 | ("!true", false), 777 | ("!false", true), 778 | ("!5", false), 779 | ("!!true", true), 780 | ("!!false", false), 781 | ("!!5", true), 782 | ("true == true", true), 783 | ("false == false", true), 784 | ("true == false", false), 785 | ("true != false", true), 786 | ("false != true", true), 787 | ("(1 < 2) == true", true), 788 | ("(1 < 2) == false", false), 789 | ("(1 > 2) == true", false), 790 | ("(1 > 2) == false", true), 791 | ]; 792 | 793 | for (input, expected) in tests.iter() { 794 | let evaluated = test_eval(input); 795 | assert_boolean_object(evaluated, *expected); 796 | } 797 | } 798 | 799 | #[test] 800 | fn test_if_else_expressions() { 801 | let tests = [ 802 | ("if (true) { 10 }", 10), 803 | ("if (1) { 10 }", 10), 804 | ("if (1 < 2) { 10 }", 10), 805 | ("if (1 > 2) { 10 } else { 20 }", 20), 806 | ("if (1 < 2) { 10 } else { 20 }", 10), 807 | ]; 808 | 809 | for (input, expected) in tests.iter() { 810 | let evaluated = test_eval(input); 811 | assert_integer_object(&evaluated, *expected); 812 | } 813 | 814 | let nil_tests = ["if (false) { 10 }", "if (1 > 2) { 10 }"]; 815 | 816 | for input in nil_tests.iter() { 817 | let evaluated = test_eval(input); 818 | assert_null_object(evaluated); 819 | } 820 | } 821 | 822 | #[test] 823 | fn test_return_statements() { 824 | let tests = [ 825 | ("return 10;", 10), 826 | ("return 10; 9;", 10), 827 | ("return 2 * 5; 9;", 10), 828 | ("(; return 2 * 5; 9;", 10), 829 | ( 830 | r#" 831 | if (10 > 1) { 832 | if (10 > 1) { 833 | return 10; 834 | } 835 | return 1; 836 | } 837 | "#, 838 | 10, 839 | ), 840 | ( 841 | r#" 842 | let f = fn(x) { 843 | return x; 844 | x + 10; 845 | }; 846 | f(10); 847 | "#, 848 | 10, 849 | ), 850 | ( 851 | r#" 852 | let f = fn(x) { 853 | let result = x + 10; 854 | return result; 855 | return 10; 856 | }; 857 | f(10); 858 | "#, 859 | 20, 860 | ), 861 | ]; 862 | 863 | for (input, expected) in tests.iter() { 864 | let evaluated = test_eval(input); 865 | assert_integer_object(&evaluated, *expected); 866 | } 867 | } 868 | 869 | #[test] 870 | fn test_error_handling() { 871 | let tests = [ 872 | ("5 + true;", "type mismatch: Integer(5) + Boolean(true)"), 873 | ("5 + true; 5;", "type mismatch: Integer(5) + Boolean(true)"), 874 | ("-true", "unknown operator: -Boolean(true)"), 875 | ( 876 | "true + false;", 877 | "unknown operator: Boolean(true) + Boolean(false)", 878 | ), 879 | ( 880 | "5; true + false; 5", 881 | "unknown operator: Boolean(true) + Boolean(false)", 882 | ), 883 | ( 884 | "if (10 > 1) { true + false; }", 885 | "unknown operator: Boolean(true) + Boolean(false)", 886 | ), 887 | ( 888 | r#" 889 | if (10 > 1) { 890 | if (10 > 1) { 891 | return true + false; 892 | } 893 | } 894 | "#, 895 | "unknown operator: Boolean(true) + Boolean(false)", 896 | ), 897 | ("foobar", "identifier not found: foobar"), 898 | ( 899 | r#""Hello" - "World""#, 900 | r#"unknown operator: "Hello" - "World""#, 901 | ), 902 | ( 903 | r#"{"name": "Monkey"}[fn(x) { x }];"#, 904 | "unusable as hash key: fn(x) {x}", 905 | ), 906 | ]; 907 | 908 | for (input, expected) in tests.iter() { 909 | let evaluated = test_eval(input); 910 | 911 | if let Object::Error(message) = evaluated { 912 | assert_eq!(message, *expected) 913 | } else { 914 | assert!(false, "no error object returned.") 915 | } 916 | } 917 | } 918 | 919 | #[test] 920 | fn test_let_statements() { 921 | let tests = [ 922 | ("let a = 5; a;", 5), 923 | ("let a = 5 * 5; a;", 25), 924 | ("let a = 5; let b = a; b;", 5), 925 | ("let a = 5; let b = a; let c = a + b + 5; c;", 15), 926 | ]; 927 | 928 | for (input, expected) in tests.iter() { 929 | assert_integer_object(&test_eval(input), *expected); 930 | } 931 | } 932 | 933 | #[test] 934 | fn test_function_object() { 935 | let input = "fn(x) { x + 2; }"; 936 | 937 | let evaluated = test_eval(input); 938 | if let Object::Function(func) = &evaluated { 939 | assert_eq!(func.parameters.len(), 1); 940 | assert_eq!(format!("{}", func.parameters[0]), "x"); 941 | assert_eq!(format!("{}", func.body), "(x + 2)"); 942 | } else { 943 | assert!(false, "object is not Function.") 944 | } 945 | } 946 | 947 | #[test] 948 | fn test_function_application() { 949 | let tests = [ 950 | ("let identity = fn(x) { x; }; identity(5);", 5), 951 | ("let identity = fn(x) { return x; }; identity(5);", 5), 952 | ("let double = fn(x) { x * 2; }; double(5);", 10), 953 | ("let add = fn(x, y) { x + y; }; add(5, 5);", 10), 954 | ("let add = fn(x, y) { x + y; }; add(5 + 5, add(5, 5));", 20), 955 | ("fn(x) { x; }(5)", 5), 956 | ]; 957 | 958 | for (input, expected) in tests.iter() { 959 | assert_integer_object(&test_eval(input), *expected); 960 | } 961 | } 962 | 963 | #[test] 964 | fn test_closures() { 965 | let input = r#" 966 | let newAdder = fn(x) { 967 | fn(y) { x + y }; 968 | }; 969 | let addTwo = newAdder(2); 970 | addTwo(2); 971 | "#; 972 | assert_integer_object(&test_eval(input), 4); 973 | } 974 | 975 | #[test] 976 | fn test_recursive() { 977 | let input = r#" 978 | let factorial = fn(n) { 979 | if (n == 0) { 980 | 1; 981 | } else { 982 | n * factorial(n - 1); 983 | } 984 | }; 985 | factorial(5); 986 | "#; 987 | 988 | let evaluated = test_eval(input); 989 | if let Object::Error(message) = evaluated { 990 | assert!(false, message); 991 | } else { 992 | assert_integer_object(&test_eval(input), 120); 993 | } 994 | } 995 | 996 | #[test] 997 | fn test_string_literal() { 998 | let input = r#""Hello World!""#; 999 | let evaluated = test_eval(input); 1000 | if let Object::String(string) = evaluated { 1001 | assert_eq!(string, "Hello World!") 1002 | } else { 1003 | assert!(false, "object is not String") 1004 | } 1005 | } 1006 | 1007 | #[test] 1008 | fn test_string_concatenation() { 1009 | let input = r#""Hello" + " " + "World!""#; 1010 | let evaluated = test_eval(input); 1011 | if let Object::String(string) = &evaluated { 1012 | assert_eq!(string, "Hello World!") 1013 | } else { 1014 | assert!(false, "object is not String") 1015 | } 1016 | } 1017 | 1018 | #[test] 1019 | fn test_builtin_functions() { 1020 | let tests = [ 1021 | (r#"len("")"#, 0), 1022 | (r#"len("four")"#, 4), 1023 | (r#"len("hello world")"#, 11), 1024 | ("len([1, 2, 3])", 3), 1025 | ("len([])", 0), 1026 | ("first([1, 2, 3])", 1), 1027 | ("last([1, 2, 3])", 3), 1028 | ]; 1029 | 1030 | for (input, expected) in tests.iter() { 1031 | let evaluated = test_eval(input); 1032 | assert_integer_object(&evaluated, *expected); 1033 | } 1034 | 1035 | let null_tests = ["first([])", "last([])", "rest([])"]; 1036 | 1037 | for tt in null_tests.iter() { 1038 | assert_null_object(test_eval(tt)); 1039 | } 1040 | 1041 | let array_tests = [("rest([1, 2, 3])", vec![2, 3]), ("push([], 1)", vec![1])]; 1042 | 1043 | for (input, expected) in array_tests.iter() { 1044 | let evaluated = test_eval(input); 1045 | if let Object::Array(array) = &evaluated { 1046 | assert_eq!(array.elements.len(), expected.len()); 1047 | for (r, i) in array.elements.iter().zip(expected.iter()) { 1048 | assert_integer_object(r, *i as i64); 1049 | } 1050 | } else { 1051 | assert!(false, "obj not Array") 1052 | } 1053 | } 1054 | 1055 | let error_tests = [ 1056 | ("len(1)", "argument to `len` not supported, got Integer(1)"), 1057 | ( 1058 | r#"len("one", "two")"#, 1059 | "wrong number of arguments. got=2, want=1", 1060 | ), 1061 | ( 1062 | "first(1)", 1063 | "argument to `first` must be ARRAY, got Integer(1)", 1064 | ), 1065 | ( 1066 | "last(1)", 1067 | "argument to `last` must be ARRAY, got Integer(1)", 1068 | ), 1069 | ( 1070 | "push(1, 1)", 1071 | "argument to `push` must be ARRAY, got Integer(1)", 1072 | ), 1073 | ]; 1074 | 1075 | for (input, expected) in error_tests.iter() { 1076 | let evaluated = test_eval(input); 1077 | if let Object::Error(message) = evaluated { 1078 | assert_eq!(message, *expected) 1079 | } else { 1080 | assert!(false, "object is not Error") 1081 | } 1082 | } 1083 | } 1084 | 1085 | #[test] 1086 | fn test_array_literals() { 1087 | let input = "[1, 2 * 2, 3 + 3]"; 1088 | 1089 | let evaluated = test_eval(input); 1090 | if let Object::Array(result) = evaluated { 1091 | assert_eq!(result.elements.len(), 3); 1092 | for (r, i) in result.elements.iter().zip([1, 4, 6].iter()) { 1093 | assert_integer_object(r, *i as i64); 1094 | } 1095 | } else { 1096 | assert!(false, "object is not array") 1097 | } 1098 | } 1099 | 1100 | #[test] 1101 | fn test_array_index_expressions() { 1102 | let tests = [ 1103 | ("[1, 2, 3][0]", 1), 1104 | ("[1, 2, 3][1]", 2), 1105 | ("[1, 2, 3][2]", 3), 1106 | ("let i = 0; [1][i]", 1), 1107 | ("[1, 2, 3][1 + 1]", 3), 1108 | ("let myArray = [1, 2, 3]; myArray[2]", 3), 1109 | ( 1110 | "let myArray = [1, 2, 3]; myArray[0] + myArray[1] + myArray[2]", 1111 | 6, 1112 | ), 1113 | ("let myArray = [1, 2, 3]; let i = myArray[0]; myArray[i]", 2), 1114 | ]; 1115 | 1116 | for (input, expected) in tests.iter() { 1117 | let evaluated = test_eval(input); 1118 | assert_integer_object(&evaluated, *expected); 1119 | } 1120 | 1121 | let null_tests = ["[1, 2, 3][3]", "[1, 2, 3][-1]"]; 1122 | 1123 | for tt in null_tests.iter() { 1124 | let input = tt; 1125 | let evaluated = test_eval(input); 1126 | assert_null_object(evaluated); 1127 | } 1128 | } 1129 | 1130 | #[test] 1131 | fn test_hash_literals() { 1132 | let input = r#" 1133 | let two = "two"; 1134 | { 1135 | "one": 10 - 9, 1136 | two: 1 + 1, 1137 | "thr" + "ee": 6 / 2, 1138 | 4: 4, 1139 | true: 5, 1140 | false: 6 1141 | }"#; 1142 | 1143 | let mut expected = HashMap::new(); 1144 | expected.insert("one".to_string().hash_key(), 1); 1145 | expected.insert("two".to_string().hash_key(), 2); 1146 | expected.insert("three".to_string().hash_key(), 3); 1147 | expected.insert((4 as i64).hash_key(), 4); 1148 | expected.insert(true.hash_key(), 5); 1149 | expected.insert(false.hash_key(), 6); 1150 | 1151 | let evaluated = test_eval(input); 1152 | if let Object::Hash(result) = evaluated { 1153 | assert_eq!(result.pairs.len(), expected.len()); 1154 | 1155 | for (expected_key, expected_value) in expected.iter() { 1156 | let pair = result.pairs.get(expected_key).unwrap(); 1157 | assert_integer_object(&pair.value, *expected_value as i64); 1158 | } 1159 | } else { 1160 | assert!(false, "Eval didn't return Hash") 1161 | } 1162 | } 1163 | 1164 | #[test] 1165 | fn test_hash_index_expressions() { 1166 | let tests = [ 1167 | (r#"{"foo": 5}["foo"]"#, 5), 1168 | (r#"let key = "foo"; {"foo": 5}[key]"#, 5), 1169 | ("{5: 5}[5]", 5), 1170 | ("{true: 5}[true]", 5), 1171 | ("{false: 5}[false]", 5), 1172 | ]; 1173 | 1174 | for (input, expected) in tests.iter() { 1175 | let evaluated = test_eval(input); 1176 | assert_integer_object(&evaluated, *expected); 1177 | } 1178 | 1179 | let null_tests = [r#"{"foo": 5}["bar"]"#, r#"{}["foo"]"#]; 1180 | 1181 | for tt in null_tests.iter() { 1182 | let input = tt; 1183 | let evaluated = test_eval(input); 1184 | assert_null_object(evaluated); 1185 | } 1186 | } 1187 | 1188 | #[test] 1189 | fn test_quote() { 1190 | let tests = [ 1191 | ("quote(5)", "5"), 1192 | ("quote(5 + 8)", "(5 + 8)"), 1193 | ("quote(foobar + barfoo)", "(foobar + barfoo)"), 1194 | ]; 1195 | 1196 | for (input, expected) in tests.iter() { 1197 | let evaluated = test_eval(input); 1198 | if let Object::Quote(quote) = evaluated { 1199 | assert_eq!(format!("{}", quote.node), expected as &str) 1200 | } else { 1201 | assert!(false, "expected Quote") 1202 | } 1203 | } 1204 | } 1205 | 1206 | #[test] 1207 | fn test_quote_unquote() { 1208 | let tests = [ 1209 | ("quote(unquote(4))", "4"), 1210 | ("quote(unquote(4 + 4))", "8"), 1211 | ("quote(8 + unquote(4 + 4))", "(8 + 8)"), 1212 | ("quote(unquote(4 + 4) + 8)", "(8 + 8)"), 1213 | ("let foobar = 8; quote(foobar)", "foobar"), 1214 | ("let foobar = 8; quote(unquote(foobar))", "8"), 1215 | ("quote(unquote(true))", "true"), 1216 | ("quote(unquote(true == false))", "false"), 1217 | ("quote(unquote(quote(4 + 4)))", "(4 + 4)"), 1218 | ( 1219 | r#"let quotedInfixExpression = quote(4 + 4); 1220 | quote(unquote(4 + 4) + unquote(quotedInfixExpression))"#, 1221 | "(8 + (4 + 4))", 1222 | ), 1223 | ]; 1224 | 1225 | for (input, expected) in tests.iter() { 1226 | let evaluated = test_eval(input); 1227 | if let Object::Quote(quote) = evaluated { 1228 | assert_eq!(format!("{}", quote.node), expected as &str) 1229 | } else { 1230 | assert!(false, "expected Quote") 1231 | } 1232 | } 1233 | } 1234 | 1235 | #[test] 1236 | fn test_define_macros() { 1237 | let input = r#" 1238 | let number = 1; 1239 | let funciton = fn(x, y) { x + y; }; 1240 | let mymacro = macro(x, y) { x + y; }; 1241 | "#; 1242 | 1243 | let env = Environment::new(); 1244 | let mut program = test_parse_program(input); 1245 | 1246 | define_macros(&mut program, Rc::clone(&env)); 1247 | 1248 | assert_eq!(program.statements.len(), 2); 1249 | 1250 | let borrowed_env = env.borrow(); 1251 | assert!(borrowed_env.get("number").is_none()); 1252 | assert!(borrowed_env.get("function").is_none()); 1253 | 1254 | if let Some(obj) = borrowed_env.get("mymacro") { 1255 | if let Object::Macro(macro_o) = obj { 1256 | assert_eq!(macro_o.parameters.len(), 2); 1257 | assert_eq!(macro_o.parameters[0].value, "x".to_string()); 1258 | assert_eq!(macro_o.parameters[1].value, "y".to_string()); 1259 | assert_eq!(format!("{}", macro_o.body), "(x + y)"); 1260 | } else { 1261 | assert!(false, "object is not Macro") 1262 | } 1263 | } else { 1264 | assert!(false, "macro not in environment.") 1265 | } 1266 | } 1267 | 1268 | #[test] 1269 | fn test_expand_macros() { 1270 | let tests = [ 1271 | ( 1272 | r#" 1273 | let infixExpression = macro() { quote(1 + 2); }; 1274 | infixExpression(); 1275 | "#, 1276 | "(1 + 2)", 1277 | ), 1278 | ( 1279 | r#" 1280 | let reverse = macro(a, b) { quote(unquote(b) - unquote(a)); }; 1281 | reverse(2 + 2, 10 - 5); 1282 | "#, 1283 | "(10 - 5) - (2 + 2)", 1284 | ), 1285 | ( 1286 | r#" 1287 | let unless = macro(condition, consequence, alternative) { 1288 | quote(if (!(unquote(condition))){ 1289 | unquote(consequence); 1290 | } else { 1291 | unquote(alternative); 1292 | }) 1293 | }; 1294 | unless(10 > 5, puts("not greater"), puts("greater")); 1295 | "#, 1296 | r#"if (!(10 > 5)) { puts("not greater") } else { puts("greater") }"#, 1297 | ), 1298 | ]; 1299 | 1300 | for (input, expected_str) in tests.iter() { 1301 | let expected = test_parse_program(expected_str); 1302 | let mut program = test_parse_program(input); 1303 | 1304 | let env = Environment::new(); 1305 | define_macros(&mut program, Rc::clone(&env)); 1306 | let expanded = expand_macros(program, &mut Rc::clone(&env)); 1307 | 1308 | assert_eq!(format!("{}", expanded), format!("{}", expected)); 1309 | } 1310 | } 1311 | 1312 | fn test_parse_program(input: &str) -> Program { 1313 | let l = Lexer::new(input); 1314 | let mut p = Parser::new(l); 1315 | p.parse_program() 1316 | } 1317 | 1318 | fn test_eval(input: &str) -> Object { 1319 | let l = Lexer::new(input); 1320 | let mut p = Parser::new(l); 1321 | let program = p.parse_program(); 1322 | let mut env = Environment::new(); 1323 | program.eval(&mut env) 1324 | } 1325 | 1326 | fn assert_integer_object(obj: &Object, expected: i64) { 1327 | if let Object::Integer(result) = obj { 1328 | assert_eq!(result, &expected) 1329 | } else { 1330 | assert!(false, "object is not Integer") 1331 | } 1332 | } 1333 | 1334 | fn assert_boolean_object(obj: Object, expected: bool) { 1335 | if let Object::Boolean(result) = obj { 1336 | assert_eq!(result, expected) 1337 | } else { 1338 | assert!(false, "object is not Boolean") 1339 | } 1340 | } 1341 | 1342 | fn assert_null_object(obj: Object) { 1343 | assert_eq!(obj, NULL); 1344 | } 1345 | } 1346 | -------------------------------------------------------------------------------- /src/lexer.rs: -------------------------------------------------------------------------------- 1 | use super::token::{lookup_ident, Token, TokenType}; 2 | 3 | pub struct Lexer { 4 | chars: std::iter::Peekable>, 5 | ch: Option, 6 | } 7 | 8 | impl Lexer { 9 | pub fn new(input: &str) -> Lexer { 10 | let mut l = Lexer { 11 | chars: input.chars().collect::>().into_iter().peekable(), 12 | ch: None, 13 | }; 14 | l.read_char(); 15 | l 16 | } 17 | 18 | fn next_token(&mut self) -> Option { 19 | self.skip_whitespace(); 20 | 21 | let tok = if let Some(ch) = self.ch { 22 | Some(match ch { 23 | '=' => { 24 | if self.peek_char().is_some() && self.peek_char().unwrap() == &'=' { 25 | self.read_char(); 26 | let literal: String = [ch, self.ch.unwrap()].iter().collect(); 27 | Token { 28 | t: TokenType::Eq, 29 | literal, 30 | } 31 | } else { 32 | Token { 33 | t: TokenType::Assign, 34 | literal: ch.to_string(), 35 | } 36 | } 37 | } 38 | '+' => Token { 39 | t: TokenType::Plus, 40 | literal: ch.to_string(), 41 | }, 42 | '-' => Token { 43 | t: TokenType::Minus, 44 | literal: ch.to_string(), 45 | }, 46 | '!' => { 47 | if self.peek_char().is_some() && self.peek_char().unwrap() == &'=' { 48 | self.read_char(); 49 | let literal: String = [ch, self.ch.unwrap()].iter().collect(); 50 | Token { 51 | t: TokenType::NotEq, 52 | literal, 53 | } 54 | } else { 55 | Token { 56 | t: TokenType::Bang, 57 | literal: ch.to_string(), 58 | } 59 | } 60 | } 61 | '*' => Token { 62 | t: TokenType::Asterisk, 63 | literal: ch.to_string(), 64 | }, 65 | '/' => Token { 66 | t: TokenType::Slash, 67 | literal: ch.to_string(), 68 | }, 69 | '<' => Token { 70 | t: TokenType::Lt, 71 | literal: ch.to_string(), 72 | }, 73 | '>' => Token { 74 | t: TokenType::Gt, 75 | literal: ch.to_string(), 76 | }, 77 | ',' => Token { 78 | t: TokenType::Comma, 79 | literal: ch.to_string(), 80 | }, 81 | ';' => Token { 82 | t: TokenType::Semicolon, 83 | literal: ch.to_string(), 84 | }, 85 | '(' => Token { 86 | t: TokenType::LParen, 87 | literal: ch.to_string(), 88 | }, 89 | ')' => Token { 90 | t: TokenType::RParen, 91 | literal: ch.to_string(), 92 | }, 93 | '{' => Token { 94 | t: TokenType::LBrace, 95 | literal: ch.to_string(), 96 | }, 97 | '}' => Token { 98 | t: TokenType::RBrace, 99 | literal: ch.to_string(), 100 | }, 101 | '"' => Token { 102 | t: TokenType::String, 103 | literal: self.read_string(), 104 | }, 105 | '[' => Token { 106 | t: TokenType::LBracket, 107 | literal: ch.to_string(), 108 | }, 109 | ']' => Token { 110 | t: TokenType::RBracket, 111 | literal: ch.to_string(), 112 | }, 113 | ':' => Token { 114 | t: TokenType::Colon, 115 | literal: ch.to_string(), 116 | }, 117 | 'a'..='z' | 'A'..='Z' | '_' => return Some(self.read_identifier()), 118 | '0'..='9' => return Some(self.read_number()), 119 | _ => Token { 120 | t: TokenType::Illegal, 121 | literal: ch.to_string(), 122 | }, 123 | }) 124 | } else { 125 | None 126 | }; 127 | 128 | self.read_char(); 129 | tok 130 | } 131 | 132 | fn read_char(&mut self) { 133 | self.ch = self.chars.next(); 134 | } 135 | 136 | fn peek_char(&mut self) -> Option<&char> { 137 | self.chars.peek() 138 | } 139 | 140 | fn read_identifier(&mut self) -> Token { 141 | let mut literal = String::new(); 142 | while let Some(ch) = self.ch { 143 | match ch { 144 | 'a'..='z' | 'A'..='Z' | '_' => { 145 | literal.push(ch); 146 | self.read_char(); 147 | } 148 | _ => { 149 | break; 150 | } 151 | } 152 | } 153 | Token { 154 | t: lookup_ident(literal.as_str()), 155 | literal, 156 | } 157 | } 158 | 159 | fn read_number(&mut self) -> Token { 160 | let mut literal = String::new(); 161 | while let Some(ch) = self.ch { 162 | match ch { 163 | '0'..='9' => { 164 | literal.push(ch); 165 | self.read_char(); 166 | } 167 | _ => { 168 | break; 169 | } 170 | }; 171 | } 172 | Token { 173 | t: TokenType::Int, 174 | literal, 175 | } 176 | } 177 | fn read_string(&mut self) -> String { 178 | let mut literal = String::new(); 179 | loop { 180 | self.read_char(); 181 | if self.ch.is_none() || self.ch.unwrap() == '"' { 182 | break; 183 | } 184 | literal.push(self.ch.unwrap()); 185 | } 186 | literal 187 | } 188 | 189 | fn skip_whitespace(&mut self) { 190 | while let Some(ch) = self.ch { 191 | match ch { 192 | ' ' | '\t' | '\n' | '\r' => self.read_char(), 193 | _ => { 194 | break; 195 | } 196 | }; 197 | } 198 | } 199 | } 200 | 201 | impl Iterator for Lexer { 202 | type Item = Token; 203 | fn next(&mut self) -> Option { 204 | self.next_token() 205 | } 206 | } 207 | 208 | #[cfg(test)] 209 | mod tests { 210 | use super::{Lexer, TokenType}; 211 | 212 | #[test] 213 | fn test_next_token() { 214 | let input = r#"let five = 5; 215 | let ten = 10; 216 | 217 | let add = fn(x, y) { 218 | x + y; 219 | }; 220 | 221 | let result = add(five, ten); 222 | !-/*5; 223 | 5 < 10 > 5; 224 | 225 | if (5 < 10) { 226 | return true; 227 | } else { 228 | return false; 229 | } 230 | 231 | 10 == 10; 232 | 10 != 9; 233 | -a * b 234 | "foobar" 235 | "foo bar" 236 | [1,2]; 237 | {"foo": "bar"} 238 | macro(x, y) { x + y; };"#; 239 | 240 | let tests = [ 241 | (TokenType::Let, "let"), 242 | (TokenType::Ident, "five"), 243 | (TokenType::Assign, "="), 244 | (TokenType::Int, "5"), 245 | (TokenType::Semicolon, ";"), 246 | (TokenType::Let, "let"), 247 | (TokenType::Ident, "ten"), 248 | (TokenType::Assign, "="), 249 | (TokenType::Int, "10"), 250 | (TokenType::Semicolon, ";"), 251 | (TokenType::Let, "let"), 252 | (TokenType::Ident, "add"), 253 | (TokenType::Assign, "="), 254 | (TokenType::Function, "fn"), 255 | (TokenType::LParen, "("), 256 | (TokenType::Ident, "x"), 257 | (TokenType::Comma, ","), 258 | (TokenType::Ident, "y"), 259 | (TokenType::RParen, ")"), 260 | (TokenType::LBrace, "{"), 261 | (TokenType::Ident, "x"), 262 | (TokenType::Plus, "+"), 263 | (TokenType::Ident, "y"), 264 | (TokenType::Semicolon, ";"), 265 | (TokenType::RBrace, "}"), 266 | (TokenType::Semicolon, ";"), 267 | (TokenType::Let, "let"), 268 | (TokenType::Ident, "result"), 269 | (TokenType::Assign, "="), 270 | (TokenType::Ident, "add"), 271 | (TokenType::LParen, "("), 272 | (TokenType::Ident, "five"), 273 | (TokenType::Comma, ","), 274 | (TokenType::Ident, "ten"), 275 | (TokenType::RParen, ")"), 276 | (TokenType::Semicolon, ";"), 277 | (TokenType::Bang, "!"), 278 | (TokenType::Minus, "-"), 279 | (TokenType::Slash, "/"), 280 | (TokenType::Asterisk, "*"), 281 | (TokenType::Int, "5"), 282 | (TokenType::Semicolon, ";"), 283 | (TokenType::Int, "5"), 284 | (TokenType::Lt, "<"), 285 | (TokenType::Int, "10"), 286 | (TokenType::Gt, ">"), 287 | (TokenType::Int, "5"), 288 | (TokenType::Semicolon, ";"), 289 | (TokenType::If, "if"), 290 | (TokenType::LParen, "("), 291 | (TokenType::Int, "5"), 292 | (TokenType::Lt, "<"), 293 | (TokenType::Int, "10"), 294 | (TokenType::RParen, ")"), 295 | (TokenType::LBrace, "{"), 296 | (TokenType::Return, "return"), 297 | (TokenType::True, "true"), 298 | (TokenType::Semicolon, ";"), 299 | (TokenType::RBrace, "}"), 300 | (TokenType::Else, "else"), 301 | (TokenType::LBrace, "{"), 302 | (TokenType::Return, "return"), 303 | (TokenType::False, "false"), 304 | (TokenType::Semicolon, ";"), 305 | (TokenType::RBrace, "}"), 306 | (TokenType::Int, "10"), 307 | (TokenType::Eq, "=="), 308 | (TokenType::Int, "10"), 309 | (TokenType::Semicolon, ";"), 310 | (TokenType::Int, "10"), 311 | (TokenType::NotEq, "!="), 312 | (TokenType::Int, "9"), 313 | (TokenType::Semicolon, ";"), 314 | (TokenType::Minus, "-"), 315 | (TokenType::Ident, "a"), 316 | (TokenType::Asterisk, "*"), 317 | (TokenType::Ident, "b"), 318 | (TokenType::String, "foobar"), 319 | (TokenType::String, "foo bar"), 320 | (TokenType::LBracket, "["), 321 | (TokenType::Int, "1"), 322 | (TokenType::Comma, ","), 323 | (TokenType::Int, "2"), 324 | (TokenType::RBracket, "]"), 325 | (TokenType::Semicolon, ";"), 326 | (TokenType::LBrace, "{"), 327 | (TokenType::String, "foo"), 328 | (TokenType::Colon, ":"), 329 | (TokenType::String, "bar"), 330 | (TokenType::RBrace, "}"), 331 | (TokenType::Macro, "macro"), 332 | (TokenType::LParen, "("), 333 | (TokenType::Ident, "x"), 334 | (TokenType::Comma, ","), 335 | (TokenType::Ident, "y"), 336 | (TokenType::RParen, ")"), 337 | (TokenType::LBrace, "{"), 338 | (TokenType::Ident, "x"), 339 | (TokenType::Plus, "+"), 340 | (TokenType::Ident, "y"), 341 | (TokenType::Semicolon, ";"), 342 | (TokenType::RBrace, "}"), 343 | (TokenType::Semicolon, ";"), 344 | ]; 345 | 346 | let mut l = Lexer::new(input); 347 | 348 | for (expected_type, expected_literal) in tests.iter() { 349 | let tok = l.next().unwrap(); 350 | assert_eq!(tok.t, *expected_type); 351 | assert_eq!(tok.literal, *expected_literal); 352 | } 353 | assert_eq!(l.next(), None); 354 | } 355 | } 356 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | mod ast; 2 | mod evaluator; 3 | pub mod lexer; 4 | mod object; 5 | mod parser; 6 | pub mod repl; 7 | pub mod token; 8 | #[macro_use] 9 | mod utils; 10 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use waiir::repl; 2 | 3 | fn main() { 4 | println!("Hello! This is the Monkey programming language!"); 5 | println!("Feel free to type in commands"); 6 | repl::start(); 7 | } 8 | -------------------------------------------------------------------------------- /src/object.rs: -------------------------------------------------------------------------------- 1 | use self::hash::HashKey; 2 | use super::ast::{BlockStatement, Expression, Identifier}; 3 | use super::enum_with_fmt; 4 | use super::evaluator::Environment; 5 | use std::cell::RefCell; 6 | use std::collections::HashMap; 7 | use std::fmt; 8 | use std::rc::Rc; 9 | 10 | enum_with_fmt!( 11 | #[derive(Debug,Clone,PartialEq,Eq)] 12 | pub enum Object { 13 | Integer(i64), 14 | Boolean(bool), 15 | ReturnValue(Box), 16 | Function(Function), 17 | Builtin(Builtin), 18 | Array(Array), 19 | Hash(Hash), 20 | String(String), 21 | Quote(Quote), 22 | Macro(Macro), 23 | => // custom format 24 | Error(String) => "Error: {}", 25 | ;=> // without data and custom format 26 | Null => "null", 27 | } 28 | ); 29 | 30 | #[derive(Debug, Clone, PartialEq, Eq)] 31 | pub struct Function { 32 | pub parameters: Vec, 33 | pub body: BlockStatement, 34 | pub env: Rc>, 35 | } 36 | 37 | impl fmt::Display for Function { 38 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 39 | write!( 40 | f, 41 | "fn({}) {{{}}}", // {{ => { 42 | self.parameters 43 | .iter() 44 | .map(|p| format!("{}", p)) 45 | .collect::>() 46 | .join(", "), 47 | self.body 48 | ) 49 | } 50 | } 51 | 52 | #[derive(Debug, Clone, PartialEq, Eq)] 53 | pub struct Array { 54 | pub elements: Vec, 55 | } 56 | 57 | impl fmt::Display for Array { 58 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 59 | write!( 60 | f, 61 | "[{}]", 62 | self.elements 63 | .iter() 64 | .map(|p| format!("{}", p)) 65 | .collect::>() 66 | .join(", ") 67 | ) 68 | } 69 | } 70 | 71 | #[derive(Debug, Clone, PartialEq, Eq)] 72 | pub struct Builtin { 73 | pub func: fn(Vec) -> Object, 74 | } 75 | 76 | impl fmt::Display for Builtin { 77 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 78 | write!(f, "builtin function") 79 | } 80 | } 81 | 82 | #[derive(Debug, Clone, PartialEq, Eq)] 83 | pub struct HashPair { 84 | pub key: Object, 85 | pub value: Object, 86 | } 87 | 88 | #[derive(Debug, Clone, PartialEq, Eq)] 89 | pub struct Hash { 90 | pub pairs: HashMap, 91 | } 92 | 93 | impl fmt::Display for Hash { 94 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 95 | write!( 96 | f, 97 | "{{{}}}", 98 | self.pairs 99 | .iter() 100 | .map(|(_, pair)| format!("{}: {}", pair.key, pair.value)) 101 | .collect::>() 102 | .join(", ") 103 | ) 104 | } 105 | } 106 | 107 | #[derive(Debug, Clone, PartialEq, Eq)] 108 | pub struct Quote { 109 | pub node: Expression, 110 | } 111 | 112 | impl fmt::Display for Quote { 113 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 114 | write!(f, "QUOTE({})", self.node) 115 | } 116 | } 117 | 118 | #[derive(Debug, Clone, PartialEq, Eq)] 119 | pub struct Macro { 120 | pub parameters: Vec, 121 | pub body: BlockStatement, 122 | pub env: Rc>, 123 | } 124 | 125 | impl fmt::Display for Macro { 126 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 127 | write!( 128 | f, 129 | "macro({}) {{{}}}", // {{ => { 130 | self.parameters 131 | .iter() 132 | .map(|p| format!("{}", p)) 133 | .collect::>() 134 | .join(", "), 135 | self.body 136 | ) 137 | } 138 | } 139 | 140 | pub mod hash { 141 | use super::Object; 142 | use std::collections::hash_map::DefaultHasher; 143 | use std::hash::Hasher; 144 | 145 | pub fn hash_key_of(object: &Object) -> Result { 146 | Ok(match object { 147 | Object::String(string) => string.hash_key(), 148 | Object::Integer(integer) => integer.hash_key(), 149 | Object::Boolean(boolean) => boolean.hash_key(), 150 | _ => return Err(format!("unusable as hash key: {}", object)), 151 | }) 152 | } 153 | 154 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 155 | pub struct HashKey { 156 | t: HashType, 157 | value: u64, 158 | } 159 | 160 | #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 161 | enum HashType { 162 | Integer, 163 | Boolean, 164 | String, 165 | } 166 | 167 | pub trait Hashable { 168 | fn hash_key(&self) -> HashKey; 169 | } 170 | 171 | impl Hashable for String { 172 | fn hash_key(&self) -> HashKey { 173 | let mut hasher = DefaultHasher::new(); 174 | hasher.write(self.as_bytes()); 175 | HashKey { 176 | t: HashType::String, 177 | value: hasher.finish(), 178 | } 179 | } 180 | } 181 | 182 | impl Hashable for i64 { 183 | fn hash_key(&self) -> HashKey { 184 | HashKey { 185 | t: HashType::Integer, 186 | value: *self as u64, 187 | } 188 | } 189 | } 190 | 191 | impl Hashable for bool { 192 | fn hash_key(&self) -> HashKey { 193 | let value = if *self { 1 } else { 0 }; 194 | 195 | HashKey { 196 | t: HashType::Boolean, 197 | value, 198 | } 199 | } 200 | } 201 | 202 | #[cfg(test)] 203 | mod tests { 204 | use super::Hashable; 205 | 206 | #[test] 207 | fn test_string_hash_key() { 208 | let hello1 = "Hello World".to_string(); 209 | let hello2 = "Hello World".to_string(); 210 | let diff1 = "My name is johnny".to_string(); 211 | let diff2 = "My name is johnny".to_string(); 212 | 213 | assert_eq!(hello1.hash_key(), hello2.hash_key()); 214 | assert_eq!(diff1.hash_key(), diff2.hash_key()); 215 | assert_ne!(hello1.hash_key(), diff2.hash_key()); 216 | } 217 | 218 | #[test] 219 | fn test_boolean_hash_key() { 220 | let true1 = true; 221 | let true2 = true; 222 | let false1 = false; 223 | let false2 = false; 224 | 225 | assert_eq!(true1.hash_key(), true2.hash_key()); 226 | assert_eq!(false1.hash_key(), false2.hash_key()); 227 | assert_ne!(true1.hash_key(), false1.hash_key()); 228 | } 229 | 230 | #[test] 231 | fn test_integer_hash_key() { 232 | let one1: i64 = 1; 233 | let one2: i64 = 1; 234 | let two1: i64 = 2; 235 | let two2: i64 = 2; 236 | 237 | assert_eq!(one1.hash_key(), one2.hash_key()); 238 | assert_eq!(two1.hash_key(), two2.hash_key()); 239 | assert_ne!(one1.hash_key(), two1.hash_key()); 240 | } 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /src/parser.rs: -------------------------------------------------------------------------------- 1 | use super::ast::{ 2 | ArrayLiteral, BlockStatement, Boolean, CallExpression, Expression, ExpressionStatement, 3 | FunctionLiteral, HashLiteral, Identifier, IfExpression, IndexExpression, InfixExpression, 4 | IntegerLiteral, LetStatement, MacroLiteral, PrefixExpression, Program, ReturnStatement, 5 | Statement, StringLiteral, 6 | }; 7 | use super::lexer::Lexer; 8 | use super::token::{Token, TokenType}; 9 | use std::collections::BTreeMap; 10 | use std::fmt; 11 | 12 | #[derive(PartialEq, PartialOrd)] 13 | enum Precedence { 14 | Lowest, 15 | Equals, // == 16 | LessGreater, // > OR < 17 | Sum, // + 18 | Product, // * 19 | Prefix, // -X OR !X 20 | Call, // myFunction(x) 21 | Index, // array[index] 22 | } 23 | 24 | #[derive(Debug)] 25 | struct ParseError { 26 | message: String, 27 | } 28 | 29 | impl fmt::Display for ParseError { 30 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 31 | write!(f, "{}", self.message) 32 | } 33 | } 34 | 35 | impl std::error::Error for ParseError {} 36 | 37 | pub struct Parser { 38 | l: Lexer, 39 | _cur_token: Option, 40 | _peek_token: Option, 41 | errors: Vec, 42 | } 43 | 44 | impl Parser { 45 | pub fn new(mut l: Lexer) -> Parser { 46 | let _cur_token = l.next(); 47 | let _peek_token = l.next(); 48 | 49 | Parser { 50 | l, 51 | _cur_token, 52 | _peek_token, 53 | errors: vec![], 54 | } 55 | } 56 | 57 | pub fn parse_program(&mut self) -> Program { 58 | let mut statements: Vec = vec![]; 59 | 60 | while self._cur_token.is_some() { 61 | match self.parse_statement() { 62 | Ok(stmt) => statements.push(stmt), 63 | Err(error) => self.errors.push(error), 64 | } 65 | self.next_token(); 66 | } 67 | Program { statements } 68 | } 69 | 70 | pub fn errors(&self) -> std::vec::Vec { 71 | self.errors.iter().map(|e| format!("{}", e)).collect() 72 | } 73 | 74 | fn parse_statement(&mut self) -> Result { 75 | Ok(match self.cur_token().t { 76 | TokenType::Let => Statement::LetStatement(self.parse_let_statement()?), 77 | TokenType::Return => Statement::ReturnStatement(self.parse_return_statement()?), 78 | _ => Statement::ExpressionStatement(self.parse_expression_statement()?), 79 | }) 80 | } 81 | 82 | fn parse_let_statement(&mut self) -> Result { 83 | self.expect_peek(&TokenType::Ident); 84 | 85 | let name = Identifier { 86 | value: self.cur_token().literal.clone(), 87 | }; 88 | 89 | self.expect_peek(&TokenType::Assign); 90 | 91 | self.next_token(); 92 | 93 | let value = self.parse_expression(Precedence::Lowest)?; 94 | 95 | if self.peek_token_is(&TokenType::Semicolon) { 96 | self.next_token(); 97 | } 98 | 99 | Ok(LetStatement { name, value }) 100 | } 101 | 102 | fn parse_return_statement(&mut self) -> Result { 103 | self.next_token(); 104 | 105 | let return_value = self.parse_expression(Precedence::Lowest)?; 106 | 107 | if self.peek_token_is(&TokenType::Semicolon) { 108 | self.next_token(); 109 | } 110 | 111 | Ok(ReturnStatement { return_value }) 112 | } 113 | 114 | fn parse_expression_statement(&mut self) -> Result { 115 | let expression = self.parse_expression(Precedence::Lowest)?; 116 | 117 | if self.peek_token_is(&TokenType::Semicolon) { 118 | self.next_token() 119 | } 120 | 121 | Ok(ExpressionStatement { expression }) 122 | } 123 | 124 | fn parse_expression(&mut self, precedence: Precedence) -> Result { 125 | let mut left_exp = self.parse_prefix()?; 126 | 127 | loop { 128 | if !self.peek_token_is(&TokenType::Semicolon) && precedence < self.peek_precedence() { 129 | left_exp = match self.peek_token().unwrap().t { 130 | TokenType::Plus 131 | | TokenType::Minus 132 | | TokenType::Slash 133 | | TokenType::Asterisk 134 | | TokenType::Eq 135 | | TokenType::NotEq 136 | | TokenType::Lt 137 | | TokenType::Gt => { 138 | self.next_token(); 139 | Expression::InfixExpression(self.parse_infix_expression(left_exp)?) 140 | } 141 | TokenType::LBracket => { 142 | self.next_token(); 143 | Expression::IndexExpression(self.parse_index_expression(left_exp)?) 144 | } 145 | TokenType::LParen => { 146 | self.next_token(); 147 | Expression::CallExpression(self.parse_call_expression(left_exp)?) 148 | } 149 | _ => return Ok(left_exp), 150 | }; 151 | } else { 152 | break; 153 | } 154 | } 155 | 156 | Ok(left_exp) 157 | } 158 | 159 | fn parse_prefix(&mut self) -> Result { 160 | Ok(match self.cur_token().t { 161 | TokenType::Ident => Expression::Identifier(self.parse_identifier()), 162 | TokenType::Int => Expression::IntegerLiteral(self.parse_integer_literal()?), 163 | TokenType::Bang | TokenType::Minus => { 164 | Expression::PrefixExpression(self.parse_prefix_expression()?) 165 | } 166 | TokenType::True | TokenType::False => Expression::Boolean(self.parse_boolean()), 167 | TokenType::LParen => self.parse_grouped_expression()?, 168 | TokenType::If => Expression::IfExpression(self.parse_if_expression()?), 169 | TokenType::Function => Expression::FunctionLiteral(self.parse_function_literal()?), 170 | TokenType::String => Expression::StringLiteral(self.parse_string_literal()?), 171 | TokenType::LBracket => Expression::ArrayLiteral(self.parse_array_literal()?), 172 | TokenType::LBrace => Expression::HashLiteral(self.parse_hash_literal()?), 173 | TokenType::Macro => Expression::MacroLiteral(self.parse_macro_literal()?), 174 | _ => { 175 | return Err(ParseError { 176 | message: String::from("not implemented"), 177 | }) 178 | } 179 | }) 180 | } 181 | 182 | fn parse_infix_expression(&mut self, left: Expression) -> Result { 183 | let operator = self.cur_token().literal.clone(); 184 | let precedence = self.cur_precedence(); 185 | self.next_token(); 186 | let right = self.parse_expression(precedence)?; 187 | Ok(InfixExpression { 188 | left: Box::new(left), 189 | operator, 190 | right: Box::new(right), 191 | }) 192 | } 193 | 194 | fn parse_index_expression(&mut self, left: Expression) -> Result { 195 | self.next_token(); 196 | let index = self.parse_expression(Precedence::Lowest)?; 197 | if !self.expect_peek(&TokenType::RBracket) { 198 | Err(ParseError { 199 | message: String::from("Missing RBracket"), 200 | }) 201 | } else { 202 | Ok(IndexExpression { 203 | left: Box::new(left), 204 | index: Box::new(index), 205 | }) 206 | } 207 | } 208 | 209 | fn parse_identifier(&self) -> Identifier { 210 | Identifier { 211 | value: self.cur_token().literal.clone(), 212 | } 213 | } 214 | 215 | fn parse_integer_literal(&self) -> Result { 216 | match self.cur_token().literal.parse() { 217 | Ok(value) => Ok(IntegerLiteral { value }), 218 | Err(_) => Err(ParseError { 219 | message: format!("could not parse {} as integer", self.cur_token().literal), 220 | }), 221 | } 222 | } 223 | 224 | fn parse_prefix_expression(&mut self) -> Result { 225 | let operator = self.cur_token().literal.clone(); 226 | 227 | self.next_token(); 228 | 229 | let right = self.parse_expression(Precedence::Prefix)?; 230 | 231 | Ok(PrefixExpression { 232 | operator, 233 | right: Box::new(right), 234 | }) 235 | } 236 | 237 | fn parse_boolean(&mut self) -> Boolean { 238 | Boolean { 239 | value: self.cur_token_is(&TokenType::True), 240 | } 241 | } 242 | 243 | fn parse_grouped_expression(&mut self) -> Result { 244 | self.next_token(); 245 | 246 | let exp = self.parse_expression(Precedence::Lowest)?; 247 | if !self.expect_peek(&TokenType::RParen) { 248 | Err(ParseError { 249 | message: String::from("Missing RParen"), 250 | }) 251 | } else { 252 | Ok(exp) 253 | } 254 | } 255 | 256 | fn parse_if_expression(&mut self) -> Result { 257 | if !self.expect_peek(&TokenType::LParen) { 258 | return Err(ParseError { 259 | message: String::from("Missing LParen"), 260 | }); 261 | } 262 | 263 | self.next_token(); 264 | let condition = self.parse_expression(Precedence::Lowest)?; 265 | 266 | if !self.expect_peek(&TokenType::RParen) { 267 | return Err(ParseError { 268 | message: String::from("Missing RParen"), 269 | }); 270 | } 271 | if !self.expect_peek(&TokenType::LBrace) { 272 | return Err(ParseError { 273 | message: String::from("Missing LBrace"), 274 | }); 275 | } 276 | 277 | let consequence = self.parse_block_statement()?; 278 | 279 | let alternative = if self.peek_token_is(&TokenType::Else) { 280 | self.next_token(); 281 | if !self.expect_peek(&TokenType::LBrace) { 282 | return Err(ParseError { 283 | message: String::from("Missing LBrace"), 284 | }); 285 | } 286 | Some(Box::new(self.parse_block_statement()?)) 287 | } else { 288 | None 289 | }; 290 | 291 | Ok(IfExpression { 292 | condition: Box::new(condition), 293 | consequence: Box::new(consequence), 294 | alternative, 295 | }) 296 | } 297 | 298 | fn parse_block_statement(&mut self) -> Result { 299 | let mut statements: Vec = vec![]; 300 | 301 | self.next_token(); 302 | 303 | while !self.cur_token_is(&TokenType::RBrace) && self._cur_token.is_some() { 304 | statements.push(self.parse_statement()?); 305 | self.next_token(); 306 | } 307 | 308 | Ok(BlockStatement { statements }) 309 | } 310 | 311 | fn parse_function_literal(&mut self) -> Result { 312 | if !self.expect_peek(&TokenType::LParen) { 313 | return Err(ParseError { 314 | message: String::from("Missing LParen"), 315 | }); 316 | } 317 | 318 | let parameters = self.parse_function_parameters()?; 319 | 320 | if !self.expect_peek(&TokenType::LBrace) { 321 | return Err(ParseError { 322 | message: String::from("Missing LBrace"), 323 | }); 324 | } 325 | 326 | let body = self.parse_block_statement()?; 327 | 328 | Ok(FunctionLiteral { 329 | parameters, 330 | body: Box::new(body), 331 | }) 332 | } 333 | 334 | fn parse_function_parameters(&mut self) -> Result, ParseError> { 335 | let mut identifiers: Vec = vec![]; 336 | 337 | if self.peek_token_is(&TokenType::RParen) { 338 | self.next_token(); 339 | return Ok(identifiers); 340 | } 341 | 342 | self.next_token(); 343 | 344 | identifiers.push(Identifier { 345 | value: self.cur_token().literal.clone(), 346 | }); 347 | 348 | while self.peek_token_is(&TokenType::Comma) { 349 | self.next_token(); 350 | self.next_token(); 351 | identifiers.push(Identifier { 352 | value: self.cur_token().literal.clone(), 353 | }); 354 | } 355 | 356 | if !self.expect_peek(&TokenType::RParen) { 357 | return Err(ParseError { 358 | message: String::from("Missing RParen"), 359 | }); 360 | } 361 | 362 | Ok(identifiers) 363 | } 364 | 365 | fn parse_call_expression( 366 | &mut self, 367 | function: Expression, 368 | ) -> Result { 369 | let arguments = self.parse_expression_list(TokenType::RParen)?; 370 | Ok(CallExpression { 371 | function: Box::new(function), 372 | arguments, 373 | }) 374 | } 375 | 376 | fn parse_expression_list(&mut self, end: TokenType) -> Result, ParseError> { 377 | let mut args: Vec = vec![]; 378 | 379 | if self.peek_token_is(&end) { 380 | self.next_token(); 381 | return Ok(args); 382 | } 383 | 384 | self.next_token(); 385 | args.push(self.parse_expression(Precedence::Lowest)?); 386 | 387 | while self.peek_token_is(&TokenType::Comma) { 388 | self.next_token(); 389 | self.next_token(); 390 | args.push(self.parse_expression(Precedence::Lowest)?); 391 | } 392 | 393 | if !self.expect_peek(&end) { 394 | return Err(ParseError { 395 | message: String::from("Missing RParen"), 396 | }); 397 | } 398 | 399 | Ok(args) 400 | } 401 | 402 | fn parse_string_literal(&self) -> Result { 403 | Ok(StringLiteral { 404 | value: self.cur_token().literal.clone(), 405 | }) 406 | } 407 | 408 | fn parse_array_literal(&mut self) -> Result { 409 | let elements = self.parse_expression_list(TokenType::RBracket)?; 410 | Ok(ArrayLiteral { elements }) 411 | } 412 | 413 | fn parse_hash_literal(&mut self) -> Result { 414 | let mut pairs = BTreeMap::new(); 415 | 416 | while !self.peek_token_is(&TokenType::RBrace) { 417 | self.next_token(); 418 | let key = self.parse_expression(Precedence::Lowest)?; 419 | 420 | if !self.expect_peek(&TokenType::Colon) { 421 | return Err(ParseError { 422 | message: String::from("Missing Colon"), 423 | }); 424 | } 425 | 426 | self.next_token(); 427 | let value = self.parse_expression(Precedence::Lowest)?; 428 | 429 | pairs.insert(key, value); 430 | 431 | if !self.peek_token_is(&TokenType::RBrace) && !self.expect_peek(&TokenType::Comma) { 432 | return Err(ParseError { 433 | message: String::from("Missing RBrace or Comma"), 434 | }); 435 | } 436 | } 437 | 438 | if !self.expect_peek(&TokenType::RBrace) { 439 | return Err(ParseError { 440 | message: String::from("Missing RBrace"), 441 | }); 442 | } 443 | 444 | Ok(HashLiteral { pairs }) 445 | } 446 | 447 | fn parse_macro_literal(&mut self) -> Result { 448 | if !self.expect_peek(&TokenType::LParen) { 449 | return Err(ParseError { 450 | message: String::from("Missing LParen"), 451 | }); 452 | } 453 | 454 | let parameters = self.parse_function_parameters()?; 455 | 456 | if !self.expect_peek(&TokenType::LBrace) { 457 | return Err(ParseError { 458 | message: String::from("Missing LBrace"), 459 | }); 460 | } 461 | 462 | let body = self.parse_block_statement()?; 463 | 464 | Ok(MacroLiteral { 465 | parameters, 466 | body: Box::new(body), 467 | }) 468 | } 469 | fn next_token(&mut self) { 470 | self._cur_token = self._peek_token.take(); 471 | self._peek_token = self.l.next(); 472 | } 473 | 474 | fn cur_token(&self) -> &Token { 475 | self._cur_token.as_ref().unwrap() 476 | } 477 | 478 | fn peek_token(&self) -> Option<&Token> { 479 | self._peek_token.as_ref() 480 | } 481 | 482 | fn cur_token_is(&self, t: &TokenType) -> bool { 483 | &self.cur_token().t == t 484 | } 485 | 486 | fn peek_token_is(&self, t: &TokenType) -> bool { 487 | self.peek_token().is_some() && &self.peek_token().unwrap().t == t 488 | } 489 | 490 | fn expect_peek(&mut self, t: &TokenType) -> bool { 491 | if self.peek_token_is(t) { 492 | self.next_token(); 493 | true 494 | } else { 495 | self.errors.push(ParseError { 496 | message: format!( 497 | "expected next token to be {:?}, got {:?} instead", 498 | t, 499 | self.peek_token().unwrap().t 500 | ), 501 | }); 502 | false 503 | } 504 | } 505 | 506 | fn cur_precedence(&self) -> Precedence { 507 | Parser::precedence(&self.cur_token().t) 508 | } 509 | 510 | fn peek_precedence(&self) -> Precedence { 511 | if let Some(peek) = self.peek_token() { 512 | Parser::precedence(&peek.t) 513 | } else { 514 | Precedence::Lowest 515 | } 516 | } 517 | 518 | fn precedence(t: &TokenType) -> Precedence { 519 | match t { 520 | TokenType::Eq => Precedence::Equals, 521 | TokenType::NotEq => Precedence::Equals, 522 | TokenType::Lt => Precedence::LessGreater, 523 | TokenType::Gt => Precedence::LessGreater, 524 | TokenType::Plus => Precedence::Sum, 525 | TokenType::Minus => Precedence::Sum, 526 | TokenType::Slash => Precedence::Product, 527 | TokenType::Asterisk => Precedence::Product, 528 | TokenType::LParen => Precedence::Call, 529 | TokenType::LBracket => Precedence::Index, 530 | _ => Precedence::Lowest, 531 | } 532 | } 533 | } 534 | 535 | #[cfg(test)] 536 | mod tests { 537 | use super::super::ast::{Expression, Statement}; 538 | use super::{Lexer, Parser}; 539 | use std::collections::HashMap; 540 | use std::vec::Vec; 541 | 542 | #[test] 543 | fn test_let_statements() { 544 | test(vec![("let x = 5;", "x", 5)]); 545 | test(vec![("let y = true;", "y", true)]); 546 | test(vec![("let foobar = y;", "foobar", "y".to_string())]); 547 | 548 | fn test(tests: Vec<(&str, &str, T)>) { 549 | for (input, expected_identifier, expected_value) in tests { 550 | let l = Lexer::new(input); 551 | let mut p = Parser::new(l); 552 | let program = p.parse_program(); 553 | check_parse_errors(p); 554 | 555 | assert_eq!(program.statements.len(), 1); 556 | assert_let_statement(&program.statements[0], expected_identifier); 557 | 558 | if let Statement::LetStatement(stmt) = &program.statements[0] { 559 | assert_literal_expression(&stmt.value, expected_value); 560 | } 561 | } 562 | } 563 | } 564 | 565 | #[test] 566 | fn test_return_statements() { 567 | test(vec![("return 5;", 5)]); 568 | test(vec![("return true;", true)]); 569 | test(vec![("return foobar", "foobar".to_string())]); 570 | 571 | fn test(tests: Vec<(&str, T)>) { 572 | for (input, expected_value) in tests { 573 | let l = Lexer::new(input); 574 | let mut p = Parser::new(l); 575 | let program = p.parse_program(); 576 | check_parse_errors(p); 577 | 578 | assert_eq!(program.statements.len(), 1); 579 | if let Statement::ReturnStatement(stmt) = &program.statements[0] { 580 | assert_literal_expression(&stmt.return_value, expected_value) 581 | } else { 582 | assert!(false, "stmt not ast::ReturnStatement") 583 | } 584 | } 585 | } 586 | } 587 | 588 | #[test] 589 | fn test_identifier_expressions() { 590 | let input = "foobar;"; 591 | 592 | let l = Lexer::new(input); 593 | let mut p = Parser::new(l); 594 | 595 | let program = p.parse_program(); 596 | check_parse_errors(p); 597 | assert_eq!(program.statements.len(), 1); 598 | 599 | if let Statement::ExpressionStatement(exp_stmt) = &program.statements[0] { 600 | if let Expression::Identifier(ident) = &exp_stmt.expression { 601 | assert_eq!(ident.value, "foobar"); 602 | } else { 603 | assert!(false, "program.statements[0] is not ast::Identifier") 604 | } 605 | } else { 606 | assert!( 607 | false, 608 | "program.statements[0] is not ast::ExpressionStatement" 609 | ) 610 | } 611 | } 612 | 613 | #[test] 614 | fn test_integer_literal_expressions() { 615 | let input = "5;"; 616 | 617 | let l = Lexer::new(input); 618 | let mut p = Parser::new(l); 619 | 620 | let program = p.parse_program(); 621 | check_parse_errors(p); 622 | assert_eq!(program.statements.len(), 1); 623 | 624 | if let Statement::ExpressionStatement(exp_stmt) = &program.statements[0] { 625 | if let Expression::IntegerLiteral(literal) = &exp_stmt.expression { 626 | assert_eq!(literal.value, 5); 627 | } else { 628 | assert!(false, "program.statements[0] is not ast::IntegerLiteral") 629 | } 630 | } else { 631 | assert!( 632 | false, 633 | "program.statements[0] is not ast::ExpressionStatement" 634 | ) 635 | } 636 | } 637 | 638 | #[test] 639 | fn test_parsing_prefix_expressions() { 640 | test(vec![("!5;", "!", 5), ("-15;", "-", 15)]); 641 | test(vec![("!true;", "!", true), ("!false;", "!", false)]); 642 | 643 | fn test(tests: Vec<(&str, &str, T)>) { 644 | for (input, expected_operator, expected_value) in tests { 645 | let l = Lexer::new(input); 646 | let mut p = Parser::new(l); 647 | let program = p.parse_program(); 648 | check_parse_errors(p); 649 | 650 | assert_eq!(program.statements.len(), 1); 651 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 652 | if let Expression::PrefixExpression(exp) = &stmt.expression { 653 | assert_eq!(exp.operator, expected_operator); 654 | assert_literal_expression(&exp.right, expected_value); 655 | } else { 656 | assert!(false, "stmt is not ast::PrefixExpression"); 657 | } 658 | } else { 659 | assert!( 660 | false, 661 | "program.statements[0] is not ast::ExpressionStatement" 662 | ); 663 | } 664 | } 665 | } 666 | } 667 | 668 | #[test] 669 | fn test_parsing_infix_expressions() { 670 | test(vec![ 671 | ("5 + 5;", 5, "+", 5), 672 | ("5 - 5;", 5, "-", 5), 673 | ("5 * 5;", 5, "*", 5), 674 | ("5 / 5;", 5, "/", 5), 675 | ("5 > 5;", 5, ">", 5), 676 | ("5 < 5;", 5, "<", 5), 677 | ("5 == 5;", 5, "==", 5), 678 | ("5 != 5;", 5, "!=", 5), 679 | ]); 680 | 681 | test(vec![ 682 | ("true == true", true, "==", true), 683 | ("true != false", true, "!=", false), 684 | ("false == false", false, "==", false), 685 | ]); 686 | 687 | fn test(tests: Vec<(&str, T, &str, U)>) { 688 | for (input, expected_left_value, expected_operator, expected_right_value) in tests { 689 | let l = Lexer::new(input); 690 | let mut p = Parser::new(l); 691 | let program = p.parse_program(); 692 | check_parse_errors(p); 693 | 694 | assert_eq!(program.statements.len(), 1); 695 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 696 | assert_infix_expression( 697 | &stmt.expression, 698 | expected_left_value, 699 | expected_operator, 700 | expected_right_value, 701 | ); 702 | } else { 703 | assert!( 704 | false, 705 | "program.statements[0] is not ast::ExpressionStatement" 706 | ); 707 | } 708 | } 709 | } 710 | } 711 | 712 | #[test] 713 | fn test_operator_precedence_parsing() { 714 | let tests = [ 715 | ("-a * b", "((-a) * b)"), 716 | ("!-a", "(!(-a))"), 717 | ("a + b + c", "((a + b) + c)"), 718 | ("a + b - c", "((a + b) - c)"), 719 | ("a * b * c", "((a * b) * c)"), 720 | ("a * b / c", "((a * b) / c)"), 721 | ("a + b / c", "(a + (b / c))"), 722 | ("a + b * c + d / e - f", "(((a + (b * c)) + (d / e)) - f)"), 723 | ("3 + 4; -5 * 5", "(3 + 4)((-5) * 5)"), 724 | ("5 > 4 == 3 < 4", "((5 > 4) == (3 < 4))"), 725 | ("5 < 4 != 3 > 4", "((5 < 4) != (3 > 4))"), 726 | ( 727 | "3 + 4 * 5 == 3 * 1 + 4 * 5", 728 | "((3 + (4 * 5)) == ((3 * 1) + (4 * 5)))", 729 | ), 730 | ("true", "true"), 731 | ("false", "false"), 732 | ("3 > 5 == false", "((3 > 5) == false)"), 733 | ("3 < 5 == true", "((3 < 5) == true)"), 734 | ("1 + (2 + 3) + 4", "((1 + (2 + 3)) + 4)"), 735 | ("(5 + 5) * 2", "((5 + 5) * 2)"), 736 | ("2 / (5 + 5)", "(2 / (5 + 5))"), 737 | ("-(5 + 5)", "(-(5 + 5))"), 738 | ("!(true == true)", "(!(true == true))"), 739 | ("a + add(b * c) + d", "((a + add((b * c))) + d)"), 740 | ( 741 | "add(a, b, 1, 2 * 3, 4 + 5, add(6, 7 * 8))", 742 | "add(a, b, 1, (2 * 3), (4 + 5), add(6, (7 * 8)))", 743 | ), 744 | ( 745 | "add(a + b + c * d / f + g)", 746 | "add((((a + b) + ((c * d) / f)) + g))", 747 | ), 748 | ( 749 | "a * [1, 2, 3, 4][b * c] * d", 750 | "((a * ([1, 2, 3, 4][(b * c)])) * d)", 751 | ), 752 | ( 753 | "add(a * b[2], b[1], 2 * [1, 2][1])", 754 | "add((a * (b[2])), (b[1]), (2 * ([1, 2][1])))", 755 | ), 756 | ]; 757 | 758 | for (input, expected) in tests.iter() { 759 | let l = Lexer::new(input); 760 | let mut p = Parser::new(l); 761 | let program = p.parse_program(); 762 | check_parse_errors(p); 763 | 764 | assert_eq!(format!("{}", program), *expected); 765 | } 766 | } 767 | 768 | #[test] 769 | fn test_boolean_expressions() { 770 | let tests = [("true;", true), ("false;", false)]; 771 | 772 | for (input, expected) in tests.iter() { 773 | let l = Lexer::new(input); 774 | let mut p = Parser::new(l); 775 | let program = p.parse_program(); 776 | check_parse_errors(p); 777 | assert_eq!(program.statements.len(), 1); 778 | 779 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 780 | if let Expression::Boolean(boolean) = &stmt.expression { 781 | assert_eq!(boolean.value, *expected); 782 | } else { 783 | assert!(false, "program.statements[0] is not ast::BooleanExpression") 784 | } 785 | } else { 786 | assert!( 787 | false, 788 | "program.statements[0] is not ast::ExpressionStatement" 789 | ) 790 | } 791 | } 792 | } 793 | 794 | #[test] 795 | fn test_if_expression() { 796 | let input = "if (x < y) { x }"; 797 | 798 | let l = Lexer::new(input); 799 | let mut p = Parser::new(l); 800 | let program = p.parse_program(); 801 | check_parse_errors(p); 802 | assert_eq!(program.statements.len(), 1); 803 | 804 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 805 | if let Expression::IfExpression(exp) = &stmt.expression { 806 | assert_infix_expression(&exp.condition, "x".to_string(), "<", "y".to_string()); 807 | assert_eq!(exp.consequence.statements.len(), 1); 808 | if let Statement::ExpressionStatement(consequence) = &exp.consequence.statements[0] 809 | { 810 | assert_identifier(&consequence.expression, "x"); 811 | } else { 812 | assert!(false, "statements[0] is not ast::ExpressionStatement") 813 | } 814 | assert_eq!(exp.alternative, None); 815 | } else { 816 | assert!(false, "stmt.expression is not ast::IfExpression") 817 | } 818 | } else { 819 | assert!( 820 | false, 821 | "program.statements[0] is not ast::ExpressionStatement" 822 | ) 823 | } 824 | } 825 | 826 | #[test] 827 | fn test_if_else_expression() { 828 | let input = "if (x < y) { x } else { y }"; 829 | 830 | let l = Lexer::new(input); 831 | let mut p = Parser::new(l); 832 | let program = p.parse_program(); 833 | check_parse_errors(p); 834 | assert_eq!(program.statements.len(), 1); 835 | 836 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 837 | if let Expression::IfExpression(exp) = &stmt.expression { 838 | assert_infix_expression(&exp.condition, "x".to_string(), "<", "y".to_string()); 839 | assert_eq!(exp.consequence.statements.len(), 1); 840 | if let Statement::ExpressionStatement(consequence) = &exp.consequence.statements[0] 841 | { 842 | assert_identifier(&consequence.expression, "x"); 843 | } else { 844 | assert!(false, "statements[0] is not ast::ExpressionStatement") 845 | } 846 | if let Some(exp_alternative) = &exp.alternative { 847 | assert_eq!(exp_alternative.statements.len(), 1); 848 | if let Statement::ExpressionStatement(alternative) = 849 | &(*exp_alternative).statements[0] 850 | { 851 | assert_identifier(&alternative.expression, "y"); 852 | } else { 853 | assert!(false, "statements[0] is not ast::ExpressionStatement") 854 | } 855 | } else { 856 | assert!(false, "exp.alternative is None") 857 | } 858 | } else { 859 | assert!(false, "stmt.expression is not ast::IfExpression") 860 | } 861 | } else { 862 | assert!( 863 | false, 864 | "program.statements[0] is not ast::ExpressionStatement" 865 | ) 866 | } 867 | } 868 | 869 | #[test] 870 | fn test_function_literal_parsing() { 871 | let input = "fn(x, y) { x + y; }"; 872 | 873 | let l = Lexer::new(input); 874 | let mut p = Parser::new(l); 875 | let program = p.parse_program(); 876 | check_parse_errors(p); 877 | assert_eq!(program.statements.len(), 1); 878 | 879 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 880 | if let Expression::FunctionLiteral(function) = &stmt.expression { 881 | assert_eq!(function.parameters[0].value, "x".to_string()); 882 | assert_eq!(format!("{}", function.parameters[0].value), "x"); 883 | assert_eq!(function.parameters[1].value, "y".to_string()); 884 | assert_eq!(format!("{}", function.parameters[1].value), "y"); 885 | } else { 886 | assert!(false, "stmt.expression is not ast::FunctionLiteral") 887 | } 888 | } else { 889 | assert!( 890 | false, 891 | "program.statements[0] is not ast::ExpressionStatement" 892 | ) 893 | } 894 | } 895 | 896 | #[test] 897 | fn test_function_parameter_parsing() { 898 | let tests = [ 899 | ("fn() {};", vec![]), 900 | ("fn(x) {};", vec!["x"]), 901 | ("fn(x, y, z) {};", vec!["x", "y", "z"]), 902 | ]; 903 | 904 | for (input, expected) in tests.iter() { 905 | let l = Lexer::new(input); 906 | let mut p = Parser::new(l); 907 | let program = p.parse_program(); 908 | check_parse_errors(p); 909 | 910 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 911 | if let Expression::FunctionLiteral(function) = &stmt.expression { 912 | assert_eq!(function.parameters.len(), expected.len()); 913 | 914 | for (i, ident) in expected.iter().enumerate() { 915 | assert_eq!(function.parameters[i].value, ident.to_string()); 916 | assert_eq!( 917 | format!("{}", function.parameters[i].value), 918 | ident.to_string() 919 | ); 920 | } 921 | } 922 | } 923 | } 924 | } 925 | 926 | #[test] 927 | fn test_call_expression_parsing() { 928 | let input = "add(1, 2 * 3, 4 + 5);"; 929 | 930 | let l = Lexer::new(input); 931 | let mut p = Parser::new(l); 932 | let program = p.parse_program(); 933 | check_parse_errors(p); 934 | 935 | assert_eq!(program.statements.len(), 1); 936 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 937 | if let Expression::CallExpression(exp) = &stmt.expression { 938 | assert_identifier(&exp.function, "add"); 939 | assert_eq!(exp.arguments.len(), 3); 940 | assert_literal_expression(&exp.arguments[0], 1); 941 | assert_infix_expression(&exp.arguments[1], 2, "*", 3); 942 | assert_infix_expression(&exp.arguments[2], 4, "+", 5); 943 | } else { 944 | assert!(false, "stmt.expression is not ast::CallExpression") 945 | } 946 | } else { 947 | assert!(false, "stmt is not ast::ExpressionStatement") 948 | } 949 | } 950 | 951 | #[test] 952 | fn test_string_literal_expression() { 953 | let input = r#""hello world";"#; 954 | 955 | let l = Lexer::new(input); 956 | let mut p = Parser::new(l); 957 | let program = p.parse_program(); 958 | check_parse_errors(p); 959 | 960 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 961 | if let Expression::StringLiteral(literal) = &stmt.expression { 962 | assert_eq!(literal.value, "hello world") 963 | } else { 964 | assert!(false, "exp not ast::StringLiteral") 965 | } 966 | } 967 | } 968 | 969 | #[test] 970 | fn test_parsing_array_literals() { 971 | let input = "[1, 2 * 2, 3 + 3]"; 972 | 973 | let l = Lexer::new(input); 974 | let mut p = Parser::new(l); 975 | let program = p.parse_program(); 976 | check_parse_errors(p); 977 | 978 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 979 | if let Expression::ArrayLiteral(array) = &stmt.expression { 980 | assert_eq!(array.elements.len(), 3); 981 | assert_integer_literal(&array.elements[0], 1); 982 | assert_infix_expression(&array.elements[1], 2, "*", 2); 983 | assert_infix_expression(&array.elements[2], 3, "+", 3); 984 | } else { 985 | assert!(false, "exp not ast::ArrayLiteral") 986 | } 987 | } 988 | } 989 | 990 | #[test] 991 | fn test_parsing_index_expressions() { 992 | let input = "myArray[1 + 1];"; 993 | 994 | let l = Lexer::new(input); 995 | let mut p = Parser::new(l); 996 | let program = p.parse_program(); 997 | check_parse_errors(p); 998 | 999 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 1000 | if let Expression::IndexExpression(index_exp) = &stmt.expression { 1001 | assert_identifier(&index_exp.left, "myArray"); 1002 | assert_infix_expression(&index_exp.index, 1, "+", 1); 1003 | } else { 1004 | assert!(false, "exp not ast::IndexExpression") 1005 | } 1006 | } 1007 | } 1008 | 1009 | #[test] 1010 | fn test_parsing_empty_hash_literal() { 1011 | let input = "{}"; 1012 | 1013 | let l = Lexer::new(input); 1014 | let mut p = Parser::new(l); 1015 | let program = p.parse_program(); 1016 | check_parse_errors(p); 1017 | 1018 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 1019 | if let Expression::HashLiteral(hash) = &stmt.expression { 1020 | assert_eq!(hash.pairs.len(), 0); 1021 | } else { 1022 | assert!(false, "exp is not ast::HashLiteral") 1023 | } 1024 | } 1025 | } 1026 | 1027 | #[test] 1028 | fn test_parsing_hash_literal_string_keys() { 1029 | let input = r#"{"one": 1, "two": 2, "three": 3}"#; 1030 | 1031 | let l = Lexer::new(input); 1032 | let mut p = Parser::new(l); 1033 | let program = p.parse_program(); 1034 | check_parse_errors(p); 1035 | 1036 | let mut expected = HashMap::new(); 1037 | expected.insert("one".to_string(), 1); 1038 | expected.insert("two".to_string(), 2); 1039 | expected.insert("three".to_string(), 3); 1040 | 1041 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 1042 | if let Expression::HashLiteral(hash) = &stmt.expression { 1043 | assert_eq!(hash.pairs.len(), 3); 1044 | for (key, value) in &hash.pairs { 1045 | if let Expression::StringLiteral(literal) = key { 1046 | let expected_value = expected.get(&literal.value).unwrap(); 1047 | assert_integer_literal(value, *expected_value as i64); 1048 | } else { 1049 | assert!(false, "key is not ast::StringLiteral") 1050 | } 1051 | } 1052 | } else { 1053 | assert!(false, "exp is not ast::HashLiteral") 1054 | } 1055 | } 1056 | } 1057 | 1058 | #[test] 1059 | fn test_parsing_hash_literal_boolean_keys() { 1060 | let input = "{true: 1, false: 2}"; 1061 | 1062 | let l = Lexer::new(input); 1063 | let mut p = Parser::new(l); 1064 | let program = p.parse_program(); 1065 | check_parse_errors(p); 1066 | 1067 | let mut expected = HashMap::new(); 1068 | expected.insert(true, 1); 1069 | expected.insert(false, 2); 1070 | 1071 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 1072 | if let Expression::HashLiteral(hash) = &stmt.expression { 1073 | assert_eq!(hash.pairs.len(), 2); 1074 | for (key, value) in &hash.pairs { 1075 | if let Expression::Boolean(literal) = key { 1076 | let expected_value = expected.get(&literal.value).unwrap(); 1077 | assert_integer_literal(value, *expected_value as i64); 1078 | } else { 1079 | assert!(false, "key is not ast::Boolean") 1080 | } 1081 | } 1082 | } else { 1083 | assert!(false, "exp is not ast::HashLiteral") 1084 | } 1085 | } 1086 | } 1087 | 1088 | #[test] 1089 | fn test_parsing_hash_literal_integer_keys() { 1090 | let input = "{1: 1, 2: 2, 3: 3}"; 1091 | 1092 | let l = Lexer::new(input); 1093 | let mut p = Parser::new(l); 1094 | let program = p.parse_program(); 1095 | check_parse_errors(p); 1096 | 1097 | let mut expected = HashMap::new(); 1098 | expected.insert(1, 1); 1099 | expected.insert(2, 2); 1100 | expected.insert(3, 3); 1101 | 1102 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 1103 | if let Expression::HashLiteral(hash) = &stmt.expression { 1104 | assert_eq!(hash.pairs.len(), 3); 1105 | for (key, value) in &hash.pairs { 1106 | if let Expression::IntegerLiteral(literal) = key { 1107 | let expected_value = expected.get(&literal.value).unwrap(); 1108 | assert_integer_literal(value, *expected_value as i64); 1109 | } else { 1110 | assert!(false, "key is not ast::Integer") 1111 | } 1112 | } 1113 | } else { 1114 | assert!(false, "exp is not ast::HashLiteral") 1115 | } 1116 | } 1117 | } 1118 | 1119 | #[test] 1120 | fn test_parsing_hash_literal_with_expressions() { 1121 | let input = r#"{"one": 0 + 1, "two": 10 - 8, "three": 15 / 5}"#; 1122 | 1123 | let l = Lexer::new(input); 1124 | let mut p = Parser::new(l); 1125 | let program = p.parse_program(); 1126 | check_parse_errors(p); 1127 | 1128 | let mut expected = HashMap::new(); 1129 | expected.insert("one".to_string(), (0, "+", 1)); 1130 | expected.insert("two".to_string(), (10, "-", 8)); 1131 | expected.insert("three".to_string(), (15, "/", 5)); 1132 | 1133 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 1134 | if let Expression::HashLiteral(hash) = &stmt.expression { 1135 | assert_eq!(hash.pairs.len(), 3); 1136 | for (key, value) in &hash.pairs { 1137 | if let Expression::StringLiteral(literal) = key { 1138 | let (left, operator, right) = expected.get(&literal.value).unwrap(); 1139 | assert_infix_expression(value, *left as i64, operator, *right as i64) 1140 | } else { 1141 | assert!(false, "key is not ast::StringLiteral") 1142 | } 1143 | } 1144 | } else { 1145 | assert!(false, "exp is not ast::HashLiteral") 1146 | } 1147 | } 1148 | } 1149 | 1150 | #[test] 1151 | fn test_macro_literal_parsing() { 1152 | let input = "macro(x, y) { x + y; }"; 1153 | 1154 | let l = Lexer::new(input); 1155 | let mut p = Parser::new(l); 1156 | let program = p.parse_program(); 1157 | check_parse_errors(p); 1158 | assert_eq!(program.statements.len(), 1); 1159 | 1160 | if let Statement::ExpressionStatement(stmt) = &program.statements[0] { 1161 | if let Expression::MacroLiteral(macro_literal) = &stmt.expression { 1162 | assert_eq!(macro_literal.parameters.len(), 2); 1163 | assert_eq!(macro_literal.parameters[0].value, "x".to_string()); 1164 | assert_eq!(format!("{}", macro_literal.parameters[0].value), "x"); 1165 | assert_eq!(macro_literal.parameters[1].value, "y".to_string()); 1166 | assert_eq!(format!("{}", macro_literal.parameters[1].value), "y"); 1167 | assert_eq!(macro_literal.body.statements.len(), 1); 1168 | if let Statement::ExpressionStatement(body_stmt) = ¯o_literal.body.statements[0] 1169 | { 1170 | assert_infix_expression( 1171 | &body_stmt.expression, 1172 | "x".to_string(), 1173 | "+", 1174 | "y".to_string(), 1175 | ) 1176 | } else { 1177 | assert!(false, "macro body stmt is not ast::ExpressionStatement") 1178 | } 1179 | } else { 1180 | assert!(false, "stmt.expression is not ast::MacroLiteral") 1181 | } 1182 | } else { 1183 | assert!( 1184 | false, 1185 | "program.statements[0] is not ast::ExpressionStatement" 1186 | ) 1187 | } 1188 | } 1189 | 1190 | fn check_parse_errors(p: Parser) { 1191 | let errors = p.errors; 1192 | let len = errors.len(); 1193 | 1194 | if len == 0 { 1195 | return; 1196 | } 1197 | for e in errors { 1198 | eprintln!("parser error: {}", e); 1199 | } 1200 | assert!(false, "parser has {} errors.", len); 1201 | } 1202 | 1203 | fn assert_let_statement(statement: &Statement, expected: &str) { 1204 | if let Statement::LetStatement(stmt) = statement { 1205 | assert_eq!(stmt.name.value, expected) 1206 | } else { 1207 | assert!(false, "statement not ast::LetStatement") 1208 | } 1209 | } 1210 | 1211 | fn assert_integer_literal(il: &Expression, value: i64) { 1212 | if let Expression::IntegerLiteral(integ) = il { 1213 | assert_eq!(integ.value, value); 1214 | assert_eq!(format!("{}", integ.value), format!("{}", value)); 1215 | } else { 1216 | assert!(false, "il not ast::IntegerLiteral"); 1217 | } 1218 | } 1219 | 1220 | fn assert_identifier(exp: &Expression, value: &str) { 1221 | if let Expression::Identifier(ident) = exp { 1222 | assert_eq!(&ident.value, value); 1223 | assert_eq!(format!("{}", ident.value), format!("{}", value)); 1224 | } else { 1225 | assert!(false, "exp not ast::Identifier"); 1226 | } 1227 | } 1228 | 1229 | fn assert_boolean_literal(exp: &Expression, value: bool) { 1230 | if let Expression::Boolean(boolean) = exp { 1231 | assert_eq!(boolean.value, value); 1232 | assert_eq!(format!("{}", boolean.value), format!("{}", value)); 1233 | } else { 1234 | assert!(false, "exp not ast::Boolean"); 1235 | } 1236 | } 1237 | 1238 | trait AssertWithExpression { 1239 | fn assert_with(self, exp: &Expression); 1240 | } 1241 | 1242 | impl AssertWithExpression for i64 { 1243 | fn assert_with(self, exp: &Expression) { 1244 | assert_integer_literal(exp, self); 1245 | } 1246 | } 1247 | 1248 | impl AssertWithExpression for String { 1249 | fn assert_with(self, exp: &Expression) { 1250 | assert_identifier(exp, &self); 1251 | } 1252 | } 1253 | 1254 | impl AssertWithExpression for bool { 1255 | fn assert_with(self, exp: &Expression) { 1256 | assert_boolean_literal(exp, self); 1257 | } 1258 | } 1259 | 1260 | fn assert_literal_expression(exp: &Expression, expected: T) { 1261 | expected.assert_with(exp); 1262 | } 1263 | 1264 | fn assert_infix_expression( 1265 | exp: &Expression, 1266 | left: T, 1267 | operator: &str, 1268 | right: U, 1269 | ) { 1270 | if let Expression::InfixExpression(op_exp) = exp { 1271 | assert_literal_expression(&op_exp.left, left); 1272 | assert_eq!(&op_exp.operator, operator); 1273 | assert_literal_expression(&op_exp.right, right); 1274 | } else { 1275 | assert!(false, "exp not ast::InfixExpression"); 1276 | } 1277 | } 1278 | } 1279 | -------------------------------------------------------------------------------- /src/repl.rs: -------------------------------------------------------------------------------- 1 | use super::evaluator::{define_macros, expand_macros, Environment, Eval}; 2 | use super::{lexer, parser}; 3 | use std::io; 4 | use std::io::prelude::Write; 5 | use std::rc::Rc; 6 | 7 | pub fn start() { 8 | const PROMPT: &str = ">> "; 9 | let mut env = Environment::new(); 10 | let macro_env = Environment::new(); 11 | loop { 12 | print!("{}", PROMPT); 13 | io::stdout().flush().unwrap(); 14 | let mut input = String::new(); 15 | io::stdin().read_line(&mut input).unwrap(); 16 | let l = lexer::Lexer::new(&input); 17 | let mut p = parser::Parser::new(l); 18 | 19 | let mut program = p.parse_program(); 20 | 21 | let errors = p.errors(); 22 | if !errors.is_empty() { 23 | print_parser_errors(errors); 24 | continue; 25 | } 26 | 27 | define_macros(&mut program, Rc::clone(¯o_env)); 28 | let expanded = expand_macros(program, &mut Rc::clone(¯o_env)); 29 | 30 | let evaluated = expanded.eval(&mut env); 31 | 32 | println!("{}", evaluated); 33 | } 34 | } 35 | 36 | fn print_parser_errors(errors: std::vec::Vec) { 37 | for msg in errors { 38 | println!("{}", msg) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/token.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug, Eq, PartialEq)] 2 | pub enum TokenType { 3 | Illegal, 4 | Eof, 5 | 6 | // 識別子 + リテラル 7 | Ident, // add, foobar, x, y, ... 8 | Int, // 12345 9 | 10 | // 演算子 11 | Assign, // = 12 | Plus, // + 13 | Minus, // - 14 | Bang, // ! 15 | Asterisk, // * 16 | Slash, // / 17 | 18 | Lt, // < 19 | Gt, // > 20 | Eq, // == 21 | NotEq, // != 22 | 23 | // デリミタ 24 | Comma, // , 25 | Semicolon, // ; 26 | 27 | LParen, // ( 28 | RParen, // ) 29 | LBrace, // { 30 | RBrace, // } 31 | 32 | // キーワード 33 | Function, 34 | Let, 35 | True, 36 | False, 37 | If, 38 | Else, 39 | Return, 40 | 41 | String, 42 | 43 | LBracket, // [ 44 | RBracket, // ] 45 | 46 | Colon, // : 47 | 48 | Macro, // macro 49 | } 50 | 51 | #[derive(Debug, Eq, PartialEq)] 52 | pub struct Token { 53 | pub t: TokenType, 54 | pub literal: String, 55 | } 56 | 57 | pub fn lookup_ident(literal: &str) -> TokenType { 58 | match literal { 59 | "fn" => TokenType::Function, 60 | "let" => TokenType::Let, 61 | "true" => TokenType::True, 62 | "false" => TokenType::False, 63 | "if" => TokenType::If, 64 | "else" => TokenType::Else, 65 | "return" => TokenType::Return, 66 | "macro" => TokenType::Macro, 67 | _ => TokenType::Ident, 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/utils.rs: -------------------------------------------------------------------------------- 1 | /* 2 | Enum with fmt generation macro 3 | 4 | This macro generates below code. 5 | 6 | ``` 7 | #[derive(Debug,PartialEq)] 8 | pub enum Statement { 9 | LetStatement(LetStatement), 10 | ReturnStatement(ReturnStatement), 11 | ... 12 | } 13 | 14 | impl fmt::Display for Statement { 15 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 16 | match self { 17 | Statement::LetStatement(x) => write!(f, "{}", x), 18 | Statement::ReturnStatement(x) => write!(f, "{}", x), 19 | ... 20 | } 21 | } 22 | } 23 | ``` 24 | 25 | Additionally, this macro generate custom output. 26 | 27 | ``` 28 | pub enum E { 29 | V1(T), 30 | => 31 | V2(T) => "Custom: {}", 32 | ; 33 | V3, 34 | => 35 | V4 => "Custom", 36 | } 37 | ``` 38 | */ 39 | #[macro_export] 40 | macro_rules! enum_with_fmt { 41 | ( 42 | $(#[$meta: meta])* 43 | pub enum $name: ident { 44 | $($a_var: ident ($a_ty: ty),)* 45 | } 46 | ) => { 47 | enum_with_fmt!( 48 | $(#[$meta])* 49 | pub enum $name { 50 | $($a_var ($a_ty),)* 51 | => 52 | ; 53 | => 54 | } 55 | ); 56 | }; 57 | ( 58 | $(#[$meta: meta])* 59 | pub enum $name: ident { 60 | $($a_var: ident ($a_ty: ty),)* 61 | => 62 | $($b_var: ident ($b_ty: ty) => $b_expr: expr,)* 63 | ; 64 | $($c_var: ident)* 65 | => 66 | $($d_var: ident => $d_expr: expr,)* 67 | } 68 | ) => { 69 | $(#[$meta])* 70 | pub enum $name { 71 | $($a_var($a_ty),)* 72 | $($b_var($b_ty),)* 73 | $($c_var,)* 74 | $($d_var,)* 75 | } 76 | 77 | impl fmt::Display for $name { 78 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 79 | match self { 80 | $($name::$a_var(x) => write!(f, "{}", x),)* 81 | $($name::$b_var(x) => write!(f, $b_expr, x),)* 82 | $($name::$c_var => write!(f, "{}", x),)* 83 | $($name::$d_var => write!(f, $d_expr),)* 84 | } 85 | } 86 | } 87 | }; 88 | } 89 | --------------------------------------------------------------------------------