loxxy 0.1.15 → 0.2.02

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c3994a3225b7dbc4a39d24cc646c20e4a7a19b074e85fe2dd9bc87d9ca1d61cb
4
- data.tar.gz: 965c328057f51fb7d13886255955e782e51b1f030f3053a6f5f6f4534962855b
3
+ metadata.gz: afc822710c5023cdffd8eeb9e9316736f2b2d9ddb2d05e4c4e835dee9b9b4d8b
4
+ data.tar.gz: 5debd7264833555cc34c64586de96d4e811eef4ebebe25f6c42a0832dee8e433
5
5
  SHA512:
6
- metadata.gz: 9db05948e45f7903ca71d7d0e3722f3c9b1fd3f50931e17b6bb1666c34cf03e1dc7f6cf32abee461dd6e6ec6824cd89b8ef5b2b56ae41fcd40068228d8cbaba2
7
- data.tar.gz: eaa762982bd89f2b4cb85e8d6831017e702b87501b7c29132f25f79fa592bf804ec95736f518d304f43caf814aa55eeadd5041ffcba1afa3aaaed631d23027af
6
+ metadata.gz: d988772978387faa28692101e6b2dab580a93b6f5738ad9094faf22d8aed78aca68123982ff0a25d9b9029d4d27ef4f82788009b10942a14ce5dd9bd9f1e37a7
7
+ data.tar.gz: 711b3188b0dd14a9821eee5227ee0d574c60144b7be88a3f722d10b4506556fa864685659c7493acfd6d63c2cf82f8c0c6c36cc0431a57a2d476efe3b4bf7efd
data/.rubocop.yml CHANGED
@@ -3,6 +3,9 @@ AllCops:
3
3
  - 'exp/**/*'
4
4
  - 'demo/**/*'
5
5
 
6
+ Gemspec/DateAssignment:
7
+ Enabled: true
8
+
6
9
  Layout/ArgumentAlignment:
7
10
  Enabled: false
8
11
 
@@ -34,7 +37,7 @@ Layout/EndOfLine:
34
37
 
35
38
  Layout/FirstArgumentIndentation:
36
39
  Enabled: false
37
-
40
+
38
41
  Layout/HashAlignment:
39
42
  Enabled: false
40
43
 
@@ -56,7 +59,7 @@ Layout/MultilineMethodCallBraceLayout:
56
59
 
57
60
  Layout/SpaceAroundOperators:
58
61
  Enabled: true
59
-
62
+
60
63
  Layout/SpaceBeforeBrackets:
61
64
  Enabled: true
62
65
 
@@ -74,10 +77,13 @@ Layout/TrailingEmptyLines:
74
77
 
75
78
  Layout/TrailingWhitespace:
76
79
  Enabled: true
77
-
80
+
78
81
  Lint/AmbiguousAssignment:
79
82
  Enabled: true
80
83
 
84
+ Lint/DeprecatedConstants:
85
+ Enabled: true
86
+
81
87
  Lint/DuplicateBranch:
82
88
  Enabled: true
83
89
 
@@ -90,24 +96,42 @@ Lint/EmptyBlock:
90
96
  Lint/EmptyClass:
91
97
  Enabled: false
92
98
 
99
+ Lint/LambdaWithoutLiteralBlock:
100
+ Enabled: true
101
+
93
102
  Lint/Loop:
94
103
  Enabled: true
95
104
 
96
105
  Lint/NoReturnInBeginEndBlocks:
97
106
  Enabled: true
98
107
 
108
+ Lint/NumberedParameterAssignment:
109
+ Enabled: true
110
+
111
+ Lint/OrAssignmentToConstant:
112
+ Enabled: true
113
+
99
114
  Lint/RaiseException:
100
115
  Enabled: true
101
116
 
117
+ Lint/RedundantDirGlobSort:
118
+ Enabled: true
119
+
102
120
  Lint/RescueException:
103
121
  Enabled: true
