Selaa lähdekoodia

Implemented enum Flags stuff.

woollybah 6 vuotta sitten
vanhempi
commit
6967d51d89
2 muutettua tiedostoa jossa 69 lisäystä ja 16 poistoa
  1. 41 12
      decl.bmx
  2. 28 4
      expr.bmx

+ 41 - 12
decl.bmx

@@ -3453,7 +3453,7 @@ Type TEnumDecl Extends TScopeDecl
 	Method OnSemant()
 	Method OnSemant()
 		' validate type
 		' validate type
 		If Not TIntegralType(ty) Then
 		If Not TIntegralType(ty) Then
-			Err "Invalid type '" + ty.ToString() + "'. Enums can only be declared with integral types."
+			Err "Invalid type '" + ty.ToString() + "'. Enums can only be declared as integral types."
 		End If
 		End If
 		
 		
 		For Local val:TEnumValueDecl = EachIn values
 		For Local val:TEnumValueDecl = EachIn values
@@ -3486,7 +3486,7 @@ Type TEnumDecl Extends TScopeDecl
 		fdecl = New TFuncDecl.CreateF("Ordinal", ty, Null, FUNC_METHOD)
 		fdecl = New TFuncDecl.CreateF("Ordinal", ty, Null, FUNC_METHOD)
 		InsertDecl fdecl
 		InsertDecl fdecl
 		fdecl.Semant()
 		fdecl.Semant()
-		
+
 		fdecl = New TFuncDecl.CreateF("Values", New TArrayType.Create(New TEnumType.Create(Self), 1), Null, 0)
 		fdecl = New TFuncDecl.CreateF("Values", New TArrayType.Create(New TEnumType.Create(Self), 1), Null, 0)
 		InsertDecl fdecl
 		InsertDecl fdecl
 		fdecl.Semant()
 		fdecl.Semant()
@@ -3500,13 +3500,12 @@ End Type
 Type TEnumValueDecl Extends TDecl
 Type TEnumValueDecl Extends TDecl
 
 
 	Field expr:TExpr
 	Field expr:TExpr
-	Field ordinal:Int
+	Field index:Int
 	
 	
-	Field generatedValue:Int
 	
 	
-	Method Create:TEnumValueDecl(id:String, ordinal:Int, expr:TExpr)
+	Method Create:TEnumValueDecl(id:String, index:Int, expr:TExpr)
 		Self.ident = id
 		Self.ident = id
-		Self.ordinal = ordinal
+		Self.index = index
 		Self.expr = expr
 		Self.expr = expr
 		Return Self
 		Return Self
 	End Method
 	End Method
@@ -3514,30 +3513,60 @@ Type TEnumValueDecl Extends TDecl
 	Method OnSemant()
 	Method OnSemant()
 		Local parent:TEnumDecl = TEnumDecl(scope)
 		Local parent:TEnumDecl = TEnumDecl(scope)
 		Local previous:TEnumValueDecl
 		Local previous:TEnumValueDecl
-		If ordinal > 0 Then
-			previous = parent.values[ordinal - 1]
+		If index > 0 Then
+			previous = parent.values[index - 1]
 		End If
 		End If
 
 
 		If expr Then
 		If expr Then
+
 			expr = expr.Semant()
 			expr = expr.Semant()
+
+			' 			
+			If TIdentEnumExpr(expr) Then
+				If TIdentEnumExpr(expr).value.scope = parent Then
+					expr = New TConstExpr.Create(parent.ty, TIdentEnumExpr(expr).value.Value()).Semant()
+				End If
+			End If
+			
+			If parent.isFlags And TBinaryMathExpr(expr) Then
+				expr = New TConstExpr.Create(parent.ty, TBinaryMathExpr(expr).Eval())
+			End If
 			
 			
 			If Not TConstExpr(expr) Or Not TIntegralType(TConstExpr(expr).ty) Then
 			If Not TConstExpr(expr) Or Not TIntegralType(TConstExpr(expr).ty) Then
 				Err "Enum values must be integral constants."
 				Err "Enum values must be integral constants."
 			End If
 			End If
 		Else
 		Else
-			Local val:Long = ordinal
+			Local val:Long
+
 			If previous Then
 			If previous Then
-				val = TConstExpr(previous.expr).value.ToLong() + 1
+				'
+				If TConstExpr(previous.expr)
+
+					val = TConstExpr(previous.expr).value.ToLong()
+
+					If parent.isFlags Then
+						If val = 0 Then
+							val = 1 
+						Else If (val & (val - 1)) = 0 Then ' power of 2 ?
+							val :Shl 1
+						Else
+							val :+ 1
+						End If
+					Else
+						val :+ 1
+					End If
+				Else
+					InternalErr "TEnumValueDecl.OnSemant"
+				End If
 			End If
 			End If
 
 
 			expr = New TConstExpr.Create( parent.ty.Copy(), val).Semant()
 			expr = New TConstExpr.Create( parent.ty.Copy(), val).Semant()
-			generatedValue = True
 		
 		
 		End If
 		End If
 	End Method
 	End Method
 
 
 	Method OnCopy:TDecl(deep:Int = True)
 	Method OnCopy:TDecl(deep:Int = True)
-		Return New TEnumValueDecl.Create(ident, ordinal, expr)
+		Return New TEnumValueDecl.Create(ident, index, expr)
 	End Method
 	End Method
 	
 	
 	Method Value:String()
 	Method Value:String()

+ 28 - 4
expr.bmx

