Parcourir la source

Updates for debugger.
Fixed flags casting and limits.

woollybah il y a 6 ans
Parent
commit
656aa73c98
5 fichiers modifiés avec 111 ajouts et 28 suppressions
  1. 2 0
      config.bmx
  2. 54 24
      ctranslator.bmx
  3. 23 3
      decl.bmx
  4. 32 0
      enums.c
  5. 0 1
      type.bmx

+ 2 - 0
config.bmx

@@ -32,6 +32,7 @@ Import BRL.Math
 Import "options.bmx"
 Import "base.stringhelper.bmx"
 Import "base64.bmx"
+Import "enums.c"
 
 ' debugging help
 Const DEBUG:Int = False
@@ -477,4 +478,5 @@ End Type
 
 Extern
 	Function strlen_:Int(s:Byte Ptr)="strlen"
+	Function bmx_enum_next_power(char:Int, val:Long Var, ret:Long Var)
 End Extern

+ 54 - 24
ctranslator.bmx

@@ -456,7 +456,13 @@ Type TCTranslator Extends TTranslator
 				End If
 			End If
 			If TFunctionPtrType( ty) Return "&brl_blitz_NullFunctionError" ' todo ??
-			If TEnumType( ty ) Return TEnumType( ty ).decl.values[0].Value()
+			If TEnumType( ty ) Then
+				If TEnumType( ty ).decl.isFlags Then
+					Return "0"
+				Else
+					Return TEnumType( ty ).decl.values[0].Value()
+				End If
+			End If
 		EndIf
 		InternalErr "TCTranslator.TransValue"
 	End Method
@@ -1103,27 +1109,43 @@ t:+"NULLNULLNULL"
 						End If
 					End If
 				Else If TCastExpr(lhs) Then
-					' create a local variable of the inner invocation
-					Local lvar:String = CreateLocal(lhs, False, False)
-					Local lvarInit:String = Bra(lvar + " = " + lhs.Trans())
 
-					Local cdecl:TClassDecl = TObjectType(TCastExpr(lhs).ty).classDecl
-					Local obj:String = Bra(TransObject(cdecl))
-					If decl.attrs & FUNC_PTR Then
-						Return "(" + obj + TransSubExpr( lhs ) + ")->" + decl.munged+TransArgs( args,decl, Null)
-					Else
-						' Null test
-						If opt_debug Then
-							lvarInit = TransDebugNullObjectError(lvarInit, cdecl)
-						End If
+					Local ty:TType = TCastExpr(lhs).ty
 
-						If cdecl.IsInterface() And Not equalsBuiltInFunc(cdecl, decl) Then
-							Local ifc:String = Bra("(struct " + cdecl.munged + "_methods*)" + Bra("bbObjectInterface(" + obj + lvarInit + ", " + "&" + cdecl.munged + "_ifc)"))
-							Return ifc + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
+					If TObjectType(ty) Then
+						' create a local variable of the inner invocation
+						Local lvar:String = CreateLocal(lhs, False, False)
+						Local lvarInit:String = Bra(lvar + " = " + lhs.Trans())
+
+						Local cdecl:TClassDecl = TObjectType(ty).classDecl
+						Local obj:String = Bra(TransObject(cdecl))
+						If decl.attrs & FUNC_PTR Then
+							Return "(" + obj + TransSubExpr( lhs ) + ")->" + decl.munged+TransArgs( args,decl, Null)
 						Else
-							Local class:String = Bra("(" + obj + lvarInit + ")->clas" + tSuper)
-							Return class + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
+							' Null test
+							If opt_debug Then
+								lvarInit = TransDebugNullObjectError(lvarInit, cdecl)
+							End If
+	
+							If cdecl.IsInterface() And Not equalsBuiltInFunc(cdecl, decl) Then
+								Local ifc:String = Bra("(struct " + cdecl.munged + "_methods*)" + Bra("bbObjectInterface(" + obj + lvarInit + ", " + "&" + cdecl.munged + "_ifc)"))
+								Return ifc + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
+							Else
+								Local class:String = Bra("(" + obj + lvarInit + ")->clas" + tSuper)
+								Return class + "->" + TransFuncPrefix(cdecl, decl) + FuncDeclMangleIdent(decl)+TransArgs( args,decl, lvar )
+							End If
+						End If
+					Else If TEnumType(ty) Then
+
+						If TEnumDecl(decl.scope) Then
+							' since we already have the ordinal, we can simply output that
+							If decl.ident = "Ordinal" Then
+								Return Bra(TransSubExpr( lhs ))
+							Else
+								Return decl.munged + Bra(TransSubExpr( lhs ))
+							End If
 						End If
+
 					End If
 
 				Else If TMemberVarExpr(lhs) Then