104
122
 
105
123
  Lint/StructNewOverride:
106
124
  Enabled: true
107
125
 
126
+ Lint/SymbolConversion:
127
+ Enabled: true
128
+
108
129
  Lint/ToEnumArguments:
109
130
  Enabled: true
110
131
 
132
+ Lint/TripleQuotes:
133
+ Enabled: true
134
+
111
135
  Lint/UnexpectedBlockArity:
112
136
  Enabled: true
113
137
 
@@ -170,7 +194,7 @@ Naming/BlockParameterName:
170
194
 
171
195
  Naming/MethodParameterName:
172
196
  Enabled: false
173
-
197
+
174
198
  Naming/MethodName:
175
199
  Enabled: false
176
200
 
@@ -200,7 +224,7 @@ Style/ClassCheck:
200
224
 
201
225
  Style/ClassVars:
202
226
  Enabled: false
203
-
227
+
204
228
  Style/CollectionCompact:
205
229
  Enabled: true
206
230
 
@@ -221,7 +245,7 @@ Style/DefWithParentheses:
221
245
 
222
246
  Style/Documentation:
223
247
  Enabled: false
224
-
248
+
225
249
  Style/DocumentDynamicEvalDefinition:
226
250
  Enabled: true
227
251
 
@@ -236,7 +260,7 @@ Style/GuardClause:
236
260
 
237
261
  Style/HashEachMethods:
238
262
  Enabled: true
239
-
263
+
240
264
  Style/HashExcept:
241
265
  Enabled: true
242
266
 
@@ -254,13 +278,13 @@ Style/InverseMethods:
254
278
 
255
279
  Style/MissingRespondToMissing:
256
280
  Enabled: false
257
-
281
+
258
282
  Style/NegatedIfElseCondition:
259
283
  Enabled: true
260
284
 
261
285
  Style/Next:
262
286
  Enabled: false
263
-
287
+
264
288
  Style/NilLambda:
265
289
  Enabled: true
266
290
 
@@ -269,7 +293,7 @@ Style/NumericLiterals:
269
293
 
270
294
  Style/RaiseArgs:
271
295
  Enabled: true
272
-
296
+
273
297
  Style/RedundantArgument:
274
298
  Enabled: true
275
299
 
@@ -290,7 +314,7 @@ Style/StderrPuts:
290
314
 
291
315
  Style/StringLiterals:
292
316
  Enabled: true
293
-
317
+
294
318
  Style/SwapValues:
295
319
  Enabled: true
296
320
 
@@ -352,6 +376,9 @@ Style/BisectedAttrAccessor:
352
376
  Style/CaseLikeIf:
353
377
  Enabled: true
354
378
 
379
+ Style/EndlessMethod:
380
+ Enabled: true
381
+
355
382
  Style/ExplicitBlockArgument:
356
383
  Enabled: true
357
384
 
@@ -361,9 +388,15 @@ Style/GlobalStdStream:
361
388
  Style/HashAsLastArrayItem:
362
389
  Enabled: true
363
390
 
391
+ Style/HashConversion:
392
+ Enabled: true
393
+
364
394
  Style/HashLikeCase:
365
395
  Enabled: true
366
396
 
397
+ Style/IfWithBooleanLiteralBranches:
398
+ Enabled: true
399
+
367
400
  Style/OptionalBooleanParameter:
368
401
  Enabled: true
369
402
 
@@ -388,5 +421,8 @@ Style/SingleArgumentDig:
388
421
  Style/SlicingWithRange:
389
422
  Enabled: true
390
423
 
424
+ Style/StringChars:
425
+ Enabled: true
426
+
391
427
  Style/StringConcatenation:
392
428
  Enabled: true
