Skip to content

Commit

Permalink
Type Inference
Browse files Browse the repository at this point in the history
* added new internal checking 'assignment()' method facility to verify
  that assigning types from a left-hand-side (lhs) and a
  right-hand-side (rhs) TypedNode do equal
  - added also a 'UndefAtom' checking routine, which assigns the lhs
  type to the rhs type if this one equals the 'UndefAtom' and is still
  not typed
* fixed UpdateRule inference
* fixed LetRule inference
  - related to ref sealangdotorg/sea#20
  • Loading branch information
ppaulweber committed Apr 19, 2017
1 parent 6111621 commit 1346f1c
Showing 1 changed file with 65 additions and 1 deletion.
66 changes: 65 additions & 1 deletion src/analyze/TypeInferencePass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -581,8 +581,13 @@ class TypeInferenceVisitor final : public RecursiveVisitor
void visit( ExistentialQuantifierExpression& node ) override;

void visit( LetRule& node ) override;
void visit( UpdateRule& node ) override;

void annotate( const libcasm_ir::Annotation& annotation, const Node& node,
void assignment( const Node& node, TypedNode& lhs, TypedNode& rhs,
const std::string& dst, const std::string& src );

void annotate( const libcasm_ir::Annotation& annotation,
const Node& node,
const std::vector< Expression::Ptr >& expressions = {} );

void inference(
Expand Down Expand Up @@ -878,6 +883,59 @@ void TypeInferenceVisitor::visit( LetRule& node )
push( *node.variable() );
RecursiveVisitor::visit( node );
pop( *node.variable() );

assignment( node, *node.variable(), *node.expression(),
"let variable '" + node.variable()->identifier()->name() + "'",
"binding expression" );
}

void TypeInferenceVisitor::visit( UpdateRule& node )
{
RecursiveVisitor::visit( node );

assignment( node, *node.function(), *node.expression(), "updated function",
"updating expression" );
}

void TypeInferenceVisitor::assignment( const Node& node, TypedNode& lhs,
TypedNode& rhs, const std::string& dst, const std::string& src )
{
if( not rhs.type() and rhs.id() == Node::ID::UNDEF_ATOM )
{
rhs.setType( lhs.type() );
}

const auto error_count = m_err;

if( not lhs.type() )
{
m_err++;
m_log.error(
{ lhs.sourceLocation() }, "unable to infer type of " + dst );
}

if( not rhs.type() )
{
m_err++;
m_log.error(
{ rhs.sourceLocation() }, "unable to infer type of " + src );
}

if( error_count != m_err )
{
return;
}

if( *lhs.type() != *rhs.type() )
{
m_err++;
m_log.error( { lhs.sourceLocation(), rhs.sourceLocation() },
"type of " + dst + " does not match type of " + src + ": '"
+ lhs.type()->description()
+ "' != '"
+ rhs.type()->description()
+ "'" );
}
}

void TypeInferenceVisitor::annotate( const libcasm_ir::Annotation& annotation,
Expand Down Expand Up @@ -1016,6 +1074,12 @@ void TypeInferenceVisitor::inference(

void TypeInferenceVisitor::inference( FunctionDefinition& node )
{
if( node.defaultValue()->id() == Node::ID::UNDEF_ATOM
and not node.defaultValue()->type() )
{
node.defaultValue()->setType( node.returnType()->type() );
}

if( node.type() )
{
return;
Expand Down

0 comments on commit 1346f1c

Please sign in to comment.