Browse Source

WIP c2mx2 dev.

Mark Sibly 9 years ago
parent
commit
e73dcd9cf3
3 changed files with 480 additions and 12 deletions
  1. 452 0
      src/c2mx2/cxxtomx2.monkey2
  2. 26 3
      src/c2mx2/test.h
  3. 2 9
      src/c2mx2/test.json

+ 452 - 0
src/c2mx2/cxxtomx2.monkey2

@@ -0,0 +1,452 @@
+
+#Import "<libc>"
+#Import "<std>"
+
+#Import "libclang_extern.monkey2"
+
+Using libc..
+Using std..
+
+Using libclang..
+
+Global tab:String
+Global buf:=New StringStack
+
+Global enumType:=""
+Global superType:=""
+Global paramDecls:=New Stack<CXCursor>
+
+Global LongType:="Long"
+Global ULongType:="ULong"
+Global LongLongType:="Long"
+Global ULongLongType:="ULong"
+
+Struct CXString Extension
+	Method To:String()
+		Return ToString( Self )
+	End
+End
+
+Function ToString:String( str:CXString )
+	Local cstr:=clang_getCString( str )
+	clang_disposeString( str )
+	Return cstr
+End
+
+Function ToCString:const_char_t Ptr( str:String )
+	Local n:=str.Length+1
+	Local buf:=Cast<Byte Ptr>( malloc( n ) )
+	str.ToCString( buf,n )
+	Return Cast<const_char_t Ptr>( buf )
+End
+
+Function Emit( str:String )
+	If str.StartsWith( "}" ) tab=tab.Slice( 0,-1 ) ; str=str.Slice( 1 )
+	If str.EndsWith( "{" )
+		buf.Push( tab+str.Slice( 0,-1 ) )
+		tab+="~t"
+	Else
+		buf.Push( tab+str )
+	Endif
+End
+
+Function Err( cursor:CXCursor )
+
+	Local srcloc:=clang_getCursorLocation( cursor )
+	
+	Local err:="Error translating '"+String( clang_getCursorDisplayName( cursor ) )+"' : cursor.kind="+Int(cursor.kind)
+	
+	Emit( "'"+err )
+End
+
+Function TransType:String( type:CXType )
+
+	If clang_isConstQualifiedType( type ) Return ""
+	
+	Select type.kind
+	
+	Case CXType_Void Return "Void"
+	
+	Case CXType_SChar Return "Byte"
+	
+	Case CXType_UChar Return "UByte"
+	
+	Case CXType_Bool Return "Bool"
+	
+	Case CXType_Short Return "Short"
+	
+	Case CXType_UShort Return "UShort"
+	
+	Case CXType_Int Return "Int"
+	
+	Case CXType_UInt Return "UInt"
+	
+	Case CXType_Float Return "Float"
+	
+	Case CXType_Double Return "Double"
+	
+	Case CXType_Long Return LongType
+	
+	Case CXType_ULong Return ULongType
+	
+	Case CXType_LongLong Return LongLongType
+	
+	Case CXType_ULongLong Return ULongLongType
+	
+	Case CXType_Pointer 
+	
+		Local ptype:=TransType( clang_getPointeeType( type ) )
+		If ptype Return ptype+" Ptr"
+		
+	Case CXType_ConstantArray
+	
+		Local ptype:=TransType( clang_getElementType( type ) )
+		If ptype Return ptype+" Ptr"
+	
+	Case CXType_IncompleteArray 
+
+		Local ptype:=TransType( clang_getElementType( type ) )
+		If ptype Return ptype+" Ptr"
+	
+	Case CXType_Record
+	
+		Return clang_getTypeSpelling( type )
+		
+	Case CXType_Elaborated
+	
+		Return TransType( clang_Type_getNamedType( type ) )
+
+	Case CXType_Typedef
+	
+		Return clang_getTypeSpelling( type )
+		
+	End
+	
+	Return "Bad("+Int(type.kind)+")"
+End
+
+Function TransType:String( cursor:CXCursor )
+
+	Return TransType( clang_getCursorType( cursor ) )
+End
+
+Function TransIdent:String( cursor:CXCursor )
+
+	Local id:=String( clang_getCursorSpelling( cursor ) )
+	
+	Return id
+
+End
+
+Function EmitTypedefDecl:Bool( cursor:CXCursor )
+
+	If cursor.kind<>CXCursor_TypedefDecl Return False
+	
+	Local id:=TransIdent( cursor )
+	If Not id Return False
+	
+	Local type:=TransType( clang_getTypedefDeclUnderlyingType( cursor ) )
+	If Not type Return False
+	
+	If id=type Return True
+	
+	Emit( "Alias "+id+":"+type )
+	
+	Return True
+End
+
+Function EmitEnumDecl:Bool( cursor:CXCursor )
+
+	If cursor.kind<>CXCursor_EnumDecl Return False
+	
+	Local id:=TransIdent( cursor )
+	If Not id Return False
+	
+	Emit( "Enum "+id )
+	Emit( "End" )
+	
+	enumType=id
+	clang_visitChildren( cursor,VisitEnumDecl,Null )
+
+	Return True	
+End
+
+Function EmitTypeDecl:Bool( cursor:CXCursor )
+
+	Local kind:=""
+	Select cursor.kind
+	Case CXCursor_ClassDecl
+		kind="Class"
+	Case CXCursor_StructDecl,CXCursor_UnionDecl
+		kind="Struct"
+	Default
+		Return False
+	End
+
+	Local id:=TransIdent( cursor )
+	If Not id Return False
+	
+	If Not clang_isCursorDefinition( cursor ) Return True
+
+	Local pos:=buf.Length
+	Emit( kind+" "+id+"{" )
+	
+	superType=""
+	clang_visitChildren( cursor,VisitTypeDecl,Null )
+	
+	If kind="Class"
+		If superType
+			buf[pos]+=" Extends "+superType
+		Else
+			buf[pos]+=" Extends Void"
+		End
+	Endif
+	
+	Emit( "}End" )
+	
+	Return True
+End
+
+Function EmitFuncDecl:Bool( cursor:CXCursor )
+
+	Local kind:="",id:=""
+	Select cursor.kind
+	Case CXCursor_FunctionDecl
+		kind="Function"
+	Case CXCursor_CXXMethod
+		kind="Method"
+	Case CXCursor_Constructor
+		kind="Method"
+		id="New"
+	Default
+		Return False
+	End
+
+	If Not id 
+		id=TransIdent( cursor )
+		If Not id Return False
+	Endif
+	
+	Local ftype:=clang_getCursorType( cursor )
+	
+	Local retType:=TransType( clang_getResultType( ftype ) )
+	If Not retType Return False
+	
+	paramDecls.Clear()
+	clang_visitChildren( cursor,VisitFuncDecl,Null )
+	
+	Local argTypes:=New Stack<String>
+	
+	For Local param:=Eachin paramDecls
+	
+		Local id:=TransIdent( param )
+		If Not id Return False
+	
+		Local type:=TransType( param )
+		If Not type Return False
+		
+		argTypes.Push( id+":"+type )
+	Next
+	
+	local mods:=""
+	If kind="Method" And clang_CXXMethod_isVirtual( cursor ) mods=" Virtual"
+	
+	Emit( kind+" "+id+":"+retType+"("+argTypes.Join( "," )+")"+mods )
+	
+	Return True
+End
+
+Function EmitVarDecl:Bool( cursor:CXCursor )
+
+	Local kind:=""
+	Select cursor.kind
+	Case CXCursor_VarDecl
+		kind=clang_isConstQualifiedType( clang_getCursorType( cursor ) ) ? "Const" Else "Global"
+	Case CXCursor_FieldDecl
+		kind="Field"
+	Default
+		Return False
+	End
+
+	Local id:=TransIdent( cursor )
+	If Not id Return False
+		
+	Local type:=TransType( cursor )
+	If Not type Return False
+	
+	Emit( kind+" "+id+":"+type )
+	
+	Return True
+End
+
+Function VisitEnumDecl:CXChildVisitResult( cursor:CXCursor,parent:CXCursor,client_data:CXClientData )
+
+	Select cursor.kind
+	
+	Case CXCursor_EnumConstantDecl
+	
+		Emit( "Const "+TransIdent( cursor )+":"+enumType )
+	
+	Default
+	
+		Err( cursor )
+	End
+	
+	Return CXChildVisit_Continue
+End
+
+Function VisitTypeDecl:CXChildVisitResult( cursor:CXCursor,parent:CXCursor,client_data:CXClientData )
+	
+	If clang_getCXXAccessSpecifier( cursor )=CX_CXXPrivate Return CXChildVisit_Continue
+
+	Select cursor.kind
+	
+	Case CXCursor_CXXBaseSpecifier
+	
+		superType=TransType( cursor )
+	
+	Case CXCursor_FieldDecl
+	
+		If Not EmitVarDecl( cursor ) Err( cursor )
+		
+	Case CXCursor_CXXMethod,CXCursor_Constructor
+	
+		If Not EmitFuncDecl( cursor ) Err( cursor )
+		
+	Case CXCursor_CXXAccessSpecifier
+	
+	Default
+	
+		Err( cursor )
+	End
+	
+	Return CXChildVisit_Continue
+End
+
+Function VisitFuncDecl:CXChildVisitResult( cursor:CXCursor,parent:CXCursor,client_data:CXClientData )
+
+	Select cursor.kind
+
+	Case CXCursor_ParmDecl
+	
+		paramDecls.Push( cursor )
+	
+	Default
+	
+		Err( cursor )
+	End
+	
+	Return CXChildVisit_Continue
+End
+
+Function VisitTransUnit:CXChildVisitResult( cursor:CXCursor,parent:CXCursor,client_data:CXClientData )
+
+	Local srcloc:=clang_getCursorLocation( cursor )
+	If clang_Location_isInSystemHeader( srcloc ) Return CXChildVisit_Continue
+
+	Select cursor.kind
+	
+	Case CXCursor_TypedefDecl
+	
+		If Not EmitTypedefDecl( cursor ) Err( cursor )
+		
+	Case CXCursor_EnumDecl
+	
+		If Not EmitEnumDecl( cursor ) Err( cursor )
+	
+	Case CXCursor_StructDecl,CXCursor_ClassDecl
+	
+		If Not EmitTypeDecl( cursor ) Err( cursor )
+		
+	Case CXCursor_FunctionDecl
+	
+		If Not EmitFuncDecl( cursor ) Err( cursor )
+
+	Case CXCursor_VarDecl
+	
+		If Not EmitVarDecl( cursor ) Err( cursor )
+		
+	Default
+	
+		Err( cursor )
+	
+	End
+	
+	Return CXChildVisit_Continue
+
+End
+
+Function VisitDebug:CXChildVisitResult( cursor:CXCursor,parent:CXCursor,client_data:CXClientData )
+
+	Local ctype:=clang_getCursorType( cursor )
+
+	Print tab+clang_getCursorSpelling( cursor )+":"+clang_getTypeSpelling( ctype )+", cursor kind="+Int( cursor.kind )+", type kind="+Int( ctype.kind )
+	
+	tab+="~t"
+	clang_visitChildren( cursor,VisitDebug,Null )
+	tab=tab.Slice( 0,-1 )
+
+	Return CXChildVisit_Continue
+End
+
+Function Main()
+
+	Local path:=RequestFile( "Select c2mx2.json file...","Json files:json" )
+	If Not path Return
+	
+	Local config:=JsonObject.Load( path )
+	If Not config
+		Print "C2mx2: Failed to load JSON object from "+path
+		Return
+	Endif
+
+	If Not config.Contains( "clangArgs" )
+		Print "C2mx2: No clangArgs specified"
+		Return
+	Endif
+	
+	If Not config.Contains( "inputFile" )
+		Print "C2mx2: No inputFile specified"
+		Return
+	Endif
+	
+	If Not config.Contains( "outputFile" )
+		Print "C2mx2: No outputFile specified"
+		Return
+	Endif
+
+	'change to working dir
+	ChangeDir( ExtractDir( path ) )
+	
+	If config.Contains( "workingDir" ) 
+		ChangeDir( config.GetString( "workingDir" ) )
+	Endif
+	
+	'clang args
+	Local cargs:=config.GetArray( "clangArgs" )
+	Local args:=New const_char_t Ptr[cargs.Length]
+	For Local i:=0 Until args.Length
+		args[i]=ToCString( cargs[i].ToString() )
+	Next
+	
+	'input file
+	Local inputFile:=config.GetString( "inputFile" )
+	
+	'outfile file
+	Local outputFile:=config.GetString( "outputFile" )
+
+	'start clang	
+	Local clangIndex:=clang_createIndex( 1,1 )
+	
+	'create trans unit
+	Local transUnit:=clang_createTranslationUnitFromSourceFile( clangIndex,inputFile,args.Length,args.Data,0,Null )
+	Assert( transUnit,"Failed to create translation unit from source file" )
+	
+	Local cursor:=clang_getTranslationUnitCursor( transUnit )
+	
+	clang_visitChildren( cursor,VisitTransUnit,Null )
+'	clang_visitChildren( cursor,VisitDebug,Null )
+	
+	Print buf.Join( "~n" )
+
+End

+ 26 - 3
src/c2mx2/test.h

@@ -1,10 +1,21 @@
 
+class C;
+
 struct S{
+	int x,y,z;
 };
 
 typedef S MS;
 
-void update( S &s );
+typedef int Myint;
+
+enum E{
+	x,y,z;
+};
+
+void Update( float f );
+
+void Update( float *p );
 
 void update2( const S *s );
 
@@ -13,11 +24,23 @@ void update3( const MS *s );
 class C{
 	public:
 	
+	C();
+	
+	C( int x );
+	
 	int x,y,z;
 	
-	void update( S &s );
+	virtual void update( float t );
+
+	void render();
+};
+
+class D : public C{
+	public:
+	
+	int d,e,f;
 	
-	const S &render();
+	virtual void update( float t );
 };
 
 float A,B,C;

+ 2 - 9
src/c2mx2/test.json

@@ -7,13 +7,6 @@
 	
 	"inputFile":"test.h",
 	
-	"outputDir":"test_api",
-	
-	"outputFile":"test",
-	
-	"header":[
-		"",
-		"Extern",
-		""
-	]
+	"outputFile":"test_extern"
+
 }