loxxy 0.2.06 → 0.3.00
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 +7 -0
- data/README.md +6 -0
- data/lib/loxxy/back_end/resolver.rb +10 -8
- data/lib/loxxy/version.rb +1 -1
- data/spec/back_end/environment_spec.rb +0 -14
- data/spec/back_end/symbol_table_spec.rb +0 -19
- data/spec/back_end/variable_spec.rb +0 -35
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 231fc227cc66ebd0b4f47a00f9fe7260146d70e64cea3581df6cfc5c71937bef
|
4
|
+
data.tar.gz: cd8117dc8ae9b631ad0d7bef34ee972bdcaa8c758045637bae2f3ea0ed25bb79
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca714bbd5fa4fcbae67548cdae0d8c43236b02f30adc45e939c0e1dcd3e6694471ea429f902d5e1a7335d4a4cf9779d167a9387b0f4f0732325bd31237630e8d
|
7
|
+
data.tar.gz: '008526b6d9a2e9f5cf27a68f796e53aa5312d67523a53d8c8682cf944ee6cd990adf3928a3af7fb66e056bca4fc6e45fc11119ffcab1dda4d41fb2ca1c1207be'
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## [0.3.00] - 2021-05-07
|
2
|
+
- Milestone: `Loxxy` passes all reference test suite.
|
3
|
+
|
4
|
+
### Fixed
|
5
|
+
- Method `BackEdn::Resolver#before_variable_expr`: Standard `Lox` allows re-declaration of a variable at top-level scope
|
6
|
+
|
7
|
+
|
1
8
|
## [0.2.06] - 2021-05-04
|
2
9
|
- Nearly passing the 'official' test suite, fixing non-compliant behavior, specialized exceptions for errors
|
3
10
|
|
data/README.md
CHANGED
@@ -19,11 +19,17 @@ Although __Lox__ is fairly simple, it is far from being a toy language:
|
|
19
19
|
### Loxxy gem features
|
20
20
|
- Complete tree-walking interpreter including lexer, parser and resolver
|
21
21
|
- 100% pure Ruby with clean design (not a port from some other language)
|
22
|
+
- Passes the `jox` (THE reference `Lox` implementation) test suite
|
22
23
|
- Minimal runtime dependency (Rley gem). Won't drag a bunch of gems...
|
23
24
|
- Ruby API for integrating a Lox interpreter with your code.
|
24
25
|
- A command-line interpreter `loxxy`
|
25
26
|
- Open for your language extensions...
|
26
27
|
|
28
|
+
### Why `Loxxy` ?
|
29
|
+
- If programming languages are one of your subject interest...
|
30
|
+
- ... and you wanted learn how to implement one in Ruby...
|
31
|
+
- ... then `Loxxy` can help to understand and experiment in this rewarding craft.
|
32
|
+
|
27
33
|
## How to start in 1, 2, 3...?
|
28
34
|
... in less than 3 minutes...
|
29
35
|
|
@@ -117,6 +117,9 @@ module Loxxy
|
|
117
117
|
|
118
118
|
# A variable declaration adds a new variable to current scope
|
119
119
|
def before_var_stmt(aVarStmt)
|
120
|
+
# Oddly enough, Lox allows the re-definition of a variable at top-level scope
|
121
|
+
return if scopes.size == 1 && scopes.last[aVarStmt.name]
|
122
|
+
|
120
123
|
declare(aVarStmt.name)
|
121
124
|
end
|
122
125
|
|
@@ -138,7 +141,7 @@ module Loxxy
|
|
138
141
|
def before_variable_expr(aVarExpr)
|
139
142
|
var_name = aVarExpr.name
|
140
143
|
if !scopes.empty? && (scopes.last[var_name] == false)
|
141
|
-
raise
|
144
|
+
raise Loxxy::RuntimeError, "Can't read variable #{var_name} in its own initializer"
|
142
145
|
end
|
143
146
|
end
|
144
147
|
|
@@ -205,19 +208,18 @@ module Loxxy
|
|
205
208
|
scopes.pop
|
206
209
|
end
|
207
210
|
|
208
|
-
# rubocop: disable Style/SoleNestedConditional
|
209
211
|
def declare(aVarName)
|
210
212
|
return if scopes.empty?
|
211
213
|
|
212
214
|
curr_scope = scopes.last
|
213
|
-
if scopes.size > 1 # Not at top-level?
|
214
215
|
# Oddly enough, Lox allows variable re-declaration at top-level
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
216
|
+
if curr_scope.include?(aVarName)
|
217
|
+
msg = "Error at '#{aVarName}': Already variable with this name in this scope."
|
218
|
+
raise Loxxy::RuntimeError, msg
|
219
|
+
elsif curr_scope.size == 255 && current_function != :none
|
220
|
+
msg = "Error at '#{aVarName}': Too many local variables in function."
|
221
|
+
raise Loxxy::RuntimeError, msg
|
219
222
|
end
|
220
|
-
# rubocop: enable Style/SoleNestedConditional
|
221
223
|
|
222
224
|
# The initializer is not yet processed.
|
223
225
|
# Mark the variable as 'not yet ready' = exists but may not be referenced yet
|
data/lib/loxxy/version.rb
CHANGED
@@ -54,20 +54,6 @@ module Loxxy
|
|
54
54
|
expect(var_b).to be_kind_of(Variable)
|
55
55
|
expect(var_b.name).to eq('b')
|
56
56
|
end
|
57
|
-
|
58
|
-
# it 'should set the suffix of just created variable' do
|
59
|
-
# subject.insert(var('a'))
|
60
|
-
# var_a = subject.defns['a']
|
61
|
-
# expect(var_a.suffix).to eq("_#{subject.object_id.to_s(16)}")
|
62
|
-
# end
|
63
|
-
|
64
|
-
# it 'should complain when variable names collide' do
|
65
|
-
# subject.insert(var('c'))
|
66
|
-
# expect(subject.defns['c']).to be_kind_of(Datatype::Variable)
|
67
|
-
# err = StandardError
|
68
|
-
# err_msg = "Variable with name 'c' already exists."
|
69
|
-
# expect { subject.insert(var('c')) }.to raise_error(err, err_msg)
|
70
|
-
# end
|
71
57
|
end # context
|
72
58
|
end # describe
|
73
59
|
end # module
|
@@ -106,25 +106,6 @@ module Loxxy
|
|
106
106
|
expect(subject.lookup('q')).to eq(subject.current_env.defns['q'])
|
107
107
|
end
|
108
108
|
|
109
|
-
# it 'should allow the search of an entry based on its i_name' do
|
110
|
-
# subject.insert(var('q'))
|
111
|
-
# i_name_x = subject.insert(var('x'))
|
112
|
-
# subject.enter_environment(BackEnd::Environment.new)
|
113
|
-
# i_name_q2 = subject.insert(var('q'))
|
114
|
-
# i_name_y = subject.insert(var('y'))
|
115
|
-
|
116
|
-
# # Search for unknown i_name
|
117
|
-
# expect(subject.lookup_i_name('dummy')).to be_nil
|
118
|
-
|
119
|
-
# curr_scope = subject.current_env
|
120
|
-
# # # Search for existing unique names
|
121
|
-
# expect(subject.lookup_i_name(i_name_y)).to eq(curr_scope.defns['y'])
|
122
|
-
# expect(subject.lookup_i_name(i_name_x)).to eq(subject.root.defns['x'])
|
123
|
-
|
124
|
-
# # Search for redefined name
|
125
|
-
# expect(subject.lookup_i_name(i_name_q2)).to eq(curr_scope.defns['q'])
|
126
|
-
# end
|
127
|
-
|
128
109
|
it 'should list all the variables defined in all the szcope chain' do
|
129
110
|
subject.insert(var('q'))
|
130
111
|
subject.enter_environment(BackEnd::Environment.new)
|
@@ -38,41 +38,6 @@ module Loxxy
|
|
38
38
|
instance = Variable.new(sample_name)
|
39
39
|
expect(instance.value).to eq(Datatype::Nil.instance)
|
40
40
|
end
|
41
|
-
|
42
|
-
# it 'should know its default internal name' do
|
43
|
-
# # By default: internal name == label
|
44
|
-
# expect(subject.i_name).to eq(subject.label)
|
45
|
-
# end
|
46
|
-
|
47
|
-
# it 'should have a nil suffix' do
|
48
|
-
# expect(subject.suffix).to be_nil
|
49
|
-
# end
|
50
|
-
end # context
|
51
|
-
|
52
|
-
context 'Provided service:' do
|
53
|
-
let(:sample_suffix) { 'sample-suffix' }
|
54
|
-
it 'should have a label equal to its user-defined name' do
|
55
|
-
# expect(subject.label).to eq(subject.name)
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'should accept a suffix' do
|
59
|
-
# expect { subject.suffix = sample_suffix }.not_to raise_error
|
60
|
-
# expect(subject.suffix).to eq(sample_suffix)
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'should calculate its internal name' do
|
64
|
-
# # Rule: empty suffix => internal name == label
|
65
|
-
# subject.suffix = ''
|
66
|
-
# expect(subject.i_name).to eq(subject.label)
|
67
|
-
|
68
|
-
# # Rule: suffix starting underscore: internal name = label + suffix
|
69
|
-
# subject.suffix = '_10'
|
70
|
-
# expect(subject.i_name).to eq(subject.label + subject.suffix)
|
71
|
-
|
72
|
-
# # Rule: ... otherwise: internal name == suffix
|
73
|
-
# subject.suffix = sample_suffix
|
74
|
-
# expect(subject.i_name).to eq(subject.suffix)
|
75
|
-
end
|
76
41
|
end # context
|
77
42
|
end # describe
|
78
43
|
end # module
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: loxxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.00
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-05-
|
11
|
+
date: 2021-05-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|