Bladeren bron

Added type function overload.
Added nomangle metadata option for functions.

woollybah 9 jaren geleden
bovenliggende
commit
617d9e9fca
4 gewijzigde bestanden met toevoegingen van 96 en 31 verwijderingen
  1. 14 14
      ctranslator.bmx
  2. 33 1
      decl.bmx
  3. 27 10
      parser.bmx
  4. 22 6
      translator.bmx

+ 14 - 14
ctranslator.bmx

@@ -426,7 +426,7 @@ Type TCTranslator Extends TTranslator
 										Local obj:String = Bra("struct " + scope.munged + "_obj*")
 										Local class:String = "o->clas"
 				
-										t:+ class + "->f_" + fdecl.ident
+										t:+ class + "->f_" + fdecl.ident + MangleMethod(fdecl)
 									Else
 										t:+ fdecl.munged
 									End If
@@ -754,7 +754,7 @@ t:+"NULLNULLNULL"
 				Local scope:TScopeDecl = _env.ClassScope()
 				Local obj:String = Bra("struct " + scope.munged + "_obj*")
 				Local class:String = "o->clas"
-				Return class + "->f_" + decl.ident
+				Return class + "->f_" + decl.ident + MangleMethod(TFuncDecl(decl))
 			Else
 				Return decl.munged
 			End If
@@ -1269,7 +1269,7 @@ t:+"NULLNULLNULL"
 			If expr.classDecl = expr.ctor.scope Then
 				ctorMunged = expr.ctor.munged
 			Else
-				ctorMunged = expr.classDecl.actual.munged + "_" + expr.ctor.ident + MangleMethodArgs(expr.ctor)
+				ctorMunged = expr.classDecl.actual.munged + "_" + expr.ctor.ident + MangleMethod(expr.ctor)
 			End If
 
 			If expr.instanceExpr Then
@@ -2348,12 +2348,12 @@ End Rem
 	
 	Method FuncDeclMangleIdent:String(fdecl:TFuncDecl)
 
-		If Not fdecl.IsMethod() Or equalsBuiltInFunc(fdecl.classScope(), fdecl) Then
+		If (Not fdecl.ClassScope()) Or equalsBuiltInFunc(fdecl.classScope(), fdecl) Then
 			Return fdecl.ident
 		End If	
 	
 		If Not fdecl.mangled Then
-			fdecl.mangled = fdecl.ident + MangleMethodArgs(fdecl)
+			fdecl.mangled = fdecl.ident + MangleMethod(fdecl)
 		End If
 
 		Return fdecl.mangled		
@@ -3027,7 +3027,7 @@ End Rem
 			Emit "{"
 			Emit "BBDEBUGDECL_CONST,"
 			Emit Enquote(decl.ident) + ","
-			Emit Enquote(TransDebugScopeType(decl.ty) + TransDebugMetaData(decl.metadata)) + ","
+			Emit Enquote(TransDebugScopeType(decl.ty) + TransDebugMetaData(decl.metadata.metadataString)) + ","
 			
 			_appInstance.mapStringConsts(decl.value)
 			
@@ -3048,7 +3048,7 @@ End Rem
 			Emit "{"
 			Emit "BBDEBUGDECL_FIELD,"
 			Emit Enquote(decl.ident) + ","
-			Emit Enquote(TransDebugScopeType(decl.ty) + TransDebugMetaData(decl.metadata)) + ","
+			Emit Enquote(TransDebugScopeType(decl.ty) + TransDebugMetaData(decl.metadata.metadataString)) + ","
 
 			Local offset:String = ".field_offset=offsetof" + Bra("struct " + classDecl.munged + "_obj," + decl.munged)
 '			If WORD_SIZE = 8 Then
@@ -3107,7 +3107,7 @@ End Rem
 				s:+ TransDebugScopeType(decl.retType)
 			End If
 
-			s:+ TransDebugMetaData(decl.metadata)
+			s:+ TransDebugMetaData(decl.metadata.metadataString)
 
 			Emit Enquote(s) + ","
 			If decl.IsMethod() Or decl.IsCTor() Then 
@@ -3408,7 +3408,7 @@ End Rem
 		Else
 			Emit "BBDEBUGSCOPE_USERTYPE,"
 		End If
-		Emit EnQuote(classDecl.ident + TransDebugMetaData(classDecl.metadata)) + ","
+		Emit EnQuote(classDecl.ident + TransDebugMetaData(classDecl.metadata.metadataString)) + ","
 
 		Emit "{"
 		
@@ -3605,7 +3605,7 @@ End Rem
 			If classDecl = fdecl.scope Then
 				t :+ fdecl.munged
 			Else
-				t :+ classDecl.munged + "_" + fdecl.ident + MangleMethodArgs(fdecl)
+				t :+ classDecl.munged + "_" + fdecl.ident + MangleMethod(fdecl)
 			End If
 		Else
 			t :+ classid + "_New"
