loxxy 0.0.19 → 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +91 -30
- data/README.md +64 -5
- data/lib/loxxy/ast/all_lox_nodes.rb +5 -0
- data/lib/loxxy/ast/ast_builder.rb +44 -2
- data/lib/loxxy/ast/ast_visitor.rb +47 -1
- data/lib/loxxy/ast/lox_assign_expr.rb +27 -0
- data/lib/loxxy/ast/lox_if_stmt.rb +35 -0
- data/lib/loxxy/ast/lox_seq_decl.rb +17 -0
- data/lib/loxxy/ast/lox_var_stmt.rb +28 -0
- data/lib/loxxy/ast/lox_variable_expr.rb +26 -0
- data/lib/loxxy/back_end/engine.rb +49 -1
- data/lib/loxxy/back_end/entry.rb +41 -0
- data/lib/loxxy/back_end/environment.rb +66 -0
- data/lib/loxxy/back_end/symbol_table.rb +135 -0
- data/lib/loxxy/back_end/variable.rb +30 -0
- data/lib/loxxy/datatype/builtin_datatype.rb +6 -0
- data/lib/loxxy/front_end/grammar.rb +9 -9
- data/lib/loxxy/interpreter.rb +1 -1
- data/lib/loxxy/version.rb +1 -1
- data/spec/back_end/engine_spec.rb +9 -0
- data/spec/back_end/environment_spec.rb +74 -0
- data/spec/back_end/symbol_table_spec.rb +142 -0
- data/spec/back_end/variable_spec.rb +79 -0
- data/spec/front_end/parser_spec.rb +21 -19
- data/spec/interpreter_spec.rb +78 -2
- metadata +17 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 6085bf18afb919e5ef4d327162470c9d5ca95dde67e00dce78bb26abd6563dec
         | 
| 4 | 
            +
              data.tar.gz: f1c7732a34b6df2721c20d82404c6ce83bdc8a75b695e4bbe13c51f62d9ac371
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 7546a14b935700e5050411a7805c2b2d00ccfc99160e3241b512289a6cc1762df2f39b7c9845c6ffe7fb95f1412865ef373f5308c9cf333fd72e2025a4a17ed8
         | 
| 7 | 
            +
              data.tar.gz: 3675956929831e52963759862e8f9d40e5ebd3df471dee87d82784c2d1230ce6057882368042c907741be1038d300b7c83c27ed4bb8d979f5efa2ac79eaa3b1a
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,16 +1,77 @@ | |
| 1 | 
            -
            ## [0.0. | 
| 1 | 
            +
            ## [0.0.24] - 2021-01-20
         | 
| 2 | 
            +
            - The interpreter implements the assignment of variables.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            ### Added
         | 
| 5 | 
            +
            - Class `Ast::LoxAssignExpr` a node that represents the assignment of a value to a variable
         | 
| 6 | 
            +
            - Method `Ast::ASTBuilder#reduce_assign_expr` creates an `Ast::LoxAssignExpr` node
         | 
| 7 | 
            +
            - Method `Ast::ASTVisitor#visit_assign_expr` for visiting an `Ast::LoxAssignExpr` node
         | 
| 8 | 
            +
            - Method `BackEnd::Engine#after_assign_expr` implementation of the assignment
         | 
| 9 | 
            +
            - Method `BackEnd::Variable#assign` to assign a value to a variable 
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            ## [0.0.23] - 2021-01-20
         | 
| 12 | 
            +
            - Fix for variables without explicit initialization.
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            ### Added
         | 
| 15 | 
            +
            - Method `Ast::ASTVisitor#visit_builtin` for visiting `Datatype::BuiltinDatatype` value.
         | 
| 16 | 
            +
            - Method `BackEnd::Engine#before_visit_builtin` push the data value onto the stack.
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            ### Fixed
         | 
| 19 | 
            +
            - Method `Ast::LoxVarStmt#initialize`: in case no explicit value provided then use `Datatype::Nil.instance`instead of Ruby `nil`
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            ## [0.0.22] - 2021-01-17
         | 
| 22 | 
            +
            - The interpreter can retrieve the value of a variable.
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            ### Added
         | 
| 25 | 
            +
            - Method `Ast::ASTBuilder#declaration_plus_more` and `Ast::ASTBuilder#declaration_plus_end` to allow multiple expressions/statements
         | 
| 26 | 
            +
            - Method `Ast::ASTBuilder#reduce_var_expression` creates an `Ast::LoxVariableExpr` node
         | 
