Goose  Diff

Differences From Artifact [969a748d1d]:

  • File bs/parse/parser.cpp — part of check-in [353fcc252a] at 2020-01-04 15:17:12 on branch trunk —
    • verifier: check compilation-time function calls.
    • verifier: improved error messages wording.
    (user: achavasse size: 10011)

To Artifact [80c98fbef0]:

  • File bs/parse/parser.cpp — part of check-in [b3aeaae2df] at 2020-01-11 18:28:15 on branch trunk —
    • Moved the cfg and lifetime management stuff into a CodeBuilder object owned by sema::Context. This is in preparation to allow alternative implementations of the builder, for instance to build classes.
    • Pass the context to intrinsic functions, which removes their dependency to the parser the need for the ugly "GetCurrentParser" static function.
    (user: achavasse size: 9748)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

#include "parse.h"
#include "builtins/builtins.h"

using namespace goose;
using namespace goose::parse;
using namespace goose::builtins;

Parser* Parser::ms_pCurrentParser = nullptr;

Parser Parser::makeNestedParser()
{
    Parser p( m_resolver );
    p.m_introDelimiter = m_introDelimiter;
    p.setCFG( cfg() );
    p.m_breakableScopeLevels = m_breakableScopeLevels;
    p.m_continuableScopeLevels = m_continuableScopeLevels;
    return p;
}

Parser Parser::makeNestedParser( Delimiter introDelimiter )
{
    Parser p( m_resolver, introDelimiter );
    p.setCFG( cfg() );
    p.m_breakableScopeLevels = m_breakableScopeLevels;
    p.m_continuableScopeLevels = m_continuableScopeLevels;
    return p;
}

// Parse a sequence of expression. Each expression is
// a statement.
void Parser::parseSequence()
{
    for(;;)
    {
        LifetimeScopeGuard lsg( *this );

        {
            // Each statement gets its own visibility scope,
            // so that vars defined inside of the statement are only
            // visible from within it.
            // However, they also have a lifetime scope, which
            // is separate because we need to flush the value








<
<




<
<
<






<
<
<









|







1
2
3
4
5
6
7
8


9
10
11
12



13
14
15
16
17
18



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

#include "parse.h"
#include "builtins/builtins.h"

using namespace goose;
using namespace goose::parse;
using namespace goose::builtins;



Parser Parser::makeNestedParser()
{
    Parser p( m_resolver );
    p.m_introDelimiter = m_introDelimiter;



    return p;
}

Parser Parser::makeNestedParser( Delimiter introDelimiter )
{
    Parser p( m_resolver, introDelimiter );



    return p;
}

// Parse a sequence of expression. Each expression is
// a statement.
void Parser::parseSequence()
{
    for(;;)
    {
        CodeBuilder::LifetimeScopeGuard lsg( context() );

        {
            // Each statement gets its own visibility scope,
            // so that vars defined inside of the statement are only
            // visible from within it.
            // However, they also have a lifetime scope, which
            // is separate because we need to flush the value
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
        if( !parseInfix( next->first, *prec ) )
            break;
    }
}

void Parser::flushValue()
{

    if( m_lastValue && cfg() && ( !cfg()->currentBB() || cfg()->currentBB()->terminator() )  )
    {
        DiagnosticsManager::GetInstance().emitSyntaxErrorMessage(
            m_lastValue->locationId(), "unreachable code.", 0 );
    }

    // Flush the pending value, by invoking the DropValue
    // extension point, where an overload will decide
    // of the value's fate (or possibly emit an error
    // if that value wasn't allowed to be discarded).
    while( m_lastValue )
    {
        auto val = move( *m_lastValue );
        m_lastValue = nullopt;

        if( val.isPoison() )
            return;

        DiagnosticsContext dc( val.locationId(), "When invoking DropValue." );
        InvokeOverloadSet( resolver()->context(), resolver()->context().env()->extDropValue(),
            MakeTuple( val ) );
    }
}

optional< uint32_t > Parser::getPrecedence( const Term& t )
{
    return visit( [&]( auto&& content )







>
|


















|







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
        if( !parseInfix( next->first, *prec ) )
            break;
    }
}

void Parser::flushValue()
{
    const auto& cb = context().codeBuilder();
    if( m_lastValue && cb && cb->cfg() && ( !cb->cfg()->currentBB() || cb->cfg()->currentBB()->terminator() )  )
    {
        DiagnosticsManager::GetInstance().emitSyntaxErrorMessage(
            m_lastValue->locationId(), "unreachable code.", 0 );
    }

    // Flush the pending value, by invoking the DropValue
    // extension point, where an overload will decide
    // of the value's fate (or possibly emit an error
    // if that value wasn't allowed to be discarded).
    while( m_lastValue )
    {
        auto val = move( *m_lastValue );
        m_lastValue = nullopt;

        if( val.isPoison() )
            return;

        DiagnosticsContext dc( val.locationId(), "When invoking DropValue." );
        InvokeOverloadSet( context(), context().env()->extDropValue(),
            MakeTuple( val ) );
    }
}

optional< uint32_t > Parser::getPrecedence( const Term& t )
{
    return visit( [&]( auto&& content )