I was feeling kinda burnt out at work, and I’m fortunate enough to have some savings, so I’m taking a career break, and trying not to computer too much. I decided to try my hand at woodworking. To keep this relatively risk-free, I decided to make some shelves for the garden shed. It’s a shed, so it doesn’t matter if it’s not perfect, or even good. I borrowed a track saw from a friend, bought some…
In the previous post, we started on Chapter 8: “Statements and State” from the book. We implemented some simple statements, primarily print . In this post, we’ll look at the next type of statement: global variable declarations. The book tells us that variables are declared with the var keyword: var beverage = "espresso"; …and that they’re different from normal statements, which gives us this…
It’s time to move on to Chapter 8: “Statements and State” from the book. To do this, we’ll implement parsing (and executing) some simple statements. The book gives us this: program → statement* EOF ; statement → exprStmt | printStmt ; exprStmt → expression ";" ; printStmt → "print" expression ";" ; So we can update our grammar accordingly: // program : statement* EOF ; pub Program = Statement*; //…
We’re almost done with expressions. Next we add grouping with parentheses. Recall that primary is defined in the book as follows: primary → NUMBER | STRING | "true" | "false" | "nil" | "(" expression ")" ; We need to implement that "(" expression ")" bit. The test looks like this: #[test] fn grouping_multiply_divide () { let parser = lox :: ExpressionParser :: new (); let expr = parser . parse (…
So far, we implemented parsing for numbers, strings, booleans, nil, unary operators ! and - , multiplication and division, and addition and subtraction. Next on the list are comparison operators (greater-than, less-than, etc.) and equality operators. As a reminder, the grammar for expressions, from the book, looks like this: expression → equality ; equality → comparison ( ( "!=" | "==" )…
At the end of the previous post, we could parse division and multiplication operators. Because we used an LALRPOP macro, it should be relatively simple to add addition and subtraction operators. Addition As usual, we start with a test: #[test] fn addition () { let parser = lox :: ExpressionParser :: new (); let expr = parser . parse ( "12 + 3" ) . unwrap (); assert_eq! ( expr, Expression ::…
In the previous post, we finished implementing parsing of unary operators. In this post, we’ll take a look at the first of the binary operators: division and multiplication. Division As usual, we start with a test: #[test] fn division () { let parser = lox :: ExpressionParser :: new (); let expr = parser . parse ( "12 / 3" ) . unwrap (); assert_eq! ( expr, Expression :: Divide { left : Box :: new…
In the last post, we implemented unary-not. In this one, we’ll implement the other unary operator: negation. As usual, we’ll start with a test: #[test] fn negation () { let parser = lox :: ExpressionParser :: new (); let expr = parser . parse ( "-42" ) . unwrap (); assert_eq! (expr, Expression :: Nil ); } Now — obviously — this isn’t going to pass, but it’ll prompt us through the steps to get it…
We’re implementing Lox’s primary rule. So far, we’ve done booleans, nil , numbers and strings. Let’s move on to some basic expressions. In this post, we’ll deal with unary-NOT — !x . In the book, Lox’s primary rule looks like this: primary → NUMBER | STRING | "true" | "false" | "nil" | "(" expression ")" ; We’ve already done numbers, strings, boleans and nil. Now we need to do expressions, which…