class ADSL::Parser::ASTAction
Public Instance Methods
optimize()
click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 571 def optimize copy = dup copy.instance_variable_set :@pre_optimize_adsl_ast_size, copy.adsl_ast_size copy.block = until_no_change(copy.block) do |block| block = block.optimize(true) variables_read = [] block.preorder_traverse do |node| next unless node.is_a? ASTVariable variables_read << node.var_name.text end block.block_replace do |node| next unless node.is_a? ASTAssignment next if node.var_name.nil? || variables_read.include?(node.var_name.text) ASTObjsetStmt.new :objset => node.objset end next block if block.statements.length != 1 if block.statements.first.is_a? ASTEither either = block.statements.first either = ASTEither.new(:blocks => either.blocks.reject{ |subblock| subblock.statements.empty? }) if either.blocks.length == 0 ASTBlock.new(:statements => []) elsif either.blocks.length == 1 either.blocks.first else ASTBlock.new(:statements => [either]) end else block end end copy end
pre_optimize_adsl_ast_size()
click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 609 def pre_optimize_adsl_ast_size @pre_optimize_adsl_ast_size || adsl_ast_size end
prepend_global_variables_by_signatures(*regexes)
click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 613 def prepend_global_variables_by_signatures(*regexes) variable_names = [] preorder_traverse do |node| next unless node.is_a? ASTVariable name = node.var_name.text variable_names << name if regexes.map{ |r| r =~ name ? true : false }.include? true end variable_names.each do |name| @block.statements.unshift ASTAssignment.new( :var_name => ASTIdent.new(:text => name), :objset => ASTEmptyObjset.new ) end end
to_adsl()
click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 628 def to_adsl args = [] @arg_cardinalities.length.times do |index| card = @arg_cardinalities[index] type = @arg_types[index].text name = @arg_names[index].text card_str = card[1] == Float::INFINITY ? "#{card[0]}+" : "#{card[0]}..#{card[1]}" args << "#{card_str} #{type} #{name}" end "action #{@name.text}(#{ args.join ', ' }) {\n#{ @block.to_adsl.adsl_indent }}\n" end
typecheck_and_resolve(context)
click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 535 def typecheck_and_resolve(context) old_action_node, old_action = context.actions[@name.text] raise ADSLError, "Duplicate action name #{@name.text} on line #{@name.lineno}; first definition on line #{old_action_node.name.lineno}" unless old_action.nil? arguments = [] cardinalities = [] block = nil context.in_stack_frame do @arg_names.length.times do |i| cardinality = @arg_cardinalities[i] if cardinality[0] > cardinality[1] raise ADSLError, "Invalid cardinality of argument #{@arg_names[i].text} of action #{@name.text} on line #{cardinality[2]}: minimum cardinality #{cardinality[0]} must not be greater than the maximum cardinality #{cardinality[1]}" end if cardinality[1] == 0 raise ADSLError, "Invalid cardinality of relation #{@arg_names[i].text} of action #{@name.text} on line #{cardinality[2]}: maximum cardinality #{cardinality[1]} must be positive" end cardinality = cardinality.first 2 klass_node, klass = context.classes[@arg_types[i].text] raise ADSLError, "Unknown class #{@arg_types[i].text} on line #{@arg_types[i].lineno}" if klass.nil? var = ADSL::DS::DSVariable.new :name => @arg_names[i].text, :type => klass context.define_var var, @arg_types[i] arguments << var cardinalities << cardinality end block = @block.typecheck_and_resolve context, false end action = ADSL::DS::DSAction.new :name => @name.text, :args => arguments, :cardinalities => cardinalities, :block => block context.actions[action.name] = [self, action] return action rescue Exception => e #pp @block new_ex = e.exception("#{e.message} in action #{@name.text}") new_ex.set_backtrace e.backtrace raise new_ex end