data/CHANGELOG.md CHANGED
@@ -1,3 +1,69 @@
1
+ ## [0.2.02] - 2021-04-21
2
+ - Improvements in the scanner class (escape sequence for quotes and newlines), error messages closer to jlox.
3
+
4
+ ### Changed
5
+ - File `loxxy` executable doesn't show a stack trace for scanner errors
6
+ - Class `ScannerError` is now a subclass of `Loxxy::Error`
7
+ - Class `Scanner` now returns a specific error message for unterminated strings
8
+ - Class `Scanner` error messages are closer to the ones from jlox
9
+ - Class `Scanner` supports now escape sequences \" for double quotes, \n for newlines
10
+ - File `README.md` Reshuffled some text
11
+
12
+ ## [0.2.01] - 2021-04-18
13
+ - Minor improvements in CLI, starting re-documenting `README.md`.
14
+
15
+ ### New
16
+ - Class `Loxxy::CLIParser` parser for the command-line options
17
+
18
+ ### Changed
19
+ - File `loxxy` executable now uses commad-line parsing
20
+ - File `.rubocop.yml` updated with new cops
21
+ - File `README.md` Added examples for command-line interface
22
+ - File `loxxy.gemspec` expanded description of gem
23
+
24
+ ## [0.2.00] - 2021-04-17
25
+ - `Loxxy` implements the complete `Lox` language including its object-oriented features.
26
+
27
+ ### New
28
+ - Class `Ast::LoxSuperExpr` an AST node that represents the occurrence of `super` in source code.
29
+ - Method `Ast::ASTBuilder#reduce_class_subclassing` action launched by the parser when detecting inheritance
30
+ - Method `Ast::ASTBuilder#reduce_super_expr` action launched by the parser when detecting the super keyword
31
+ - Method `Ast::Visitor#visit_super_expr` visit of an `Ast::LoxSuperExpr` node
32
+ - Method `BackEnd::Engine#after_super_stmt` does the lookup of an inherited method.
33
+ - Method `BackEnd::Resolver#after_super_stmt` checks for correct context for super occurrence
34
+
35
+
36
+ ### Changed
37
+ - Method `Ast::ASTBuilder#reduce_class_decl` expanded in order to support superclass
38
+ - Class `Ast::LoxClassStmt` added `superclass` attribute, expanded constructor signature.
39
+ - Method `BackEnd::Engine#after_class_stmt` adds an environment for super variable.
40
+ - Class `BackEnd::LoxClass` added `superclass` attribute, expanded constructor signature.
41
+ - Method `BackEnd::LoxClass#find_method` now does the lookup in superclass(es)
42
+ - Method `BackEnd::Resolver#after_class_stmt` super variable resolution
43
+ - File `grammar.rb` changed rules to cope with superclass name and super keyword
44
+ - File `README.md` updated to reflect current implementation level
45
+
46
+ ## [0.1.17] - 2021-04-11
47
+ - `Loxxy` now support custom initializer.
48
+
49
+ ### Changed
50
+ - Method `BackEnd::Class#call` updated for custom initializer.
51
+ - Class `BackEnd::LoxFunction` added an attribute `is_initializer`
52
+ - Class `BackEnd::Resolver#before_return_stmt` added a check that return in initializer may not return a value
53
+
54
+ ### Fixed
55
+ - Method `BackEnd::Engine#after_call_expr` now does arity checking also for initalizer.
56
+ - Method `BackEnd::LoxInstance#set` removed the check of field existence that prevented the creation of ... fields
57
+
58
+ ## [0.1.16] - 2021-04-10
59
+ - Fixed an issue in name lookup. All the `this` test suite is passing.
60
+
61
+ ### Changed
62
+ - Method `BackEnd::Engine#after_var_stmt` now it creates the variable and pouts it in the symbol table
63
+
64
+ ### Removed
65
+ - Method `BackEnd::Engine#before_var_stmt` it generated bug when assigning a value to a var, when that var name occurred elsewhere
66
+
1
67
  ## [0.1.15] - 2021-04-08
2
68
  - Fixed the `dangling else`by tweaking the grammar rules
3
69
 
