Просмотр исходного кода

Improved function pointer handling - args generation, interface persistence.
Correctly parse array types from interface.
Object/String cast improvement.
Added brl.linkedlist test.

woollybah 11 лет назад
Родитель
Сommit
a2741c561d

+ 51 - 6
ctranslator.bmx

@@ -48,7 +48,15 @@ Type TCTranslator Extends TTranslator
 		If TLongPtrType( ty ) Return "BBLONG *"
 		If TFunctionPtrType( ty ) Then
 			Local retType:String = TransType(TFunctionPtrType(ty).func.retType, "")
-			Local args:String = "/* TODO */"
+			Local args:String
+			For Local arg:TArgDecl = EachIn TFunctionPtrType(ty).func.argDecls
+				arg.Semant()
+				If args Then
+					args :+ ","
+				End If
+				
+				args :+ TransType(arg.ty, "")
+			Next
 			Return retType + Bra("* " + ident) + Bra(args)
 		End If
 		If TBytePtrPtrType( ty ) Return "BBBYTE **"
@@ -175,6 +183,10 @@ Type TCTranslator Extends TTranslator
 '		End If
 
 		If TStringType(ty) And TObjectType(src) Then
+			If Not TStringType(ty).cDecl Then
+				ty.Semant()
+			End If
+
 			Return "bbObjectDowncast" + Bra(expr + ",&" + TStringType(ty).cDecl.munged)
 		End If
 
@@ -252,6 +264,8 @@ Type TCTranslator Extends TTranslator
 			Return decl.munged
 		Else If TModuleDecl( decl.scope )
 			Return decl.munged
+		Else If TFuncDecl(decl.scope)
+			Return decl.munged
 		EndIf
 		InternalErr
 	End Method
@@ -299,18 +313,23 @@ Type TCTranslator Extends TTranslator
 				
 				If TVarExpr(lhs) Then
 					Local cdecl:TClassDecl = TObjectType(TVarExpr(lhs).decl.ty).classDecl
-					Local obj:String = Bra("struct " + cdecl.munged + "_obj*")
+ 					Local obj:String = TransFuncObj(cdecl)
 					Local class:String = Bra("(" + obj + TransSubExpr( lhs ) + ")->clas")
-					Return class + "->md_" + decl.ident+TransArgs( args,decl, TransSubExpr( lhs ) )
+					Return class + "->" + TransFuncPrefix(cdecl) + decl.ident+TransArgs( args,decl, TransSubExpr( lhs ) )
 				Else If TNewObjectExpr(lhs) Then
 					Local cdecl:TClassDecl = TNewObjectExpr(lhs).classDecl
 					Local class:String = cdecl.munged
-					Return class + ".md_" + decl.ident+TransArgs( args,decl, TransSubExpr( lhs ) )
+					Return class + "." + TransFuncPrefix(cdecl) + decl.ident+TransArgs( args,decl, TransSubExpr( lhs ) )
 				Else If TCastExpr(lhs) Then
 					Local cdecl:TClassDecl = TObjectType(TCastExpr(lhs).ty).classDecl
-					Local obj:String = Bra("struct " + cdecl.munged + "_obj*")
+					Local obj:String = TransFuncObj(cdecl)
+					Local class:String = Bra("(" + obj + TransSubExpr( lhs ) + ")->clas")
+					Return class + "->" + TransFuncPrefix(cdecl) + decl.ident+TransArgs( args,decl, TransSubExpr( lhs ) )
+				Else If TMemberVarExpr(lhs) Then
+					Local cdecl:TClassDecl = TObjectType(TMemberVarExpr(lhs).decl.ty).classDecl
+					Local obj:String = TransFuncObj(cdecl)
 					Local class:String = Bra("(" + obj + TransSubExpr( lhs ) + ")->clas")
-					Return class + "->md_" + decl.ident+TransArgs( args,decl, TransSubExpr( lhs ) )
+					Return class + "->" + TransFuncPrefix(cdecl) + decl.ident+TransArgs( args,decl, TransSubExpr( lhs ) )
 				Else
 					InternalErr
 				End If
@@ -333,6 +352,22 @@ Type TCTranslator Extends TTranslator
 		Return TransStatic( decl )+TransArgs( args,decl )
 	End Method
 	
+	Method TransFuncObj:String(decl:TClassDecl)
+		If decl.ident = "Object"
+			Return Bra("BBOBJECT")
+		Else
+			Return Bra("struct " + decl.munged + "_obj*")
+		End If
+	End Method
+
+	Method TransFuncPrefix:String(decl:TClassDecl)
+		If decl.ident = "Object"
+			Return ""
+		Else
+			Return "md_"
+		End If
+	End Method
+	
 	Method TransSuperFunc$( decl:TFuncDecl,args:TExpr[] )
 		If decl.IsMethod()
 			Return decl.ClassScope().munged+".md_"+decl.ident+TransArgs( args,decl, "o" )
