Changes in / [3cd5fdd:8568319]


Ignore:
Location:
src
Files:
4 deleted
11 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Print.hpp

    r3cd5fdd r8568319  
    2929void print( std::ostream & os, const ast::Node * node, Indenter indent = {} );
    3030
     31/// Wrap any standard format printer (matching above) with integer Indenter constructor
     32template<typename T>
     33inline void print( std::ostream & os, T && x, unsigned int indent ) {
     34    print( os, std::forward<T>(x), Indenter{ Indenter::tabsize, indent });
     35}
     36
    3137/// Print a declaration in its short form
    3238void printShort( std::ostream & os, const ast::Decl * node, Indenter indent = {} );
    3339
    3440inline void printShort( std::ostream & os, const ast::Decl * node, unsigned int indent ) {
    35     printShort( os, node, Indenter{ indent } );
     41    printShort( os, node, Indenter{ Indenter::tabsize, indent } );
    3642}
    3743
  • src/AST/SymbolTable.hpp

    r3cd5fdd r8568319  
    8585
    8686public:
    87         SymbolTable();
     87        explicit SymbolTable();
    8888        ~SymbolTable();
    8989
  • src/AST/porting.md

    r3cd5fdd r8568319  
    295295* changed `WidenMode widenMode` => `WidenMode widen`
    296296
    297 `Alternative` => `Candidate`
    298 * `openVars` => `open`
    299 
    300297[1] https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Type-Attributes.html#Type-Attributes
    301298
  • src/Common/Indenter.h

    r3cd5fdd r8568319  
    1818
    1919struct Indenter {
    20         static unsigned tabsize;  ///< default number of spaces in one level of indentation
     20        static unsigned tabsize;
    2121
    22         unsigned int indent;      ///< number of spaces to indent
    23         unsigned int amt;         ///< spaces in one level of indentation
     22        Indenter( unsigned int amt = tabsize, unsigned int indent = 0 ) : amt( amt ), indent( indent ) {}
     23        unsigned int amt;  // amount 1 level increases indent by (i.e. how much to increase by in operator++)
     24        unsigned int indent;
    2425
    25         Indenter( unsigned int indent = 0, unsigned int amt = tabsize )
    26         : indent( indent*amt ), amt( amt ) {}
    27        
    2826        Indenter & operator+=(int nlevels) { indent += amt*nlevels; return *this; }
    2927        Indenter & operator-=(int nlevels) { indent -= amt*nlevels; return *this; }
  • src/Makefile.in

    r3cd5fdd r8568319  
    189189        ResolvExpr/Alternative.$(OBJEXT) \
    190190        ResolvExpr/AlternativeFinder.$(OBJEXT) \
    191         ResolvExpr/Candidate.$(OBJEXT) \
    192         ResolvExpr/CandidateFinder.$(OBJEXT) \
    193191        ResolvExpr/CastCost.$(OBJEXT) ResolvExpr/CommonType.$(OBJEXT) \
    194192        ResolvExpr/ConversionCost.$(OBJEXT) \
     
    624622      ResolvExpr/Alternative.cc \
    625623      ResolvExpr/AlternativeFinder.cc \
    626       ResolvExpr/Candidate.cpp \
    627       ResolvExpr/CandidateFinder.cpp \
    628624      ResolvExpr/CastCost.cc \
    629625      ResolvExpr/CommonType.cc \
     
    876872ResolvExpr/AlternativeFinder.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    877873        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    878 ResolvExpr/Candidate.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    879         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    880 ResolvExpr/CandidateFinder.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    881         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    882874ResolvExpr/CastCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    883875        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     
    12621254@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/AlternativeFinder.Po@am__quote@
    12631255@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/AlternativePrinter.Po@am__quote@
    1264 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Candidate.Po@am__quote@
    1265 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CandidateFinder.Po@am__quote@
    12661256@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CastCost.Po@am__quote@
    12671257@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CommonType.Po@am__quote@
  • src/ResolvExpr/AlternativeFinder.cc

    r3cd5fdd r8568319  
    136136
    137137        void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt ) {
    138                 Indenter indent = { indentAmt };
     138                Indenter indent = { Indenter::tabsize, indentAmt };
    139139                for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
    140140                        i->print( os, indent );
  • src/ResolvExpr/ResolveAssertions.cc

    r3cd5fdd r8568319  
    365365                                        // fail early if any assertion is not resolvable
    366366                                        if ( ! resolveAssertion( assn, resn ) ) {
    367                                                 Indenter tabs{ 3 };
     367                                                Indenter tabs{ Indenter::tabsize, 3 };
    368368                                                std::ostringstream ss;
    369369                                                ss << tabs << "Unsatisfiable alternative:\n";
     
    391391                                        // fail early if no mutually-compatible assertion satisfaction
    392392                                        if ( compatible.empty() ) {
    393                                                 Indenter tabs{ 3 };
     393                                                Indenter tabs{ Indenter::tabsize, 3 };
    394394                                                std::ostringstream ss;
    395395                                                ss << tabs << "Unsatisfiable alternative:\n";
  • src/ResolvExpr/Resolver.cc

    r3cd5fdd r8568319  
    2121#include "Alternative.h"                 // for Alternative, AltList
    2222#include "AlternativeFinder.h"           // for AlternativeFinder, resolveIn...
    23 #include "Candidate.hpp"
    24 #include "CandidateFinder.hpp"
    2523#include "CurrentObject.h"               // for CurrentObject
    2624#include "RenameVars.h"                  // for RenameVars, global_renamer
     
    3331#include "AST/Init.hpp"
    3432#include "AST/Pass.hpp"
    35 #include "AST/Print.hpp"
    3633#include "AST/SymbolTable.hpp"
    3734#include "Common/PassVisitor.h"          // for PassVisitor
     
    119116
    120117        namespace {
    121                 struct DeleteFinder_old : public WithShortCircuiting    {
     118                struct DeleteFinder : public WithShortCircuiting        {
    122119                        DeletedExpr * delExpr = nullptr;
    123120                        void previsit( DeletedExpr * expr ) {
     
    133130
    134131        DeletedExpr * findDeletedExpr( Expression * expr ) {
    135                 PassVisitor<DeleteFinder_old> finder;
     132                PassVisitor<DeleteFinder> finder;
    136133                expr->accept( finder );
    137134                return finder.pass.delExpr;
     
    139136
    140137        namespace {
    141                 struct StripCasts_old {
     138                struct StripCasts {
    142139                        Expression * postmutate( CastExpr * castExpr ) {
    143140                                if ( castExpr->isGenerated && ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, SymTab::Indexer() ) ) {
     
    152149
    153150                        static void strip( Expression *& expr ) {
    154                                 PassVisitor<StripCasts_old> stripper;
     151                                PassVisitor<StripCasts> stripper;
    155152                                expr = expr->acceptMutator( stripper );
    156153                        }
     
    160157                        expr->env = oldenv ? oldenv->clone() : new TypeSubstitution;
    161158                        env.makeSubstitution( *expr->env );
    162                         StripCasts_old::strip( expr ); // remove unnecessary casts that may be buried in an expression
     159                        StripCasts::strip( expr ); // remove unnecessary casts that may be buried in an expression
    163160                }
    164161
     
    943940        ///////////////////////////////////////////////////////////////////////////
    944941
    945         namespace {
    946                 /// Finds deleted expressions in an expression tree
    947                 struct DeleteFinder_new final : public ast::WithShortCircuiting {
    948                         const ast::DeletedExpr * delExpr = nullptr;
    949 
    950                         void previsit( const ast::DeletedExpr * expr ) {
    951                                 if ( delExpr ) { visit_children = false; }
    952                                 else { delExpr = expr; }
    953                         }
    954 
    955                         void previsit( const ast::Expr * ) {
    956                                 if ( delExpr ) { visit_children = false; }
    957                         }
    958                 };
    959 
    960                 /// Check if this expression is or includes a deleted expression
    961                 const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) {
    962                         ast::Pass<DeleteFinder_new> finder;
    963                         expr->accept( finder );
    964                         return finder.pass.delExpr;
    965                 }
    966 
    967                 /// Calls the CandidateFinder and finds the single best candidate
    968                 CandidateRef findUnfinishedKindExpression(
    969                         const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,
    970                         std::function<bool(const Candidate &)> pred, ResolvMode mode = {}
    971                 ) {
    972                         if ( ! untyped ) return nullptr;
    973 
    974                         // xxx - this isn't thread-safe, but should work until we parallelize the resolver
    975                         static unsigned recursion_level = 0;
    976 
    977                         ++recursion_level;
    978                         ast::TypeEnvironment env;
    979                         CandidateFinder finder{ symtab, env };
    980                         finder.find( untyped, recursion_level == 1 ? mode.atTopLevel() : mode );
    981                         --recursion_level;
    982 
    983                         // produce a filtered list of candidates
    984                         CandidateList candidates;
    985                         for ( auto & cand : finder.candidates ) {
    986                                 if ( pred( *cand ) ) { candidates.emplace_back( cand ); }
    987                         }
    988 
    989                         // produce invalid error if no candidates
    990                         if ( candidates.empty() ) {
    991                                 SemanticError( untyped,
    992                                         toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""),
    993                                         "expression: ") );
    994                         }
    995 
    996                         // search for cheapest candidate
    997                         CandidateList winners;
    998                         bool seen_undeleted = false;
    999                         for ( CandidateRef & cand : candidates ) {
    1000                                 int c = winners.empty() ? -1 : cand->cost.compare( winners.front()->cost );
    1001 
    1002                                 if ( c > 0 ) continue;  // skip more expensive than winner
    1003 
    1004                                 if ( c < 0 ) {
    1005                                         // reset on new cheapest
    1006                                         seen_undeleted = ! findDeletedExpr( cand->expr );
    1007                                         winners.clear();
    1008                                 } else /* if ( c == 0 ) */ {
    1009                                         if ( findDeletedExpr( cand->expr ) ) {
    1010                                                 // skip deleted expression if already seen one equivalent-cost not
    1011                                                 if ( seen_undeleted ) continue;
    1012                                         } else if ( ! seen_undeleted ) {
    1013                                                 // replace list of equivalent-cost deleted expressions with one non-deleted
    1014                                                 winners.clear();
    1015                                                 seen_undeleted = true;
    1016                                         }
    1017                                 }
    1018 
    1019                                 winners.emplace_back( std::move( cand ) );
    1020                         }
    1021 
    1022                         // promote candidate.cvtCost to .cost
    1023                         for ( CandidateRef & cand : winners ) {
    1024                                 cand->cost = cand->cvtCost;
    1025                         }
    1026 
    1027                         // produce ambiguous errors, if applicable
    1028                         if ( winners.size() != 1 ) {
    1029                                 std::ostringstream stream;
    1030                                 stream << "Cannot choose between " << winners.size() << " alternatives for "
    1031                                         << kind << (kind != "" ? " " : "") << "expression\n";
    1032                                 ast::print( stream, untyped );
    1033                                 stream << " Alternatives are:\n";
    1034                                 print( stream, winners, 1 );
    1035                                 SemanticError( untyped->location, stream.str() );
    1036                         }
    1037 
    1038                         // single selected choice
    1039                         CandidateRef & choice = winners.front();
    1040 
    1041                         // fail on only expression deleted
    1042                         if ( ! seen_undeleted ) {
    1043                                 SemanticError( untyped->location, choice->expr.get(), "Unique best alternative "
    1044                                 "includes deleted identifier in " );
    1045                         }
    1046 
    1047                         return std::move( choice );
    1048                 }
    1049 
    1050                 /// Strips extraneous casts out of an expression
    1051                 struct StripCasts_new final {
    1052                         const ast::Expr * postmutate( const ast::CastExpr * castExpr ) {
    1053                                 if (
    1054                                         castExpr->isGenerated
    1055                                         && typesCompatible( castExpr->arg->result, castExpr->result )
    1056                                 ) {
    1057                                         // generated cast is the same type as its argument, remove it after keeping env
    1058                                         ast::ptr<ast::Expr> arg = castExpr->arg;
    1059                                         arg.get_and_mutate()->env = castExpr->env;
    1060                                         return arg;
    1061                                 }
    1062                                 return castExpr;
    1063                         }
    1064 
    1065                         static void strip( ast::ptr< ast::Expr > & expr ) {
    1066                                 ast::Pass< StripCasts_new > stripper;
    1067                                 expr = expr->accept( stripper );
    1068                         }
    1069                 };
    1070 
    1071                 /// Establish post-resolver invariants for expressions
    1072                 void finishExpr(
    1073                         ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env,
    1074                         const ast::TypeSubstitution * oldenv = nullptr
    1075                 ) {
    1076                         // set up new type substitution for expression
    1077                         ast::ptr< ast::TypeSubstitution > newenv =
    1078                                  oldenv ? oldenv : new ast::TypeSubstitution{};
    1079                         env.writeToSubstitution( *newenv.get_and_mutate() );
    1080                         expr.get_and_mutate()->env = std::move( newenv );
    1081                         // remove unncecessary casts
    1082                         StripCasts_new::strip( expr );
    1083                 }
    1084                
    1085                 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the
    1086                 /// lowest cost, returning the resolved version
    1087                 ast::ptr< ast::Expr > findKindExpression(
    1088                         const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,
    1089                         std::function<bool(const Candidate &)> pred, ResolvMode mode = {}
    1090                 ) {
    1091                         if ( ! untyped ) return {};
    1092                         CandidateRef choice =
    1093                                 findUnfinishedKindExpression( untyped, symtab, kind, pred, mode );
    1094                         finishExpr( choice->expr, choice->env, untyped->env );
    1095                         return std::move( choice->expr );
    1096                 }
    1097 
    1098                 /// Predicate for "Candidate has integral type"
    1099                 bool hasIntegralType( const Candidate & i ) {
    1100                         const ast::Type * type = i.expr->result;
    1101                        
    1102                         if ( auto bt = dynamic_cast< const ast::BasicType * >( type ) ) {
    1103                                 return bt->isInteger();
    1104                         } else if (
    1105                                 dynamic_cast< const ast::EnumInstType * >( type )
    1106                                 || dynamic_cast< const ast::ZeroType * >( type )
    1107                                 || dynamic_cast< const ast::OneType * >( type )
    1108                         ) {
    1109                                 return true;
    1110                         } else return false;
    1111                 }
    1112 
    1113                 /// Resolve `untyped` as an integral expression, returning the resolved version
    1114                 ast::ptr< ast::Expr > findIntegralExpression(
    1115                         const ast::Expr * untyped, const ast::SymbolTable & symtab
    1116                 ) {
    1117                         return findKindExpression( untyped, symtab, "condition", hasIntegralType );
    1118                 }
    1119         }
    1120 
    1121942        class Resolver_new final
    1122943        : public ast::WithSymbolTable, public ast::WithGuards,
     
    1126947                ast::ptr< ast::Type > functionReturn = nullptr;
    1127948                // ast::CurrentObject currentObject = nullptr;
    1128                 bool inEnumDecl = false;
     949                // bool inEnumDecl = false;
    1129950
    1130951        public:
     
    1132953                Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; }
    1133954
    1134                 void previsit( const ast::FunctionDecl * );
    1135                 const ast::FunctionDecl * postvisit( const ast::FunctionDecl * );
    1136                 void previsit( const ast::ObjectDecl * );
    1137                 void previsit( const ast::EnumDecl * );
    1138                 const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * );
    1139 
    1140                 void previsit( const ast::ArrayType * );
    1141                 void previsit( const ast::PointerType * );
    1142 
    1143                 void previsit( const ast::ExprStmt * );
    1144                 void previsit( const ast::AsmExpr * );
    1145                 void previsit( const ast::AsmStmt * );
    1146                 void previsit( const ast::IfStmt * );
    1147                 void previsit( const ast::WhileStmt * );
    1148                 void previsit( const ast::ForStmt * );
    1149                 void previsit( const ast::SwitchStmt * );
    1150                 void previsit( const ast::CaseStmt * );
    1151                 void previsit( const ast::BranchStmt * );
    1152                 void previsit( const ast::ReturnStmt * );
    1153                 void previsit( const ast::ThrowStmt * );
    1154                 void previsit( const ast::CatchStmt * );
    1155                 void previsit( const ast::WaitForStmt * );
    1156 
    1157                 void previsit( const ast::SingleInit * );
    1158                 void previsit( const ast::ListInit * );
    1159                 void previsit( const ast::ConstructorInit * );
     955                void previsit( const ast::FunctionDecl * functionDecl );
     956                const ast::FunctionDecl * postvisit( const ast::FunctionDecl * functionDecl );
     957                void previsit( const ast::ObjectDecl * objectDecl );
     958                void previsit( const ast::EnumDecl * enumDecl );
     959                void previsit( const ast::StaticAssertDecl * assertDecl );
     960
     961                void previsit( const ast::ArrayType * at );
     962                void previsit( const ast::PointerType * pt );
     963
     964                void previsit( const ast::ExprStmt * exprStmt );
     965                void previsit( const ast::AsmExpr * asmExpr );
     966                void previsit( const ast::AsmStmt * asmStmt );
     967                void previsit( const ast::IfStmt * ifStmt );
     968                void previsit( const ast::WhileStmt * whileStmt );
     969                void previsit( const ast::ForStmt * forStmt );
     970                void previsit( const ast::SwitchStmt * switchStmt );
     971                void previsit( const ast::CaseStmt * caseStmt );
     972                void previsit( const ast::BranchStmt * branchStmt );
     973                void previsit( const ast::ReturnStmt * returnStmt );
     974                void previsit( const ast::ThrowStmt * throwStmt );
     975                void previsit( const ast::CatchStmt * catchStmt );
     976                void previsit( const ast::WaitForStmt * stmt );
     977
     978                void previsit( const ast::SingleInit * singleInit );
     979                void previsit( const ast::ListInit * listInit );
     980                void previsit( const ast::ConstructorInit * ctorInit );
    1160981        };
    1161982
     
    11831004                                        ast::chain_mutate( ret )
    11841005                                                ( &ast::FunctionDecl::type )
    1185                                                         ( &ast::FunctionType::params )[i]
     1006                                                        ( &ast::FunctionType::params )
     1007                                                                [i]
    11861008                                                                ( &ast::ObjectDecl::init )
    11871009                                                                        ( &ast::SingleInit::value )->env = nullptr;
     
    12011023        }
    12021024
    1203         void Resolver_new::previsit( const ast::EnumDecl * ) {
    1204                 // in case we decide to allow nested enums
    1205                 GuardValue( inEnumDecl );
    1206                 inEnumDecl = false;
    1207         }
    1208 
    1209         const ast::StaticAssertDecl * Resolver_new::previsit(
    1210                 const ast::StaticAssertDecl * assertDecl
    1211         ) {
    1212                 ast::ptr< ast::Expr > cond = findIntegralExpression( assertDecl->cond, symtab );
    1213                 if ( cond == assertDecl->cond ) return assertDecl;
    1214                
    1215                 ast::StaticAssertDecl * ret = mutate( assertDecl );
    1216                 ret->cond = cond;
    1217                 return ret;
     1025        void Resolver_new::previsit( const ast::EnumDecl * enumDecl ) {
     1026                #warning unimplemented; Resolver port in progress
     1027                (void)enumDecl;
     1028                assert(false);
     1029        }
     1030
     1031        void Resolver_new::previsit( const ast::StaticAssertDecl * assertDecl ) {
     1032                #warning unimplemented; Resolver port in progress
     1033                (void)assertDecl;
     1034                assert(false);
    12181035        }
    12191036
  • src/ResolvExpr/module.mk

    r3cd5fdd r8568319  
    1919      ResolvExpr/Alternative.cc \
    2020      ResolvExpr/AlternativeFinder.cc \
    21       ResolvExpr/Candidate.cpp \
    22       ResolvExpr/CandidateFinder.cpp \
    2321      ResolvExpr/CastCost.cc \
    2422      ResolvExpr/CommonType.cc \
  • src/ResolvExpr/typeops.h

    r3cd5fdd r8568319  
    103103
    104104        bool typesCompatible(
    105                 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
     105                const ast::Type *, const ast::Type *, const ast::SymbolTable &,
    106106                const ast::TypeEnvironment & env = {} );
    107107       
  • src/SynTree/BaseSyntaxNode.h

    r3cd5fdd r8568319  
    4141  /// * Expressions should not finish with a newline, since the expression's parent has better information.
    4242        virtual void print( std::ostream & os, Indenter indent = {} ) const = 0;
     43  void print( std::ostream & os, unsigned int indent ) {
     44    print( os, Indenter{ Indenter::tabsize, indent });
     45  }
    4346};
    4447
Note: See TracChangeset for help on using the changeset viewer.