loxxy 0.0.9 → 0.0.14
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 +48 -0
- data/README.md +159 -20
- data/lib/loxxy.rb +23 -2
- data/lib/loxxy/ast/all_lox_nodes.rb +5 -0
- data/lib/loxxy/ast/ast_builder.rb +123 -37
- data/lib/loxxy/ast/ast_visitor.rb +43 -55
- data/lib/loxxy/ast/lox_binary_expr.rb +6 -0
- data/lib/loxxy/ast/lox_compound_expr.rb +1 -1
- data/lib/loxxy/ast/lox_node.rb +5 -0
- data/lib/loxxy/ast/lox_noop_expr.rb +16 -0
- data/lib/loxxy/ast/lox_print_stmt.rb +21 -0
- data/lib/loxxy/back_end/engine.rb +62 -0
- data/lib/loxxy/datatype/boolean.rb +11 -0
- data/lib/loxxy/datatype/builtin_datatype.rb +6 -0
- data/lib/loxxy/datatype/false.rb +6 -0
- data/lib/loxxy/datatype/lx_string.rb +29 -6
- data/lib/loxxy/datatype/nil.rb +6 -0
- data/lib/loxxy/datatype/number.rb +33 -1
- data/lib/loxxy/datatype/true.rb +6 -0
- data/lib/loxxy/front_end/grammar.rb +13 -13
- data/lib/loxxy/interpreter.rb +40 -0
- data/lib/loxxy/version.rb +1 -1
- data/spec/back_end/engine_spec.rb +43 -0
- data/spec/datatype/boolean_spec.rb +31 -0
- data/spec/datatype/lx_string_spec.rb +27 -5
- data/spec/datatype/nil_spec.rb +26 -0
- data/spec/datatype/number_spec.rb +47 -0
- data/spec/front_end/parser_spec.rb +92 -59
- data/spec/interpreter_spec.rb +54 -0
- 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: 18b1d3e9f498ca8249775f55cc3950622d9f5a49cd67db912816cc60f15b3d16
|
4
|
+
data.tar.gz: 5766130089ebbe6d85a90a9f59ac1a505202c0e2646d4d7da93af025a80b0651
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 621832b48a5625081a0b82a8f8992d78709a1d4a053d8e4719140510242ce14d4418ca23c82d9f52186453c42d5d432203e7af496d7f92726f75622c743119e2
|
7
|
+
data.tar.gz: aa67901fae29e13d3154e274c7014fe2002fb7e054c62cf253e87e44ac421747db9f5f05ef1e108cd92c8c0124ceb93b31fa537de64f875607c096465f89aee4
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,51 @@
|
|
1
|
+
## [0.0.13] - 2021-01-10
|
2
|
+
- The interpreter can evaluate directly simple literals.
|
3
|
+
|
4
|
+
## Changed
|
5
|
+
- Class `AST::ASTBuilder` added `reduce_exprStmt` to support the evaluation of literals.
|
6
|
+
- File `README.md` added one more example.
|
7
|
+
- File `parser_spec.rb` Updated the tests to reflect the change in the AST.
|
8
|
+
- File `interpreter_spec.rb` Added a test for literal expression.
|
9
|
+
|
10
|
+
## Fixed
|
11
|
+
- File `loxxy.rb`: shorthand method `lox_true` referenced the ... false object (oops).
|
12
|
+
|
13
|
+
## [0.0.12] - 2021-01-09
|
14
|
+
- Initial interpreter capable of evaluating a tiny subset of Lox language.
|
15
|
+
|
16
|
+
## Added
|
17
|
+
- Class `AST::LoxNoopExpr`
|
18
|
+
- Class `AST::LoxPrintStmt`
|
19
|
+
- Class `BackEnd::Engine` implementation of the print statement logic
|
20
|
+
- Class `Interpreter`
|
21
|
+
|
22
|
+
## Changed
|
23
|
+
- Class `Ast::ASTVisitor` Added visit method
|
24
|
+
- File `README.md` added Hello world example.
|
25
|
+
|
26
|
+
## [0.0.11] - 2021-01-08
|
27
|
+
- AST node generation for logical expression (and, or).
|
28
|
+
|
29
|
+
## Changed
|
30
|
+
- Class `AST::ASTBuilder` added `reduce_` methods for logical operations.
|
31
|
+
- File `grammar.rb`added name to logical expression rules
|
32
|
+
- File `README.md` added gem version and license badges, expanded roadmap section.
|
33
|
+
|
34
|
+
## Fixed
|
35
|
+
- File `grammar.rb`: a rule had incomplete non-terminal name `conjunct_` in its lhs.
|
36
|
+
|
37
|
+
|
38
|
+
## [0.0.10] - 2021-01-08
|
39
|
+
- AST node generation for equality expression.
|
40
|
+
|
41
|
+
## Changed
|
42
|
+
- Class `AST::ASTBuilder` refactoring and added `reduce_` methods for equality operations.
|
43
|
+
- File `grammar.rb`added name to equality rules
|
44
|
+
- File `README.md` added gem version and license badges, expanded roadmap section.
|
45
|
+
|
46
|
+
## Fixed
|
47
|
+
- File `grammar.rb`: a rule had still the discarded non-terminal `equalityTest_star` in its lhs.
|
48
|
+
|
1
49
|
## [0.0.9] - 2021-01-07
|
2
50
|
- AST node generation for comparison expression.
|
3
51
|
|
data/README.md
CHANGED
@@ -1,31 +1,88 @@
|
|
1
|
-
#
|
1
|
+
# loxxy
|
2
|
+
[](https://badge.fury.io/rb/loxxy)
|
3
|
+
[](https://github.com/famished-tiger/loxxy/blob/main/LICENSE.txt)
|
4
|
+
|
2
5
|
|
3
6
|
A Ruby implementation of the [Lox programming language](https://craftinginterpreters.com/the-lox-language.html ),
|
4
7
|
a simple language used in Bob Nystrom's online book [Crafting Interpreters](https://craftinginterpreters.com/ ).
|
5
8
|
|
6
|
-
|
9
|
+
### Purpose of this project:
|
7
10
|
- To deliver an open source example of a programming language fully implemented in Ruby
|
8
|
-
(from the scanner, parser,
|
9
|
-
- The implementation should be mature enough to run (
|
11
|
+
(from the scanner, parser, an interpreter).
|
12
|
+
- The implementation should be mature enough to run [LoxLox](https://github.com/benhoyt/loxlox),
|
10
13
|
a Lox interpreter written in Lox.
|
11
14
|
|
12
|
-
|
13
|
-
The
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
-
|
25
|
-
-
|
26
|
-
-
|
15
|
+
### Current status
|
16
|
+
The project is still in inception and the interpreter is being implemented...
|
17
|
+
Currently it can execute a tiny subset of __Lox__ language.
|
18
|
+
|
19
|
+
The __loxxy__ gem also a parser class `RawPaser` that can parse, in principle, any valid Lox input.
|
20
|
+
|
21
|
+
## What's the fuss about Lox?
|
22
|
+
... Nothing...
|
23
|
+
Bob Nystrom designed a language __simple__ enough so that he could present
|
24
|
+
two implementations (an interpreter, then a compiler) in one single book.
|
25
|
+
|
26
|
+
Although __Lox__ is fairly simple, it is far from a toy language:
|
27
|
+
- Dynamically typed,
|
28
|
+
- Provides datatypes such as booleans, number, strings,
|
29
|
+
- Supports arithmetic operations (+, -, *, / ) and comparison ( >, >= , <, <=)
|
30
|
+
- Implements equality operators (==, !=) and the logical connectors `and` and `or`.
|
31
|
+
- Control flow statements `if`, `for` and `while`
|
32
|
+
- Functions and closures
|
33
|
+
- Object-orientation (classes, methods, inheritance).
|
34
|
+
|
35
|
+
In other words, __Lox__ contains interesting features expected from most general-purpose
|
36
|
+
languages.
|
37
|
+
|
38
|
+
### What's missing in Lox?
|
39
|
+
__Lox__ was constrained by design and therefore was not aimed to be a language used in real-world applications.
|
40
|
+
Here are some missing parts to make it a _practical_ language:
|
41
|
+
- Collections (arrays, maps, ...)
|
42
|
+
- Modules (importing stuff from other packages/files)
|
43
|
+
- Error handling (e.g. exceptions)
|
44
|
+
- Support for concurrency (e.g. threads, coroutines)
|
45
|
+
|
46
|
+
Also a decent standard library for IO, networking,... is lacking.
|
47
|
+
|
48
|
+
For sure, the language has shortcomings but on the other hand, it exhibits the essential features
|
49
|
+
to cover in an introduction to language implementation.
|
50
|
+
|
51
|
+
That's already fun... and if all this gives you the inspiration for creating your own
|
52
|
+
language, that might be even funnier...
|
53
|
+
|
54
|
+
Last point: what's makes __Lox__ interesting is the fact that there are implementations in many [languages](https://github.com/munificent/craftinginterpreters/wiki/Lox-implementations)
|
55
|
+
|
56
|
+
## Hello world example
|
57
|
+
```ruby
|
58
|
+
require 'loxxy'
|
59
|
+
|
60
|
+
lox_program = <<LOX_END
|
61
|
+
// Your first Lox program!
|
62
|
+
print "Hello, world!";
|
63
|
+
LOX_END
|
64
|
+
|
65
|
+
lox = Loxxy::Interpreter.new
|
66
|
+
lox.evaluate(lox_program) # Output: Hello, world!
|
67
|
+
```
|
68
|
+
|
69
|
+
## Retrieving the result from a Lox program
|
70
|
+
The __Loxxy__ interpreter returns the value of the last evaluated expression.
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
require 'loxxy'
|
74
|
+
|
75
|
+
lox = Loxxy::Interpreter.new
|
76
|
+
|
77
|
+
lox_program = '37 + 5; // THE answer'
|
78
|
+
result = lox.evaluate(lox_program) # => Loxxy::Datatype::Number
|
79
|
+
|
80
|
+
# `result` is a Ruby object, so let's use it...
|
81
|
+
puts result.value # Output: 42
|
82
|
+
```
|
27
83
|
|
28
84
|
## Example using RawParser class
|
85
|
+
|
29
86
|
```ruby
|
30
87
|
require 'loxxy'
|
31
88
|
|
@@ -70,6 +127,89 @@ program
|
|
70
127
|
+-- EOF: ''
|
71
128
|
```
|
72
129
|
|
130
|
+
## Suppported Lox language features
|
131
|
+
Although the interpreter should parse almost any valid Lox program,
|
132
|
+
it currently can evaluate a tiny set of AST node (AST = Abstract Syntax Tree).
|
133
|
+
|
134
|
+
Here are the language features currently supported by the interpreter:
|
135
|
+
|
136
|
+
- [Comments](#comments)
|
137
|
+
- [Keywords](#keywords)
|
138
|
+
- [Operators and Special Chars](#operators-and-special-chars)
|
139
|
+
- [Datatypes](#datatypes)
|
140
|
+
- [Statements](#statements)
|
141
|
+
- `print` statement.
|
142
|
+
|
143
|
+
### Comments
|
144
|
+
|
145
|
+
Loxxy supports single line C-style comments.
|
146
|
+
|
147
|
+
```javascript
|
148
|
+
// single line comment
|
149
|
+
```
|
150
|
+
|
151
|
+
### Keywords
|
152
|
+
|
153
|
+
The parser knows all the __Lox__ reserved keywords:
|
154
|
+
```lang-none
|
155
|
+
and, class, else, false, fun, for, if, nil, or,
|
156
|
+
print, return, super, this, true, var, while
|
157
|
+
```
|
158
|
+
Of these, the interpreter implements: `false`, `nil`, `true`
|
159
|
+
|
160
|
+
### Operators and Special Chars
|
161
|
+
#### Operators
|
162
|
+
The parser recognizes all the __Lox__ operators, delimiters and separators:
|
163
|
+
- Arithmetic operators: `+`, `-`, `*`, `/`
|
164
|
+
- Comparison operators: `>`, `>=`, `<`, `<=`
|
165
|
+
- Equality operators: `==`, `!=`
|
166
|
+
|
167
|
+
Of these, the interpreter implements:
|
168
|
+
`+` (addition of two numbers or string concatenation)
|
169
|
+
|
170
|
+
#### Delimiters
|
171
|
+
The parser knows all the __Lox__ grouping delimiters:
|
172
|
+
(`, ), `{`, `}`
|
173
|
+
|
174
|
+
These aren't yet implemented in the interpreter.
|
175
|
+
|
176
|
+
The other characters that have a special meaning in __Lox__ are:
|
177
|
+
- `,` Used in parameter list
|
178
|
+
- `.` For the dot notation (i.e. calling a method)
|
179
|
+
- `;` The semicolon is used to terminates expressions
|
180
|
+
- `=` Assignment
|
181
|
+
|
182
|
+
The parser recognizes them all but the interpreter accepts the semicolons only.
|
183
|
+
|
184
|
+
### Datatypes
|
185
|
+
|
186
|
+
Loxxy supports the following standard __Lox__ datatypes:
|
187
|
+
- `Boolean`: Can be `true` or `false`
|
188
|
+
- `Number`: Can be an integer or a floating-point numbers. For example: `123, 12.34, -45.67`
|
189
|
+
- `String`: Sequence of characters surrounded by `"`. For example: `"Hello!"`
|
190
|
+
- `Nil`: Used to define a null value, denoted by the `nil` keyword
|
191
|
+
|
192
|
+
All the Lox literals (booleans, numbers, strings and nil),
|
193
|
+
|
194
|
+
## Statements
|
195
|
+
### Implemented expressions
|
196
|
+
Loxxy implements expressions:
|
197
|
+
- Consisting of literals only; or,
|
198
|
+
- Addition of two numbers; or,
|
199
|
+
- Concatenation of two strings
|
200
|
+
|
201
|
+
### Implemented statements
|
202
|
+
Loxxy implements the following statements:
|
203
|
+
- Expressions (see above sub-section)
|
204
|
+
- Print statement
|
205
|
+
|
206
|
+
```javascript
|
207
|
+
// Print statement with nested concatenation
|
208
|
+
print "Hello" + ", " + "world!";
|
209
|
+
```
|
210
|
+
|
211
|
+
|
212
|
+
|
73
213
|
## Installation
|
74
214
|
|
75
215
|
Add this line to your application's Gemfile:
|
@@ -91,7 +231,6 @@ Or install it yourself as:
|
|
91
231
|
TODO: Write usage instructions here
|
92
232
|
|
93
233
|
## Other Lox implementations in Ruby
|
94
|
-
An impressive list of Lox implementations can be found [here](https://github.com/munificent/craftinginterpreters/wiki/Lox-implementations)
|
95
234
|
|
96
235
|
For Ruby, there is the [lox](https://github.com/rdodson41/ruby-lox) gem.
|
97
236
|
There are other Ruby-based projects as well:
|
data/lib/loxxy.rb
CHANGED
@@ -1,10 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'loxxy/version'
|
4
|
+
require_relative 'loxxy/interpreter'
|
4
5
|
require_relative 'loxxy/front_end/raw_parser'
|
5
|
-
require_relative 'loxxy/front_end/parser'
|
6
6
|
|
7
|
+
# Namespace for all classes and constants of __loxxy__ gem.
|
7
8
|
module Loxxy
|
8
9
|
class Error < StandardError; end
|
9
|
-
|
10
|
+
|
11
|
+
# Shorthand method. Returns the sole object that represents
|
12
|
+
# a Lox false literal.
|
13
|
+
# @return [Loxxy::Datatype::False]
|
14
|
+
def self.lox_false
|
15
|
+
Datatype::False.instance
|
16
|
+
end
|
17
|
+
|
18
|
+
# Shorthand method. Returns the sole object that represents
|
19
|
+
# a Lox nil literal.
|
20
|
+
# @return [Loxxy::Datatype::Nil]
|
21
|
+
def self.lox_nil
|
22
|
+
Datatype::Nil.instance
|
23
|
+
end
|
24
|
+
|
25
|
+
# Shorthand method. Returns the sole object that represents
|
26
|
+
# a Lox true literal.
|
27
|
+
# @return [Loxxy::Datatype::True]
|
28
|
+
def self.lox_true
|
29
|
+
Datatype::True.instance
|
30
|
+
end
|
10
31
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../datatype/all_datatypes'
|
4
|
-
require_relative '
|
4
|
+
require_relative 'all_lox_nodes'
|
5
5
|
require_relative 'lox_binary_expr'
|
6
6
|
|
7
7
|
module Loxxy
|
@@ -10,13 +10,33 @@ module Loxxy
|
|
10
10
|
# (Abstract Syntax Tree) from a sequence of input tokens and
|
11
11
|
# visit events produced by walking over a GFGParsing object.
|
12
12
|
class ASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
unless defined?(Name2special)
|
14
|
+
# Mapping Token name => operator | separator | delimiter characters
|
15
|
+
# @return [Hash{String => String}]
|
16
|
+
Name2special = {
|
17
|
+
'AND' => 'and',
|
18
|
+
'BANG' => '!',
|
19
|
+
'BANG_EQUAL' => '!=',
|
20
|
+
'COMMA' => ',',
|
21
|
+
'DOT' => '.',
|
22
|
+
'EQUAL' => '=',
|
23
|
+
'EQUAL_EQUAL' => '==',
|
24
|
+
'GREATER' => '>',
|
25
|
+
'GREATER_EQUAL' => '>=',
|
26
|
+
'LEFT_BRACE' => '{',
|
27
|
+
'LEFT_PAREN' => '(',
|
28
|
+
'LESS' => '<',
|
29
|
+
'LESS_EQUAL' => '<=',
|
30
|
+
'MINUS' => '-',
|
31
|
+
'OR' => 'or',
|
32
|
+
'PLUS' => '+',
|
33
|
+
'RIGHT_BRACE' => '}',
|
34
|
+
'RIGHT_PAREN' => ')',
|
35
|
+
'SEMICOLON' => ';',
|
36
|
+
'SLASH' => '/',
|
37
|
+
'STAR' => '*'
|
38
|
+
}.freeze
|
39
|
+
end # defined
|
20
40
|
|
21
41
|
attr_reader :strict
|
22
42
|
|
@@ -76,7 +96,7 @@ module Loxxy
|
|
76
96
|
def reduce_binary_operator(_production, _range, tokens, theChildren)
|
77
97
|
operand1 = theChildren[0]
|
78
98
|
|
79
|
-
# Second child is
|
99
|
+
# Second child is array with couples [operator, operand2]
|
80
100
|
theChildren[1].each do |(operator, operand2)|
|
81
101
|
operand1 = LoxBinaryExpr.new(tokens[0].position, operator, operand1, operand2)
|
82
102
|
end
|
@@ -84,6 +104,90 @@ module Loxxy
|
|
84
104
|
operand1
|
85
105
|
end
|
86
106
|
|
107
|
+
# rule('something_plus' => 'something_plus operator symbol')
|
108
|
+
def reduce_binary_plus_more(_production, _range, _tokens, theChildren)
|
109
|
+
result = theChildren[0]
|
110
|
+
operator = Name2special[theChildren[1].symbol.name].to_sym
|
111
|
+
operand2 = theChildren[2]
|
112
|
+
result << [operator, operand2]
|
113
|
+
end
|
114
|
+
|
115
|
+
# rule('something_plus' => 'something_plus symbol')
|
116
|
+
def reduce_binary_plus_end(_production, _range, _tokens, theChildren)
|
117
|
+
operator = Name2special[theChildren[0].symbol.name].to_sym
|
118
|
+
operand2 = theChildren[1]
|
119
|
+
[[operator, operand2]]
|
120
|
+
end
|
121
|
+
|
122
|
+
#####################################
|
123
|
+
# SEMANTIC ACTIONS
|
124
|
+
#####################################
|
125
|
+
|
126
|
+
# rule('program' => 'EOF').as 'null_program'
|
127
|
+
def reduce_null_program(_production, _range, _tokens, _theChildren)
|
128
|
+
Ast::LoxNoopExpr.new(tokens[0].position)
|
129
|
+
end
|
130
|
+
|
131
|
+
# rule('program' => 'declaration_plus EOF').as ''
|
132
|
+
def reduce_lox_program(_production, range, tokens, theChildren)
|
133
|
+
return_first_child(range, tokens, theChildren) # Discard the semicolon
|
134
|
+
end
|
135
|
+
|
136
|
+
# rule('exprStmt' => 'expression SEMICOLON')
|
137
|
+
def reduce_exprStmt(_production, range, tokens, theChildren)
|
138
|
+
return_first_child(range, tokens, theChildren) # Discard the semicolon
|
139
|
+
end
|
140
|
+
|
141
|
+
# rule('printStmt' => 'PRINT expression SEMICOLON')
|
142
|
+
def reduce_print_stmt(_production, _range, tokens, theChildren)
|
143
|
+
Ast::LoxPrintStmt.new(tokens[1].position, theChildren[1])
|
144
|
+
end
|
145
|
+
|
146
|
+
# rule('logic_or' => 'logic_and disjunct_plus')
|
147
|
+
def reduce_logic_or_plus(production, range, tokens, theChildren)
|
148
|
+
reduce_binary_operator(production, range, tokens, theChildren)
|
149
|
+
end
|
150
|
+
|
151
|
+
# rule('disjunct_plus' => 'disjunct_plus OR logic_and')
|
152
|
+
def reduce_logic_or_plus_more(production, range, tokens, theChildren)
|
153
|
+
reduce_binary_plus_more(production, range, tokens, theChildren)
|
154
|
+
end
|
155
|
+
|
156
|
+
# rule('disjunct_plus' => 'OR logic_and')
|
157
|
+
def reduce_logic_or_plus_end(production, range, tokens, theChildren)
|
158
|
+
reduce_binary_plus_end(production, range, tokens, theChildren)
|
159
|
+
end
|
160
|
+
|
161
|
+
# rule('logic_and' => 'equality conjunct_plus')
|
162
|
+
def reduce_logic_and_plus(production, range, tokens, theChildren)
|
163
|
+
reduce_binary_operator(production, range, tokens, theChildren)
|
164
|
+
end
|
165
|
+
|
166
|
+
# rule('conjunct_plus' => 'conjunct_plus AND equality')
|
167
|
+
def reduce_logic_and_plus_more(production, range, tokens, theChildren)
|
168
|
+
reduce_binary_plus_more(production, range, tokens, theChildren)
|
169
|
+
end
|
170
|
+
|
171
|
+
# rule('conjunct_plus' => 'AND equality')
|
172
|
+
def reduce_logic_and_plus_end(production, range, tokens, theChildren)
|
173
|
+
reduce_binary_plus_end(production, range, tokens, theChildren)
|
174
|
+
end
|
175
|
+
|
176
|
+
# rule('equality' => 'comparison equalityTest_plus')
|
177
|
+
def reduce_equality_plus(production, range, tokens, theChildren)
|
178
|
+
reduce_binary_operator(production, range, tokens, theChildren)
|
179
|
+
end
|
180
|
+
|
181
|
+
# rule('equalityTest_plus' => 'equalityTest_plus equalityTest comparison')
|
182
|
+
def reduce_equality_t_plus_more(production, range, tokens, theChildren)
|
183
|
+
reduce_binary_plus_more(production, range, tokens, theChildren)
|
184
|
+
end
|
185
|
+
|
186
|
+
# rule('equalityTest_star' => 'equalityTest comparison')
|
187
|
+
def reduce_equality_t_plus_end(production, range, tokens, theChildren)
|
188
|
+
reduce_binary_plus_end(production, range, tokens, theChildren)
|
189
|
+
end
|
190
|
+
|
87
191
|
# rule('comparison' => 'term comparisonTest_plus')
|
88
192
|
def reduce_comparison_plus(production, range, tokens, theChildren)
|
89
193
|
reduce_binary_operator(production, range, tokens, theChildren)
|
@@ -93,16 +197,8 @@ module Loxxy
|
|
93
197
|
# TODO: is it meaningful to implement this rule?
|
94
198
|
|
95
199
|
# rule('comparisonTest_plus' => 'comparisonTest term')
|
96
|
-
def reduce_comparison_t_plus_end(
|
97
|
-
|
98
|
-
'GREATER' => '>',
|
99
|
-
'GREATER_EQUAL' => '>=',
|
100
|
-
'LESS' => '<',
|
101
|
-
'LESS_EQUAL' => '<='
|
102
|
-
}
|
103
|
-
operator = name2operators[theChildren[0].symbol.name].to_sym
|
104
|
-
operand2 = theChildren[1]
|
105
|
-
[[operator, operand2]]
|
200
|
+
def reduce_comparison_t_plus_end(production, range, tokens, theChildren)
|
201
|
+
reduce_binary_plus_end(production, range, tokens, theChildren)
|
106
202
|
end
|
107
203
|
|
108
204
|
# rule('term' => 'factor additive_plus')
|
@@ -111,18 +207,13 @@ module Loxxy
|
|
111
207
|
end
|
112
208
|
|
113
209
|
# rule('additive_star' => 'additive_star additionOp factor').as 'additionOp_expr'
|
114
|
-
def reduce_additive_plus_more(
|
115
|
-
|
116
|
-
operator = theChildren[1].symbol.name == 'MINUS' ? :- : :+
|
117
|
-
operand2 = theChildren[2]
|
118
|
-
result << [operator, operand2]
|
210
|
+
def reduce_additive_plus_more(production, range, tokens, theChildren)
|
211
|
+
reduce_binary_plus_more(production, range, tokens, theChildren)
|
119
212
|
end
|
120
213
|
|
121
214
|
# rule('additive_plus' => 'additionOp factor')
|
122
|
-
def reduce_additive_plus_end(
|
123
|
-
|
124
|
-
operand2 = theChildren[1]
|
125
|
-
[[operator, operand2]]
|
215
|
+
def reduce_additive_plus_end(production, range, tokens, theChildren)
|
216
|
+
reduce_binary_plus_end(production, range, tokens, theChildren)
|
126
217
|
end
|
127
218
|
|
128
219
|
# rule('factor' => 'multiplicative_plus')
|
@@ -131,18 +222,13 @@ module Loxxy
|
|
131
222
|
end
|
132
223
|
|
133
224
|
# rule('multiplicative_plus' => 'multiplicative_plus multOp unary')
|
134
|
-
def reduce_multiplicative_plus_more(
|
135
|
-
|
136
|
-
operator = theChildren[1].symbol.name == 'SLASH' ? :/ : :*
|
137
|
-
operand2 = theChildren[2]
|
138
|
-
result << [operator, operand2]
|
225
|
+
def reduce_multiplicative_plus_more(production, range, tokens, theChildren)
|
226
|
+
reduce_binary_plus_more(production, range, tokens, theChildren)
|
139
227
|
end
|
140
228
|
|
141
229
|
# rule('multiplicative_plus' => 'multOp unary')
|
142
|
-
def reduce_multiplicative_plus_end(
|
143
|
-
|
144
|
-
operand2 = theChildren[1]
|
145
|
-
[[operator, operand2]]
|
230
|
+
def reduce_multiplicative_plus_end(production, range, tokens, theChildren)
|
231
|
+
reduce_binary_plus_end(production, range, tokens, theChildren)
|
146
232
|
end
|
147
233
|
|
148
234
|
# rule('primary' => 'FALSE' | TRUE').as 'literal_expr'
|