loxxy 0.1.15 → 0.1.16
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 +9 -0
- data/lib/loxxy/back_end/engine.rb +2 -8
- data/lib/loxxy/back_end/symbol_table.rb +1 -18
- data/lib/loxxy/interpreter.rb +12 -1
- data/lib/loxxy/version.rb +1 -1
- data/spec/back_end/engine_spec.rb +0 -8
- data/spec/interpreter_spec.rb +42 -0
- 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: 60e57ef9264b4239571378ddcbefe044ff63192534ce94fc99b9a3b1c1813f02
|
4
|
+
data.tar.gz: 94c26f57455d0e267354f68655e86288dd00f5c322df3e4d1b6f5478cad0eb17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e5d6f864c1a340aecc7a362d8f2c311dc553869fc72b40d287736df2b62715eb208b2b299f1106dba5645dc4bb859f1d96fbfa79441c83c0e5faa223dd6642d
|
7
|
+
data.tar.gz: 452f9815e8812d9313c228697410a4c7433ec12c58269da305999f1de2822c89ad0b9a0f4e72865c333ddbee725b0ff102b4bc14ab4c51dcf7dba2784a08074a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## [0.1.16] - 2021-04-10
|
2
|
+
- Fixed an issue in name lookup. All the `this` test suite is passing.
|
3
|
+
|
4
|
+
### Changed
|
5
|
+
- Method `BackEnd::Engine#after_var_stmt` now it creates the variable and pouts it in the symbol table
|
6
|
+
|
7
|
+
### Removed
|
8
|
+
- Method `BackEnd::Engine#before_var_stmt` it generated bug when assigning a value to a var, when that var name occurred elsewhere
|
9
|
+
|
1
10
|
## [0.1.15] - 2021-04-08
|
2
11
|
- Fixed the `dangling else`by tweaking the grammar rules
|
3
12
|
|
@@ -82,18 +82,12 @@ module Loxxy
|
|
82
82
|
symbol_table.insert(new_var)
|
83
83
|
end
|
84
84
|
|
85
|
-
def
|
85
|
+
def after_var_stmt(aVarStmt)
|
86
86
|
new_var = Variable.new(aVarStmt.name, Datatype::Nil.instance)
|
87
87
|
symbol_table.insert(new_var)
|
88
|
-
end
|
89
|
-
|
90
|
-
def after_var_stmt(aVarStmt)
|
91
|
-
var_name = aVarStmt.name
|
92
|
-
variable = symbol_table.lookup(var_name)
|
93
|
-
raise StandardError, "Unknown variable #{var_name}" unless variable
|
94
88
|
|
95
89
|
value = stack.pop
|
96
|
-
|
90
|
+
new_var.assign(value)
|
97
91
|
end
|
98
92
|
|
99
93
|
def before_for_stmt(aForStmt)
|
@@ -85,7 +85,7 @@ module Loxxy
|
|
85
85
|
name2envs[name] = [current_env]
|
86
86
|
end
|
87
87
|
|
88
|
-
anEntry.name
|
88
|
+
anEntry.name
|
89
89
|
end
|
90
90
|
|
91
91
|
# Search for the object with the given name
|
@@ -99,23 +99,6 @@ module Loxxy
|
|
99
99
|
sc.defns[aName]
|
100
100
|
end
|
101
101
|
|
102
|
-
# Search for the object with the given i_name
|
103
|
-
# @param anIName [String]
|
104
|
-
# @return [BackEnd::Variable]
|
105
|
-
# def lookup_i_name(anIName)
|
106
|
-
# found = nil
|
107
|
-
# environment = current_env
|
108
|
-
|
109
|
-
# begin
|
110
|
-
# found = environment.defns.values.find { |e| e.i_name == anIName }
|
111
|
-
# break if found
|
112
|
-
|
113
|
-
# environment = environment.parent
|
114
|
-
# end while environment
|
115
|
-
|
116
|
-
# found
|
117
|
-
# end
|
118
|
-
|
119
102
|
# Return all variables defined in the current .. root chain.
|
120
103
|
# Variables are sorted top-down and left-to-right.
|
121
104
|
def all_variables
|
data/lib/loxxy/interpreter.rb
CHANGED
@@ -24,6 +24,15 @@ module Loxxy
|
|
24
24
|
# @param lox_input [String] Lox program to evaluate
|
25
25
|
# @return [Loxxy::Datatype::BuiltinDatatype]
|
26
26
|
def evaluate(lox_input)
|
27
|
+
raw_evaluate(lox_input).first
|
28
|
+
end
|
29
|
+
|
30
|
+
# Evaluate the given Lox program.
|
31
|
+
# Return the pair [result, a BackEnd::Engine instance]
|
32
|
+
# where result is the value of the last executed expression (if any)
|
33
|
+
# @param lox_input [String] Lox program to evaluate
|
34
|
+
# @return Loxxy::Datatype::BuiltinDatatype, Loxxy::BackEnd::Engine]
|
35
|
+
def raw_evaluate(lox_input)
|
27
36
|
# Front-end scans, parses the input and blurps an AST...
|
28
37
|
parser = FrontEnd::Parser.new
|
29
38
|
|
@@ -34,7 +43,9 @@ module Loxxy
|
|
34
43
|
# Back-end launches the tree walking & responds to visit events
|
35
44
|
# by executing the code determined by the visited AST node.
|
36
45
|
engine = BackEnd::Engine.new(config)
|
37
|
-
engine.execute(visitor)
|
46
|
+
result = engine.execute(visitor)
|
47
|
+
|
48
|
+
[result, engine]
|
38
49
|
end
|
39
50
|
end # class
|
40
51
|
end # module
|
data/lib/loxxy/version.rb
CHANGED
@@ -34,15 +34,7 @@ module Loxxy
|
|
34
34
|
let(:var_decl) { Ast::LoxVarStmt.new(sample_pos, 'greeting', greeting) }
|
35
35
|
let(:lit_expr) { Ast::LoxLiteralExpr.new(sample_pos, greeting) }
|
36
36
|
|
37
|
-
it "should react to 'before_var_stmt' event" do
|
38
|
-
expect { subject.before_var_stmt(var_decl) }.not_to raise_error
|
39
|
-
current_env = subject.symbol_table.current_env
|
40
|
-
expect(current_env.defns['greeting']).to be_kind_of(Variable)
|
41
|
-
end
|
42
|
-
|
43
37
|
it "should react to 'after_var_stmt' event" do
|
44
|
-
# Precondition: `before_var_stmt` is called...
|
45
|
-
expect { subject.before_var_stmt(var_decl) }.not_to raise_error
|
46
38
|
# Precondition: value to assign is on top of stack
|
47
39
|
subject.stack.push(greeting)
|
48
40
|
|
data/spec/interpreter_spec.rb
CHANGED
@@ -525,6 +525,48 @@ LOX_END
|
|
525
525
|
expect { subject.evaluate(program) }.not_to raise_error
|
526
526
|
expect(sample_cfg[:ostream].string).to eq('Egotist instance')
|
527
527
|
end
|
528
|
+
|
529
|
+
it 'should support a closure nested in a method' do
|
530
|
+
lox_snippet = <<-LOX_END
|
531
|
+
class Foo {
|
532
|
+
getClosure() {
|
533
|
+
fun closure() {
|
534
|
+
return this.toString();
|
535
|
+
}
|
536
|
+
return closure;
|
537
|
+
}
|
538
|
+
|
539
|
+
toString() { return "foo"; }
|
540
|
+
}
|
541
|
+
|
542
|
+
var closure = Foo().getClosure();
|
543
|
+
closure;
|
544
|
+
LOX_END
|
545
|
+
# Expected result: Backend::LoxFunction('closure')
|
546
|
+
# Expected function's closure ()environment layout):
|
547
|
+
# Environment('global')
|
548
|
+
# defns
|
549
|
+
# +- ['clock'] => BackEnd::Engine::NativeFunction
|
550
|
+
# *- ['Foo'] => BackEnd::LoxClass
|
551
|
+
# Environment
|
552
|
+
# defns
|
553
|
+
# ['this'] => BackEnd::LoxInstance
|
554
|
+
# Environment
|
555
|
+
# defns
|
556
|
+
# +- ['closure'] => Backend::LoxFunction
|
557
|
+
result = subject.evaluate(lox_snippet)
|
558
|
+
expect(result).to be_kind_of(BackEnd::LoxFunction)
|
559
|
+
expect(result.name).to eq('closure')
|
560
|
+
closure = result.closure
|
561
|
+
expect(closure).to be_kind_of(Loxxy::BackEnd::Environment)
|
562
|
+
expect(closure.defns['closure'].value).to eq(result)
|
563
|
+
expect(closure.enclosing).to be_kind_of(Loxxy::BackEnd::Environment)
|
564
|
+
expect(closure.enclosing.defns['this'].value).to be_kind_of(Loxxy::BackEnd::LoxInstance)
|
565
|
+
global_env = closure.enclosing.enclosing
|
566
|
+
expect(global_env).to be_kind_of(Loxxy::BackEnd::Environment)
|
567
|
+
expect(global_env.defns['clock'].value).to be_kind_of(BackEnd::Engine::NativeFunction)
|
568
|
+
expect(global_env.defns['Foo'].value).to be_kind_of(BackEnd::LoxClass)
|
569
|
+
end
|
528
570
|
end # context
|
529
571
|
end # describe
|
530
572
|
# rubocop: enable Metrics/BlockLength
|
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.1.
|
4
|
+
version: 0.1.16
|
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-04-
|
11
|
+
date: 2021-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|