@@ -1296,6 +1318,14 @@ t:+"NULLNULLNULL"
 							End If
 						End If
 					End If
+				Else If TEnumType(lhs.exprType) Then
+
+					If decl.ident = "Ordinal" Then
+						Return Bra(TransSubExpr( lhs ))
+					Else
+						Return decl.munged + Bra(TransSubExpr( lhs ))
+					End If
+
 				Else
 					InternalErr "TCTranslator.TransFunc"
 				End If
@@ -5952,6 +5982,11 @@ End If
 			Next
 		Next
 
+		' initialise enums
+		For Local decl:TEnumDecl = EachIn app.Semanted()
+			Emit decl.munged + "_BBEnum_impl = &" + decl.munged + "_BBEnum;"
+		Next
+
 		' register types
 		For Local decl:TDecl=EachIn app.Semanted()
 
@@ -5972,7 +6007,7 @@ End If
 			EndIf
 			Local edecl:TEnumDecl = TEnumDecl( decl )
 			If edecl Then
-				Emit "bbObjectRegisterEnum(&" + edecl.munged + "_scope);"
+				Emit "bbEnumRegister(" + decl.munged + "_BBEnum_impl, &" + edecl.munged + "_scope);"
 			End If
 		Next
 		'
@@ -5982,11 +6017,6 @@ End If
 			Emit "_defDataOffset = &_defData;"
 		End If
 
-		' initialise enums
-		For Local decl:TEnumDecl = EachIn app.Semanted()
-			Emit decl.munged + "_BBEnum_impl = &" + decl.munged + "_BBEnum;"
-		Next
-
 		' initialise globals
 		For Local decl:TGlobalDecl=EachIn app.semantedGlobals
 

+ 23 - 3
decl.bmx

@@ -3552,11 +3552,21 @@ Type TEnumValueDecl Extends TDecl
 					If parent.isFlags Then
 						If val = 0 Then
 							val = 1 
-						Else If (val & (val - 1)) = 0 Then ' power of 2 ?
-							val :Shl 1
 						Else
+							If (val & (val - 1)) = 0 Then
+								val :+ 1
+							End If
 							' find next power of 2
-							val = 2 ^ Ceil(Log(val)/Log(2))
+
+							Local res:Long
+							bmx_enum_next_power(Asc(TypeCode(parent.ty)), val, res)
+
+							If Not res Then
+								Err "Flags out of bounds at '" + ident + "'."
+							End If
+							
+							val = res
+							
 						End If
 					Else
 						val :+ 1
@@ -3578,6 +3588,16 @@ Type TEnumValueDecl Extends TDecl
 	Method Value:String()
 		Return TConstExpr(expr).value
 	End Method
+
+	Method TypeCode:String(ty:TType)
+		If TByteType( ty ) Return "b"
+		If TShortType( ty ) Return "s"
+		If TIntType( ty ) Return "i"
+		If TUIntType( ty ) Return "u"
+		If TLongType( ty ) Return "l"
+		If TULongType( ty ) Return "y"
+		If TSizeTType( ty ) Return "z"
+	End Method
 	
 	Method ToString:String()
 		Return "TEnumValueDecl"

+ 32 - 0
enums.c

@@ -0,0 +1,32 @@
+
+#include <math.h>
+#include <stdio.h>
+
+void bmx_enum_next_power(int t, long long * val, unsigned long long * ret) {
+	unsigned long long result = pow(2.0, ceil(log(*val)/log(2))) + 0.5;
+
+	switch (t) {
+		case 'b':
+			*ret = result < 0xffLLU ? result : 0;
+			break;	
+		case 's':
+			*ret  = result < 0xffffLLU ? result : 0;
+			break;	
+		case 'i':
+		case 'u':
+			*ret = result < 0xffffffffLLU ? result : 0;
+			break;	
+		case 'l':
+		case 'y':
+			*ret = result < 0xffffffffffffffffLLU ? result : 0;
+			break;	
+		case 'z':
+			if (sizeof(size_t) == 8) {
+				*ret = result < 0xffffffffLLU ? result : 0;
+			} else {
+				*ret = result < 0xffffffffffffffffLLU ? result : 0;
+			}
+			break;	
+	}
+}
+

+ 0 - 1
type.bmx

@@ -2042,7 +2042,6 @@ Type TEnumType Extends TType
 
 	Method ExtendsType:Int( ty:TType, noExtendString:Int = False, widensTest:Int = False )
 		If _flags & T_VARPTR And (TEnumType(ty) <> Null Or IsPointerType(ty, 0, T_POINTER)) Return True
-		Return (widensTest And WidensToType(ty)) Or (Not noExtendString And TStringType( ty )<>Null)
 	End Method
 
 	Method WidensToType:Int( ty:TType )