| 880 | |
| 881 | |
| 882 | Expression * ast_makeBlock ( yyscan_t scanner, int bal, AnnotationList * annL, vector<CaptureEntry> * clist, |
| 883 | vector<VariableDeclaration*> * list, TypeDecl * result, Expression * block, const LineInfo & blockAt, const LineInfo & annLAt, const LineInfo & clistAt ) { |
| 884 | auto mkb = new ExprMakeBlock(blockAt,block, bal==1, bal==2); |
| 885 | mkb->captureAt = clistAt; |
| 886 | ExprBlock * closure = (ExprBlock *) block; |
| 887 | closure->returnType = result; |
| 888 | if ( list ) { |
| 889 | for ( auto pDecl : *list ) { |
| 890 | if ( pDecl->pTypeDecl ) { |
| 891 | for ( const auto & name_at : *pDecl->pNameList ) { |
| 892 | // Macro-tagged names (`$i(expr)` in block-arg position) all parse to the |
| 893 | // literal placeholder "``MACRO``TAG``"; the actual name is resolved later |
| 894 | // when the macro processor substitutes the tag expression. Skip the dup |
| 895 | // check for tagged names so multi-arg lists like |
| 896 | // `$($i(a) : T, $i(b) : T) { ... }` aren't false-positive at parse time. |
| 897 | // After resolution, duplicate names surface as ordinary local-lookup |
| 898 | // conflicts during type inference. |
| 899 | if ( name_at.tag || !closure->findArgument(name_at.name) ) { |
| 900 | VariablePtr pVar = new Variable(); |
| 901 | pVar->name = name_at.name; |
| 902 | pVar->aka = name_at.aka; |
| 903 | pVar->at = name_at.at; |
| 904 | if ( pDecl->pNameList->size()>1 ) { |
| 905 | pVar->type = new TypeDecl(*pDecl->pTypeDecl); |
| 906 | } else { |
| 907 | pVar->type = pDecl->pTypeDecl; pDecl->pTypeDecl = nullptr; |
| 908 | } |
| 909 | if ( pDecl->pInit ) { |
| 910 | if ( pDecl->pNameList->size()>1 ) { |
| 911 | pVar->init = pDecl->pInit->clone(); |
| 912 | } else { |
| 913 | pVar->init = pDecl->pInit; pDecl->pInit = nullptr; |
| 914 | } |
| 915 | pVar->init_via_move = pDecl->init_via_move; |
| 916 | pVar->init_via_clone = pDecl->init_via_clone; |
| 917 | } |
| 918 | if ( pDecl->annotation ) { |
| 919 | pVar->annotation = *pDecl->annotation; |
| 920 | } |
| 921 | if ( auto pTagExpr = name_at.tag ) { |
| 922 | pVar->tag = true; |
| 923 | pVar->source = pTagExpr; |
| 924 | } |
| 925 | closure->arguments.push_back(pVar); |
| 926 | } else { |
| 927 | das_yyerror(scanner,"block argument is already declared " + name_at.name, |
| 928 | name_at.at,CompilationError::already_declared_block_argument); |
| 929 | } |
| 930 | } |
| 931 | } |
| 932 | } |
| 933 | deleteVariableDeclarationList(list); |
| 934 | } |
| 935 | if ( clist ) { |
| 936 | swap ( mkb->capture, *clist ); |
| 937 | delete clist; |
| 938 | if ( bal != 1 ) { // if its not lambda, can't capture |
| 939 | das_yyerror(scanner,"can only have capture section for the lambda", |
no test coverage detected