@@ -1726,6 +1761,16 @@ End Rem
 		If TStringType(expr.exprType) Then
 			Return "$" + Enquote(expr.Eval())
 		EndIf
+		
+		If TFunctionPtrType(expr.exprType) Then
+			If TCastExpr(expr) Then
+				If TInvokeExpr(TCastExpr(expr).expr) Then
+					Return Enquote(TInvokeExpr(TCastExpr(expr).expr).decl.munged)
+				End If
+			End If
+			
+			InternalErr
+		End If
 
 	End Method
 

+ 29 - 3
decl.bmx

@@ -211,7 +211,31 @@ Type TValDecl Extends TDecl
 	Method OnSemant()
 		If declTy
 			ty=declTy.Semant()
-			If declInit init=declInit.Copy().SemantAndCast(ty)
+			If declInit Then
+				If TFunctionPtrType(ty) Then
+'If ident = "compareFunc" DebugStop
+					'init=declInit.Copy().SemantAndCast(ty)
+					
+					Local argExpr:TExpr[] = New TExpr[0]
+					For Local arg:TArgDecl = EachIn TFunctionPtrType(ty).func.argDecls
+						Local aexp:TIdentTypeExpr = New TIdentTypeExpr.Create(arg.declTy)
+						aexp._Semant()
+						argExpr :+ [aexp]
+					Next
+					
+					Local expr:TExpr=declInit.Copy().SemantFunc(argExpr)
+					If expr.exprType.EqualsType( ty ) Then
+						init = expr
+					Else
+						init = New TCastExpr.Create( ty,expr,CAST_EXPLICIT ).Semant()
+					End If
+
+					
+					
+				Else
+					init=declInit.Copy().SemantAndCast(ty)
+				End If
+			End If
 		Else If declInit
 			init=declInit.Copy().Semant()
 			ty=init.exprType
@@ -586,7 +610,7 @@ End Rem
 	
 	Method FindFuncDecl:TFuncDecl( ident$,argExprs:TExpr[] = Null,explicit:Int=False )
 'DebugLog "FindFuncDecl : " + ident
-'If ident = "Print" Then DebugStop
+'If ident = "compareFunc" Then DebugStop
 		'Local funcs:TFuncDeclList=TFuncDeclList( FindDecl( ident ) )
 		Local f:TDecl = TDecl(findDecl(ident))
 		If Not f Then Return Null
@@ -846,7 +870,9 @@ Type TFuncDecl Extends TBlockDecl
 
 		'semant ret type
 		If Not retTypeExpr Then
-			retType = TType.voidType
+			If Not retType Then ' may have previously been set (if this is a function pointer)
+				retType = TType.voidType
+			End If
 		Else
 			retType=retTypeExpr.Semant()
 		End If

+ 42 - 1
expr.bmx

@@ -646,12 +646,16 @@ Type TCastExpr Extends TExpr
 		
 		'upcast?
 		If src.ExtendsType( ty )
-	
 			'cast from void[] to T[]
 			If TArrayType(src) And TVoidType( TArrayType(src).elemType )
 				Return New TConstExpr.Create( ty,"" ).Semant()
 			EndIf
 		
+		
+			If TStringType(src) And TObjectType(ty)
+				exprType = ty
+				Return expr
+			End If
 			'Box/unbox?...
 			'If TObjectType( ty ) And Not TObjectType( src )
 
@@ -1198,3 +1202,40 @@ Type TArrayExpr Extends TExpr
 	End Method
 
 End Type
+
+Type TIdentTypeExpr Extends TExpr
+	Field cdecl:TClassDecl
+	
+	Method Create:TIdentTypeExpr( ty:TType )
+		Self.exprType=ty
+		Return Self
+	End Method
+	
+	Method Copy:TExpr()
+		Return New TIdentTypeExpr.Create( exprType )
+	End Method
+
+	Method _Semant()
+		If cdecl Return
+		exprType=exprType.Semant()
+		cdecl=exprType.GetClass()
+		If Not cdecl InternalErr
+	End Method
+		
+	Method Semant:TExpr()
+		_Semant
+		Err "Expression can't be used in this way"
+	End Method
+	
+	Method SemantFunc:TExpr( args:TExpr[] )
+		_Semant
+		If args.Length=1 And args[0] Return args[0].Cast( cdecl.objectType,CAST_EXPLICIT )
+		Err "Illegal number of arguments for type conversion"
+	End Method
+	
+	Method SemantScope:TScopeDecl()
+		_Semant
+		Return cdecl
+	End	Method
+
+End Type

