require "dyn"
describe SymTable do
-# subject {
-# symtab = SymTable.new
-# symtab[:a] = {}
-# symtab
-# }
-
-# context ".clone" do
-# if "keeps a reference to the parent environment when cloned" do
-# symtab = SymTable.new("foo")
-# expect(symtab.instance_variable_get(:@parent)).to eq "foo"
-# end
-# end
+ subject {
+ symtab1 = SymTable.new
+ symtab1[:a] = {}
+ symtab1[:d] = {}
+ symtab2 = symtab1.clone
+ symtab2.is_func = true
+ symtab2[:b] = {}
+ symtab3 = symtab2.clone
+ symtab3[:c] = {}
+ symtab3[:d] = {}
+ symtab3
+ }
+
+ it "keeps a reference to the parent environment when cloned" do
+ symtab = SymTable.new("foo")
+ expect(symtab.instance_variable_get(:@parent)).to eq "foo"
+ end
+
+ context "lookup/store" do
+ it "will find the symbol in the inner most context" do
+ expect(subject[:c]).to eq({})
+ end
+
+ it "will find the symbol in global context" do
+ expect(subject[:a]).to eq({})
+ end
+
+ it "will find the symbol in the middle context" do
+ expect(subject[:b]).to eq({})
+ end
+
+ it "will return nil if no symbol defined with the given name" do
+ expect(subject[:z]).to eq(nil)
+ end
+ end
+
+ context "global?" do
+ it "returns true if the symbol is defined in global context" do
+ expect(subject.global? :a).to eq true
+ end
+
+ it "returns false if the symbol is defined in non-global context" do
+ expect(subject.global? :b).to eq false
+ end
+ end
+
+ context "local?" do
+ it "returns true if the symbol is defined in local function context" do
+ expect(subject.local? :b).to eq true
+ end
+ it "returns false if the symbol is defined outside of the current function context" do
+ expect(subject.local? :a).to eq false
+ end
+ end
+
+ context "block_local?" do
+ it "returns true if the symbol is defined in context of the inner most block" do
+ expect(subject.block_local? :d).to eq true
+ end
+
+ it "returns false if the symbol is defined outside the context of the inner most block" do
+ expect(subject.block_local? :b).to eq false
+ end
+ end
end
\ No newline at end of file