Created
August 14, 2013 13:02
-
-
Save kenpusney/6230837 to your computer and use it in GitHub Desktop.
use FM.rb for fast OO Modeling see https://github.com/kenpusney/fm.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class FMClass | |
def initialize | |
@deps = [] | |
@childs = [] | |
@comps = [] | |
@parent = nil | |
@methods = { | |
:public => [], | |
:private => [] | |
} | |
end | |
def dump(driver = nil) | |
info = { | |
:deps => @deps, | |
:childs => @childs, | |
:parent => @parent, | |
:methods => @methods, | |
:comps => @comps, | |
:self => self.to_s | |
} | |
if driver | |
driver.dump(info) | |
else | |
info | |
end | |
end | |
## Class Relations | |
def compose(cls) | |
cls.composed_by(self) | |
end | |
def composed_by(cls) | |
@deps << cls | |
@comps << cls | |
@deps.uniq! | |
end | |
def depend(cls) | |
@deps << cls | |
@deps.uniq! | |
end | |
def depended_by(other) | |
other.depend(self) | |
end | |
def inherit( parent ) | |
parent.derive(self) | |
@parent = parent | |
end | |
def derive(cls) | |
@childs << cls | |
@childs.uniq! | |
end | |
def to_s | |
self.class.name | |
end | |
def to_sym | |
self.to_s.to_sym | |
end | |
def add_method(mtd) | |
acl = (mtd =~ /^\b*-/) | |
resolve_signature(acl,mtd) | |
end | |
alias_method :is_a, :inherit | |
alias_method :has_a, :composed_by | |
alias_method :<<, :add_method | |
private | |
def resolve_signature(acl = true,mtd = "") | |
if mtd.empty? | |
return | |
else | |
mtd =~ /^ \s* [+\-]? # acl | |
\s* (\w+)\s* # method name | |
\( (.*) \) # method argument list | |
:?\s*(\w+)? # method return type | |
/x | |
mtd_name = $1 | |
mtd_args = $2.empty? ? nil : $2 | |
mtd_ret = $3 | |
if mtd_args | |
mtd_args = mtd_args.split(',').map do | elem | | |
pair = elem.split ':' | |
{ :type => pair[1].strip, :name => pair[0].strip } | |
end | |
end | |
@methods[ acl ? :private : :public] << { | |
:name => mtd_name, | |
:return => mtd_ret, | |
:args => mtd_args | |
} | |
end | |
end | |
end | |
class FMDriver | |
def initialize | |
@info = nil | |
@body = "" | |
end | |
[:deps,:parent,:comps,:methods].each do |iattr| | |
define_method("dump_#{iattr}".to_sym) { @info[iattr] } | |
end | |
def dump(info) | |
@info = info | |
dump_all | |
end | |
def dump_all | |
"deps: " + dump_deps.to_s + | |
"\nparent: " + dump_parent.to_s + | |
"\ncomps: " + dump_comps.to_s + | |
"\nmethods: " + dump_methods.to_s | |
end | |
end | |
class CPPDriver < FMDriver | |
def dump_all | |
dump_deps | |
dump_parent | |
dump_comps | |
dump_methods | |
dump_end | |
end | |
def dump_deps | |
@body += @info[:deps].map { |elem| | |
if [:int,:float,:short,:long,:double,:char,:bool].include? elem.to_sym | |
"" | |
else | |
"#include <#{elem}.h>\n" | |
end | |
}.join("") | |
@body | |
end | |
def dump_parent | |
@body += "class #{@info[:self]}#{@info[:parent]? ':public': ''} #{@info[:parent]}{\n" | |
@body | |
end | |
def dump_comps | |
cnt = 0 | |
@body += @info[:comps].map do |elem| | |
"\t#{elem} __#{elem}_#{cnt};\n" | |
end .join("") | |
@body | |
end | |
def dump_methods | |
for k,v in @info[:methods] | |
@body += "#{k}:\n" | |
@body += v.reduce("") do |total,mem| | |
total + dump_sign(mem) | |
end | |
end | |
@body | |
end | |
def dump_sign(elem) | |
"\t#{elem[:return]} #{elem[:name]}(#{dump_args(elem[:args])});\n" | |
end | |
def dump_args(args) | |
if args | |
args.map {|elem| | |
"#{elem[:type]} #{elem[:name]}" | |
}.join(", ") | |
else | |
"" | |
end | |
end | |
def dump_end | |
@body +="};\n" | |
@body | |
end | |
end | |
class A < FMClass | |
end | |
class B < FMClass | |
end | |
class C < FMClass | |
end | |
a = A.new | |
b = B.new | |
c = C.new | |
a.is_a b | |
b.is_a c | |
a.has_a c | |
a.has_a :int | |
a << "+hula(pululu:int, kim:string):int" | |
a << "-blublu():void" | |
c.derive b | |
puts a.dump(CPPDriver.new) | |
puts b.dump(CPPDriver.new) | |
puts c.dump(CPPDriver.new) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment