



$Cclasses={}
class CInterface
	attr_accessor :nam,:predes
	attr_accessor :variables, :pointers,:backpointers
	attr_accessor :cmethods
	def initialize(nam,prede=nil)
		@predes=prede
		@ln=$line
		@nam=nam.to_s
		$Cclasses[nam]=self
		@predes= $Cclasses[@predes] if @predes
		@variables={}
		@varlist=[]
		@pointers={}
		@ptrlist=[]
		@backpointers={}
		@cmethods={}
	end
	def rvariables
		v=@varlist.clone
		v.concat @predes.rvariables if @predes
		v
	end
	def rpointers
		v=@ptrlist.clone
		v.concat @predes.rpointers if @predes
		v
	end

	def addcmethod(str)
		l=str[0]
		 tp,nm,args=methodhdr(l.str)
		@cmethods[nm]=[tp,args,str]
	end
	def addvariable(tp,nm,flags={})
		@varlist<< [nm,tp,flags]
		@variables[nm]=[tp,flags]
	end
	def addpointer(nm,flags={},backptr=nil)
		@pointers[nm]=[flags]
		@ptrlist<<[nm,"_interface",flags]
	end
	def makecode
		a=@ln.clone
		a.str="struct _#{@nam} {"
			
		s=[a]


			a=@ln.clone
			a.str="struct _data; struct _variables; struct _interface #{@predes  ? " : public #{@predes.nam}" : ""} {typedef _data data;static _interface create(){_interface i(new _data); return i;}"
			s<< a
		@cmethods.each{|nam,m|
			t=[]
			m[2].each{|l|
				ll= l.clone
				ll.str.gsub!("THIS","_interface")
				@cmethods[nam][1][:recalculate]=true if ll.str!=l.str
				t<< ll
			}
			s.concat t
		}
			a=@ln.clone
			a.str="			#{(@predes)? "" : "_data *_datas;"}
			_data *datas(){return (_data *) _datas;}
			_variables * operator ->(){return (_variables *) this;}
			_interface(_data *d){_datas=d; } _interface(){_datas=NULL;} "
			s<< a

			a=@ln.clone;a.str=""
			rvariables.each{|nm,tp,f|
				a.str<< " #{tp} get#{nm}(){return datas()->#{nm};} void set#{nm}(#{tp} _x){datas()->#{nm}=_x;}  static #{tp} _get#{nm}(_interface *n){return (*n).get#{nm}();} static void _set#{nm}(_interface *n,#{tp} _x){(*n).set#{nm}(_x);} "
			}
			rpointers.each{|nm,tp,f|
		a.str<< " _interface get#{nm}(){return _interface((_data *) datas()->#{nm}._datas);} void set#{nm}(_interface _x){datas()->#{nm}._datas=_x.datas();}  static #{tp} _get#{nm}(_interface *n){return (*n).get#{nm}();} static void _set#{nm}(_interface *n,#{tp} _x){(*n).set#{nm}(_x);} "
			}

			a.str<< "}; "
			s<< a 

		a=@ln.clone
		a.str="struct _data #{@predes ? " : public #{@predes.nam.to_s+"::data" }" : ""} {"
		s<< a
			a=@ln.clone;a.str=""
			(@varlist+@ptrlist).each{|nm,tp,flags|
				a.str<< " #{tp} #{nm}; "
			}
			s<< a

			a=@ln.clone;a.str="_interface operator ->(){return _interface(this);} };"
			s<< a

			a=@ln.clone
			a.str=" struct _variables {"
			lens=0
			(rvariables+rpointers).each{|nm,tp,flags|
				a.str<< "_variable <#{tp},_interface,_interface::_get#{nm},_interface::_set#{nm},#{lens}*sizeof(voi)> #{nm}; "
				lens+=1;
			}
			a.str<< "};"
			s<< a


		a=@ln.clone
		a.str="};typedef _#{nam}::_interface #{nam};"
		s << a
		RubyPP::Input.new(s)
	end
	def methodhdr(str)
		j=i=str.index(?{)
		j-=1 until str[j]==?)
		j-=1
		par=1
		while par>0
			par+=1 if str[j]==?)
			par-=1 if str[j]==?(
			j-=1
		end
		j-=1 while str[j]==?\s || str[j]==?\t
		arg=str[(j+1)...i]
		k=j
		k-=1 while /\w/===str[k,1]
		nm=str[k..j]
		tp=str[0...k]
		[tp,nm,arg]
	end
	def parbal(s)
		b=0
		s.each{|c|
			b+=1 if c==?{
			b-=1 if c==?}
		}
		b
	end
	def interpret(input)
		input=$RubyPP.process(input)	
		parelvl=0
		meth=nil
		input.each{|l|
			if parelvl==0
				if l.str.index(?{)
					addcmethod(meth) if meth
					meth=[]
				end
			end
			meth << l if meth
			parelvl += parbal(l.str)
		}
		addcmethod(meth) if meth
	end
end

$RubyPP.adddirective("class"){|l,exp,input|
	$curclass=c=eval("CInterface.new #{exp}")
	c.interpret(input)
	c.makecode.input
}
def variables(*a)
	a.each {|i| $curclass.addvariable(*i)}
end
def pointers(*a)
	a.each {|i| $curclass.addpointer(*i)}
end



