summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Mike Barnett <mbarnett@microsoft.com>2011-05-29 20:26:26 -0700
committerGravatar Mike Barnett <mbarnett@microsoft.com>2011-05-29 20:26:26 -0700
commitf0d77f50a0f7d9dd88f6508d33ce2b81f24ef809 (patch)
treea1f6005bb1ed2f34832b8bb83aef10e9ce82bfab
parent404ff152f889a827ddeafae34125064f65182d10 (diff)
Handle more conversions.
-rw-r--r--BCT/BytecodeTranslator/ExpressionTraverser.cs55
-rw-r--r--BCT/BytecodeTranslator/HeapFactory.cs7
-rw-r--r--BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt4
-rw-r--r--BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt4
4 files changed, 65 insertions, 5 deletions
diff --git a/BCT/BytecodeTranslator/ExpressionTraverser.cs b/BCT/BytecodeTranslator/ExpressionTraverser.cs
index 2a879059..2052177a 100644
--- a/BCT/BytecodeTranslator/ExpressionTraverser.cs
+++ b/BCT/BytecodeTranslator/ExpressionTraverser.cs
@@ -341,11 +341,28 @@ namespace BytecodeTranslator
lit.Type = Bpl.Type.Int;
TranslatedExpressions.Push(lit);
break;
+ case PrimitiveTypeCode.UInt16:
+ case PrimitiveTypeCode.UInt32:
+ case PrimitiveTypeCode.UInt64:
+ case PrimitiveTypeCode.UInt8:
+ lit = Bpl.Expr.Literal((int)(uint)constant.Value);
+ lit.Type = Bpl.Type.Int;
+ TranslatedExpressions.Push(lit);
+ break;
case PrimitiveTypeCode.Float32:
case PrimitiveTypeCode.Float64:
var c = this.sink.FindOrCreateConstant((double)(constant.Value));
TranslatedExpressions.Push(Bpl.Expr.Ident(c));
return;
+ case PrimitiveTypeCode.NotPrimitive:
+ if (constant.Type.IsEnum) {
+ lit = Bpl.Expr.Literal((int)constant.Value);
+ lit.Type = Bpl.Type.Int;
+ TranslatedExpressions.Push(lit);
+ return;
+ }
+ throw new NotImplementedException(String.Format("Can't translate compile-time constant of type '{0}'",
+ TypeHelper.GetTypeName(constant.Type)));
default:
throw new NotImplementedException();
}
@@ -1075,6 +1092,10 @@ namespace BytecodeTranslator
// then this conversion is a nop, just ignore it
return;
}
+ var nameOfTypeToConvert = TypeHelper.GetTypeName(conversion.ValueToConvert.Type);
+ var nameOfTypeToBeConvertedTo = TypeHelper.GetTypeName(conversion.TypeAfterConversion);
+ var msg = String.Format("Can't convert '{0}' to '{1}'", nameOfTypeToConvert, nameOfTypeToBeConvertedTo);
+
var exp = TranslatedExpressions.Pop();
switch (conversion.TypeAfterConversion.TypeCode) {
case PrimitiveTypeCode.Int16:
@@ -1109,15 +1130,36 @@ namespace BytecodeTranslator
return;
}
+ case PrimitiveTypeCode.NotPrimitive:
+ TranslatedExpressions.Push(new Bpl.NAryExpr(
+ conversion.Token(),
+ new Bpl.FunctionCall(this.sink.Heap.Ref2Int),
+ new Bpl.ExprSeq(exp,
+ new Bpl.IdentifierExpr(tok, this.sink.FindOrCreateType(conversion.ValueToConvert.Type)),
+ new Bpl.IdentifierExpr(tok, this.sink.FindOrCreateType(conversion.TypeAfterConversion))
+ )
+ ));
+ return;
+
default:
- throw new NotImplementedException();
+ throw new NotImplementedException(msg);
}
case PrimitiveTypeCode.Boolean:
if (TypeHelper.IsPrimitiveInteger(conversion.ValueToConvert.Type)) {
TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, exp, Bpl.Expr.Literal(0)));
return;
+ } else if (conversion.ValueToConvert.Type.TypeCode == PrimitiveTypeCode.NotPrimitive) {
+ TranslatedExpressions.Push(new Bpl.NAryExpr(
+ conversion.Token(),
+ new Bpl.FunctionCall(this.sink.Heap.Ref2Bool),
+ new Bpl.ExprSeq(exp,
+ new Bpl.IdentifierExpr(tok, this.sink.FindOrCreateType(conversion.ValueToConvert.Type)),
+ new Bpl.IdentifierExpr(tok, this.sink.FindOrCreateType(conversion.TypeAfterConversion))
+ )
+ ));
+ return;
} else {
- throw new NotImplementedException();
+ throw new NotImplementedException(msg);
}
case PrimitiveTypeCode.NotPrimitive:
Bpl.Function func;
@@ -1128,8 +1170,11 @@ namespace BytecodeTranslator
} else if (conversion.ValueToConvert.Type.TypeCode == PrimitiveTypeCode.NotPrimitive) {
// REVIEW: Do we need to check to make sure that conversion.ValueToConvert.Type.IsValueType?
func = this.sink.Heap.Struct2Ref;
+ } else if (conversion.ValueToConvert.Type.TypeCode == PrimitiveTypeCode.Float32 ||
+ conversion.ValueToConvert.Type.TypeCode == PrimitiveTypeCode.Float64) {
+ func = this.sink.Heap.Real2Ref;
} else {
- throw new NotImplementedException();
+ throw new NotImplementedException(msg);
}
var boxExpr = new Bpl.NAryExpr(
conversion.Token(),
@@ -1163,10 +1208,10 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(convExpr);
return;
} else {
- throw new NotImplementedException();
+ throw new NotImplementedException(msg);
}
default:
- throw new NotImplementedException();
+ throw new NotImplementedException(msg);
}
}
diff --git a/BCT/BytecodeTranslator/HeapFactory.cs b/BCT/BytecodeTranslator/HeapFactory.cs
index 5a14285b..3dc1b5f9 100644
--- a/BCT/BytecodeTranslator/HeapFactory.cs
+++ b/BCT/BytecodeTranslator/HeapFactory.cs
@@ -229,6 +229,13 @@ namespace BytecodeTranslator {
public Bpl.Function Real2Ref = null;
#endregion
+ #region Ref conversions
+ [RepresentationFor("Ref2Int", "function Ref2Int(Ref, Type, Type): int;")]
+ public Bpl.Function Ref2Int = null;
+ [RepresentationFor("Ref2Bool", "function Ref2Bool(Ref, Type, Type): bool;")]
+ public Bpl.Function Ref2Bool = null;
+ #endregion
+
#endregion
/// <summary>
diff --git a/BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt b/BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt
index 03f26c13..eff71038 100644
--- a/BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt
+++ b/BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt
@@ -333,6 +333,10 @@ function Ref2Real(Ref, Type, Type) : Real;
function Real2Ref(Real, Type, Type) : Ref;
+function Ref2Int(Ref, Type, Type) : int;
+
+function Ref2Bool(Ref, Type, Type) : bool;
+
function $DynamicType(Ref) : Type;
function $TypeOf(Type) : Ref;
diff --git a/BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt b/BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt
index dd3e629b..77d0950a 100644
--- a/BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt
+++ b/BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt
@@ -323,6 +323,10 @@ function Ref2Real(Ref, Type, Type) : Real;
function Real2Ref(Real, Type, Type) : Ref;
+function Ref2Int(Ref, Type, Type) : int;
+
+function Ref2Bool(Ref, Type, Type) : bool;
+
function $DynamicType(Ref) : Type;
function $TypeOf(Type) : Ref;