@@ -3648,7 +3648,7 @@ End Rem
 		If newDecl And newDecl.chainedCtor Then
 			mungdecl newDecl.chainedCtor.ctor
 			
-			Emit "_" + newDecl.chainedCtor.ctor.ClassScope().munged + "_" + newDecl.chainedCtor.ctor.ident + MangleMethodArgs(newDecl.chainedCtor.ctor) + TransArgs(newDecl.chainedCtor.args, newDecl.chainedCtor.ctor, "o") + ";"
+			Emit "_" + newDecl.chainedCtor.ctor.ClassScope().munged + "_" + newDecl.chainedCtor.ctor.ident + MangleMethod(newDecl.chainedCtor.ctor) + TransArgs(newDecl.chainedCtor.args, newDecl.chainedCtor.ctor, "o") + ";"
 		Else
 			If classDecl.superClass.ident = "Object" Then
 				Emit "bbObjectCtor(o);"
@@ -3758,7 +3758,7 @@ End Rem
 		If classDecl = fdecl.scope Then
 			funcMunged = fdecl.munged
 		Else
-			funcMunged = classDecl.munged + "_" + fdecl.ident + MangleMethodArgs(fdecl)
+			funcMunged = classDecl.munged + "_" + fdecl.ident + MangleMethod(fdecl)
 		End If
 
 		Local t:String = TransObject(classdecl) + " _" + funcMunged + "_ObjectNew"
@@ -3829,7 +3829,7 @@ End Rem
 			If classDecl = fdecl.scope Then
 				t :+ fdecl.munged
 			Else
-				t :+ classDecl.munged + "_" + fdecl.ident + MangleMethodArgs(fdecl)
+				t :+ classDecl.munged + "_" + fdecl.ident + MangleMethod(fdecl)
 			End If
 		Else
 			t :+ classid + "_New"
@@ -3874,7 +3874,7 @@ End Rem
 		If classDecl = fdecl.scope Then
 			t :+ fdecl.munged
 		Else
-			t :+ classDecl.munged + "_" + fdecl.ident + MangleMethodArgs(fdecl)
+			t :+ classDecl.munged + "_" + fdecl.ident + MangleMethod(fdecl)
 		End If
 		
 		t:+ "_ObjectNew"

+ 33 - 1
decl.bmx

@@ -78,6 +78,27 @@ Type TFuncDeclList Extends TList
 	End Method
 End Type
 
+Type TMetadata
+
+	Field metadataString:String
+
+	' key/value pairs
+	Field meta:TMap
+
+	Method InsertMeta(key:String, value:String)
+		If Not meta Then
+			meta = New TMap
+		End If
+		
+		meta.Insert(key, value)
+	End Method
+
+	Method HasMeta:Int(key:String)
+		Return meta And meta.Contains(key.ToLower())
+	End Method
+	
+End Type
+
 Type TDecl
 	Field ident$
 	Field munged$
@@ -85,7 +106,7 @@ Type TDecl
 	Field actual:TDecl
 	Field scope:TScopeDecl
 	Field attrs:Int
-	Field metadata:String
+	Field metadata:TMetadata = New TMetadata
 	
 	Field declImported:Int = False
 	Field generated:Int
@@ -1368,6 +1389,7 @@ Type TFuncDecl Extends TBlockDecl
 	Field returnTypeSubclassed:Int
 	
 	Field mangled:String
+	Field noMangle:Int
 	
 	Field equalsBuiltIn:Int = -1
 	
@@ -1403,6 +1425,7 @@ Type TFuncDecl Extends TBlockDecl
 		t.munged = munged
 		t.metadata = metadata
 		t.mangled = mangled
+		t.noMangle = noMangle
 		Return  t
 	End Method
 
@@ -1549,6 +1572,15 @@ Type TFuncDecl Extends TBlockDecl
 				If decl<>Self And EqualsArgs( decl )
 					Err "Duplicate declaration "+ToString()
 				EndIf
+				If noMangle Then
+					If decl<>Self Then
+						If decl.argDecls.Length = 0 Then
+							Err "You cannot apply NoMangle to the function, as another function with no arguments exists."
+						Else If decl.NoMangle Then
+							Err "Another function is already declared with NoMangle."
+						End If
+					End If
+				End If
 			Next
 		End If
 		

+ 27 - 10
parser.bmx

@@ -2448,14 +2448,15 @@ End Rem
 
 	'should return a specific "metadata object" ?
 	' metadata is in the form : {key key=value key="value"}
-	Method ParseMetaData:String()
-		Local metaDataString:String = ""
+	Method ParseMetaData:TMetadata()
+		Local meta:TMetadata = New TMetadata
+
 		SkipEols
 
 		Repeat
 			
-			If metaDataString Then
-				metaDataString :+ " "
+			If meta.metadataString Then
+				meta.metadataString :+ " "
 			End If
 			
 			Select _tokeType
@@ -2470,11 +2471,13 @@ End Rem
 			End Select
 			
 			'append current token to metaDataString
