- Timestamp:
- Dec 13, 2016, 4:59:46 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- ea83e00a
- Parents:
- fc638d2
- Location:
- src
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
rfc638d2 r7933351 185 185 if ( alternatives.begin() == oldBegin ) { 186 186 std::ostringstream stream; 187 stream << "Can't choose between alternatives for expression ";187 stream << "Can't choose between " << alternatives.size() << " alternatives for expression "; 188 188 expr->print( stream ); 189 189 stream << "Alternatives are:"; … … 308 308 (*actualType)->print( std::cerr, 8 ); 309 309 std::cerr << std::endl << " to "; 310 (*formal )->get_type()->print( std::cerr, 8 );310 (*formalType)->print( std::cerr, 8 ); 311 311 ) 312 312 Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env ); … … 511 511 if ( ! cur->second ) { 512 512 inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/ level, indexer, out ); 513 return; // xxx - should this continue? previously this wasn't here, and it looks like it should be 513 514 } 514 515 DeclarationWithType *curDecl = cur->first; 516 515 517 PRINT( 516 518 std::cerr << "inferRecursive: assertion is "; … … 649 651 AltList candidates; 650 652 SemanticError errors; 651 652 653 for ( AltList::const_iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) { 653 654 try { … … 758 759 void AlternativeFinder::visit( CastExpr *castExpr ) { 759 760 Type *& toType = castExpr->get_result(); 761 assert( toType ); 760 762 toType = resolveTypeof( toType, indexer ); 761 763 SymTab::validateType( toType, &indexer ); … … 763 765 764 766 AlternativeFinder finder( indexer, env ); 767 finder.targetType = toType; 765 768 finder.findWithAdjustment( castExpr->get_arg() ); 766 769 … … 776 779 int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size(); 777 780 if ( discardedValues < 0 ) continue; 778 // xxx - may need to go into tuple types and extract relavent types and use unifyList 781 // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not 782 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3])) 779 783 // unification run for side-effects 780 784 unify( castExpr->get_result(), (*i).expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer ); … … 783 787 // count one safe conversion for each value that is thrown away 784 788 thisCost += Cost( 0, 0, discardedValues ); 785 CastExpr *newExpr = castExpr->clone(); 786 newExpr->set_arg( i->expr->clone() ); 787 candidates.push_back( Alternative( newExpr, i->env, i->cost, thisCost ) ); 789 790 Expression * argExpr = i->expr->clone(); 791 if ( argExpr->get_result()->size() > 1 && ! castExpr->get_result()->isVoid() ) { 792 // Argument expression is a tuple and the target type is not void. Cast each member of the tuple 793 // to its corresponding target type, producing the tuple of those cast expressions. If there are 794 // more components of the tuple than components in the target type, then excess components do not 795 // come out in the result expression (but UniqueExprs ensure that side effects will still be done). 796 if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) { 797 // expressions which may contain side effects require a single unique instance of the expression. 798 argExpr = new UniqueExpr( argExpr ); 799 } 800 std::list< Expression * > componentExprs; 801 for ( unsigned int i = 0; i < castExpr->get_result()->size(); i++ ) { 802 // cast each component 803 TupleIndexExpr * idx = new TupleIndexExpr( argExpr->clone(), i ); 804 componentExprs.push_back( new CastExpr( idx, castExpr->get_result()->getComponent( i )->clone() ) ); 805 } 806 delete argExpr; 807 assert( componentExprs.size() > 0 ); 808 // produce the tuple of casts 809 candidates.push_back( Alternative( new TupleExpr( componentExprs ), i->env, i->cost, thisCost ) ); 810 } else { 811 // handle normally 812 candidates.push_back( Alternative( new CastExpr( argExpr->clone(), toType->clone() ), i->env, i->cost, thisCost ) ); 813 } 788 814 } // if 789 815 } // for -
src/ResolvExpr/AlternativeFinder.h
rfc638d2 r7933351 91 91 AltList alternatives; 92 92 const TypeEnvironment &env; 93 Type * targetType = nullptr; 93 94 }; // AlternativeFinder 94 95 -
src/SynTree/Type.h
rfc638d2 r7933351 72 72 virtual unsigned size() const { return 1; }; 73 73 virtual bool isVoid() const { return size() == 0; } 74 virtual Type * getComponent( unsigned i ) { assertf( size() == 1 && i == 0, "Type::getComponent was called with size %d and index %d\n", size(), i ); return this; } 74 75 75 76 virtual Type *clone() const = 0; … … 372 373 iterator end() { return types.end(); } 373 374 375 virtual Type * getComponent( unsigned i ) { 376 assertf( i < size(), "TupleType::getComponent: index %d must be less than size %d", i, size() ); 377 return *(begin()+i); 378 } 379 374 380 virtual TupleType *clone() const { return new TupleType( *this ); } 375 381 virtual void accept( Visitor &v ) { v.visit( this ); } -
src/tests/.expect/castError.txt
rfc638d2 r7933351 1 1 CFA Version 1.0.0 (debug) 2 Error: Can't choose between alternatives for expression Cast of:2 Error: Can't choose between 3 alternatives for expression Cast of: 3 3 Name: f 4 4 -
src/tests/.expect/tupleCast.txt
rfc638d2 r7933351 1 1 10 A 3.14 2 2 10 A 3 10 3 4 10 65 4 5 ran f -
src/tests/tupleCast.c
rfc638d2 r7933351 20 20 printf("%d %c %g\n", ([int, char, float])x); 21 21 printf("%d %c\n", ([int, char])x); 22 printf("%d\n", ([int])x); 23 // printf("%d\n", (int)x); 22 24 printf("%g %g\n", ([double, float])x); 23 25 printf("%d %c\n", ([int, char])f());
Note: See TracChangeset
for help on using the changeset viewer.