| 27 | 
            +
            - Method `Ast::ASTVisitor#visit_var_expr` for visiting `Ast::LoxVariableExpr` nodes
         | 
| 28 | 
            +
            - Class `Ast::LoxSeqDecl` a node that represents a sequence of declarations/statements
         | 
| 29 | 
            +
            - Class `Ast::LoxVarExpr` a node that represents a variable occurrence in an expression
         | 
| 30 | 
            +
            - Method `Engine::after_variable_expr`: retrieve the value of variable with given name
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            ### Changed
         | 
| 33 | 
            +
            - Method `Ast::ASTBuilder#reduce_lox_program` to support multiple statements/declarations
         | 
| 34 | 
            +
            - File `README.md` updated.
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            ## [0.0.21] - 2021-01-16
         | 
| 37 | 
            +
            - The interpreter supports the declaration global variables.
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            ### Added
         | 
| 40 | 
            +
            - Class `BackEnd::Entry`, mixin module for objects put in the symbol table
         | 
| 41 | 
            +
            - Class `BackEnd::Environment` that keeps track of variables in a given context.
         | 
| 42 | 
            +
            - Class `BackEnd::SymbolTable` that keeps track of environments.
         | 
| 43 | 
            +
            - Class `BackEnd::Variable` internal representation of a `Lox` variable
         | 
| 44 | 
            +
            - Method `Ast::ASTBuilder#reduce_var_declaration` and `Ast::ASTBuilder#reduce_var_declaration`
         | 
| 45 | 
            +
            - Method `Ast::ASTVisitor#visit_var_stmt` for visiting `LoxVarStmt` nodes
         | 
| 46 | 
            +
            - Attribute `Engine::symbol_table`for keeping track of variables
         | 
| 47 | 
            +
            - Method `Engine::after_var_stmt` for the implementation of variable declarations
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            ## [0.0.20] - 2021-01-15
         | 
| 50 | 
            +
            - The interpreter supports the `if` ... `else` statement.
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            ### Added
         | 
| 53 | 
            +
            - Class `Ast::LoxItStmt`, AST node specific for `if` `else` statements
         | 
| 54 | 
            +
            - Method `Ast::ASTBuilder#reduce_if_stmt` as semantic action for if ... else
         | 
| 55 | 
            +
            - Method `Ast::ASTVisitor#visit_if_stmt` for visiting `LoxIfStmt` nodes
         | 
| 56 | 
            +
            - Method `Engine::after_if_stmt` implementation of the control flow
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            ## [0.0.19] - 2021-01-14
         | 
| 2 59 | 
             
            - The interpreter supports expressions between parentheses (grouping).
         | 
| 3 60 |  | 
| 4 | 
            -
             | 
| 61 | 
            +
            ### Added
         | 
| 5 62 | 
             
            - Class `Ast::LoxLogicalExpr`
         | 
| 6 63 | 
             
            - Method `Ast::ASTBuilder#reduce_grouping_expr` as semantic action for grouping expression
         | 
| 7 64 | 
             
            - Method `Ast::ASTVisitor#visit_grouping_expr` for visiting grouping expressions
         | 
| 8 65 | 
             
            - Method `Engine::after_grouping_expr`for the evaluation of grouping expressions
         | 
| 9 66 |  | 
| 67 | 
            +
            ### Changed
         | 
| 68 | 
            +
            - File `grammar.rb` rules for if ... else were given names in order to activate semantic actions.
         | 
| 69 | 
            +
            - File `README.md` updated with little `if ... else` documentation.
         | 
| 70 | 
            +
             | 
| 10 71 | 
             
            ## [0.0.18] - 2021-01-13
         | 
| 11 72 | 
             
            - The interpreter can evaluate `and`, `or`expressions.
         | 
| 12 73 |  | 
| 13 | 
            -
             | 
| 74 | 
            +
            ### Added
         | 
| 14 75 | 
             
            - Class `Ast::LoxLogicalExpr`
         | 
| 15 76 | 
             
            - Method `Ast::ASTBuilder#reduce_logical_expr` for the semantic action require for `and`, `or`
         | 
| 16 77 | 
             
            - Method `Ast::ASTVisitor#visit_logical_expr` for visiting logical expressions
         | 
| @@ -20,7 +81,7 @@ | |
| 20 81 | 
             
            - The interpreter can evaluate all arithmetic and comparison operations.
         | 
| 21 82 | 
             
            - It implements `==`, `!=` and the unary operations `!`, `-`
         | 
| 22 83 |  | 
| 23 | 
            -
             | 
