loxxy 0.1.15 → 0.1.16

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c3994a3225b7dbc4a39d24cc646c20e4a7a19b074e85fe2dd9bc87d9ca1d61cb
4
- data.tar.gz: 965c328057f51fb7d13886255955e782e51b1f030f3053a6f5f6f4534962855b
3
+ metadata.gz: 60e57ef9264b4239571378ddcbefe044ff63192534ce94fc99b9a3b1c1813f02
4
+ data.tar.gz: 94c26f57455d0e267354f68655e86288dd00f5c322df3e4d1b6f5478cad0eb17
5
5
  SHA512:
6
- metadata.gz: 9db05948e45f7903ca71d7d0e3722f3c9b1fd3f50931e17b6bb1666c34cf03e1dc7f6cf32abee461dd6e6ec6824cd89b8ef5b2b56ae41fcd40068228d8cbaba2
7
- data.tar.gz: eaa762982bd89f2b4cb85e8d6831017e702b87501b7c29132f25f79fa592bf804ec95736f518d304f43caf814aa55eeadd5041ffcba1afa3aaaed631d23027af
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 before_var_stmt(aVarStmt)
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
- variable.assign(value)
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 # anEntry.i_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
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Loxxy
4
- VERSION = '0.1.15'
4
+ VERSION = '0.1.16'
5
5
  end
@@ -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
 
@@ -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.15
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-08 00:00:00.000000000 Z
11
+ date: 2021-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rley