+ 4 - 0
iparser.bmx

@@ -940,6 +940,10 @@ End Rem
 		
 		If CParse( "&" ) Then
 		End If
+
+		While CParse( "[]" )
+			ty=New TArrayType.Create( ty )
+		Wend
 		
 		Return ty
 	End Method

+ 5 - 37
parser.bmx

@@ -119,41 +119,6 @@ Type TForEachinStmt Extends TStmt
 
 End Type
 
-Type TIdentTypeExpr Extends TExpr
-	Field cdecl:TClassDecl
-	
-	Method Create:TIdentTypeExpr( ty:TType )
-		Self.exprType=ty
-	End Method
-	
-	Method Copy:TExpr()
-		Return New TIdentTypeExpr.Create( exprType )
-	End Method
-
-	Method _Semant()
-		If cdecl Return
-		exprType=exprType.Semant()
-		cdecl=exprType.GetClass()
-		If Not cdecl InternalErr
-	End Method
-		
-	Method Semant:TExpr()
-		_Semant
-		Err "Expression can't be used in this way"
-	End Method
-	
-	Method SemantFunc:TExpr( args:TExpr[] )
-		_Semant
-		If args.Length=1 And args[0] Return args[0].Cast( cdecl.objectType,CAST_EXPLICIT )
-		Err "Illegal number of arguments for type conversion"
-	End Method
-	
-	Method SemantScope:TScopeDecl()
-		_Semant
-		Return cdecl
-	End	Method
-
-End Type
 
 Type TIdentExpr Extends TExpr
 	Field ident$
@@ -1795,8 +1760,11 @@ End If
 
 		If funcDecl.IsExtern() Or (attrs & FUNC_PTR)
 			funcDecl.munged=funcDecl.ident
-			If CParse( "=" )
-				funcDecl.munged=ParseStringLit()
+			
+			If Not (attrs & FUNC_PTR) Then
+				If CParse( "=" )
+					funcDecl.munged=ParseStringLit()
+				End If
 
 				'Array $resize hack!
 				'If funcDecl.munged="$resize"

+ 26 - 0
tests/framework/mod/brl/linkedlist/list_01.bmx

@@ -0,0 +1,26 @@
+SuperStrict
+
+Framework BRL.LinkedList
+Import BRL.StandardIO
+
+Local planets:String[] = ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
+
+Local list:TList = CreateList()
+
+For Local planet:String = EachIn planets
+	list.AddLast(planet)
+Next
+
+Print "IsEmpty = " + list.IsEmpty()
+Print "Count   = " + list.Count()
+Print "First   = " + String(list.First())
+Print "Last    = " + String(list.Last())
+Print "Contains(Pluto) = " + list.Contains("Pluto")
+Print "Contains(Earth) = " + list.Contains("Earth")
+Print "First Removed   = " + String(list.RemoveFirst())
+Print "First   = " + String(list.First())
+Print "Last Removed    = " + String(list.RemoveLast())
+Print "Last    = " + String(list.Last())
+Print "Count   = " + list.Count()
+Print "ValueAtIndex(2) = " + String(list.ValueAtIndex(2))
+

+ 12 - 0
tests/framework/mod/brl/linkedlist/list_01.res

@@ -0,0 +1,12 @@
+IsEmpty = 0
+Count   = 8
+First   = Mercury
+Last    = Neptune
+Contains(Pluto) = 0
+Contains(Earth) = 1
+First Removed   = Mercury
+First   = Venus
+Last Removed    = Neptune
+Last    = Uranus
+Count   = 6
+ValueAtIndex(2) = Mars

+ 3 - 0
tests/todos/allowPropertyField.bmx

@@ -1,4 +1,7 @@
 SuperStrict
+
+Framework BRL.StandardIO
+
 'Ron: No .res file is needed as we just care for "compiling successful".
 
 local property:string = "allowed in original bcc but not in bcc-ng"

+ 7 - 0
translator.bmx

@@ -138,6 +138,13 @@ Type TTranslator
 		EndIf
 		mungScope.Insert munged,decl
 		decl.munged=munged
+		
+		' a function pointers' real function is stored in "func" - need to set its munged to match the parent.
+		If TValDecl(decl) Then
+			If TFunctionPtrType(TValDecl(decl).ty) Then
+				TFunctionPtrType(TValDecl(decl).ty).func.munged = munged
+			End If
+		End If
 	End Method
 
 Rem

+ 5 - 0
type.bmx

@@ -354,6 +354,11 @@ Type TStringType Extends TType
 		Return cdecl
 	End Method
 	
+	Method Semant:TType()
+		GetClass()
+		Return Self
+	End Method
+	
 	Method ToString$()
 		Return "String"
 	End Method