module Emfrp::AlphaConvert
Public Instance Methods
alpha_convert(top, syntax, tbl=nil)
click to toggle source
# File lib/emfrp/pre_convert/alpha_convert.rb, line 5 def alpha_convert(top, syntax, tbl=nil) tbl ||= Hash.new{|h,k| h[k] = []} case syntax when InputDef alpha_convert(top, syntax[:init_exp], tbl) if syntax[:init_exp] when NodeDef alpha_convert(top, syntax[:init_exp], tbl) if syntax[:init_exp] if syntax[:params] check_duplicate_name(syntax[:params].map{|x| x[:name]}) vars = syntax[:params].map{|x| x[:as]} check_duplicate_name(vars) vars.each do |v| tbl[v].push(syntax) end alpha_convert(top, syntax[:exp], tbl) vars.each do |v| tbl[v].pop end else syntax[:params] = [] vars = (top[:nodes] + top[:inputs]).map{|x| [x[:name], SSymbol.new(:desc => x[:name][:desc] + "@last")] }.flatten vars.each do |v| tbl[v].push(syntax) end alpha_convert(top, syntax[:exp], tbl) vars.each do |v| tbl[v].pop end end when FuncDef vars = syntax[:params].map{|x| x[:name]} check_duplicate_name(vars) vars.each do |v| tbl[v].push(syntax) end alpha_convert(top, syntax[:exp], tbl) vars.each do |v| tbl[v].pop end when DataDef alpha_convert(top, syntax[:exp], tbl) when Case vars = syntax[:pattern].find_refs() check_duplicate_name(vars) vars.each do |v| tbl[v].push(syntax) end alpha_convert(top, syntax[:exp], tbl) vars.each do |v| tbl[v].pop end when VarRef if tbl[syntax[:name]].size == 0 if top[:dict][:data_space][syntax[:name][:desc]] syntax[:binder] = top[:dict][:data_space][syntax[:name][:desc]] else PreConvert.err(:unbound, "Unbound variable `#{syntax[:name][:desc]}':\n", syntax) end else binder = tbl[syntax[:name]].last if binder.is_a?(NodeDef) && !binder[:params].find{|x| x[:as] == syntax[:name]} if syntax[:name][:desc] =~ /^(.+)@last$/ name = SSymbol.new(:desc => $1) last = true else name = syntax[:name] last = false end binder[:params] << NodeRef.new(:as => syntax[:name], :name => name, :last => last) end syntax[:binder] = Link.new(binder) end when ValueConst, ValuePattern name = syntax[:name][:desc] if tvalue_link = top[:dict][:const_space][name] tvalue = tvalue_link.get if syntax[:args].size != tvalue[:params].size s = "#{syntax[:args].size} for #{tvalue[:params].size}" PreConvert.err(:arg_num, "Wrong number of arguments (#{s}) for `#{name}':\n", syntax) end else PreConvert.err(:undef, "Undefined value-constructor `#{name}':\n", syntax) end alpha_convert(top, syntax.values, tbl) when FuncCall name = syntax[:name][:desc] if func_link = top[:dict][:func_space][name] f = func_link.get if syntax[:args].size != f[:params].size s = "#{syntax[:args].size} for #{f[:params].size}" PreConvert.err(:arg_num, "Wrong number of arguments (#{s}) for `#{name}':\n", syntax) end else PreConvert.err(:undef, "Undefined function `#{name}':\n", syntax) end alpha_convert(top, syntax.values, tbl) when Syntax alpha_convert(top, syntax.values, tbl) when Array syntax.each{|e| alpha_convert(top, e, tbl)} end end
check_duplicate_name(names)
click to toggle source
# File lib/emfrp/pre_convert/alpha_convert.rb, line 110 def check_duplicate_name(names) names.each do |name| dups = names.select{|x| x == name} if dups.size > 1 PreConvert.err(:dup, "Duplicate variable names `#{name[:desc]}':\n", *dups) end end end