data/README.md CHANGED
@@ -1,59 +1,202 @@
1
1
  # loxxy
2
2
  [![Gem Version](https://badge.fury.io/rb/loxxy.svg)](https://badge.fury.io/rb/loxxy)
3
+ [![Build status](https://ci.appveyor.com/api/projects/status/8e5p7dgjanm0qjkp?svg=true)](https://ci.appveyor.com/project/famished-tiger/loxxy)
3
4
  [![License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://github.com/famished-tiger/loxxy/blob/main/LICENSE.txt)
4
5
 
5
- ### What is loxxy?
6
+ ## What is loxxy?
6
7
  A Ruby implementation of the [Lox programming language](https://craftinginterpreters.com/the-lox-language.html ),
7
- a simple language defined in Bob Nystrom's online book [Crafting Interpreters](https://craftinginterpreters.com/ ).
8
+ a simple language defined in Bob Nystrom's excellent online book [Crafting Interpreters](https://craftinginterpreters.com/ ).
8
9
 
9
- ### Purpose of this project:
10
- - To deliver an open source example of a programming language fully implemented in Ruby
11
- (from the scanner and parser to an interpreter).
12
- - The implementation should be mature enough to run [LoxLox](https://github.com/benhoyt/loxlox),
13
- a Lox interpreter written in Lox.
10
+ Although __Lox__ is fairly simple, it is far from being a toy language:
11
+ - Dynamically typed,
12
+ - Provides data types such as booleans, number, strings,
13
+ - Supports arithmetic operations (+, -, *, / ) and comparison ( >, >= , <, <=)
14
+ - Implements equality operators (==, !=) and the logical connectors `and` and `or`.
15
+ - Control flow statements `if`, `for` and `while`
16
+ - Functions and closures
17
+ - Object-orientation (classes, methods, inheritance).
18
+
19
+ ### Loxxy gem features
20
+ - Complete tree-walking interpreter including lexer, parser and resolver
21
+ - 100% pure Ruby with clean design (not a port from some other language)
22
+ - Minimal runtime dependency (Rley gem). Won't drag a bunch of gems...
23
+ - Ruby API for integrating a Lox interpreter with your code.
24
+ - A command-line interpreter `loxxy`
25
+ - Open for your language extensions
26
+
27
+ ## How to start in 1, 2, 3...?
28
+ ... in less than 3 minutes...
29
+
30
+ ### 1. Installing
31
+ Install __Loxxy__ as a gem:
32
+
33
+
34
+ $ gem install loxxy
35
+
36
+ ### 2. Your first `Lox` program
37
+ Create a text file and enter the following lines:
38
+ ```javascript
39
+ // Your firs Lox program
40
+ print "Hello, world.";
41
+ ```
42
+
43
+ ### 3. Running your program...
44
+ Assuming that you named the file `hello.lox`, launch the `Loxxy` interpreter in same directory:
45
+
46
+ $ loxxy hello.lox
47
+
48
+ Lo and behold! The output device displays the famous greeting:
49
+
50
+ Hello, world.
51
+
52
+
53
+ Congrats! You ran your first `Lox` program thanks __Loxxy__ gem.
54
+ For a less superficial encounter with the language jump to the next section.
55
+
56
+ ## So you want something beefier?...
57
+ Let's admit it, the hello world example was unimpressive.
58
+ To a get a taste of `Lox` object-oriented capabilities, let's try another `Hello world` variant:
59
+
60
+ ```javascript
61
+ // Object-oriented hello world
62
+ class Greeter {
63
+ // in Lox, initializers/constructors are named `init`
64
+ init(who) {
65
+ this.interjection = "Hello";
66
+ this.subject = who;
67
+ }
68
+
69
+ greeting() {
70
+ this.interjection + ", " + this.subject + ".";
71
+ }
72
+ }
73
+
74
+ var greeter = Greeter("world"); // an instance is created here...
75
+ print greeter.greeting();
76
+ ```
77
+
78
+ Running this version will result in the same famous greeting.
79
+
80
+ Our next assignment: compute the first 20 elements of the Fibbonacci sequence.
81
+ Here's an answer using the `while` loop construct:
82
+
83
+ ```javascript
84
+ // Compute the first 20 elements from the Fibbonacci sequence
85
+
86
+ var a = 0; // Use the var keyword to declare a new variable
87
+ var b = 1;
88
+ var count = 20;
89
+
90
+ while (count > 0) {
91
+ print a;
92
+ print " ";
93
+ var tmp = a;
94
+ a = b;
95
+ b = tmp + b;
96
+ count = count - 1;
97
+ }
98
+ ```
99
+
100
+ Assuming, that this source code was put in a file named `fibbonacci.lox`, then
101
+ the command line
102
+
103
+ $ loxxy fibbonacci.lox
104
+
105
+ Results in:
14
106
 
15
- ### Current status
16
- The interpreter currently can execute all allowed __Lox__ expressions and statements except
17
- object-oriented feaures (classes and objects).
18
- The goal is to implement these missing features in Q2 2021.
107
+ 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
108
+
109
+ Fans of `for` loops will be pleased to find their favorite looping construct.
110
+ Here again, the Fibbonacci sequence refactored with a `for` loop:
19
111
 
112
+ ```javascript
113
+ // Fibbonacci sequence - version 2
114
+ var a = 0;
115
+ var b = 1;
116
+ var count = 20;
117
+
118
+ for (var i = 0; i < count; i = i + 1) {
119
+ print a;
120
+ print " ";
121
+ var tmp = a;
122
+ a = b;
123
+ b = tmp + b;
124
+ }
125
+ ```
126
+ Lets's call this file `fibbonacci_v2.lox` and execute it thanks `loxxy` CLI:
127
+
128
+ $ loxxy fibbonacci_v2.lox
129
+
130
+ We see again the same sequence:
131
+
132
+ 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
133
+
134
+ To complete our quick tour of `Lox` language, let's calculate the sequence with a recursive function:
135
+
136
+ ```javascript
137
+ // Fibbonacci sequence - version 3
138
+ var count = 20;
139
+
140
+ // Let's define a recursive function
141
+ fun fib(n) {
142
+ if (n < 2) return n;
143
+ return fib(n - 1) + fib(n - 2);
144
+ }
145
+
146
+ // For demo purposes, let's assign the function to a variable
147
+ var fib_fun = fib;
148
+
149
+ for (var i = 0; i < count; i = i + 1) {
150
+ print fib_fun(i);
151
+ print " ";
152
+ }
153
+ ```
154
+
155
+ This completes our quick tour of `Lox`, to learn more about the language,
156
+ check the online book [Crafting Interpreters](https://craftinginterpreters.com/ )
20
157
 
21
158
  ## What's the fuss about Lox?
22
159
  ... Nothing...
23
- Bob Nystrom designed a language __simple__ enough so that he could present
160
+ Bob Nystrom designed a language __simple__ enough so that he could present
24
161
  two implementations (an interpreter, then a compiler) in one single book.
25
162
 
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).
163
+ In other words, __Lox__ contains interesting features found in most general-purpose
164
+ languages. In addition to that, there are [numerous implementations](https://github.com/munificent/craftinginterpreters/wiki/Lox-implementations) in different languages
34
165
 
35
- In other words, __Lox__ contains interesting features found in most general-purpose
36
- languages.
166
+ Lox interpreters, like `Loxxy` give the unique opportunity for the curious to learn the internals of reasonably-sized language.
37
167
 
38
168
  ### What's missing in Lox?
39
- __Lox__ was constrained by design and was therefore 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)
169
+ While `Lox` blends interesting features from the two mainstream paradigms (OO and functional),
170
+ it doesn't pretend to be used in real-life projects.
45
171
 
46
- Also a decent standard library for IO, networking,... is lacking.
172
+ In fact, the language was designed to be simple to implement at the expense of missing advanced features.
173
+ Here are features I'll like to put on my wish list:
174
+ - Collection classes (e.g. Arrays, Maps (Hash))
175
+ - Modules
176
+ - Standard library
177
+ - Concurrency / parallelism constructs
47
178
 
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.
179
+ That `Lox` cannot be compared to a full-featured language, is both a drawback and and an opportunity.
180
+ Indeed, an open-source language that misses some features is an invitation for the curious to tinker and experiment with extensions.
181
+ There are already a number of programming languages derived from `Lox`...
50
182
 
51
- That's already fun... and if all this gives you the inspiration for creating your own
52
- language, that might be even funnier...
183
+ ## Why `Loxxy`? What's in it for me?...
53
184
 
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)
185
+ ### Purpose of this project:
186
+ - To deliver an open source example of a programming language fully implemented in Ruby
187
+ (from the scanner and parser to an interpreter).
188
+ - The implementation should be mature enough to run [LoxLox](https://github.com/benhoyt/loxlox),
189
+ a Lox interpreter written in Lox.
190
+
191
+ ### Roadmap
192
+ - Extend the test suite
193
+ - Improve the error handling
194
+ - Improve the documentation
195
+ - Ability run the LoxLox interpreter
55
196
 
56
197
  ## Hello world example
198
+ The next examples show how to use the interpreter directly from Ruby code.
199
+
57
200
  ```ruby
58
201
  require 'loxxy'
59
202
 
@@ -108,48 +251,10 @@ lox_input = <<-LOX_END
108
251
  print "Hello, world!";
109
252
  LOX_END
110
253
 
111
- # Show that the raw parser accepts the above program
112
- base_parser = Loxxy::FrontEnd::RawParser.new
113
254
 
114
- # Now parse the input into a concrete parse tree...
115
- ptree = base_parser.parse(lox_input)
116
-
117
- # Display the parse tree thanks to Rley formatters...
118
- visitor = Rley::ParseTreeVisitor.new(ptree)
119
- tree_formatter = Rley::Formatter::Asciitree.new($stdout)
120
- tree_formatter.render(visitor)
121
- ```
122
-
123
- This is the output produced by the above example:
124
- ```
125
- program
126
- +-- declaration_plus
127
- | +-- declaration
128
- | +-- statement
129
- | +-- printStmt
130
- | +-- PRINT: 'print'
131
- | +-- expression
132
- | | +-- assignment
133
- | | +-- logic_or
134
- | | +-- logic_and
135
- | | +-- equality
136
- | | +-- comparison
137
- | | +-- term
138
- | | +-- factor
139
- | | +-- unary
140
- | | +-- call
141
- | | +-- primary
142
- | | +-- STRING: '"Hello, world!"'
143
- | +-- SEMICOLON: ';'
144
- +-- EOF: ''
145
- ```
146
255
 
147
256
  ## Suppported Lox language features
148
- On one hand, the parser covers the complete Lox grammar and should therefore, in principle,
149
- parse any valid Lox program.
150
257
 
151
- On the other hand, the interpreter is under development and currently it can evaluate only a subset of __Lox__.
152
- But the situation is changing almost daily, stay tuned...
153
258
 
154
259
  Here are the language features currently supported by the interpreter:
155
260
 
@@ -377,25 +482,7 @@ fun add4(n) // `add4` will be the name of the function
377
482
  print add4(6); // output: 10
378
483
  ```
379
484
 
380
- ## Installation
381
-
382
- Add this line to your application's Gemfile:
383
-
384
- ```ruby
385
- gem 'loxxy'
386
- ```
387
-
388
- And then execute:
389
-
390
- $ bundle install
391
-
392
- Or install it yourself as:
393
-
394
- $ gem install loxxy
395
-
396
- ## Usage
397
485
 
398
- TODO: Write usage instructions here
399
486
 
400
487
  ## Other Lox implementations in Ruby
401
488