Goose  Diff

Differences From Artifact [fa2ec840f5]:

  • File bs/parse/parser.cpp — part of check-in [b4385d9930] at 2019-11-04 19:53:00 on branch trunk — Verifier: more work on loop verification. (user: achavasse size: 9663)

To Artifact [7b8622593c]:

  • File bs/parse/parser.cpp — part of check-in [b702561850] at 2019-12-11 15:38:14 on branch trunk —
    • Compile-time execution: don't attempt to perform a compile time evaluation of every invocation. Instead, wait until a type is being used by a decl to try and evaluate it.
    • Diagnostics: simplify accordingly (no need for the mode that silences all errors during attempted comptime evaluation)
    • Added some verification conditions to the mandelbrot sample, and created a broken variant as a verification diagnostics test.
    (user: achavasse size: 10248)

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

    // If the identifier is preceded by a TExpr or a Type,
    // then this becomes a TDecl or a Decl, respectively.
    if( IsTExpr( *leftVal ) )
    {
        auto loc = Location::CreateSpanningLocation( leftVal->locationId(), nameTerm->second );

        auto texpr = ValueToIRExpr( *popValue() );
        pushValue( ToValue( TNamedDecl( move( texpr ), *name ) ).setLocationId( loc ) );
        return true;
    }
    else if( IsType( *leftVal ) )
    {
        auto loc = Location::CreateSpanningLocation( leftVal->locationId(), nameTerm->second );

        auto type = ValueToIRExpr( *popValue() );
        pushValue( ToValue( Decl( move( type ), *name ) ).setLocationId( loc ) );
        return true;
    }

    return parsePrefix( strid, prec );
}

bool Parser::parsePrefix( const pvec& vec, uint32_t prec )
{
    auto t = *m_resolver->lookAhead();

    auto val = ValueFromIRExpr( t.first );
    if( !val )
        return false;

    if( val->isPoison() )
        DiagnosticsManager::GetInstance().setCurrentVerbosityLevel( Verbosity::SilentLocally );

    // If the term is a prefix rule value, invoke its parsePrefix() function.
    auto rule = FromValue< Rule >( *val );
    if( !rule )
    {
        m_resolver->consume();
        pushValue( Value( move( *val ) ).setLocationId( t.second ) );







|







|
















|







217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

    // If the identifier is preceded by a TExpr or a Type,
    // then this becomes a TDecl or a Decl, respectively.
    if( IsTExpr( *leftVal ) )
    {
        auto loc = Location::CreateSpanningLocation( leftVal->locationId(), nameTerm->second );

        auto texpr = ValueToIRExpr( *popAndEvalType() );
        pushValue( ToValue( TNamedDecl( move( texpr ), *name ) ).setLocationId( loc ) );
        return true;
    }
    else if( IsType( *leftVal ) )
    {
        auto loc = Location::CreateSpanningLocation( leftVal->locationId(), nameTerm->second );

        auto type = ValueToIRExpr( *popAndEvalType() );
        pushValue( ToValue( Decl( move( type ), *name ) ).setLocationId( loc ) );
        return true;
    }

    return parsePrefix( strid, prec );
}

bool Parser::parsePrefix( const pvec& vec, uint32_t prec )
{
    auto t = *m_resolver->lookAhead();

    auto val = ValueFromIRExpr( t.first );
    if( !val )
        return false;

    if( val->isPoison() )
        DiagnosticsManager::GetInstance().setCurrentVerbosityLevel( Verbosity::Silent );

    // If the term is a prefix rule value, invoke its parsePrefix() function.
    auto rule = FromValue< Rule >( *val );
    if( !rule )
    {
        m_resolver->consume();
        pushValue( Value( move( *val ) ).setLocationId( t.second ) );
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320

























    auto t = *m_resolver->lookAhead();

    auto val = ValueFromIRExpr( t.first );
    if( !val )
        return false;

    if( val->isPoison() )
        DiagnosticsManager::GetInstance().setCurrentVerbosityLevel( Verbosity::SilentLocally );

    if( val->type() == GetValueType< ptr< OverloadSet > >() )
        return parseInfixOverloadSet( *FromValue< ptr< OverloadSet > >( *val ), prec );

    // If the term is an infix rule value, invoke its parseInfix() function.
    auto rule = FromValue< Rule >( *val );
    if( !rule )
        return false;

    m_resolver->consume();

    if( !( *rule )->isInfix() )
        return false;

    return ( *rule )->parseInfix( *this, t.second, prec );
}
































|
















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
    auto t = *m_resolver->lookAhead();

    auto val = ValueFromIRExpr( t.first );
    if( !val )
        return false;

    if( val->isPoison() )
        DiagnosticsManager::GetInstance().setCurrentVerbosityLevel( Verbosity::Silent );

    if( val->type() == GetValueType< ptr< OverloadSet > >() )
        return parseInfixOverloadSet( *FromValue< ptr< OverloadSet > >( *val ), prec );

    // If the term is an infix rule value, invoke its parseInfix() function.
    auto rule = FromValue< Rule >( *val );
    if( !rule )
        return false;

    m_resolver->consume();

    if( !( *rule )->isInfix() )
        return false;

    return ( *rule )->parseInfix( *this, t.second, prec );
}

optional< Value > Parser::popAndEvalType()
{
    if( !m_lastValue )
        return nullopt;

    auto typeVal = *popValue();
    bool typeOk = llr::CanValueBeEagerlyEvaluated( typeVal );

    if( typeOk )
    {
        execute::VM vm;
        typeVal = execute::Evaluate( typeVal, vm );
        typeOk = !typeVal.isPoison() && typeVal.isConstant();
    }

    if( !typeOk )
    {
        DiagnosticsManager::GetInstance().emitErrorMessage( typeVal.locationId(),
            "this type expression can't be evaluated here.", 0 );
        return PoisonType();
    }

    return typeVal;
}