| 84 | 
            +
            ### Added
         | 
| 24 85 | 
             
            - Class `Ast::LoxUnaryExpr`
         | 
| 25 86 | 
             
            - Method `Ast::ASTBuilder#reduce_unary_expr` to support the evaluation of `!` and ``-@`
         | 
| 26 87 | 
             
            - Method `Ast::ASTVisitor#visit_unnary_expr` for visiting unary expressions
         | 
| @@ -28,14 +89,14 @@ | |
| 28 89 | 
             
            - In class `Datatype::BuiltinDatatype` the methods `falsey?`, `truthy?`, `!`, `!=`
         | 
| 29 90 | 
             
            - In class `Datatype::Number`the methods `<`, `<=`, ´>´, `>=` and `-@`
         | 
| 30 91 |  | 
| 31 | 
            -
             | 
| 92 | 
            +
            ### Changed
         | 
| 32 93 | 
             
            - File `README.md` updated.
         | 
| 33 94 |  | 
| 34 95 | 
             
            ## [0.0.16] - 2021-01-11
         | 
| 35 96 | 
             
            - The interpreter can evaluate product and division of two numbers.
         | 
| 36 97 | 
             
            - It also implements equality `==` and inequality `!=` operators
         | 
| 37 98 |  | 
| 38 | 
            -
             | 
| 99 | 
            +
            ### Added
         | 
| 39 100 | 
             
            - Method `Datatype::False#==` for equality testing
         | 
| 40 101 | 
             
            - Method `Datatype::False#!=` for inequality testing
         | 
| 41 102 | 
             
            - Method `Datatype::LXString#==` for equality testing
         | 
| @@ -49,17 +110,17 @@ | |
| 49 110 | 
             
            - Method `Datatype::True#==` for equality testing
         | 
| 50 111 | 
             
            - Method `Datatype::True#!=` for inequality testing
         | 
| 51 112 |  | 
| 52 | 
            -
             | 
| 113 | 
            +
            ### Changed
         | 
| 53 114 | 
             
            - Method `BackEnd::Engine#after_binary_expr` to allow `*`, `/`, `==`, `!=` operators
         | 
| 54 115 | 
             
            - File `README.md` updated for the newly implemented operators
         | 
| 55 116 |  | 
| 56 117 | 
             
            ## [0.0.15] - 2021-01-11
         | 
| 57 118 | 
             
            - The interpreter can evaluate substraction between two numbers.
         | 
| 58 119 |  | 
| 59 | 
            -
             | 
| 120 | 
            +
            ### Added
         | 
| 60 121 | 
             
            - Method `Datatype::Number#-` implmenting the subtraction operation
         | 
| 61 122 |  | 
| 62 | 
            -
             | 
| 123 | 
            +
            ### Changed
         | 
| 63 124 | 
             
            - File `README.md` minor editorial changes.
         | 
| 64 125 | 
             
            - File `lx_string_spec.rb` Added test for string concatentation
         | 
| 65 126 | 
             
            - File `number_spec.rb` Added tests for addition and subtraction operations
         | 
| @@ -68,7 +129,7 @@ | |
| 68 129 | 
             
            ## [0.0.14] - 2021-01-10
         | 
| 69 130 | 
             
            - The interpreter can evaluate addition of numbers and string concatenation
         | 
| 70 131 |  | 
| 71 | 
            -
             | 
| 132 | 
            +
            ### Added
         | 
| 72 133 | 
             
            - Method `Ast::ASTVisitor#visit_binary_expr` for visiting binary expressions
         | 
| 73 134 | 
             
            - Method `Ast::LoxBinaryExpr#accept` for visitor pattern
         | 
| 74 135 | 
             
            - Method `BackEnd::Engine#after_binary_expr` to trigger execution of binary operator
         | 
| @@ -76,79 +137,79 @@ | |
| 76 137 | 
             
            - Method `Datatype::LXString#+` implementation of the string concatenation
         | 
| 77 138 | 
             
            - Method `Datatype::Number#+` implementation of the addition of numbers
         | 
| 78 139 |  | 
| 79 | 
            -
             | 
| 140 | 
            +
            ### Changed
         | 
| 80 141 | 
             
            - File `interpreter_spec.rb` Added tests for addition operation and string concatenation
         | 
| 81 142 |  | 
| 82 143 |  | 
| 83 144 | 
             
            ## [0.0.13] - 2021-01-10
         | 
| 84 145 | 
             
            - The interpreter can evaluate directly simple literals.
         | 
| 85 146 |  | 
| 86 | 
            -
             | 
