This repository contains the language lexer, parser and interpreter for Robert Nystrom's lox language from the Crafting Interpreters book. The virtual machine will be added later.
This is to show case modern Rust, using a few selected libraries. It's a good opportunity to get experience with the following crates.
logos- a fast / simple lexerchumsky- a parser library & parser combinatorariadne- a compiler diagnostics crate for error reporting
The idea is not to translate the content to code directly, but to learn how to use the existing libraries to provide the same functionality.
The following is the current list of expression and statement grammar as implemented. This is based on Crafting Interpreter's Syntax Grammar.
expression → assignment ;
assignment → ( call "." )? IDENTIFIER "=" assignment | logic_or ;
logic_or → logic_and ( "or" logic_and )* ;
logic_and → equality ( "and" equality )* ;
equality → comparison ( ( "!=" | "==" ) comparison )* ;
comparison → term ( ( ">" | ">=" | "<" | "<=" ) term )* ;
term → factor ( ( "-" | "+" ) factor )* ;
factor → unary ( ( "/" | "*" ) )* unary ;
unary → ( "!" | "-" ) unary | call ;
call → primary ( "(" arguments? ")" | "." IDENTIFIER )* ;
primary → literal | "(" expression ")" | IDENTIFIER ;
literal → NUMBER | STRING | "true" | "false" | "nil" | "this" ;
grouping → "(" expression ")" ;
arguments → expression "(" "," expression )* ;
program → statement* EOF ;
declaration → classDecl
| funDecl
| varDecl
| statement ;
classDecl → "class" IDENTIFIER ( "<" IDENTIFIER )? "{" function* "}" ;
funDecl → fun function ;
function → IDENTIFIER "(" parameters? ")" block ;
parameters → IDENTIFIER ( "," IDENTIFIER )* ;
varDecl → "var" IDENTIFIER ( "=" expression )? ";" ;
statement → exprStmt
| forStmt
| ifStmt
| printStmt
| returnStmt
| whileStmt
| block ;
exprStmt → expression ";" ;
forStmt → "for" "(" ( varDecl | exprStmt | ";" ) expression? ";" expression? ")" statement ;
ifStmt → "if" "(" expression ")" statement ( "else" statement )? ;
printStmt → "print" expression ";" ;
returnStmt → "return" expression? ";" ;
whileStmt → "while" "(" expression ")" statement ;
block → "{" declaration* "}" ;
The fundamental rules used by the scanner.
NUMBER → DIGIT+ ( "." DIGIT+ )? ;
STRING → "\"" <any char except "\"">* "\"" ;
IDENTIFIER → ALPHA ( ALPHA | DIGIT )* ;
ALPHA → "a" ... "z" | "A" ... "Z" | "_" ;
DIGIT → "0" ... "9" ;