diff --git a/image/imageSource.st b/image/imageSource.st index 1362582..264d585 100644 --- a/image/imageSource.st +++ b/image/imageSource.st @@ -776,18 +776,115 @@ COMMENT CLASS BranchTest Test METHOD BranchTest -ifTrue |x| +ifBlock |x| + [ true ] ifTrue: [ x <- 123 ]. + [ x ] assertEq: 123 withComment: '1'. + + [ false ] ifFalse: [ x <- 151 ]. + [ x ] assertEq: 151 withComment: '2'. + [ true ] ifTrue: [ x <- 123 ] - ifFalse: [ x <- 151 ] - [ x ] assertEq: 123 -! + ifFalse: [ x <- 151 ]. + [ x ] assertEq: 123 withComment: '3'. + [ false ] ifFalse: [ x <- 521 ] + ifTrue: [ x <- 34 ]. + [ x ] assertEq: 521 withComment: '4'. +! METHOD BranchTest -ifFalse |x| +ifBlockBadCodegenIfTrue |x| [ false ] ifTrue: [ x <- 34 ] - ifFalse: [ x <- 521 ] - [ x ] assertEq: 521 + ifFalse: [ x <- 521 ]. + [ x ] assertEq: 521. +! + +METHOD BranchTest +ifBlockBadCodegenIfFalse |x| + [ true ] ifFalse: [ x <- 151 ] + ifTrue: [ x <- 123 ]. + [ x ] assertEq: 123. +! + +METHOD BranchTest +ifLiteral |x| + true ifTrue: [ x <- 123 ]. + [ x ] assertEq: 123 withComment: '1'. + + false ifFalse: [ x <- 151 ]. + [ x ] assertEq: 151 withComment: '2'. + + true ifTrue: [ x <- 123 ] + ifFalse: [ x <- 151 ]. + [ x ] assertEq: 123 withComment: '3'. + + false ifTrue: [ x <- 34 ] + ifFalse: [ x <- 521 ]. + [ x ] assertEq: 521 withComment: '4'. + + true ifFalse: [ x <- 151 ] + ifTrue: [ x <- 123 ]. + [ x ] assertEq: 123 withComment: '5'. + + false ifFalse: [ x <- 521 ] + ifTrue: [ x <- 34 ]. + [ x ] assertEq: 521 withComment: '6'. +! + +METHOD BranchTest +ifRealBooleanMethods |arr x| + Context new performTest: (Boolean methods at: #ifTrue:) + withArguments: (Array with: true with: [ x <- 123 ] + ). + [ x ] assertEq: 123 withComment: '1'. + + Context new performTest: (Boolean methods at: #ifFalse:) + withArguments: (Array with: false with: [ x <- 151 ] + ). + [ x ] assertEq: 151 withComment: '2'. + + Context new performTest: (Boolean methods at: #ifTrue:ifFalse:) + withArguments: (Array with: true with: [ x <- 123 ] with: [ x <- 151 ] + ). + [ x ] assertEq: 123 withComment: '3'. + + Context new performTest: (Boolean methods at: #ifTrue:ifFalse:) + withArguments: (Array with: false with: [ x <- 32 ] with: [ x <- 521 ] + ). + [ x ] assertEq: 521 withComment: '4'. + + Context new performTest: (Boolean methods at: #ifFalse:ifTrue:) + withArguments: (Array with: true with: [ x <- 151 ] with: [ x <- 123 ] + ). + [ x ] assertEq: 123 withComment: '5'. + + Context new performTest: (Boolean methods at: #ifFalse:ifTrue:) + withArguments: (Array with: false with: [ x <- 521 ] with: [ x <- 34 ] + ). + [ x ] assertEq: 521 withComment: '6'. +! + +METHOD BranchTest +ifRealTrueFalseMethods |arr x| + Context new performTest: (True methods at: #ifTrue:) + withArguments: (Array with: true with: [ x <- 123 ] + ). + [ x ] assertEq: 123 withComment: '1'. + + Context new performTest: (True methods at: #ifFalse:) + withArguments: (Array with: true with: [ x <- 151 ] + ). + [ x ] assertEq: 123 withComment: '2'. + + Context new performTest: (False methods at: #ifTrue:) + withArguments: (Array with: false with: [ x <- 151 ] + ). + [ x ] assertEq: 123 withComment: '3'. + + Context new performTest: (False methods at: #ifFalse:) + withArguments: (Array with: false with: [ x <- 151 ] + ). + [ x ] assertEq: 151 withComment: '4'. ! METHOD BranchTest @@ -1008,7 +1105,7 @@ init arrOfChars <- Array new: 257. 1 to: 257 do: [:idx| - arrOfChars at: idx put: (Char basicNew: idx-1) + arrOfChars at: idx put: (Char new: idx-1) ]. ! @@ -2057,7 +2154,6 @@ run4: rounds | list indices tree | METHOD Undefined main | command data x | - Char initialize. Class fillChildren. System fixMethodClasses. @@ -2072,35 +2168,40 @@ main | command data x | COMMENT -----------Boolean-------------- +METHOD MetaBoolean +new: arg + arg ifTrue: [ ^ true ]. + ^ false +! METHOD Boolean -and: aBlock - ^ self - ifTrue: [ aBlock value ] - ifFalse: [ false ] +ifTrue: aBlock + self ifTrue: [ ^ aBlock value ]. ! METHOD Boolean -or: aBlock - ^ self - ifTrue: [ true ] - ifFalse: [ aBlock value ] +ifFalse: aBlock + self ifFalse: [ ^ aBlock value ]. ! METHOD Boolean -not - ^ self - ifTrue: [ false ] - ifFalse: [ true ] +ifTrue: trueBlock ifFalse: falseBlock + self ifTrue: [ ^ trueBlock value ]. + self ifFalse:[ ^ falseBlock value ]. ! METHOD Boolean ifFalse: falseBlock ifTrue: trueBlock - ^ self ifTrue: [ trueBlock value ] ifFalse: [ falseBlock value ] + self ifTrue: [ ^ trueBlock value ]. + self ifFalse:[ ^ falseBlock value ]. ! METHOD Boolean -ifTrue: aBlock - ^ self ifTrue: [ aBlock value ] ifFalse: [ nil ] +and: aBlock + ^ self and: [ ^ Boolean new: aBlock value ] ! METHOD Boolean -ifFalse: aBlock - ^ self ifTrue: [ nil ] ifFalse: [ aBlock value ] +or: aBlock + ^ self or: [ ^ Boolean new: aBlock value ] +! +METHOD Boolean +not + ^ self not ! COMMENT -----------True-------------- METHOD MetaTrue @@ -2109,10 +2210,6 @@ new ^ true ! METHOD True -not - ^ false -! -METHOD True asString ^'true' ! @@ -2121,16 +2218,24 @@ printString ^self asString ! METHOD True -ifTrue: trueBlock ifFalse: falseBlock - ^ trueBlock value +ifTrue: aBlock + ^ aBlock value ! METHOD True -or: aBlock - ^ true +ifFalse: aBlock + ^ nil ! METHOD True and: aBlock - ^ aBlock value + ^ Boolean new: aBlock value +! +METHOD True +or: aBlock + ^ true +! +METHOD True +not + ^ false ! COMMENT -----------False-------------- METHOD MetaFalse @@ -2139,10 +2244,6 @@ new ^ false ! METHOD False -not - ^ true -! -METHOD False asString ^'false' ! @@ -2151,17 +2252,27 @@ printString ^self asString ! METHOD False -ifTrue: trueBlock ifFalse: falseBlock - ^ falseBlock value +ifTrue: aBlock + ^ nil ! METHOD False -or: aBlock - ^ aBlock value +ifFalse: aBlock + ^ aBlock value ! METHOD False and: aBlock ^ false ! +METHOD False +or: aBlock + ^ Boolean new: aBlock value +! +METHOD False +not + ^ true +! + +COMMENT -----------Thread-------------- METHOD MetaThread new: aBlock |instance| instance <- self new. @@ -2484,15 +2595,6 @@ args: argNames inst: instNames temp: tempNames ! COMMENT -----------Chars-------------- METHOD MetaChar -initialize - chars isNil ifTrue: [ - chars <- Array new: 257. - 1 to: 257 do: [:idx| - chars at: idx put: (Char basicNew: idx-1) - ] - ] -! -METHOD MetaChar basicNew: value " create and initialize a new char " ^ self in: self new at: 1 put: value @@ -2500,14 +2602,21 @@ basicNew: value METHOD MetaChar new: value " return unique Char for ASCII value (or EOF) " - (value < 257) ifTrue: [ ^ chars at: value+1 ]. - + (value < 257) ifTrue: [ + chars isNil ifTrue: [ + chars <- Array new: 257. + 1 to: 257 do: [:idx| + chars at: idx put: (Char basicNew: idx-1) + ] + ]. + ^ chars at: value+1 + ]. " otherwise build a custom Char " ^ self basicNew: value ! METHOD MetaChar newline - " return newline character " + " return newline character " ^ self new: 10 ! METHOD MetaChar diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 98a7cde..d3d9ecb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,6 +5,9 @@ add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure) macro(cxx_test pretty_name bin_name sources libs) add_executable(${bin_name} ${sources}) target_link_libraries(${bin_name} supc++ -pthread ${libs} ${GTEST_BOTH_LIBRARIES} ${READLINE_LIBS_TO_LINK}) + if (USE_LLVM) + target_link_libraries(${bin_name} jit trampoline ${LLVM_LIBS} ${LLVM_LD_FLAGS}) + endif() set_target_properties(${bin_name} PROPERTIES COMPILE_DEFINITIONS TESTS_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/\") add_test(${pretty_name} ${bin_name}) add_dependencies(check ${bin_name}) @@ -22,3 +25,4 @@ cxx_test(StackSemantics test_stack_semantics "${CMAKE_CURRENT_SOURCE_DIR}/stack_ # TODO cxx_test(StackUnderflow test_stack_underflow "${CMAKE_CURRENT_SOURCE_DIR}/stack_underflow.cpp" "stapi") cxx_test(DecodeAllMethods test_decode_all_methods "${CMAKE_CURRENT_SOURCE_DIR}/decode_all_methods.cpp" "stapi;memory_managers;standard_set") cxx_test("VM::primitives" test_vm_primitives "${CMAKE_CURRENT_SOURCE_DIR}/vm_primitives.cpp" "memory_managers;standard_set") +cxx_test(Inference test_inference "${CMAKE_CURRENT_SOURCE_DIR}/inference.cpp" "stapi;memory_managers;standard_set") diff --git a/tests/data/Inference.image b/tests/data/Inference.image new file mode 100755 index 0000000..f97bf11 Binary files /dev/null and b/tests/data/Inference.image differ diff --git a/tests/inference.cpp b/tests/inference.cpp new file mode 100644 index 0000000..09d10c3 --- /dev/null +++ b/tests/inference.cpp @@ -0,0 +1,375 @@ +#include +#include "patterns/InitVMImage.h" +#include + +class P_Inference : public P_InitVM_Image +{ +public: + type::TypeSystem* m_type_system; + + P_Inference() : P_InitVM_Image(), m_type_system(0) {} + virtual ~P_Inference() {} + + virtual void SetUp() + { + P_InitVM_Image::SetUp(); + m_type_system = new type::TypeSystem(*m_vm); + } + virtual void TearDown() { + P_InitVM_Image::TearDown(); + delete m_type_system; + } + + type::InferContext* inferMessage( + TClass* const objectClass, + const std::string& methodName, + const type::Type& args, + type::TContextStack* parent, + bool sendToSuper = false + ) { + EXPECT_NE(static_cast(0), objectClass) << "Class is null"; + TMethod* const method = objectClass->methods->find(methodName.c_str()); + EXPECT_NE(static_cast(0), method) << "Method is null"; + + TSymbol* const selector = method->name; + return m_type_system->inferMessage(selector, args, parent, sendToSuper); + } + + type::InferContext* inferMessage( + const std::string& className, + const std::string& methodName, + const type::Type& args, + type::TContextStack* parent, + bool sendToSuper = false + ) { + TClass* const objectClass = m_image->getGlobal(className.c_str()); + return this->inferMessage(objectClass, methodName, args, parent, sendToSuper); + } + +}; + +INSTANTIATE_TEST_CASE_P(_, P_Inference, ::testing::Values(std::string("Inference")) ); + +TEST_P(P_Inference, new) +{ + std::vector types; + types.push_back("Array"); + types.push_back("List"); + types.push_back("True"); + types.push_back("False"); + types.push_back("Dictionary"); + + for(std::vector::const_iterator it = types.begin(); it != types.end(); ++it) { + const std::string& type = *it; + SCOPED_TRACE(type); + TClass* const klass = m_image->getGlobal(type.c_str()); + ASSERT_TRUE(klass != 0) << "could not find class for " << type; + + TClass* const metaClass = klass->getClass(); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(klass, type::Type::tkLiteral)); + + type::InferContext* const inferContext = this->inferMessage(metaClass, "new", args, 0, true); + ASSERT_EQ( type::Type(klass), inferContext->getReturnType() ); + } +} + + +TEST_P(P_Inference, SmallInt) +{ + { + SCOPED_TRACE("SmallInt>>asSmallInt"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(TInteger(42))); + + type::InferContext* const inferContext = this->inferMessage("SmallInt", "asSmallInt", args, 0); + ASSERT_EQ( type::Type(TInteger(42)), inferContext->getReturnType() ); + } + { + SCOPED_TRACE("SmallInt>>+ SmallInt"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(TInteger(40))); + args.pushSubType(type::Type(TInteger(2))); + + type::InferContext* const inferContext = this->inferMessage("SmallInt", "+", args, 0); + ASSERT_EQ( type::Type(TInteger(42)), inferContext->getReturnType() ); + } +} + +TEST_P(P_Inference, Number) +{ + { + SCOPED_TRACE("Number::new"); + type::Type args(globals.arrayClass, type::Type::tkArray); + TClass* const metaNumberClass = m_image->getGlobal("Number")->getClass(); + args.pushSubType(type::Type(metaNumberClass)); + + type::InferContext* const inferContext = this->inferMessage(metaNumberClass, "new", args, 0); + ASSERT_EQ( type::Type(TInteger(0)), inferContext->getReturnType() ); + } + { + SCOPED_TRACE("Number>>factorial"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(TInteger(4))); + + type::InferContext* const inferContext = this->inferMessage("Number", "factorial", args, 0); + ASSERT_EQ( type::Type(TInteger(24)), inferContext->getReturnType() ); + } + { + SCOPED_TRACE("Number>>negative"); + { + SCOPED_TRACE("-SmallInt"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(TInteger(-1))); + + type::InferContext* const inferContext = this->inferMessage("Number", "negative", args, 0); + ASSERT_EQ( type::Type(globals.trueObject), inferContext->getReturnType() ); + } + { + SCOPED_TRACE("+SmallInt"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(TInteger(1))); + + type::InferContext* const inferContext = this->inferMessage("Number", "negative", args, 0); + ASSERT_EQ( type::Type(globals.falseObject), inferContext->getReturnType() ); + } + } + { + SCOPED_TRACE("Number>>negated"); + { + SCOPED_TRACE("-SmallInt"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(TInteger(-1))); + + type::InferContext* const inferContext = this->inferMessage("Number", "negated", args, 0); + ASSERT_EQ( type::Type(TInteger(1)), inferContext->getReturnType() ); + } + { + SCOPED_TRACE("+SmallInt"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(TInteger(1))); + + type::InferContext* const inferContext = this->inferMessage("Number", "negated", args, 0); + ASSERT_EQ( type::Type(TInteger(-1)), inferContext->getReturnType() ); + } + } + { + SCOPED_TRACE("Number>>absolute"); + { + SCOPED_TRACE("-SmallInt"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(TInteger(-1))); + + type::InferContext* const inferContext = this->inferMessage("Number", "absolute", args, 0); + ASSERT_EQ( type::Type(TInteger(1)), inferContext->getReturnType() ); + } + { + SCOPED_TRACE("+SmallInt"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(TInteger(1))); + + type::InferContext* const inferContext = this->inferMessage("Number", "absolute", args, 0); + ASSERT_EQ( type::Type(TInteger(1)), inferContext->getReturnType() ); + } + } +} + +TEST_P(P_Inference, True) +{ + { + SCOPED_TRACE("True>>not"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.trueObject)); + + type::InferContext* const inferContext = this->inferMessage("True", "not", args, 0); + ASSERT_EQ( type::Type(globals.falseObject), inferContext->getReturnType() ); + } + { + SCOPED_TRACE("True>>and:"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.trueObject)); + args.pushSubType(type::Type(globals.blockClass)); + + type::InferContext* const inferContext = this->inferMessage("True", "and:", args, 0); + const type::Type& returnType = inferContext->getReturnType(); + ASSERT_TRUE( returnType.isComposite() ); + ASSERT_EQ( 2, returnType.getSubTypes().size() ); + ASSERT_EQ( type::Type(globals.trueObject), returnType.getSubTypes().at(0)); + ASSERT_EQ( type::Type(globals.falseObject), returnType.getSubTypes().at(1)); + } + { + SCOPED_TRACE("True>>or:"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.trueObject)); + args.pushSubType(type::Type(globals.blockClass)); + + type::InferContext* const inferContext = this->inferMessage("True", "or:", args, 0); + ASSERT_EQ( type::Type(globals.trueObject), inferContext->getReturnType() ); + } +} + +TEST_P(P_Inference, False) +{ + { + SCOPED_TRACE("False>>not"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.falseObject)); + + type::InferContext* const inferContext = this->inferMessage("False", "not", args, 0); + ASSERT_EQ( type::Type(globals.trueObject), inferContext->getReturnType() ); + } + { + SCOPED_TRACE("False>>and:"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.falseObject)); + args.pushSubType(type::Type(globals.blockClass)); + + type::InferContext* const inferContext = this->inferMessage("False", "and:", args, 0); + ASSERT_EQ( type::Type(globals.falseObject), inferContext->getReturnType() ); + } + { + SCOPED_TRACE("False>>or:"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.falseObject)); + args.pushSubType(type::Type(globals.blockClass)); + + type::InferContext* const inferContext = this->inferMessage("False", "or:", args, 0); + const type::Type& returnType = inferContext->getReturnType(); + ASSERT_TRUE( returnType.isComposite() ); + ASSERT_EQ( 2, returnType.getSubTypes().size() ); + ASSERT_EQ( type::Type(globals.trueObject), returnType.getSubTypes().at(0)); + ASSERT_EQ( type::Type(globals.falseObject), returnType.getSubTypes().at(1)); + } +} + +TEST_P(P_Inference, Boolean) +{ + { + SCOPED_TRACE("not"); + { + SCOPED_TRACE("False"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.falseObject)); + + type::InferContext* const inferContext = this->inferMessage("Boolean", "not", args, 0, true); + ASSERT_EQ( type::Type(globals.trueObject), inferContext->getReturnType() ); + } + { + SCOPED_TRACE("False"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.trueObject)); + + type::InferContext* const inferContext = this->inferMessage("Boolean", "not", args, 0, true); + ASSERT_EQ( type::Type(globals.falseObject), inferContext->getReturnType() ); + } + } + { + SCOPED_TRACE("and:"); + { + SCOPED_TRACE("False + block"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.falseObject)); + args.pushSubType(type::Type(globals.blockClass)); + + type::InferContext* const inferContext = this->inferMessage("Boolean", "and:", args, 0, true); + ASSERT_EQ( type::Type(globals.falseObject), inferContext->getReturnType() ); + } + { + SCOPED_TRACE("True + block"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.trueObject)); + args.pushSubType(type::Type(globals.blockClass)); + + type::InferContext* const inferContext = this->inferMessage("Boolean", "and:", args, 0, true); + const type::Type& returnType = inferContext->getReturnType(); + ASSERT_TRUE( returnType.isComposite() ); + ASSERT_EQ( 2, returnType.getSubTypes().size() ); + ASSERT_EQ( type::Type(globals.trueObject), returnType.getSubTypes().at(0)); + ASSERT_EQ( type::Type(globals.falseObject), returnType.getSubTypes().at(1)); + } + } + { + SCOPED_TRACE("or:"); + { + SCOPED_TRACE("False + block"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.falseObject)); + args.pushSubType(type::Type(globals.blockClass)); + + type::InferContext* const inferContext = this->inferMessage("Boolean", "or:", args, 0, true); + const type::Type& returnType = inferContext->getReturnType(); + ASSERT_TRUE( returnType.isComposite() ); + ASSERT_EQ( 2, returnType.getSubTypes().size() ); + ASSERT_EQ( type::Type(globals.trueObject), returnType.getSubTypes().at(0)); + ASSERT_EQ( type::Type(globals.falseObject), returnType.getSubTypes().at(1)); + } + { + SCOPED_TRACE("True + block"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.trueObject)); + args.pushSubType(type::Type(globals.blockClass)); + + type::InferContext* const inferContext = this->inferMessage("Boolean", "or:", args, 0, true); + ASSERT_EQ( type::Type(globals.trueObject), inferContext->getReturnType() ); + } + } +} + +TEST_P(P_Inference, String) +{ + { + SCOPED_TRACE("String>>words"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.stringClass)); + + type::InferContext* const inferContext = this->inferMessage("String", "words", args, 0); + ASSERT_EQ( type::Type(m_image->getGlobal("List")), inferContext->getReturnType() ); + } +} + +TEST_P(P_Inference, Array) +{ + { + SCOPED_TRACE("Array>>sort:"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.arrayClass)); + args.pushSubType(type::Type(globals.blockClass)); + + type::InferContext* const inferContext = this->inferMessage("Array", "sort:", args, 0); + ASSERT_EQ( type::Type(globals.arrayClass), inferContext->getReturnType() ); + } + { + SCOPED_TRACE("Array>>size"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.arrayClass)); + + type::InferContext* const inferContext = this->inferMessage("Array", "size", args, 0); + ASSERT_EQ( type::Type(globals.smallIntClass), inferContext->getReturnType() ); + } +} + +TEST_P(P_Inference, DISABLED_Char) +{ + { + SCOPED_TRACE("Char::basicNew:"); + TClass* const charClass = m_image->getGlobal("Char"); + ASSERT_TRUE(charClass != 0) << "could not find class for Char"; + TClass* const metaCharClass = charClass->getClass(); + + type::Type argsBasicNew(globals.arrayClass, type::Type::tkArray); + argsBasicNew.pushSubType(type::Type(charClass, type::Type::tkLiteral)); + argsBasicNew.pushSubType(type::Type(TInteger(33))); + + type::InferContext* const inferBasicNewContext = this->inferMessage(metaCharClass, "basicNew:", argsBasicNew, 0); + ASSERT_EQ( type::Type(charClass), inferBasicNewContext->getReturnType() ); + + { + SCOPED_TRACE("Char>>value"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(inferBasicNewContext->getReturnType())); + + type::InferContext* const inferContext = this->inferMessage(charClass, "value", args, 0); + ASSERT_EQ( type::Type(globals.smallIntClass), inferContext->getReturnType() ); + } + } +} diff --git a/tests/patterns/InitVMImage.h b/tests/patterns/InitVMImage.h index 7206014..bef2b7f 100644 --- a/tests/patterns/InitVMImage.h +++ b/tests/patterns/InitVMImage.h @@ -2,13 +2,16 @@ #define LLST_PATTERN_INIT_VM_IMAGE_INCLUDED #include -#include "../helpers/VMImage.h" +#include class P_InitVM_Image : public ::testing::TestWithParam { protected: - H_VMImage* m_image; + std::auto_ptr m_memoryManager; public: + std::auto_ptr m_image; + std::auto_ptr m_vm; + P_InitVM_Image() : m_memoryManager(), m_image(), m_vm() {} virtual ~P_InitVM_Image() {} virtual void SetUp() @@ -19,10 +22,21 @@ class P_InitVM_Image : public ::testing::TestWithParaminitializeHeap(1024*1024, 1024*1024); + m_image.reset(new Image(m_memoryManager.get())); + m_image->loadImage(TESTS_DIR "./data/" + image_name + ".image"); + m_vm.reset(new SmalltalkVM(m_image.get(), m_memoryManager.get())); } virtual void TearDown() { - delete m_image; + m_vm.reset(); + m_image.reset(); + m_memoryManager.reset(); } };