| 147 | 
            +
            ### Changed
         | 
| 87 148 | 
             
            - Class `AST::ASTBuilder` added `reduce_exprStmt` to support the evaluation of literals.
         | 
| 88 149 | 
             
            - File `README.md` added one more example.
         | 
| 89 150 | 
             
            - File `parser_spec.rb` Updated the tests to reflect the change in the AST.
         | 
| 90 151 | 
             
            - File `interpreter_spec.rb` Added a test for literal expression.
         | 
| 91 152 |  | 
| 92 | 
            -
             | 
| 153 | 
            +
            ### Fixed
         | 
| 93 154 | 
             
            - File `loxxy.rb`: shorthand method `lox_true` referenced the ... false object (oops).
         | 
| 94 155 |  | 
| 95 156 | 
             
            ## [0.0.12] - 2021-01-09
         | 
| 96 157 | 
             
            - Initial interpreter capable of evaluating a tiny subset of Lox language.
         | 
| 97 158 |  | 
| 98 | 
            -
             | 
| 159 | 
            +
            ### Added
         | 
| 99 160 | 
             
            - Class `AST::LoxNoopExpr`
         | 
| 100 161 | 
             
            - Class `AST::LoxPrintStmt`
         | 
| 101 162 | 
             
            - Class `BackEnd::Engine` implementation of the print statement logic
         | 
| 102 163 | 
             
            - Class `Interpreter`
         | 
| 103 164 |  | 
| 104 | 
            -
             | 
| 165 | 
            +
            ### Changed
         | 
| 105 166 | 
             
            - Class `Ast::ASTVisitor` Added visit method
         | 
| 106 167 | 
             
            - File `README.md` added Hello world example.
         | 
| 107 168 |  | 
| 108 169 | 
             
            ## [0.0.11] - 2021-01-08
         | 
| 109 170 | 
             
            - AST node generation for logical expression (and, or).
         | 
| 110 171 |  | 
| 111 | 
            -
             | 
| 172 | 
            +
            ### Changed
         | 
| 112 173 | 
             
            - Class `AST::ASTBuilder` added `reduce_` methods for logical operations.
         | 
| 113 174 | 
             
            - File `grammar.rb`added name to logical expression rules
         | 
| 114 175 | 
             
            - File `README.md` added gem version and license badges, expanded roadmap section.
         | 
| 115 176 |  | 
| 116 | 
            -
             | 
| 177 | 
            +
            ### Fixed
         | 
| 117 178 | 
             
            - File `grammar.rb`: a rule had incomplete non-terminal name `conjunct_` in its lhs.
         | 
| 118 179 |  | 
| 119 180 |  | 
| 120 181 | 
             
            ## [0.0.10] - 2021-01-08
         | 
| 121 182 | 
             
            - AST node generation for equality expression.
         | 
| 122 183 |  | 
| 123 | 
            -
             | 
| 184 | 
            +
            ### Changed
         | 
| 124 185 | 
             
            - Class `AST::ASTBuilder` refactoring and added `reduce_` methods for equality operations.
         | 
| 125 186 | 
             
            - File `grammar.rb`added name to equality rules
         | 
| 126 187 | 
             
            - File `README.md` added gem version and license badges, expanded roadmap section.
         | 
| 127 188 |  | 
| 128 | 
            -
             | 
| 189 | 
            +
            ### Fixed
         | 
| 129 190 | 
             
            - File `grammar.rb`: a rule had still the discarded non-terminal `equalityTest_star` in its lhs.
         | 
| 130 191 |  | 
| 131 192 | 
             
            ## [0.0.9] - 2021-01-07
         | 
| 132 193 | 
             
            - AST node generation for comparison expression.
         | 
| 133 194 |  | 
| 134 | 
            -
             | 
| 195 | 
            +
            ### Changed
         | 
| 135 196 | 
             
            - Class `AST::ASTBuilder` added `reduce_` methods for comparison operations.
         | 
| 136 197 | 
             
            - File `grammar.rb`added name to comparison rules
         | 
| 137 198 |  | 
| 138 199 | 
             
            ## [0.0.8] - 2021-01-07
         | 
| 139 200 | 
             
            - AST node generation for arithmetic operations of number literals.
         | 
| 140 201 |  | 
| 141 | 
            -
             | 
| 202 | 
            +
            ### Changed
         | 
| 142 203 | 
             
            - Class `AST::ASTBuilder` added `reduce_` methods for arithmetic operations.
         | 
