Changeset b32ada31


Ignore:
Timestamp:
Mar 17, 2017, 1:33:47 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
7c70089
Parents:
17af7d1
Message:

First draft implementation of the coroutine keyword

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    r17af7d1 rb32ada31  
    1717#include "Concurrency/Keywords.h"
    1818
     19#include "SymTab/AddVisit.h"
    1920#include "SynTree/Declaration.h"
    2021#include "SynTree/Expression.h"
     
    2930        namespace {
    3031                const std::list<Label> noLabels;
     32                const std::list< Attribute * > noAttributes;
    3133                Type::StorageClasses noStorage;
    3234                Type::Qualifiers noQualifiers;
     
    6365        //                                           void main( MyCoroutine * this );
    6466        //
    65         class CoroutineKeyword final : public Mutator {
     67        class CoroutineKeyword final : public Visitor {
     68            template< typename Visitor >
     69            friend void SymTab::acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor );
    6670          public:
    6771
    68                 static void implement( std::list< Declaration * > & translationUnit ) {}
     72                using Visitor::visit;
     73                virtual void visit( StructDecl * decl ) override final;
     74
     75                void handle( StructDecl * );
     76                Declaration * addField( StructDecl * );
     77                void addRoutines( StructDecl *, Declaration * );
     78
     79                static void implement( std::list< Declaration * > & translationUnit ) {
     80                        CoroutineKeyword impl;
     81                        SymTab::acceptAndAdd( translationUnit, impl );
     82                }
     83
     84          private:
     85                std::list< Declaration * > declsToAdd, declsToAddAfter;
     86                StructDecl* coroutine_decl = nullptr;
    6987        };
    7088
     
    97115
    98116                using Visitor::visit;
    99                 virtual void visit( FunctionDecl *functionDecl ) override final;
    100                 virtual void visit(   StructDecl *functionDecl ) override final;
     117                virtual void visit( FunctionDecl * decl ) override final;
     118                virtual void visit(   StructDecl * decl ) override final;
    101119
    102120                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
     
    125143
    126144        //=============================================================================================
     145        // Coroutine keyword implementation
     146        //=============================================================================================
     147        void CoroutineKeyword::visit(StructDecl * decl) {
     148                if( decl->get_name() == "coroutine_desc" ) {
     149                        assert( !coroutine_decl );
     150                        coroutine_decl = decl;
     151                }
     152                else if ( false ) {
     153                        handle( decl );
     154                }
     155
     156        }
     157
     158        void CoroutineKeyword::handle( StructDecl * decl ) {
     159                if( ! decl->has_body() ) return;
     160
     161                if( !coroutine_decl ) throw SemanticError( "coroutine keyword requires coroutines to be in scope, add #include <coroutine>", decl );
     162
     163                Declaration * field = addField( decl );
     164                addRoutines( decl, field );
     165        }
     166
     167        Declaration * CoroutineKeyword::addField( StructDecl * decl ) {
     168                Declaration * cor = new ObjectDecl(
     169                        "__cor",
     170                        noStorage,
     171                        LinkageSpec::Cforall,
     172                        nullptr,
     173                        new StructInstType(
     174                                noQualifiers,
     175                                coroutine_decl
     176                        ),
     177                        nullptr
     178                );
     179
     180                decl->get_members().push_front( cor );
     181
     182                return cor;
     183        }
     184
     185        void CoroutineKeyword::addRoutines( StructDecl * decl, Declaration * field ) {
     186                FunctionType * type = new FunctionType( noQualifiers, false );
     187                type->get_parameters().push_back(
     188                        new ObjectDecl(
     189                                "this",
     190                                noStorage,
     191                                LinkageSpec::Cforall,
     192                                nullptr,
     193                                new PointerType(
     194                                        noQualifiers,
     195                                        new StructInstType(
     196                                                noQualifiers,
     197                                                decl
     198                                        )
     199                                ),
     200                                nullptr
     201                        )
     202                );
     203
     204                CompoundStmt * statement = new CompoundStmt( noLabels );
     205                statement->push_back(
     206                        new ReturnStmt(
     207                                noLabels,
     208                                new UntypedMemberExpr(
     209                                        new NameExpr( "__cor" ),
     210                                        new NameExpr( "this" )
     211                                )
     212                        )
     213                );
     214
     215                declsToAddAfter.push_back(
     216                        new FunctionDecl(
     217                                "get_coroutine",
     218                                Type::Static,
     219                                LinkageSpec::Cforall,
     220                                type,
     221                                statement,
     222                                noAttributes,
     223                                Type::Inline
     224                        )
     225                );
     226        }
     227       
     228
     229        //=============================================================================================
    127230        // Mutex keyword implementation
    128231        //=============================================================================================
     
    137240                CompoundStmt* body = decl->get_statements();
    138241                if( ! body ) return;
     242
     243                if( !monitor_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
     244                if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    139245
    140246                addStatments( body, mutexArgs );
     
    183289
    184290        void MutexKeyword::addStatments( CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
    185                 assert(monitor_decl);
    186                 assert(guard_decl);
    187 
    188291                ObjectDecl * monitors = new ObjectDecl(
    189292                        "__monitors",
Note: See TracChangeset for help on using the changeset viewer.