loxxy 0.0.16 → 0.0.21
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/.rubocop.yml +1 -1
- data/CHANGELOG.md +60 -1
- data/README.md +155 -52
- data/lib/loxxy/ast/all_lox_nodes.rb +7 -1
- data/lib/loxxy/ast/ast_builder.rb +57 -3
- data/lib/loxxy/ast/ast_visitor.rb +62 -2
- data/lib/loxxy/ast/lox_binary_expr.rb +1 -1
- data/lib/loxxy/ast/lox_grouping_expr.rb +23 -0
- data/lib/loxxy/ast/lox_if_stmt.rb +35 -0
- data/lib/loxxy/ast/lox_logical_expr.rb +28 -0
- data/lib/loxxy/ast/lox_unary_expr.rb +27 -0
- data/lib/loxxy/ast/lox_var_stmt.rb +28 -0
- data/lib/loxxy/back_end/engine.rb +71 -4
- data/lib/loxxy/back_end/entry.rb +41 -0
- data/lib/loxxy/back_end/environment.rb +66 -0
- data/lib/loxxy/back_end/symbol_table.rb +135 -0
- data/lib/loxxy/back_end/variable.rb +25 -0
- data/lib/loxxy/datatype/builtin_datatype.rb +55 -0
- data/lib/loxxy/datatype/false.rb +14 -8
- data/lib/loxxy/datatype/lx_string.rb +0 -14
- data/lib/loxxy/datatype/nil.rb +12 -6
- data/lib/loxxy/datatype/number.rb +44 -6
- data/lib/loxxy/datatype/true.rb +1 -9
- data/lib/loxxy/front_end/grammar.rb +7 -7
- data/lib/loxxy/interpreter.rb +1 -1
- data/lib/loxxy/version.rb +1 -1
- data/spec/back_end/engine_spec.rb +8 -0
- data/spec/back_end/environment_spec.rb +74 -0
- data/spec/back_end/symbol_table_spec.rb +142 -0
- data/spec/back_end/variable_spec.rb +79 -0
- data/spec/front_end/parser_spec.rb +4 -4
- data/spec/interpreter_spec.rb +152 -0
- metadata +17 -2
@@ -51,7 +51,23 @@ module Loxxy
|
|
51
51
|
broadcast(:after_ptree, aParseTree)
|
52
52
|
end
|
53
53
|
|
54
|
-
# Visit event. The visitor is about to visit a
|
54
|
+
# Visit event. The visitor is about to visit a variable declaration statement.
|
55
|
+
# @param aPrintStmt [AST::LOXVarStmt] the variable declaration node to visit
|
56
|
+
def visit_var_stmt(aVarStmt)
|
57
|
+
broadcast(:before_var_stmt, aVarStmt)
|
58
|
+
traverse_subnodes(aVarStmt)
|
59
|
+
broadcast(:after_var_stmt, aVarStmt)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Visit event. The visitor is about to visit a if statement.
|
63
|
+
# @param anIfStmt [AST::LOXIfStmt] the if statement node to visit
|
64
|
+
def visit_if_stmt(anIfStmt)
|
65
|
+
broadcast(:before_if_stmt, anIfStmt)
|
66
|
+
traverse_subnodes(anIfStmt) # The condition is visited/evaluated here...
|
67
|
+
broadcast(:after_if_stmt, anIfStmt, self)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Visit event. The visitor is about to visit a print statement.
|
55
71
|
# @param aPrintStmt [AST::LOXPrintStmt] the print statement node to visit
|
56
72
|
def visit_print_stmt(aPrintStmt)
|
57
73
|
broadcast(:before_print_stmt, aPrintStmt)
|
@@ -59,7 +75,21 @@ module Loxxy
|
|
59
75
|
broadcast(:after_print_stmt, aPrintStmt)
|
60
76
|
end
|
61
77
|
|
62
|
-
# Visit event. The visitor is about to visit a
|
78
|
+
# Visit event. The visitor is about to visit a logical expression.
|
79
|
+
# Since logical expressions may take shorcuts by not evaluating all their
|
80
|
+
# sub-expressiosns, they are responsible for visiting or not their children.
|
81
|
+
# @param aBinaryExpr [AST::LOXBinaryExpr] the logical expression node to visit
|
82
|
+
def visit_logical_expr(aLogicalExpr)
|
83
|
+
broadcast(:before_logical_expr, aLogicalExpr)
|
84
|
+
|
85
|
+
# As logical connectors may take a shortcut only the first argument is visited
|
86
|
+
traverse_given_subnode(aLogicalExpr, 0)
|
87
|
+
|
88
|
+
# The second child could be visited: this action is deferred in handler
|
89
|
+
broadcast(:after_logical_expr, aLogicalExpr, self)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Visit event. The visitor is about to visit a binary expression.
|
63
93
|
# @param aBinaryExpr [AST::LOXBinaryExpr] the binary expression node to visit
|
64
94
|
def visit_binary_expr(aBinaryExpr)
|
65
95
|
broadcast(:before_binary_expr, aBinaryExpr)
|
@@ -67,6 +97,22 @@ module Loxxy
|
|
67
97
|
broadcast(:after_binary_expr, aBinaryExpr)
|
68
98
|
end
|
69
99
|
|
100
|
+
# Visit event. The visitor is about to visit an unary expression.
|
101
|
+
# @param anUnaryExpr [AST::anUnaryExpr] unary expression node to visit
|
102
|
+
def visit_unary_expr(anUnaryExpr)
|
103
|
+
broadcast(:before_unary_expr, anUnaryExpr)
|
104
|
+
traverse_subnodes(anUnaryExpr)
|
105
|
+
broadcast(:after_unary_expr, anUnaryExpr)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Visit event. The visitor is about to visit a grouping expression.
|
109
|
+
# @param aGroupingExpr [AST::LoxGroupingExpr] grouping expression to visit
|
110
|
+
def visit_grouping_expr(aGroupingExpr)
|
111
|
+
broadcast(:before_grouping_expr, aGroupingExpr)
|
112
|
+
traverse_subnodes(aGroupingExpr)
|
113
|
+
broadcast(:after_grouping_expr, aGroupingExpr)
|
114
|
+
end
|
115
|
+
|
70
116
|
# Visit event. The visitor is visiting the
|
71
117
|
# given terminal node containing a datatype object.
|
72
118
|
# @param aLiteralExpr [AST::LoxLiteralExpr] the leaf node to visit.
|
@@ -98,6 +144,20 @@ module Loxxy
|
|
98
144
|
broadcast(:after_subnodes, aParentNode, subnodes)
|
99
145
|
end
|
100
146
|
|
147
|
+
# Visit event. The visitor is about to visit one given subnode of a non
|
148
|
+
# terminal node.
|
149
|
+
# @param aParentNode [Ast::LocCompoundExpr] the parent node.
|
150
|
+
# @param index [integer] index of child subnode
|
151
|
+
def traverse_given_subnode(aParentNode, index)
|
152
|
+
subnode = aParentNode.subnodes[index]
|
153
|
+
broadcast(:before_given_subnode, aParentNode, subnode)
|
154
|
+
|
155
|
+
# Now, let's proceed with the visit of that subnode
|
156
|
+
subnode.accept(self)
|
157
|
+
|
158
|
+
broadcast(:after_given_subnode, aParentNode, subnode)
|
159
|
+
end
|
160
|
+
|
101
161
|
# Send a notification to all subscribers.
|
102
162
|
# @param msg [Symbol] event to notify
|
103
163
|
# @param args [Array] arguments of the notification.
|
@@ -5,7 +5,7 @@ require_relative 'lox_compound_expr'
|
|
5
5
|
module Loxxy
|
6
6
|
module Ast
|
7
7
|
class LoxBinaryExpr < LoxCompoundExpr
|
8
|
-
# @return [Symbol]
|
8
|
+
# @return [Symbol] message name to be sent to receiver
|
9
9
|
attr_reader :operator
|
10
10
|
|
11
11
|
# @param aPosition [Rley::Lexical::Position] Position of the entry in the input stream.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lox_compound_expr'
|
4
|
+
|
5
|
+
module Loxxy
|
6
|
+
module Ast
|
7
|
+
class LoxGroupingExpr < LoxCompoundExpr
|
8
|
+
# @param aPosition [Rley::Lexical::Position] Position of the entry in the input stream.
|
9
|
+
# @param subExpr [Loxxy::Ast::LoxNode]
|
10
|
+
def initialize(aPosition, subExpr)
|
11
|
+
super(aPosition, [subExpr])
|
12
|
+
end
|
13
|
+
|
14
|
+
# Part of the 'visitee' role in Visitor design pattern.
|
15
|
+
# @param visitor [Ast::ASTVisitor] the visitor
|
16
|
+
def accept(visitor)
|
17
|
+
visitor.visit_grouping_expr(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
alias operands subnodes
|
21
|
+
end # class
|
22
|
+
end # module
|
23
|
+
end # module
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lox_compound_expr'
|
4
|
+
|
5
|
+
module Loxxy
|
6
|
+
module Ast
|
7
|
+
class LoxIfStmt < LoxCompoundExpr
|
8
|
+
# @return [LoxNode] code of then branch
|
9
|
+
attr_reader :then_stmt
|
10
|
+
|
11
|
+
# @return [LoxNode, NilClass] code of else branch
|
12
|
+
attr_reader :else_stmt
|
13
|
+
|
14
|
+
# @param aPosition [Rley::Lexical::Position] Position of the entry in the input stream.
|
15
|
+
# @param subExpr [Loxxy::Ast::LoxNode]
|
16
|
+
def initialize(aPosition, condExpr, thenStmt, elseStmt)
|
17
|
+
super(aPosition, [condExpr])
|
18
|
+
@then_stmt = thenStmt
|
19
|
+
@else_stmt = elseStmt
|
20
|
+
end
|
21
|
+
|
22
|
+
# Part of the 'visitee' role in Visitor design pattern.
|
23
|
+
# @param visitor [Ast::ASTVisitor] the visitor
|
24
|
+
def accept(visitor)
|
25
|
+
visitor.visit_if_stmt(self)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Accessor to the condition expression
|
29
|
+
# @return [LoxNode]
|
30
|
+
def condition
|
31
|
+
subnodes[0]
|
32
|
+
end
|
33
|
+
end # class
|
34
|
+
end # module
|
35
|
+
end # module
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lox_compound_expr'
|
4
|
+
|
5
|
+
module Loxxy
|
6
|
+
module Ast
|
7
|
+
class LoxLogicalExpr < LoxCompoundExpr
|
8
|
+
# @return [Symbol] message name to be sent to receiver
|
9
|
+
attr_reader :operator
|
10
|
+
|
11
|
+
# @param aPosition [Rley::Lexical::Position] Position of the entry in the input stream.
|
12
|
+
# @param operand1 [Loxxy::Ast::LoxNode]
|
13
|
+
# @param operand2 [Loxxy::Ast::LoxNode]
|
14
|
+
def initialize(aPosition, anOperator, operand1, operand2)
|
15
|
+
super(aPosition, [operand1, operand2])
|
16
|
+
@operator = anOperator
|
17
|
+
end
|
18
|
+
|
19
|
+
# Part of the 'visitee' role in Visitor design pattern.
|
20
|
+
# @param visitor [Ast::ASTVisitor] the visitor
|
21
|
+
def accept(visitor)
|
22
|
+
visitor.visit_logical_expr(self)
|
23
|
+
end
|
24
|
+
|
25
|
+
alias operands subnodes
|
26
|
+
end # class
|
27
|
+
end # module
|
28
|
+
end # module
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lox_compound_expr'
|
4
|
+
|
5
|
+
module Loxxy
|
6
|
+
module Ast
|
7
|
+
class LoxUnaryExpr < LoxCompoundExpr
|
8
|
+
# @return [Symbol] message name to be sent to receiver
|
9
|
+
attr_reader :operator
|
10
|
+
|
11
|
+
# @param aPosition [Rley::Lexical::Position] Position of the entry in the input stream.
|
12
|
+
# @param operand [Loxxy::Ast::LoxNode]
|
13
|
+
def initialize(aPosition, anOperator, operand)
|
14
|
+
super(aPosition, [operand])
|
15
|
+
@operator = anOperator
|
16
|
+
end
|
17
|
+
|
18
|
+
# Part of the 'visitee' role in Visitor design pattern.
|
19
|
+
# @param visitor [Ast::ASTVisitor] the visitor
|
20
|
+
def accept(visitor)
|
21
|
+
visitor.visit_unary_expr(self)
|
22
|
+
end
|
23
|
+
|
24
|
+
alias operands subnodes
|
25
|
+
end # class
|
26
|
+
end # module
|
27
|
+
end # module
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lox_compound_expr'
|
4
|
+
|
5
|
+
module Loxxy
|
6
|
+
module Ast
|
7
|
+
# This AST node represents a variable declaration
|
8
|
+
class LoxVarStmt < LoxCompoundExpr
|
9
|
+
# @return [String] variable name
|
10
|
+
attr_reader :name
|
11
|
+
|
12
|
+
# @param aPosition [Rley::Lexical::Position] Position of the entry in the input stream.
|
13
|
+
# @param aName [String] name of the variable
|
14
|
+
# @param aValue [Loxxy::Ast::LoxNode, NilClass] initial value for the variable
|
15
|
+
def initialize(aPosition, aName, aValue)
|
16
|
+
initial_value = aValue ? [aValue] : []
|
17
|
+
super(aPosition, initial_value)
|
18
|
+
@name = aName
|
19
|
+
end
|
20
|
+
|
21
|
+
# Part of the 'visitee' role in Visitor design pattern.
|
22
|
+
# @param visitor [Ast::ASTVisitor] the visitor
|
23
|
+
def accept(visitor)
|
24
|
+
visitor.visit_var_stmt(self)
|
25
|
+
end
|
26
|
+
end # class
|
27
|
+
end # module
|
28
|
+
end # module
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
# Load all the classes implementing AST nodes
|
4
4
|
require_relative '../ast/all_lox_nodes'
|
5
|
+
require_relative 'symbol_table'
|
5
6
|
|
6
7
|
module Loxxy
|
7
8
|
module BackEnd
|
@@ -12,17 +13,21 @@ module Loxxy
|
|
12
13
|
# @return [Hash] A set of configuration options
|
13
14
|
attr_reader :config
|
14
15
|
|
15
|
-
# @return [
|
16
|
+
# @return [BackEnd::SymbolTable]
|
17
|
+
attr_reader :symbol_table
|
18
|
+
|
19
|
+
# @return [Array<Datatype::BuiltinDatatyp>] Stack for the values of expr
|
16
20
|
attr_reader :stack
|
17
21
|
|
18
22
|
# @param theOptions [Hash]
|
19
23
|
def initialize(theOptions)
|
20
24
|
@config = theOptions
|
21
25
|
@ostream = config.include?(:ostream) ? config[:ostream] : $stdout
|
26
|
+
@symbol_table = SymbolTable.new
|
22
27
|
@stack = []
|
23
28
|
end
|
24
29
|
|
25
|
-
# Given an abstract syntax parse tree visitor,
|
30
|
+
# Given an abstract syntax parse tree visitor, launch the visit
|
26
31
|
# and execute the visit events in the output stream.
|
27
32
|
# @param aVisitor [AST::ASTVisitor]
|
28
33
|
# @return [Loxxy::Datatype::BuiltinDatatype]
|
@@ -33,19 +38,66 @@ module Loxxy
|
|
33
38
|
stack.empty? ? Datatype::Nil.instance : stack.pop
|
34
39
|
end
|
35
40
|
|
41
|
+
##########################################################################
|
36
42
|
# Visit event handling
|
43
|
+
##########################################################################
|
44
|
+
def after_var_stmt(aVarStmt)
|
45
|
+
new_var = Variable.new(aVarStmt.name, aVarStmt.subnodes[0])
|
46
|
+
symbol_table.insert(new_var)
|
47
|
+
end
|
48
|
+
|
49
|
+
def after_if_stmt(anIfStmt, aVisitor)
|
50
|
+
# Retrieve the result of the condition evaluation
|
51
|
+
condition = stack.pop
|
52
|
+
if condition.truthy?
|
53
|
+
result = anIfStmt.then_stmt.accept(aVisitor)
|
54
|
+
elsif anIfStmt.else_stmt
|
55
|
+
anIfStmt.else_stmt.accept(aVisitor)
|
56
|
+
end
|
57
|
+
end
|
37
58
|
|
38
59
|
def after_print_stmt(_printStmt)
|
39
60
|
tos = stack.pop
|
40
61
|
@ostream.print tos.to_str
|
41
62
|
end
|
42
63
|
|
64
|
+
def after_logical_expr(aLogicalExpr, visitor)
|
65
|
+
op = aLogicalExpr.operator
|
66
|
+
operand1 = stack.pop # only first operand was evaluated
|
67
|
+
result = nil
|
68
|
+
if ((op == :and) && operand1.falsey?) || ((op == :or) && operand1.truthy?)
|
69
|
+
result = operand1
|
70
|
+
else
|
71
|
+
raw_operand2 = aLogicalExpr.subnodes[1]
|
72
|
+
raw_operand2.accept(visitor) # Visit means operand2 is evaluated
|
73
|
+
operand2 = stack.pop
|
74
|
+
result = logical_2nd_arg(operand2)
|
75
|
+
end
|
76
|
+
|
77
|
+
stack.push result
|
78
|
+
end
|
79
|
+
|
80
|
+
def logical_2nd_arg(operand2)
|
81
|
+
case operand2
|
82
|
+
when false
|
83
|
+
False.instance # Convert to Lox equivalent
|
84
|
+
when nil
|
85
|
+
Nil.instance # Convert to Lox equivalent
|
86
|
+
when true
|
87
|
+
True.instance # Convert to Lox equivalent
|
88
|
+
when Proc
|
89
|
+
# Second operand wasn't yet evaluated...
|
90
|
+
operand2.call
|
91
|
+
else
|
92
|
+
operand2
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
43
96
|
def after_binary_expr(aBinaryExpr)
|
44
97
|
op = aBinaryExpr.operator
|
45
98
|
operand2 = stack.pop
|
46
99
|
operand1 = stack.pop
|
47
|
-
|
48
|
-
if implemented && operand1.respond_to?(op)
|
100
|
+
if operand1.respond_to?(op)
|
49
101
|
stack.push operand1.send(op, operand2)
|
50
102
|
else
|
51
103
|
msg1 = "`#{op}': Unimplemented operator for a #{operand1.class}."
|
@@ -53,6 +105,21 @@ module Loxxy
|
|
53
105
|
end
|
54
106
|
end
|
55
107
|
|
108
|
+
def after_unary_expr(anUnaryExpr)
|
109
|
+
op = anUnaryExpr.operator
|
110
|
+
operand = stack.pop
|
111
|
+
if operand.respond_to?(op)
|
112
|
+
stack.push operand.send(op)
|
113
|
+
else
|
114
|
+
msg1 = "`#{op}': Unimplemented operator for a #{operand1.class}."
|
115
|
+
raise StandardError, msg1
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def after_grouping_expr(_groupingExpr)
|
120
|
+
# Do nothing: work was already done by visiting /evaluating the subexpression
|
121
|
+
end
|
122
|
+
|
56
123
|
# @param literalExpr [Ast::LoxLiteralExpr]
|
57
124
|
def before_literal_expr(literalExpr)
|
58
125
|
stack.push(literalExpr.literal)
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Loxxy
|
4
|
+
module BackEnd
|
5
|
+
# Mix-in module that implements the expected common behaviour of entries
|
6
|
+
# placed in the symbol table.
|
7
|
+
module Entry
|
8
|
+
# @return [String] User-defined name of the entry.
|
9
|
+
attr_reader :name
|
10
|
+
|
11
|
+
=begin
|
12
|
+
# @return [String] Suffix for building the internal name of the entry.
|
13
|
+
attr_accessor :suffix
|
14
|
+
=end
|
15
|
+
|
16
|
+
# Initialize the entry with given name
|
17
|
+
# @param aName [String] The name of the entry
|
18
|
+
def init_name(aName)
|
19
|
+
@name = aName.dup
|
20
|
+
@name.freeze
|
21
|
+
end
|
22
|
+
=begin
|
23
|
+
# Return the internal name of the entry
|
24
|
+
# Internal names used to disambiguate entry names.
|
25
|
+
# There might be homonyns between variable because:
|
26
|
+
# - A child Scope may have a entry with same name as one of its
|
27
|
+
# ancestor(s).
|
28
|
+
# - Multiple calls to same defrel or procedure may imply multiple creation
|
29
|
+
# of a entry given name...
|
30
|
+
# @return [String] internal name
|
31
|
+
def i_name
|
32
|
+
if suffix =~ /^_/
|
33
|
+
label + suffix
|
34
|
+
else
|
35
|
+
(suffix.nil? || suffix.empty?) ? label : suffix
|
36
|
+
end
|
37
|
+
end
|
38
|
+
=end
|
39
|
+
end # module
|
40
|
+
end # module
|
41
|
+
end # module
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'variable'
|
4
|
+
|
5
|
+
module Loxxy
|
6
|
+
module BackEnd
|
7
|
+
# A environment is a name space that corresponds either to a specific
|
8
|
+
# delimited region in Loxxy source code or to an activation record
|
9
|
+
# of a relation or a relation definition.
|
10
|
+
# It contains a map of names to the objects they name (e.g. logical var)
|
11
|
+
class Environment
|
12
|
+
# The parent (enclosing) environment.
|
13
|
+
# @return [Environment, NilClass]
|
14
|
+
attr_accessor :parent
|
15
|
+
|
16
|
+
# Mapping from user-defined name to related definition
|
17
|
+
# (say, a variable object)
|
18
|
+
# @return [Hash{String => Variable}] Pairs of the kind
|
19
|
+
attr_reader :defns
|
20
|
+
|
21
|
+
# Construct a environment instance.
|
22
|
+
# @param aParent [Environment, NilClass] Parent environment to this one.
|
23
|
+
def initialize(aParent = nil)
|
24
|
+
@parent = aParent
|
25
|
+
@defns = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
# Add a new variable to the environment.
|
29
|
+
# @param anEntry [BackEnd::Variable]
|
30
|
+
# @return [BackEnd::Variable] the variable
|
31
|
+
def insert(anEntry)
|
32
|
+
e = validated_entry(anEntry)
|
33
|
+
# e.suffix = default_suffix if e.kind_of?(BackEnd::Variable)
|
34
|
+
defns[e.name] = e
|
35
|
+
|
36
|
+
e
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns a string with a human-readable representation of the object.
|
40
|
+
# @return [String]
|
41
|
+
def inspect
|
42
|
+
+"#<#{self.class}:#{object_id.to_s(16)}>"
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def validated_entry(anEntry)
|
48
|
+
name = anEntry.name
|
49
|
+
unless name.kind_of?(String) && !name.empty?
|
50
|
+
err_msg = 'Invalid variable name argument.'
|
51
|
+
raise StandardError, err_msg
|
52
|
+
end
|
53
|
+
if defns.include?(name) && !anEntry.kind_of?(Variable)
|
54
|
+
err_msg = "Variable with name '#{name}' already exists."
|
55
|
+
raise StandardError, err_msg
|
56
|
+
end
|
57
|
+
|
58
|
+
anEntry
|
59
|
+
end
|
60
|
+
|
61
|
+
# def default_suffix
|
62
|
+
# @default_suffix ||= "_#{object_id.to_s(16)}"
|
63
|
+
# end
|
64
|
+
end # class
|
65
|
+
end # module
|
66
|
+
end # module
|