| 143 204 | 
             
            - File `grammar.rb`added name to arithmetic rules
         | 
| 144 205 |  | 
| 145 | 
            -
             | 
| 206 | 
            +
            ### Fixed
         | 
| 146 207 | 
             
            - File `grammar.rb`: second rule for `factor` had a missing member in rhs.
         | 
| 147 208 |  | 
| 148 209 | 
             
            ## [0.0.7] - 2021-01-06
         | 
| 149 210 | 
             
            - Lox grammar reworked, initial AST classes created.
         | 
| 150 211 |  | 
| 151 | 
            -
             | 
| 212 | 
            +
            ### Added
         | 
| 152 213 | 
             
            - Class `Parser` this one generates AST's (Abstract Syntax Tree)
         | 
| 153 214 | 
             
            - Class `AST::ASTVisitor` draft initial implementation.
         | 
| 154 215 | 
             
            - Class `AST::BinaryExpr` draft initial implementation.
         | 
| @@ -156,7 +217,7 @@ | |
| 156 217 | 
             
            - Class `AST::LiteralExpr` draft initial implementation.
         | 
| 157 218 | 
             
            - Class `AST::LoxNode` draft initial implementation.
         | 
| 158 219 |  | 
| 159 | 
            -
             | 
| 220 | 
            +
            ### Changed
         | 
| 160 221 | 
             
            - File `spec_helper.rb`: removed Bundler dependency
         | 
| 161 222 | 
             
            - Class `AST::ASTBuilder` added initial `reduce_` methods.
         | 
| 162 223 | 
             
            - File `README.md` Removed example with AST generation since this is in flux.
         | 
| @@ -164,31 +225,31 @@ | |
| 164 225 | 
             
            ## [0.0.6] - 2021-01-03
         | 
| 165 226 | 
             
            - First iteration of a parser with AST generation.
         | 
| 166 227 |  | 
| 167 | 
            -
             | 
| 228 | 
            +
            ### Added
         | 
| 168 229 | 
             
            - Class `Parser` this one generates AST's (Abstract Syntax Tree)
         | 
| 169 230 | 
             
            - Class `AST::ASTBuilder` default code to generate an AST.
         | 
| 170 231 |  | 
| 171 | 
            -
             | 
| 232 | 
            +
            ### Changed
         | 
| 172 233 | 
             
            - File `spec_helper.rb`: removed Bundler dependency
         | 
| 173 234 | 
             
            - File `README.md` Added example with AST visualization.
         | 
| 174 235 |  | 
| 175 | 
            -
             | 
| 236 | 
            +
            ### Fixed
         | 
| 176 237 | 
             
            - File `grammar.rb` ensure that the constant `Grammar` is created once only.
         | 
| 177 238 |  | 
| 178 239 | 
             
            ## [0.0.5] - 2021-01-02
         | 
| 179 240 | 
             
            - Improved example in `README.md`, code re-styling to please `Rubocop` 1.7
         | 
| 180 241 |  | 
| 181 | 
            -
             | 
| 242 | 
            +
            ### Changed
         | 
| 182 243 | 
             
            - Code re-styling to please `Rubocop` 1.7
         | 
| 183 244 | 
             
            - File `README.md` Improved example with better parse tree visualization.
         | 
| 184 245 |  | 
| 185 246 | 
             
            ## [0.0.4] - 2021-01-01
         | 
| 186 247 | 
             
            - A first parser implementation able to parse Lox source code.
         | 
| 187 248 |  | 
| 188 | 
            -
             | 
| 249 | 
            +
            ### Added
         | 
| 189 250 | 
             
            - Method `LXString::==` equality operator.
         | 
| 190 251 |  | 
| 191 | 
            -
             | 
| 252 | 
            +
            ### Changed
         | 
| 192 253 | 
             
            - class `Parser` renamed to `RawParser`
         | 
| 193 254 | 
             
            - File `README.md` Added an example showing the use of `RawParser` class.
         | 
| 194 255 |  | 
    
        data/README.md
    CHANGED
    
    | @@ -8,7 +8,7 @@ a simple language used in Bob Nystrom's online book [Crafting Interpreters](http | |
| 8 8 |  | 
| 9 9 | 
             
            ### Purpose of this project:
         | 
| 10 10 | 
             
            - To deliver an open source example of a programming language fully implemented in Ruby  
         | 
