|
@@ -0,0 +1,202 @@
|
|
|
+
|
|
|
+Namespace mx2
|
|
|
+
|
|
|
+Function BalanceIntegralTypes:Type( lhs:PrimType,rhs:PrimType )
|
|
|
+
|
|
|
+ If Not lhs Or Not rhs Or Not lhs.IsIntegral Or Not rhs.IsIntegral
|
|
|
+ Throw New SemantEx( "Types must be integral" )
|
|
|
+ Endif
|
|
|
+
|
|
|
+ If lhs=Type.ULongType Or rhs=Type.ULongType Return Type.ULongType
|
|
|
+
|
|
|
+ If lhs=Type.LongType Or rhs=Type.LongType Return Type.LongType
|
|
|
+
|
|
|
+ If lhs.IsUnsignedIntegral Or rhs.IsUnsignedIntegral Return Type.UIntType
|
|
|
+
|
|
|
+ Return Type.IntType
|
|
|
+End
|
|
|
+
|
|
|
+Function BalanceNumericTypes:Type( lhs:PrimType,rhs:PrimType )
|
|
|
+
|
|
|
+ If Not lhs Or Not rhs Or Not lhs.IsNumeric Or Not rhs.IsNumeric
|
|
|
+ Throw New SemantEx( "Types must be numeric" )
|
|
|
+ Endif
|
|
|
+
|
|
|
+ If lhs=Type.DoubleType Or rhs=Type.DoubleType Return Type.DoubleType
|
|
|
+
|
|
|
+ If lhs=Type.FloatType Or rhs=Type.FloatType Return Type.FloatType
|
|
|
+
|
|
|
+ Return BalanceIntegralTypes( lhs,rhs )
|
|
|
+End
|
|
|
+
|
|
|
+Function BalancePrimTypes:Type( lhs:PrimType,rhs:PrimType )
|
|
|
+
|
|
|
+ If Not lhs Or Not rhs
|
|
|
+ Throw New SemantEx( "Types must be primitive" )
|
|
|
+ Endif
|
|
|
+
|
|
|
+ If lhs=Type.StringType Or rhs=Type.StringType Return Type.StringType
|
|
|
+
|
|
|
+ Return BalanceNumericTypes( lhs,rhs )
|
|
|
+End
|
|
|
+
|
|
|
+Function BalanceTypes:Type( lhs:Type,rhs:Type )
|
|
|
+
|
|
|
+ Local plhs:=TCast<PrimType>( lhs )
|
|
|
+ Local prhs:=TCast<PrimType>( rhs )
|
|
|
+
|
|
|
+ If plhs And prhs Return BalancePrimTypes( plhs,prhs )
|
|
|
+
|
|
|
+ If lhs.DistanceToType( rhs )>=0 Return rhs 'And rhs.DistanceToType( lhs )<=0 Return rhs
|
|
|
+ If rhs.DistanceToType( lhs )>=0 Return lhs 'And lhs.DistanceToType( rhs )<=0 Return lhs
|
|
|
+
|
|
|
+ Throw New SemantEx( "Types '"+lhs.Name+"' and '"+rhs.Name+"' are incompatible" )
|
|
|
+
|
|
|
+ Return Null
|
|
|
+End
|
|
|
+
|
|
|
+'returns result type and lhs/rhs cast types in argTtypes
|
|
|
+'
|
|
|
+Function BalanceBinaryopTypes:Type( op:String,lhs:Type,rhs:Type,argTypes:Type[] )
|
|
|
+
|
|
|
+ Local plhs:=TCast<PrimType>( lhs )
|
|
|
+ Local prhs:=TCast<PrimType>( rhs )
|
|
|
+
|
|
|
+ Local type:Type,ltype:Type,rtype:Type
|
|
|
+
|
|
|
+ Select op
|
|
|
+ Case "+"
|
|
|
+
|
|
|
+ If TCast<PointerType>( lhs )
|
|
|
+ type=lhs
|
|
|
+ rtype=BalanceIntegralTypes( prhs,prhs )
|
|
|
+ Else If TCast<PointerType>( rhs )
|
|
|
+ type=rhs
|
|
|
+ ltype=BalanceIntegralTypes( plhs,plhs )
|
|
|
+ Else
|
|
|
+ type=BalancePrimTypes( plhs,prhs )
|
|
|
+ Endif
|
|
|
+
|
|
|
+ Case "-"
|
|
|
+
|
|
|
+ If TCast<PointerType>( lhs )
|
|
|
+ type=lhs
|
|
|
+ rtype=BalanceIntegralTypes( prhs,prhs )
|
|
|
+ Else
|
|
|
+ type=BalanceNumericTypes( plhs,prhs )
|
|
|
+ Endif
|
|
|
+
|
|
|
+ Case "*","/","mod","+","-"
|
|
|
+
|
|
|
+ type=BalanceNumericTypes( plhs,prhs )
|
|
|
+
|
|
|
+ Case "&","|","~"
|
|
|
+
|
|
|
+ If TCast<EnumType>( lhs ) Or TCast<EnumType>( rhs )
|
|
|
+ If lhs.Equals( rhs ) type=lhs
|
|
|
+ Else
|
|
|
+ type=BalanceIntegralTypes( plhs,prhs )
|
|
|
+ Endif
|
|
|
+
|
|
|
+ Case "shl","shr"
|
|
|
+
|
|
|
+ If plhs And plhs.IsIntegral
|
|
|
+ type=BalanceIntegralTypes( plhs,plhs )
|
|
|
+ rtype=Type.IntType
|
|
|
+ Endif
|
|
|
+
|
|
|
+ Case "=","<>","<",">","<=",">="
|
|
|
+
|
|
|
+ type=Type.BoolType
|
|
|
+ ltype=BalanceTypes( lhs,rhs )
|
|
|
+ rtype=ltype
|
|
|
+
|
|
|
+ Case "<=>"
|
|
|
+
|
|
|
+ type=Type.IntType
|
|
|
+ ltype=BalanceTypes( lhs,rhs )
|
|
|
+ rtype=ltype
|
|
|
+
|
|
|
+ End
|
|
|
+
|
|
|
+ If Not type Throw New SemantEx( "Invalid operand types for binary operator '"+op+"'" )
|
|
|
+
|
|
|
+ argTypes[0]=ltype ? ltype Else type
|
|
|
+ argTypes[1]=rtype ? rtype Else type
|
|
|
+
|
|
|
+ Return type
|
|
|
+
|
|
|
+End
|
|
|
+
|
|
|
+'returns type to cast rhs to...
|
|
|
+'
|
|
|
+Function BalanceAssignTypes:Type( op:String,lhs:Type,rhs:Type )
|
|
|
+
|
|
|
+ If op="=" Return lhs
|
|
|
+
|
|
|
+ Local plhs:=TCast<PrimType>( lhs )
|
|
|
+
|
|
|
+ Select op
|
|
|
+ Case "+="
|
|
|
+
|
|
|
+ If plhs
|
|
|
+
|
|
|
+ If plhs=Type.StringType Or plhs.IsNumeric Return lhs
|
|
|
+
|
|
|
+ Else If TCast<PointerType>( lhs )
|
|
|
+
|
|
|
+ Local prhs:=TCast<PrimType>( rhs )
|
|
|
+ If prhs
|
|
|
+ If prhs=Type.LongType Or prhs=Type.ULongType Return rhs
|
|
|
+ If prhs.IsIntegral Return Type.IntType
|
|
|
+ Endif
|
|
|
+
|
|
|
+ Else If TCast<FuncType>( lhs )
|
|
|
+
|
|
|
+ Return lhs
|
|
|
+
|
|
|
+ Endif
|
|
|
+
|
|
|
+ Case "-="
|
|
|
+
|
|
|
+ If plhs
|
|
|
+
|
|
|
+ If plhs.IsNumeric Return lhs
|
|
|
+
|
|
|
+ Else If TCast<PointerType>( lhs )
|
|
|
+
|
|
|
+ Local prhs:=TCast<PrimType>( rhs )
|
|
|
+ If prhs
|
|
|
+ If prhs=Type.LongType Or prhs=Type.ULongType Return rhs
|
|
|
+ If prhs And prhs.IsIntegral Return Type.IntType
|
|
|
+ Endif
|
|
|
+
|
|
|
+ Else If TCast<FuncType>( lhs )
|
|
|
+
|
|
|
+ Return lhs
|
|
|
+
|
|
|
+ Endif
|
|
|
+
|
|
|
+ Case "*=","/=","mod="
|
|
|
+
|
|
|
+ If plhs And plhs.IsNumeric Return lhs
|
|
|
+
|
|
|
+ Case "&=","|=","~="
|
|
|
+
|
|
|
+ If plhs And plhs.IsIntegral Return lhs
|
|
|
+
|
|
|
+ If TCast<EnumType>( lhs ) And lhs.Equals( rhs ) Return lhs
|
|
|
+
|
|
|
+ Case "shl=","shr="
|
|
|
+
|
|
|
+ If plhs And plhs.IsIntegral Return Type.IntType
|
|
|
+
|
|
|
+ Case "and=","or="
|
|
|
+
|
|
|
+ If plhs And plhs=Type.BoolType Return Type.BoolType
|
|
|
+
|
|
|
+ End
|
|
|
+
|
|
|
+ Throw New SemantEx( "Invalid type for assignment" )
|
|
|
+
|
|
|
+End
|