defgen - Generate .def files for dll compilation

BlitzMax Forums/BlitzMax Programming/defgen - Generate .def files for dll compilation

This is a modified version of my BriskVM bcs generator, so it is a little bloated, but it works. It will automatically skip Private sections of sections commented like this:

'-dll
Function MyFunc()
EndFunction
'+dll

For n=1 To appargs.length-1
	infile$:+AppArgs[n]
Next
outfile$=StripExt(infile)+".def"

Global LineCount

Type BVMType
	Global list:TList=New TList
	
	Method New()
		list.addfirst(Self)
	EndMethod
	
	Field name$
	Field methods:TList=New TList
	Field fields:TList=New TList
EndType

Global functions:TList=New TList
Global globals:TList=New TList
Global constants:TList=New TList
Global types:TList=New TList

commandset:TStream=WriteFile(outfile$)
If Not commandset
	Notify "Failed to write file "+Chr(34)+outfile+Chr(34)+"."
EndIf

ExtractCommandSet(infile)


For func$=EachIn functions
	
	'Unsupported parameters
	ok=True
	'If Instr(Lower(func),":byte ptr") ok=False
	'If Instr(Lower(func),":int ptr") ok=False
	'If Instr(Lower(func),":float ptr") ok=False
	'If Instr(Lower(func),"]") ok=False
	'If Instr(Lower(func),"[") ok=False
	'If Instr(Lower(func)," var,") ok=False
	'If Instr(Lower(func)," var ") ok=False
	'If Instr(Lower(func)," var)") ok=False
	'If Instr(Lower(func),"callback") ok=False
	
	If Not ok
		functions.remove func
		Continue
	EndIf

	Rem
	For c$=EachIn constants
		constname$=Piece(c,2)
		constname$=Trim(Piece(constname,1,"="))
		If Instr(func,"="+constname)
			constval$=Trim(Piece(c,2,"="))
			functions.remove func
			functions.addlast Replace(func,"="+constname,"="+constval)
			Exit
		EndIf
	Next
	EndRem
		
Next

SortList functions

commandset.writeline "EXPORTS"
commandset.writeline ""

For s$=EachIn functions
	s=Replace(s,"%",":Int")
	s=Replace(s,"$",":String")
	s=Replace(s,"#",":Float")
	s=Piece(s,1,"(")
	s=Piece(s,1,":")
	commandset.writeline s+"=bb_"+s
Next

commandset.close

Print ""
Print LineCount+" lines"

End

Function ExtractCommandSet:Int(file$)
	in:TStream=ReadStream(file)
	If Not in
		Notify "Failed to load file "+Chr(34)+file+Chr(34)+"."
		Return False
	EndIf
	
	Global bvmskip
	
	incdir$=ExtractDir(RealPath(file))
	
	While Not in.Eof()
		LineCount:+1
		s$=in.readline()
		s=Replace(s,"'",";")
		s=Trim(s)
		'If Left(s,1)="'" Continue


		If Lower(Trim(s))=";-dll"
			bvmskip=bvmskip+1
		EndIf

		If Lower(Trim(s))=";+dll"
			bvmskip=bvmskip-1
		EndIf		

		If Not bvmskip
	
			If Lower(Piece(s,1))="rem"
				comment=True
			EndIf
	
			If Lower(Piece(s,1))="endrem" Or (Lower(Piece(s,1))="end" And Lower(Piece(s,2))="rem")
				comment=False
			EndIf
			
			If Not comment
	
				If Lower(Piece(s,1))="private"
					InPriv=True
				EndIf
				
				If Lower(Piece(s,1))="public"
					InPriv=False
				EndIf
				
				If Not inPriv
					
					
					If Lower(Piece(s,1))="type"
						bvmt:BVMType=New BVMType
						bvmt.name=Trim(s)
						types.addlast(Trim(s))
						InType=True
					EndIf
			
					If Lower(Piece(s,1))="endtype" Or (Lower(Piece(s,1))="end" And Lower(Piece(s,2))="type")
						InType=False
						expose=False
					EndIf
	
					If Not InType
	
						If Lower(Piece(s,1))="function"
							's$=Replace(s,"=Null","")
							s=Replace(s,"Function","")
							functions.addfirst Trim(s)
							infunction:+1
						EndIf
				
						If Lower(Piece(s,1))="endfunction" Or (Lower(Piece(s,1))="end" And Lower(Piece(s,2))="function")
							infunction:-1
							If infunction<0 Notify "Error parsing file."
						EndIf
						
						If Not infunction
	
							If Lower(Piece(s,1))="global"
								globals.addfirst Trim(s)
							EndIf
							
							If Lower(Piece(s,1))="const"
								constants.addfirst(Trim(s))
							EndIf
						
						EndIf
					
					Else
						
						If expose
							
							If Lower(s)=";endexpose" expose=False
							
							If Lower(Piece(s,1))="field"
								bvmt.fields.addlast(Trim(Piece(s,1,"=")))
							EndIf
						
							If Lower(Piece(s,1))="method"
								bvmt.methods.addlast(Trim(s))
								InMethod=True
							EndIf
							
							If Lower(Piece(s,1))="endmethod" Or (Lower(Piece(s,1))="end" And Lower(Piece(s,2))="method")
								InMethod=False
							EndIf
						
						Else
						
							If Lower(s)=";expose" expose=True
						
						EndIf
						
					EndIf
						
				EndIf
							
				If Lower(Piece(s,1))="include"
					text$=Trim(Right(s,s.length-8))
					text=Replace(text,Chr(34),"")
					Print "Loading include file "+Chr(34)+incdir+"/"+text+Chr(34)+"..."
					ExtractCommandSet incdir+"/"+text		
				EndIf
				
			EndIf
		EndIf
	Wend
	in.close()
	Return True
EndFunction

Function Piece$(s$,entry,char$=" ")
	Local n
	Local p
	Local a$
	While Instr(s,char+char)
		s=Replace(s,char+char,char)
	Wend
	For n=1 To entry-1
		p=Instr(s,char)
		s=Right(s,Len(s)-p)
		If Not p
			If entry=n Exit Else Return
		EndIf
	Next
	p=Instr(s,char)
	If p<1
		a$=s
	Else
		a=Left(s,p-1)
	EndIf
	Return a
End Function


You should also have a COMPILE_DLL constant, and add this to the start of each function:

If COMPILE_DLL GCEnter()

O_o .... This is awesome.