| 11 | 
            -
              (from the scanner | 
| 11 | 
            +
              (from the scanner and parser to an interpreter).
         | 
| 12 12 | 
             
            - The implementation should be mature enough to run [LoxLox](https://github.com/benhoyt/loxlox),  
         | 
| 13 13 | 
             
              a Lox interpreter written in Lox.
         | 
| 14 14 |  | 
| @@ -141,7 +141,9 @@ Here are the language features currently supported by the interpreter: | |
| 141 141 | 
             
            - [Datatypes](#datatypes)
         | 
| 142 142 | 
             
            - [Statements](#statements)  
         | 
| 143 143 | 
             
              -[Expressions](#expressions)  
         | 
| 144 | 
            -
             | 
| 144 | 
            +
            - [Variable declarations](#var-statement)  
         | 
| 145 | 
            +
            - [If Statement](#if-statement)   
         | 
| 146 | 
            +
            - [Print Statement](#print-statement)
         | 
| 145 147 |  | 
| 146 148 | 
             
            ### Comments
         | 
| 147 149 |  | 
| @@ -168,12 +170,16 @@ loxxy supports  all the standard __Lox__ datatypes: | |
| 168 170 | 
             
            ### Statements
         | 
| 169 171 |  | 
| 170 172 | 
             
            Loxxy supports the following statements:  
         | 
| 171 | 
            -
            -[Expressions](#expressions)  
         | 
| 173 | 
            +
            - [Expressions](#expressions)  
         | 
| 172 174 | 
             
              -[Arithmetic expressions](#arithmetic-expressions)  
         | 
| 173 175 | 
             
              -[String concatenation](#string-concatenation)  
         | 
| 174 176 | 
             
              -[Comparison expressions](#comparison-expressions)  
         | 
| 175 177 | 
             
              -[Logical expressions](#logical-expressions)  
         | 
| 176 178 | 
             
              -[Grouping expressions](#grouping-expressions)  
         | 
| 179 | 
            +
              -[Variable expressions and assignments](#variable-expressions)
         | 
| 180 | 
            +
              
         | 
| 181 | 
            +
            -[Variable declarations](#var-statement)  
         | 
| 182 | 
            +
            -[If Statement](#if-statement)  
         | 
| 177 183 | 
             
            -[Print Statement](#print-statement)
         | 
| 178 184 |  | 
| 179 185 | 
             
            #### Expressions
         | 
| @@ -245,7 +251,7 @@ REMINDER: In __Lox__, `false` and `nil` are considered falsey, everything else i | |
| 245 251 | 
             
              `!!true; // => true`  
         | 
| 246 252 | 
             
              `!0; // => false`
         | 
| 247 253 |  | 
| 248 | 
            -
             | 
| 254 | 
            +
            ####  Grouping expressions
         | 
| 249 255 | 
             
            Use parentheses `(` `)` for a better control in expression/operator precedence.
         | 
| 250 256 |  | 
| 251 257 | 
             
            ``` javascript
         | 
| @@ -253,8 +259,61 @@ print 3 + 4 * 5;  // => 23 | |
| 253 259 | 
             
            print (3 + 4) * 5; // => 35
         | 
| 254 260 | 
             
            ```
         | 
| 255 261 |  | 
| 262 | 
            +
            ####  Variable expressions and assignments
         | 
| 263 | 
            +
            In __Lox__, a variable expression is nothing than retrieving the value of a variable.
         | 
| 264 | 
            +
            ``` javascript
         | 
| 265 | 
            +
            var foo = "bar;" // Variable declaration
         | 
| 266 | 
            +
            print foo;  // Variable expression (= use its value)
         | 
| 267 | 
            +
            foo = "baz"; // Variable assignment
         | 
| 268 | 
            +
            print foo; // Output: baz
         | 
| 269 | 
            +
            ```
         | 
| 270 | 
            +
             | 
| 271 | 
            +
             | 
| 272 | 
            +
             | 
| 273 | 
            +
            #### Variable declarations
         | 
| 274 | 
            +
            ``` javascript
         | 
| 275 | 
            +
            var iAmAVariable = "my-initial-value";
         | 
| 276 | 
            +
            var iAmNil; // __Lox__ initializes variables to nil by default;
         | 
| 277 | 
            +
            print iAmNil; // output: nil
         | 
| 278 | 
            +
            ```
         | 
| 256 279 |  | 
| 257 | 
            -
             | 
| 280 | 
            +
            #### If statement
         | 
| 281 | 
            +
             | 
| 282 | 
            +
            Based on a given condition, an if statement executes one of two statements:
         | 
| 283 | 
            +
            ``` javascript
         | 
| 284 | 
            +
            if (condition) {
         | 
| 285 | 
            +
            print "then-branch";
         | 
| 286 | 
            +
            } else {
         | 
| 287 | 
            +
            print "else-branch";
         | 
| 288 | 
            +
            }
         | 
| 289 | 
            +
            ```
         | 
| 290 | 
            +
             | 
| 291 | 
            +
            As for other languages, the `else` part is optional.
         | 
| 292 | 
            +
            ##### Warning: nested `if`...`else`
         | 
| 293 | 
            +
            Call it a bug ... Nested `if` `else` control flow structure aren't yet supported by __Loxxy__.  
         | 
| 294 | 
            +
            The culprit has a name: [the dangling else](https://en.wikipedia.org/wiki/Dangling_else). 
         | 
| 295 | 
            +
             | 
| 296 | 
            +
            The problem in a nutshell: in a nested if ... else ... statement like this:
         | 
| 297 | 
            +
            ``` javascript
         | 
| 298 | 
            +
            'if (true) if (false) print "bad"; else print "good";
         | 
| 299 | 
            +
            ```
         | 
| 300 | 
            +
            ... there is an ambiguity. Indeed, according to the __Lox__ grammar, the `else` could be bound 
         | 
| 301 | 
            +
            either to the first `if` or to the second one.
         | 
| 302 | 
            +
            This ambiguity is usually lifted by applying an ad-hoc rule: an `else` is aways bound to the most 
         | 
| 303 | 
            +
            recent (rightmost) `if`.  
         | 
| 304 | 
            +
            Being a generic parsing library, `Rley` doesn't apply any of these supplemental rules.
         | 
| 305 | 
            +
            As a consequence,it complains about the found ambiguity and stops the parsing...
         | 
| 306 | 
            +
            Although `Rley` can cope with ambiguities, this requires the use of an advanced data structure
         | 
| 307 | 
            +
            called `Shared Packed Parse Forest (SPPF)`.
         | 
| 308 | 
            +
            SPPF are much more complex to handle than the `common` parse trees present in most compiler or interpreter books.
         | 
| 309 | 
            +
            Therefore, a future version of `Rley` will incorporate the capability to define disambuiguation rules.  
         | 
| 310 | 
            +
             | 
| 311 | 
            +
            In the meantime, the `Loxxy` will progress on other __Lox__ features like:
         | 
| 312 | 
            +
            - Variables,
         | 
| 313 | 
            +
            - Block structures...
         | 
| 314 | 
            +
             | 
| 315 | 
            +
             | 
| 316 | 
            +
            ####  Print Statement
         | 
| 258 317 |  | 
| 259 318 | 
             
            The statement print + expression + ; prints the result of the expression to stdout.
         | 
| 260 319 |  | 
| @@ -1,9 +1,14 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require_relative 'lox_variable_expr'
         | 
| 3 4 | 
             
            require_relative 'lox_literal_expr'
         | 
| 4 5 | 
             
            require_relative 'lox_noop_expr'
         | 
| 5 6 | 
             
            require_relative 'lox_grouping_expr'
         | 
| 6 7 | 
             
            require_relative 'lox_unary_expr'
         | 
| 7 8 | 
             
            require_relative 'lox_binary_expr'
         | 
| 8 9 | 
             
            require_relative 'lox_logical_expr'
         | 
| 10 | 
            +
            require_relative 'lox_assign_expr'
         | 
| 9 11 | 
             
            require_relative 'lox_print_stmt'
         | 
| 12 | 
            +
            require_relative 'lox_if_stmt'
         | 
| 13 | 
            +
            require_relative 'lox_var_stmt'
         | 
| 14 | 
            +
            require_relative 'lox_seq_decl'
         | 
| @@ -149,8 +149,18 @@ module Loxxy | |
| 149 149 | 
             
                  end
         | 
| 150 150 |  | 
| 151 151 | 
             
                  # rule('program' => 'declaration_plus EOF').as ''
         | 
| 152 | 
            -
                  def reduce_lox_program(_production,  | 
| 153 | 
            -
                     | 
| 152 | 
            +
                  def reduce_lox_program(_production, _range, tokens, theChildren)
         | 
| 153 | 
            +
                    LoxSeqDecl.new(tokens[0].position, theChildren[0])
         | 
| 154 | 
            +
                  end
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                  # rule('declaration_plus' => 'declaration_plus declaration').as ''
         | 
| 157 | 
            +
                  def reduce_declaration_plus_more(_production, _range, _tokens, theChildren)
         | 
| 158 | 
            +
                    theChildren[0] << theChildren[1]
         | 
| 159 | 
            +
                  end
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                  # rule('declaration_plus' => 'declaration')
         | 
| 162 | 
            +
                  def reduce_declaration_plus_end(_production, _range, _tokens, theChildren)
         | 
| 163 | 
            +
                    [theChildren[0]]
         | 
| 154 164 | 
             
                  end
         | 
| 155 165 |  | 
| 156 166 | 
             
                  # rule('exprStmt' => 'expression SEMICOLON')
         | 
| @@ -158,11 +168,37 @@ module Loxxy | |
| 158 168 | 
             
                  return_first_child(range, tokens, theChildren) # Discard the semicolon
         | 
| 159 169 | 
             
                  end
         | 
| 160 170 |  | 
| 171 | 
            +
                  # rule('varDecl' => 'VAR IDENTIFIER SEMICOLON')
         | 
| 172 | 
            +
                  def reduce_var_declaration(_production, _range, tokens, theChildren)
         | 
| 173 | 
            +
                    var_name = theChildren[1].token.lexeme.dup
         | 
| 174 | 
            +
                    Ast::LoxVarStmt.new(tokens[1].position, var_name, nil)
         | 
| 175 | 
            +
                  end
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                  # rule('varDecl' => 'VAR IDENTIFIER EQUAL expression SEMICOLON')
         | 
| 178 | 
            +
                  def reduce_var_initialization(_production, _range, tokens, theChildren)
         | 
| 179 | 
            +
                    var_name = theChildren[1].token.lexeme.dup
         | 
| 180 | 
            +
                    Ast::LoxVarStmt.new(tokens[1].position, var_name, theChildren[3])
         | 
| 181 | 
            +
                  end
         | 
| 182 | 
            +
             | 
| 183 | 
            +
                  # rule('ifStmt' => 'IF ifCondition statement elsePart_opt')
         | 
| 184 | 
            +
                  def reduce_if_stmt(_production, _range, tokens, theChildren)
         | 
| 185 | 
            +
                    condition = theChildren[1]
         | 
| 186 | 
            +
                    then_stmt = theChildren[2]
         | 
| 187 | 
            +
                    else_stmt = theChildren[3]
         | 
| 188 | 
            +
                    LoxIfStmt.new(tokens[0].position, condition, then_stmt, else_stmt)
         | 
| 189 | 
            +
                  end
         | 
| 190 | 
            +
             | 
| 161 191 | 
             
                  # rule('printStmt' => 'PRINT expression SEMICOLON')
         | 
| 162 192 | 
             
                  def reduce_print_stmt(_production, _range, tokens, theChildren)
         | 
| 163 193 | 
             
                    Ast::LoxPrintStmt.new(tokens[1].position, theChildren[1])
         | 
| 164 194 | 
             
                  end
         | 
| 165 195 |  | 
| 196 | 
            +
                  # rule('assignment' => 'owner_opt IDENTIFIER EQUAL assignment')
         | 
| 197 | 
            +
                  def reduce_assign_expr(_production, _range, tokens, theChildren)
         | 
| 198 | 
            +
                    var_name = theChildren[1].token.lexeme.dup
         | 
| 199 | 
            +
                    Ast::LoxAssignExpr.new(tokens[1].position, var_name, theChildren[3])
         | 
| 200 | 
            +
                  end
         | 
| 201 | 
            +
             | 
| 166 202 | 
             
                  # rule('logic_or' => 'logic_and disjunct_plus')
         | 
| 167 203 | 
             
                  def reduce_logic_or_plus(production, range, tokens, theChildren)
         | 
| 168 204 | 
             
                    reduce_logical_expr(production, range, tokens, theChildren)
         | 
| @@ -271,6 +307,12 @@ module Loxxy | |
| 271 307 | 
             
                    literal = first_child.token.value
         | 
| 272 308 | 
             
                    LoxLiteralExpr.new(pos, literal)
         | 
| 273 309 | 
             
                  end
         | 
| 310 | 
            +
             | 
| 311 | 
            +
                  # rule('primary' => 'IDENTIFIER')
         | 
| 312 | 
            +
                  def reduce_variable_expr(_production, _range, tokens, theChildren)
         | 
| 313 | 
            +
                    var_name = theChildren[0].token.lexeme
         | 
| 314 | 
            +
                    LoxVariableExpr.new(tokens[0].position, var_name)
         | 
| 315 | 
            +
                  end
         | 
| 274 316 | 
             
                end # class
         | 
| 275 317 | 
             
              end # module
         | 
| 276 318 | 
             
            end # module
         |