From 06d090184d674d15bbd0cd5ac76a2937bbfbe432 Mon Sep 17 00:00:00 2001 From: Roman Proskuryakov Date: Sat, 13 Aug 2016 02:43:54 +0300 Subject: [PATCH] Adds basic tests and patterns for type inference Issue: #92 --- image/imageSource.st | 219 ++++++++++---- src/TauLinker.cpp | 2 +- tests/CMakeLists.txt | 4 + tests/data/Inference.image | Bin 0 -> 232051 bytes tests/inference.cpp | 541 +++++++++++++++++++++++++++++++++++ tests/patterns/InitVMImage.h | 22 +- 6 files changed, 728 insertions(+), 60 deletions(-) create mode 100755 tests/data/Inference.image create mode 100644 tests/inference.cpp 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/src/TauLinker.cpp b/src/TauLinker.cpp index ec51670..6b49736 100644 --- a/src/TauLinker.cpp +++ b/src/TauLinker.cpp @@ -275,7 +275,7 @@ void TauLinker::eraseRedundantTau() { if (traces_enabled) printf("Erasing processed tau %.2u\n", processedTau->getIndex()); - assert(processedTau->getIncomingMap().empty()); + //FIXME assert(processedTau->getIncomingMap().empty()); getGraph().eraseNode(processedTau); } 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 0000000000000000000000000000000000000000..f97bf11bfc47b655115016d6c8d7b6a2fed8cc55 GIT binary patch literal 232051 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 +#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")) ); + +template +std::vector convert_array_to_vector(const T (&source_array)[N]) { + return std::vector(source_array, source_array+N); +} + +TEST_P(P_Inference, new) +{ + std::string types_array[] = {"Array", "List", "True", "False", "Dictionary"}; + std::vector types = convert_array_to_vector<>(types_array); + + 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, Object__isNil) +{ + { + SCOPED_TRACE("nil"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.nilObject)); + + type::InferContext* const inferContext = this->inferMessage("Object", "isNil", args, 0); + ASSERT_EQ( type::Type(globals.trueObject), inferContext->getReturnType() ); + } + { + SCOPED_TRACE("not nil"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.trueObject)); + + type::InferContext* const inferContext = this->inferMessage("Object", "isNil", args, 0); + ASSERT_EQ( type::Type(globals.falseObject), inferContext->getReturnType() ); + } +} + +TEST_P(P_Inference, Object__notNil) +{ + { + SCOPED_TRACE("nil"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.nilObject)); + + type::InferContext* const inferContext = this->inferMessage("Object", "notNil", args, 0); + ASSERT_EQ( type::Type(globals.falseObject), inferContext->getReturnType() ); + } + { + SCOPED_TRACE("not nil"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.trueObject)); + + type::InferContext* const inferContext = this->inferMessage("Object", "notNil", args, 0); + ASSERT_EQ( type::Type(globals.trueObject), inferContext->getReturnType() ); + } +} + +TEST_P(P_Inference, Object__class) +{ + TClass* classes_array[] = {globals.smallIntClass, globals.stringClass, globals.arrayClass, globals.blockClass}; + std::vector classes = convert_array_to_vector<>(classes_array); + + for(std::vector::const_iterator it = classes.begin(); it != classes.end(); ++it) { + TClass* klass = *it; + SCOPED_TRACE(klass->name->toString()); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(klass)); + + type::InferContext* const inferContext = this->inferMessage("Object", "class", args, 0); + ASSERT_EQ( type::Type(klass, type::Type::tkLiteral), inferContext->getReturnType() ) ; + } +} + +TEST_P(P_Inference, Object__isMemberOf) +{ + { + SCOPED_TRACE("42 isMemberOf: SmallInt"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(TInteger(42))); + args.pushSubType(type::Type(globals.smallIntClass, type::Type::tkLiteral)); + + type::InferContext* const inferContext = this->inferMessage("Object", "isMemberOf:", args, 0); + ASSERT_EQ( type::Type(globals.trueObject), inferContext->getReturnType() ); + } + { + SCOPED_TRACE("42 isMemberOf: (SmallInt)"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(TInteger(42))); + args.pushSubType(type::Type(globals.smallIntClass)); + + type::InferContext* const inferContext = this->inferMessage("Object", "isMemberOf:", args, 0); + ASSERT_EQ( type::Type(m_image->getGlobal("Boolean")), inferContext->getReturnType() ); + } +} + +TEST_P(P_Inference, Object__isKindOf) +{ + { + SCOPED_TRACE("42 isKindOf: SmallInt"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(TInteger(42))); + args.pushSubType(type::Type(globals.smallIntClass, type::Type::tkLiteral)); + + type::InferContext* const inferContext = this->inferMessage("Object", "isKindOf:", args, 0); + ASSERT_EQ( type::Type(globals.trueObject), inferContext->getReturnType() ); + } + { + SCOPED_TRACE("42 isKindOf: Number"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(TInteger(42))); + args.pushSubType(type::Type(globals.smallIntClass)); + + type::InferContext* const inferContext = this->inferMessage("Object", "isKindOf:", args, 0); + ASSERT_EQ( type::Type(m_image->getGlobal("Boolean")), inferContext->getReturnType().fold() ); + } +} + +TEST_P(P_Inference, Object__respondsTo) +{ + { + SCOPED_TRACE("42 respondsTo: #<"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(TInteger(42))); + args.pushSubType(type::Type(globals.binaryMessages[0])); + + type::InferContext* const inferContext = this->inferMessage("Object", "respondsTo:", args, 0); + ASSERT_EQ( type::Type(type::Type::tkPolytype), inferContext->getReturnType() ); // FIXME + } +} + +TEST_P(P_Inference, Collection__includes) +{ + { + SCOPED_TRACE("Array new includes: 42"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(globals.arrayClass)); + args.pushSubType(type::Type(TInteger(42))); + + type::InferContext* const inferContext = this->inferMessage("Collection", "includes:", args, 0); + ASSERT_EQ( type::Type(m_image->getGlobal("Boolean")), inferContext->getReturnType().fold() ); + } +} + +TEST_P(P_Inference, OrderedArray) +{ + { + SCOPED_TRACE("OrderedArray new location: 42"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(m_image->getGlobal("OrderedArray"))); + args.pushSubType(type::Type(TInteger(42))); + + type::InferContext* const inferContext = this->inferMessage("OrderedArray", "location:", args, 0); + ASSERT_EQ( type::Type(globals.smallIntClass), inferContext->getReturnType().fold() ); + } +} + +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); + ASSERT_EQ( type::Type(m_image->getGlobal("Boolean")), inferContext->getReturnType().fold() ); + } + { + 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); + ASSERT_EQ( type::Type(m_image->getGlobal("Boolean")), inferContext->getReturnType().fold() ); + } +} + +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); + ASSERT_EQ( type::Type(m_image->getGlobal("Boolean")), inferContext->getReturnType().fold() ); + } + } + { + 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); + ASSERT_EQ( type::Type(m_image->getGlobal("Boolean")), inferContext->getReturnType().fold() ); + } + { + 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, 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() ); + } + } + { + SCOPED_TRACE("Number>>to:do:"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(TInteger(1))); + args.pushSubType(type::Type(TInteger(100))); + args.pushSubType(type::Type(globals.blockClass)); + + type::InferContext* const inferContext = this->inferMessage("Number", "to:do:", args, 0); + ASSERT_EQ( type::Type(TInteger(1)), 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, Char) +{ + TClass* const charClass = m_image->getGlobal("Char"); + ASSERT_TRUE(charClass != 0) << "could not find class for Char"; + TClass* const metaCharClass = charClass->getClass(); + + { + SCOPED_TRACE("Char::basicNew:"); + + 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() ); + }*/ + } + { + SCOPED_TRACE("Char::new:"); + + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(charClass, type::Type::tkLiteral)); + args.pushSubType(type::Type(TInteger(42))); + + type::InferContext* const inferBasicNewContext = this->inferMessage(metaCharClass, "new:", args, 0); + ASSERT_EQ( type::Type(type::Type::tkPolytype), inferBasicNewContext->getReturnType() ); + } +} + +TEST_P(P_Inference, DISABLED_Includes) +{ + { + SCOPED_TRACE("Dictionary new includes: #asd"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(m_image->getGlobal("Dictionary"))); + args.pushSubType(type::Type(m_image->getGlobal("Symbol"))); + + type::InferContext* const inferContext = this->inferMessage("Collection", "includes:", args, 0); + ASSERT_EQ( type::Type(m_image->getGlobal("Boolean")), inferContext->getReturnType().fold() ); + } + { + SCOPED_TRACE("OrderedArray new includes: 42"); + type::Type args(globals.arrayClass, type::Type::tkArray); + args.pushSubType(type::Type(m_image->getGlobal("OrderedArray"))); + args.pushSubType(type::Type(TInteger(42))); + + type::InferContext* const inferContext = this->inferMessage("Collection", "includes:", args, 0); + ASSERT_EQ( type::Type(m_image->getGlobal("Boolean")), inferContext->getReturnType().fold() ); + } +} 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(); } };