Commit 414d207f authored by Kevin Modzelewski's avatar Kevin Modzelewski

Type system fix: need to add unpacking to the type system

ie concerning things like:
  a, b = 1, 2

The irgen phase already knows how to do unpacking in a type-analyzed
way (a and b will be of type int), but type speculation needed to
have that added.
parent 7b84d99d
...@@ -177,8 +177,10 @@ private: ...@@ -177,8 +177,10 @@ private:
break; break;
case AST_TYPE::Tuple: { case AST_TYPE::Tuple: {
AST_Tuple* tt = ast_cast<AST_Tuple>(target); AST_Tuple* tt = ast_cast<AST_Tuple>(target);
auto val_types = t->unpackTypes(tt->elts.size());
assert(val_types.size() == tt->elts.size());
for (int i = 0; i < tt->elts.size(); i++) { for (int i = 0; i < tt->elts.size(); i++) {
_doSet(tt->elts[i], UNKNOWN); _doSet(tt->elts[i], val_types[i]);
} }
break; break;
} }
......
...@@ -57,6 +57,12 @@ CompilerType::Result CompilerType::hasattr(BoxedString* attr) { ...@@ -57,6 +57,12 @@ CompilerType::Result CompilerType::hasattr(BoxedString* attr) {
return Result::Yes; return Result::Yes;
} }
std::vector<CompilerType*> CompilerType::unpackTypes(int num_into) {
assert((CompilerType*)this != UNKNOWN);
return UNKNOWN->unpackTypes(num_into);
}
void ConcreteCompilerType::serializeToFrame(VAR* var, std::vector<llvm::Value*>& stackmap_args) { void ConcreteCompilerType::serializeToFrame(VAR* var, std::vector<llvm::Value*>& stackmap_args) {
#ifndef NDEBUG #ifndef NDEBUG
if (llvmType() == g.i1) { if (llvmType() == g.i1) {
...@@ -490,6 +496,10 @@ public: ...@@ -490,6 +496,10 @@ public:
} }
return rtn; return rtn;
} }
std::vector<CompilerType*> unpackTypes(int num_into) override {
return std::vector<CompilerType*>(num_into, UNKNOWN);
}
}; };
ConcreteCompilerType* UNKNOWN = new UnknownType(); ConcreteCompilerType* UNKNOWN = new UnknownType();
...@@ -2506,6 +2516,14 @@ public: ...@@ -2506,6 +2516,14 @@ public:
return *var->getValue(); return *var->getValue();
} }
std::vector<CompilerType*> unpackTypes(int num_into) override {
if (num_into != elt_types.size()) {
return ValuedCompilerType::unpackTypes(num_into);
}
return elt_types;
}
}; };
CompilerType* makeTupleType(const std::vector<CompilerType*>& elt_types) { CompilerType* makeTupleType(const std::vector<CompilerType*>& elt_types) {
......
...@@ -57,6 +57,7 @@ public: ...@@ -57,6 +57,7 @@ public:
virtual BoxedClass* guaranteedClass() = 0; virtual BoxedClass* guaranteedClass() = 0;
virtual Box* deserializeFromFrame(const FrameVals& vals) = 0; virtual Box* deserializeFromFrame(const FrameVals& vals) = 0;
virtual int numFrameArgs() = 0; virtual int numFrameArgs() = 0;
virtual std::vector<CompilerType*> unpackTypes(int num_into);
}; };
typedef std::unordered_map<CompilerVariable*, CompilerVariable*> DupCache; typedef std::unordered_map<CompilerVariable*, CompilerVariable*> DupCache;
......
# Regression test: make sure that irgen and type analysis
# both handle tuple -packing and -unpcaking.
def get_str():
return "Hello world"
def f():
_, a = 1, get_str()
a.lower()
for i in xrange(100000):
f()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment