From f0d77f50a0f7d9dd88f6508d33ce2b81f24ef809 Mon Sep 17 00:00:00 2001 From: Mike Barnett Date: Sun, 29 May 2011 20:26:26 -0700 Subject: Handle more conversions. --- BCT/BytecodeTranslator/ExpressionTraverser.cs | 55 ++++++++++++++++++++-- BCT/BytecodeTranslator/HeapFactory.cs | 7 +++ .../TranslationTest/GeneralHeapInput.txt | 4 ++ .../TranslationTest/SplitFieldsHeapInput.txt | 4 ++ 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 /// 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; -- cgit v1.2.3