class ADSL::Parser::ASTTypecheckResolveContext
Attributes
actions[RW]
classes[RW]
invariants[RW]
pre_stmts[RW]
relations[RW]
var_stack[RW]
Public Class Methods
context_vars_that_differ(*contexts)
click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 517 def self.context_vars_that_differ(*contexts) vars_per_context = [] contexts.each do |context| vars_per_context << context.var_stack.inject(ActiveSupport::OrderedHash.new) { |so_far, frame| so_far.merge! frame } end all_vars = vars_per_context.map{ |c| c.keys }.flatten.uniq packed = ActiveSupport::OrderedHash.new all_vars.each do |v| packed[v] = vars_per_context.map{ |vpc| vpc[v][1] } end packed.delete_if { |v, vars| vars.uniq.length == 1 } packed end
new()
click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 394 def initialize # name => [astnode, dsobj] @classes = ActiveSupport::OrderedHash.new # classname => name => [astnode, dsobj] @relations = ActiveSupport::OrderedHash.new{ |hash, key| hash[key] = ActiveSupport::OrderedHash.new } # stack of name => [astnode, dsobj] @actions = ActiveSupport::OrderedHash.new @invariants = [] @var_stack = [] @pre_stmts = [] end
Public Instance Methods
define_var(var, node)
click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 449 def define_var(var, node) raise ADSLError, "Defining variables on a stack with no stack frames" if @var_stack.empty? prev_var_node, prev_var = lookup_var var.name raise ADSLError, "Duplicate identifier '#{var.name}' on line #{node.lineno}; previous definition on line #{prev_var_node.lineno}" unless prev_var.nil? @var_stack.last[var.name] = [node, var] @var_stack.last.fire_write_event var.name return var end
find_relation(from_type, rel_name, lineno, to_type=nil)
click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 501 def find_relation(from_type, rel_name, lineno, to_type=nil) iter = from_type relation_node, relation = @relations[iter.name][rel_name] while relation.nil? iter = iter.parent raise ADSLError, "Unknown relation #{from_type.name}.#{rel_name} on line #{lineno}" if iter.nil? relation_node, relation = @relations[iter.name][rel_name] end unless to_type.nil? raise ADSLError, "Mismatched right-hand-side type for relation #{from_type.name}.#{rel_name} on line #{lineno}. Expected #{relation.to_class.name} but was #{to_type.name}" unless relation.to_class.superclass_of? to_type end relation end
in_stack_frame() { || ... }
click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 434 def in_stack_frame push_frame yield ensure pop_frame end
initialize_copy(source)
click to toggle source
Calls superclass method
# File lib/adsl/parser/ast_nodes.rb, line 409 def initialize_copy(source) super source.classes.each do |name, value| @classes[name] = value.dup end source.relations.each do |class_name, class_entry| entries = @relations[class_name] class_entry.each do |name, value| entries[name] = value.dup end end @actions = source.actions.dup @invariants = source.invariants.dup @var_stack = source.var_stack.map{ |frame| frame.dup } @pre_stmts = source.pre_stmts.map{ |stmt| stmt.dup } end
lookup_var(name, fire_read_event=true)
click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 483 def lookup_var(name, fire_read_event=true) @var_stack.length.times do |index| frame = @var_stack[index] next if frame[name].nil? var = frame[name] if fire_read_event @var_stack[index..-1].reverse.each do |subframe| subframe.fire_read_event name end end # handle events here, none defined atm return var end nil end
on_var_read(&block)
click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 430 def on_var_read(&block) @var_stack.last.on_var_read(&block) end
on_var_write(&block)
click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 426 def on_var_write(&block) @var_stack.last.on_var_write(&block) end
pop_frame()
click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 445 def pop_frame @var_stack.pop end
push_frame()
click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 441 def push_frame @var_stack.push ASTStackFrame.new end
redefine_var(var, node)
click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 458 def redefine_var(var, node) @var_stack.length.times do |frame_index| frame = @var_stack[frame_index] next unless frame.include? var.name old_var = frame[var.name][1] if old_var.type.nil? # nothing? elsif var.type.nil? var.type = old_var.type elsif var.type != old_var.type raise ADSLError, "Unmatched type '#{var.type.name}' for variable '#{var.name}' on line #{node.lineno}" end frame[var.name][1] = var @var_stack[frame_index..-1].reverse.each do |subframe| subframe.fire_write_event var.name end return var end return define_var var, node end