-			metaDataString :+ _toke
+			Local key:String = _toke
+			meta.metadataString :+ key
 
 			'read next token
 			NextToke()
 
+			Local value:String
 			' got a value
 			If CParse("=") Then
 				
@@ -2482,14 +2485,18 @@ End Rem
 					Err "Meta data must be literal constant"
 				End If
 				
-				metaDataString :+ "=" + _toke
+				value = _toke
+				meta.metadataString :+ "=" + value
 
 				'read next token
 				NextToke()
 			Else
-				metaDataString :+ "=1"	
+				value = "1"
+				meta.metadataString :+ "=1"	
 			End If
 			
+			meta.InsertMeta(key.ToLower(), value)
+			
 			'reached end of meta data declaration
 			If _toke="}" Then Exit
 		Forever
@@ -2498,7 +2505,7 @@ End Rem
 		NextToke()
 
 		'parse this into something
-		Return metaDataString
+		Return meta
 	End Method
 
 
@@ -2510,7 +2517,8 @@ End Rem
 		Local id$
 		Local ty:TType
 		Local meth:Int = attrs & FUNC_METHOD
-		Local meta:String
+		Local meta:TMetadata
+		Local noMangle:Int
 
 		If attrs & FUNC_METHOD
 			If _toke="new"
@@ -2615,6 +2623,14 @@ End Rem
 				'meta data for functions/methods
 				'print "meta for func/meth: "+id+ " -> "+ParseMetaData()
 				meta = ParseMetaData()
+				
+				If meta.HasMeta("nomangle") Then
+					If attrs & FUNC_METHOD Then
+						Err "Only functions can specify NoMangle"
+					Else
+						noMangle = True
+					End If
+				End If
 			Else If _tokeType=TOKE_STRINGLIT
 				' "win32", etc
 				' TODO ? something with this??
@@ -2632,6 +2648,7 @@ End Rem
 			funcDecl=New TNewDecl.CreateF( id,ty,args,attrs )
 		Else
 			funcDecl=New TFuncDecl.CreateF( id,ty,args,attrs )
+			funcDecl.noMangle = noMangle
 		End If
 		If meta Then
 			funcDecl.metadata = meta
@@ -2727,7 +2744,7 @@ End Rem
 		Local args:TClassDecl[]
 		Local superTy:TIdentType
 		Local imps:TIdentType[]
-		Local meta:String
+		Local meta:TMetadata
 
 		'If (attrs & CLASS_INTERFACE) And (attrs & DECL_EXTERN)
 		'	Err "Interfaces cannot be extern."

+ 22 - 6
translator.bmx

@@ -217,7 +217,23 @@ Type TTranslator
 			Return s + "_" + TransMangleType(func.retType) + "_"
 		End If
 	End Method
-		
+
+	Method MangleMethod:String(fdecl:TFuncDecl)
+		If fdecl.IsMethod() Or fdecl.IsCtor() Then
+			Return MangleMethodArgs(fdecl)
+		Else
+			Return MangleMethodRetType(fdecl) + MangleMethodArgs(fdecl)
+		End If
+	End Method
+	
+	Method MangleMethodRetType:String(fdecl:TFuncDecl)
+		If fdecl.retType Then
+			Return "_" + TransMangleType(fdecl.retType)
+		Else
+			Return "_v"
+		End If
+	End Method
+	
 	Method MangleMethodArgs:String(fdecl:TFuncDecl)
 		Local s:String
 		For Local arg:TArgDecl = EachIn fdecl.argDecls
@@ -264,7 +280,7 @@ Type TTranslator
 		Return False
 	End Method
 
-	Method MungMethodDecl( fdecl:TFuncDecl )
+	Method MungFuncDecl( fdecl:TFuncDecl )
 
 		If fdecl.munged Return
 		
@@ -284,8 +300,8 @@ Type TTranslator
 		If fdecl.scope Then
 			fdecl.munged = fdecl.scope.munged + "_" + fdecl.ident
 			
-			If Not equalsBuiltInFunc(fdecl.classScope(), fdecl) Then
-				fdecl.munged :+ MangleMethodArgs(fdecl)
+			If Not equalsBuiltInFunc(fdecl.classScope(), fdecl) And Not fdecl.noMangle Then
+				fdecl.munged :+ MangleMethod(fdecl)
 			End If
 			
 			' fields are lowercase with underscore prefix.
@@ -316,8 +332,8 @@ Type TTranslator
 		
 		' apply mangling to methods and New (ctors)
 		' but don't apply mangling to function pointers
-		If fdecl And (fdecl.IsMethod() Or fdecl.IsCtor()) And Not (fdecl.attrs & FUNC_PTR)
-			MungMethodDecl( fdecl )
+		If fdecl And fdecl.ClassScope() And Not (fdecl.attrs & FUNC_PTR)
+			MungFuncDecl( fdecl )
 			Return
 		End If