@@ -1558,10 +1558,15 @@ Type TCastExpr Extends TExpr
 			Return expr
 			Return expr
 		End If
 		End If
 		
 		
-		If TIntegralType(ty) And TEnumType(src) And flags & CAST_EXPLICIT Then
+		If TIntegralType(ty) And TEnumType(src) And (flags & CAST_EXPLICIT Or flags & 2) Then
 			exprType = ty
 			exprType = ty
 			Return Self
 			Return Self
 		End If
 		End If
+		
+		If TIntegralType(src) And TEnumType(ty) And flags & 2 Then
+			exprType = src
+			Return Self
+		End If
 
 
 		If Not exprType
 		If Not exprType
 			Err "Unable to convert from "+src.ToString()+" to "+ty.ToString()+"."
 			Err "Unable to convert from "+src.ToString()+" to "+ty.ToString()+"."
@@ -1806,6 +1811,7 @@ Type TBinaryMathExpr Extends TBinaryExpr
 			End Try
 			End Try
 		End If
 		End If
 
 
+		Local bitEnumOp:Int
 		Select op
 		Select op
 		Case "&","~~","|","shl","shr","sar"
 		Case "&","~~","|","shl","shr","sar"
 			If TFloat128Type(lhs.exprType) Then
 			If TFloat128Type(lhs.exprType) Then
@@ -1830,6 +1836,12 @@ Type TBinaryMathExpr Extends TBinaryExpr
 				exprType=New TWParamType
 				exprType=New TWParamType
 			Else If TLParamType(lhs.exprType) Then
 			Else If TLParamType(lhs.exprType) Then
 				exprType=New TLParamType
 				exprType=New TLParamType
+			Else If TEnumType(lhs.exprType) And TEnumType(lhs.exprType).decl.isFlags Then
+				exprType = lhs.exprType.Copy()
+				bitEnumOp = 2
+			Else If TEnumType(rhs.exprType) And TEnumType(rhs.exprType).decl.isFlags Then
+				exprType = rhs.exprType.Copy()
+				bitEnumOp = 2
 			Else
 			Else
 				exprType=New TIntType
 				exprType=New TIntType
 			End If
 			End If
@@ -1855,13 +1867,13 @@ Type TBinaryMathExpr Extends TBinaryExpr
 		If (op = "+" Or op = "-") And IsPointerType(exprType, 0, TType.T_POINTER) And TNumericType(lhs.exprType) Then
 		If (op = "+" Or op = "-") And IsPointerType(exprType, 0, TType.T_POINTER) And TNumericType(lhs.exprType) Then
 			' with pointer addition we don't cast the numeric to a pointer
 			' with pointer addition we don't cast the numeric to a pointer
 		Else
 		Else
-			lhs=lhs.Cast( exprType )
+			lhs=lhs.Cast( exprType, bitEnumOp )
 		End If
 		End If
 		
 		
 		If (op = "+" Or op = "-") And IsPointerType(exprType, 0, TType.T_POINTER) And TNumericType(rhs.exprType) Then
 		If (op = "+" Or op = "-") And IsPointerType(exprType, 0, TType.T_POINTER) And TNumericType(rhs.exprType) Then
 			' with pointer addition we don't cast the numeric to a pointer
 			' with pointer addition we don't cast the numeric to a pointer
 		Else
 		Else
-			rhs=rhs.Cast( exprType )
+			rhs=rhs.Cast( exprType, bitEnumOp )
 		End If
 		End If
 		
 		
 		If IsPointerType( lhs.exprType, 0, TType.T_POINTER ) And IsPointerType( rhs.exprType, 0, TType.T_POINTER ) And op = "-" Then
 		If IsPointerType( lhs.exprType, 0, TType.T_POINTER ) And IsPointerType( rhs.exprType, 0, TType.T_POINTER ) And op = "-" Then
@@ -1876,7 +1888,7 @@ Type TBinaryMathExpr Extends TBinaryExpr
 	Method Eval$()
 	Method Eval$()
 		Local lhs$=Self.lhs.Eval()
 		Local lhs$=Self.lhs.Eval()
 		Local rhs$=Self.rhs.Eval()
 		Local rhs$=Self.rhs.Eval()
-		If TIntType( exprType )
+		If TIntType( exprType ) Or TByteType( exprType ) Or TShortType( exprType )
 			Local x:Int=Int(lhs),y:Int=Int(rhs)
 			Local x:Int=Int(lhs),y:Int=Int(rhs)
 			Select op
 			Select op
 			Case "^" Return x^y
 			Case "^" Return x^y
@@ -1951,6 +1963,18 @@ Type TBinaryMathExpr Extends TBinaryExpr
 				_appInstance.removeStringConst(rhs)
 				_appInstance.removeStringConst(rhs)
 				Return lhs+rhs
 				Return lhs+rhs
 			End Select
 			End Select
+		Else If TEnumType( exprType )
+			Local x:Long=Long(lhs),y:Long=Long(rhs)
+			Select op
+			Case "shl" Return x Shl y
+			Case "shr" Return x Shr y
+			Case "sar" Return x Sar y
+			Case "+" Return x + y
+			Case "-" Return x - y
+			Case "&" Return x & y
+			Case "~~" Return x ~ y
+			Case "|" Return x | y
+			End Select
 		EndIf
 		EndIf
 		InternalErr "TBinaryMathExpr.Eval"
 		InternalErr "TBinaryMathExpr.Eval"
 	End Method
 	End Method