Changeset e01eb4a for src/AST


Ignore:
Timestamp:
Sep 22, 2022, 2:23:18 PM (22 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, ast-experimental, master
Children:
5d8dae7
Parents:
0bd46fd
Message:

Moved some functions from InitTweak? to Inspect.

Location:
src/AST
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Expr.cpp

    r0bd46fd re01eb4a  
    2222#include "Copy.hpp"                // for shallowCopy
    2323#include "GenericSubstitution.hpp"
     24#include "Inspect.hpp"
    2425#include "LinkageSpec.hpp"
    2526#include "Stmt.hpp"
     
    2930#include "Common/SemanticError.h"
    3031#include "GenPoly/Lvalue.h"        // for referencesPermissable
    31 #include "InitTweak/InitTweak.h"   // for getFunction, getPointerBase
    3232#include "ResolvExpr/typeops.h"    // for extractResultType
    3333#include "Tuples/Tuples.h"         // for makeTupleType
     
    5858
    5959bool ApplicationExpr::get_lvalue() const {
    60         if ( const DeclWithType * func = InitTweak::getFunction( this ) ) {
     60        if ( const DeclWithType * func = getFunction( this ) ) {
    6161                return func->linkage == Linkage::Intrinsic && lvalueFunctionNames.count( func->name );
    6262        }
     
    6767
    6868bool UntypedExpr::get_lvalue() const {
    69         std::string fname = InitTweak::getFunctionName( this );
     69        std::string fname = getFunctionName( this );
    7070        return lvalueFunctionNames.count( fname );
    7171}
     
    7676        UntypedExpr * ret = createCall( loc, "*?", { arg } );
    7777        if ( const Type * ty = arg->result ) {
    78                 const Type * base = InitTweak::getPointerBase( ty );
     78                const Type * base = getPointerBase( ty );
    7979                assertf( base, "expected pointer type in dereference (type was %s)", toString( ty ).c_str() );
    8080
     
    335335        // first argument
    336336        assert( callExpr );
    337         const Expr * arg = InitTweak::getCallArg( callExpr, 0 );
     337        const Expr * arg = getCallArg( callExpr, 0 );
    338338        assert( arg );
    339339        result = arg->result;
  • src/AST/Inspect.cpp

    r0bd46fd re01eb4a  
    1010// Created On       : Fri Jun 24 13:16:31 2022
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Jun 27 15:35:00 2022
    13 // Update Count     : 1
     12// Last Modified On : Wed Sep 22 13:50:00 2022
     13// Update Count     : 2
    1414//
    1515
    16 #include "AST/Decl.hpp"
    17 #include "AST/Type.hpp"
     16#include "Inspect.hpp"
    1817
    1918#include <iostream>
    20 #include <AST/Print.hpp>
     19
     20#include "AST/Decl.hpp"
     21#include "AST/Expr.hpp"
     22#include "AST/Print.hpp"
     23#include "AST/Stmt.hpp"
     24#include "AST/Type.hpp"
     25#include "CodeGen/OperatorTable.h"
    2126
    2227namespace ast {
     28
     29const Type * getPointerBase( const Type * t ) {
     30        if ( const auto * p = dynamic_cast< const PointerType * >( t ) ) {
     31                return p->base;
     32        } else if ( const auto * a = dynamic_cast< const ArrayType * >( t ) ) {
     33                return a->base;
     34        } else if ( const auto * r = dynamic_cast< const ReferenceType * >( t ) ) {
     35                return r->base;
     36        } else {
     37                return nullptr;
     38        }
     39}
     40
     41template<typename CallExpr>
     42static const Expr * callArg( const CallExpr * call, unsigned int pos ) {
     43        assertf( pos < call->args.size(),
     44                "getCallArg for argument that doesn't exist: (%u); %s.",
     45                pos, toString( call ).c_str() );
     46        for ( const Expr * arg : call->args ) {
     47                if ( 0 == pos ) return arg;
     48                --pos;
     49        }
     50        assert( false );
     51}
     52
     53template<typename CallExpr, typename Ret>
     54static Ret throughDeref( const CallExpr * expr, Ret(*func)( const Expr * ) ) {
     55        // In `(*f)(x)` the function we want is `f`.
     56        std::string name = getFunctionName( expr );
     57        assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() );
     58        assertf( !expr->args.empty(), "Cannot get function name from dereference with no arguments" );
     59        return func( expr->args.front() );
     60}
     61
     62static const DeclWithType * getCalledFunction( const Expr * expr ) {
     63        assert( expr );
     64        if ( const ast::VariableExpr * varExpr = dynamic_cast< const ast::VariableExpr * >( expr ) ) {
     65                return varExpr->var;
     66        } else if ( const ast::MemberExpr * memberExpr = dynamic_cast< const ast::MemberExpr * >( expr ) ) {
     67                return memberExpr->member;
     68        } else if ( const ast::CastExpr * castExpr = dynamic_cast< const ast::CastExpr * >( expr ) ) {
     69                return getCalledFunction( castExpr->arg );
     70        } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * >( expr ) ) {
     71                return throughDeref( untypedExpr, getCalledFunction );
     72        } else if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * > ( expr ) ) {
     73                return throughDeref( appExpr, getCalledFunction );
     74        } else if ( const ast::AddressExpr * addrExpr = dynamic_cast< const ast::AddressExpr * >( expr ) ) {
     75                return getCalledFunction( addrExpr->arg );
     76        } else if ( const ast::CommaExpr * commaExpr = dynamic_cast< const ast::CommaExpr * >( expr ) ) {
     77                return getCalledFunction( commaExpr->arg2 );
     78        }
     79        return nullptr;
     80}
     81
     82const DeclWithType * getFunction( const Expr * expr ) {
     83        if ( auto app = dynamic_cast< const ApplicationExpr * >( expr ) ) {
     84                return getCalledFunction( app->func );
     85        } else if ( auto untyped = dynamic_cast< const UntypedExpr * >( expr ) ) {
     86                return getCalledFunction( untyped->func );
     87        }
     88        assertf( false, "getFunction received unknown expression: %s", toString( expr ).c_str() );
     89}
     90
     91// There is a lot of overlap with getCalledFunction. Ideally it would use
     92// it as a helper function and return the name of the DeclWithType. But the
     93// NameExpr and UntypedMemberExpr only work on this version.
     94static std::string funcName( const Expr * func ) {
     95        assert( func );
     96        if ( const ast::NameExpr * nameExpr = dynamic_cast< const ast::NameExpr * >( func ) ) {
     97                return nameExpr->name;
     98        } else if ( const ast::VariableExpr * varExpr = dynamic_cast< const ast::VariableExpr * >( func ) ) {
     99                return varExpr->var->name;
     100        } else if ( const ast::CastExpr * castExpr = dynamic_cast< const ast::CastExpr * >( func ) ) {
     101                return funcName( castExpr->arg );
     102        } else if ( const ast::MemberExpr * memberExpr = dynamic_cast< const ast::MemberExpr * >( func ) ) {
     103                return memberExpr->member->name;
     104        } else if ( const ast::UntypedMemberExpr * memberExpr = dynamic_cast< const ast::UntypedMemberExpr * > ( func ) ) {
     105                return funcName( memberExpr->member );
     106        } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * >( func ) ) {
     107                return throughDeref( untypedExpr, funcName );
     108        } else if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( func ) ) {
     109                return throughDeref( appExpr, funcName );
     110        } else if ( const ast::ConstructorExpr * ctorExpr = dynamic_cast< const ast::ConstructorExpr * >( func ) ) {
     111                return funcName( getCallArg( ctorExpr->callExpr, 0 ) );
     112        } else {
     113                assertf( false, "Unexpected expression type being called as a function in call expression: %s", toString( func ).c_str() );
     114        }
     115}
     116
     117std::string getFunctionName( const Expr * expr ) {
     118        // There's some unforunate overlap here with getCalledFunction. Ideally
     119        // this would be able to use getCalledFunction and return the name of the
     120        // DeclWithType, but this needs to work for NameExpr and UntypedMemberExpr,
     121        // where getCalledFunction can't possibly do anything reasonable.
     122        if ( auto app = dynamic_cast< const ApplicationExpr * >( expr ) ) {
     123                return funcName( app->func );
     124        } else if ( auto untyped = dynamic_cast< const UntypedExpr * >( expr ) ) {
     125                return funcName( untyped->func );
     126        } else {
     127                assertf( false, "Unexpected expression type passed to getFunctionName: %s", toString( expr ).c_str() );
     128        }
     129}
     130
     131const Expr * getCallArg( const Expr * call, unsigned int pos ) {
     132        if ( auto app = dynamic_cast< const ApplicationExpr * >( call ) ) {
     133                return callArg( app, pos );
     134        } else if ( auto untyped = dynamic_cast< const UntypedExpr * >( call ) ) {
     135                return callArg( untyped, pos );
     136        } else if ( auto tupleAssn = dynamic_cast< const TupleAssignExpr * >( call ) ) {
     137                const std::list<ptr<Stmt>>& stmts = tupleAssn->stmtExpr->stmts->kids;
     138                assertf( !stmts.empty(), "TupleAssignExpr missing statements." );
     139                auto stmt  = strict_dynamic_cast< const ExprStmt * >( stmts.back().get() );
     140                auto tuple = strict_dynamic_cast< const TupleExpr * >( stmt->expr.get() );
     141                assertf( !tuple->exprs.empty(), "TupleAssignExpr has empty tuple expr." );
     142                return getCallArg( tuple->exprs.front(), pos );
     143        } else if ( auto ctor = dynamic_cast< const ImplicitCopyCtorExpr * >( call ) ) {
     144                return getCallArg( ctor->callExpr, pos );
     145        } else {
     146                assertf( false, "Unexpected expression type passed to getCallArg: %s",
     147                        toString( call ).c_str() );
     148        }
     149}
    23150
    24151bool structHasFlexibleArray( const ast::StructDecl * decl ) {
     
    33160}
    34161
     162const ApplicationExpr * isIntrinsicCallExpr( const Expr * expr ) {
     163        auto appExpr = dynamic_cast< const ApplicationExpr * >( expr );
     164        if ( !appExpr ) return nullptr;
     165
     166        const DeclWithType * func = getCalledFunction( appExpr->func );
     167        assertf( func,
     168                "getCalledFunction returned nullptr: %s", toString( appExpr->func ).c_str() );
     169
     170        return func->linkage == ast::Linkage::Intrinsic ? appExpr : nullptr;
     171}
     172
    35173} // namespace ast
  • src/AST/Inspect.hpp

    r0bd46fd re01eb4a  
    1010// Created On       : Fri Jun 24 13:16:31 2022
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Jun 27 15:35:00 2022
    13 // Update Count     : 1
     12// Last Modified On : Thr Sep 22 13:44:00 2022
     13// Update Count     : 2
    1414//
    1515
     
    1818namespace ast {
    1919
    20 // Does the structure end in a flexable array declaration?
    21 bool structHasFlexibleArray( const ast::StructDecl * );
     20/// Returns the base type of an pointer/array/reference type,
     21/// if the argument is not one of those types, return null.
     22const Type * getPointerBase( const Type * );
     23
     24/// Get the declaration of the function called (ApplicationExpr or UntypedExpr).
     25const DeclWithType * getFunction( const Expr * expr );
     26
     27/// Get the name of the function being called.
     28std::string getFunctionName( const Expr * expr );
     29
     30/// Returns the argument to a call expression in position N, indexed from 0.
     31const Expr * getCallArg( const Expr * call, unsigned pos );
     32
     33/// Does the structure end in a flexable array declaration?
     34bool structHasFlexibleArray( const StructDecl * );
     35
     36/// If the expression is an application whose target function is an
     37/// intrinsic, then returns a pointer to that application.
     38const ApplicationExpr * isIntrinsicCallExpr( const Expr * expr );
    2239
    2340}
  • src/AST/SymbolTable.cpp

    r0bd46fd re01eb4a  
    2020#include "Decl.hpp"
    2121#include "Expr.hpp"
     22#include "Inspect.hpp"
    2223#include "Type.hpp"
    2324#include "CodeGen/OperatorTable.h"  // for isCtorDtorAssign
     
    466467                assert( ! params.empty() );
    467468                // use base type of pointer, so that qualifiers on the pointer type aren't considered.
    468                 const Type * base = InitTweak::getPointerBase( params.front() );
     469                const Type * base = ast::getPointerBase( params.front() );
    469470                assert( base );
    470471                if (stripParams) {
  • src/AST/Type.cpp

    r0bd46fd re01eb4a  
    2222#include "Decl.hpp"
    2323#include "Init.hpp"
     24#include "Inspect.hpp"
    2425#include "Common/utility.h"      // for copy, move
    25 #include "InitTweak/InitTweak.h" // for getPointerBase
    2626#include "Tuples/Tuples.h"       // for isTtype
    2727
     
    3636        const Type * t;
    3737        const Type * a;
    38         for ( t = this; (a = InitTweak::getPointerBase( t )); t = a );
     38        for ( t = this; (a = ast::getPointerBase( t )); t = a );
    3939        return t;
    4040}
Note: See TracChangeset for help on using the changeset viewer.