Goose  Diff

Differences From Artifact [b089669b65]:

  • File bs/builtins/api/compiler.cpp — part of check-in [ffa2c830dd] at 2019-08-10 19:33:22 on branch trunk — Implemented a DiagnosticsContext class which can be used to push contextual informations that are printed when an error is emitted. (user: achavasse size: 5077)

To Artifact [af576722ee]:

  • File bs/builtins/api/compiler.cpp — part of check-in [b8548d8b24] at 2019-08-11 17:18:45 on branch trunk —
    • Converted more error messages to the new system.
    • Propagated value locations in some missing places.
    • Added the location of template function calls as diagnostics context.
    (user: achavasse size: 5820)

22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53

54
55
56
57
58
59
60
61

        RegisterBuiltinFunc< Eager< uint32_t > ( string ) >( e, "ExecuteFile"_sid,
            [pEnv]( const string& filename ) -> uint32_t
            {
                ifstream sourcefile( filename.c_str() );
                if( !sourcefile.good() )
                {

                    cout << "can't open '" << filename << "'\n";
                    return 0;
                }

                sema::Context c( pEnv.lock(), RootIdentity(), GetValueType< uint32_t >() );
                DiagnosticsContext dc( 0, true );

                auto r = make_shared< parse::Resolver >(
                    make_shared< lex::Lexer >( sourcefile, filename ), c );
                parse::Parser p( r );

                auto cfg = make_shared< llr::CFG >();
                p.setCFG( cfg );
                p.setCurrentBB( cfg->entryBB() );

                p.parseSequence();

                if( !r->eos() )
                {

                    cout << filename << ": syntax error.\n";
                    return 0;
                }

                if( !cfg->entryBB()->canBeExecuted() )
                {

                    cout << filename << ": can not be executed.\n";
                    return 0;
                }

                execute::VM vm;
                auto result = vm.execute( cfg->entryBB() );
                if( !result )
                    return 1;







>
|


















>
|





>
|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

        RegisterBuiltinFunc< Eager< uint32_t > ( string ) >( e, "ExecuteFile"_sid,
            [pEnv]( const string& filename ) -> uint32_t
            {
                ifstream sourcefile( filename.c_str() );
                if( !sourcefile.good() )
                {
                    DiagnosticsManager::GetInstance().emitErrorMessage( 0,
                        format( "can't open '{}'.", filename ) );
                    return 0;
                }

                sema::Context c( pEnv.lock(), RootIdentity(), GetValueType< uint32_t >() );
                DiagnosticsContext dc( 0, true );

                auto r = make_shared< parse::Resolver >(
                    make_shared< lex::Lexer >( sourcefile, filename ), c );
                parse::Parser p( r );

                auto cfg = make_shared< llr::CFG >();
                p.setCFG( cfg );
                p.setCurrentBB( cfg->entryBB() );

                p.parseSequence();

                if( !r->eos() )
                {
                    DiagnosticsManager::GetInstance().emitErrorMessage(
                        r->getCurrentLocation(), "syntax error." );
                    return 0;
                }

                if( !cfg->entryBB()->canBeExecuted() )
                {
                    DiagnosticsManager::GetInstance().emitErrorMessage( 0,
                        format( "{}: can not be executed.", filename ) );
                    return 0;
                }

                execute::VM vm;
                auto result = vm.execute( cfg->entryBB() );
                if( !result )
                    return 1;
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
118
119
120
121
122
123
124
125



126
127
128
129
130
131
132
133
134
                auto func = BuildFunc( c, ftype, identity, params, make_shared< Vector >(), c );
                const auto& pFuncLLR = func.llr();

                ifstream sourcefile( filename.c_str() );
                if( !sourcefile.good() )
                {
                    pFuncLLR->setInvalid();

                    cout << "can't open '" << filename << "'\n";
                    return ToValue( func );
                }

                auto r = make_shared< parse::Resolver >( make_shared< lex::Lexer >( sourcefile, filename ), c );
                parse::Parser p( r );

                auto cfg = make_shared< llr::CFG >();
                p.setCFG( cfg );
                p.setCurrentBB( cfg->entryBB() );

                p.parseSequence();

                if( !r->eos() )
                {
                    pFuncLLR->setInvalid();

                    cout << "syntax error.\n";
                    return ToValue( func );
                }

                if( c.returnType() != GetValueType< void >()
                    && !cfg->areAllBBTerminated() )
                {
                    pFuncLLR->setInvalid();

                    // TODO error management etc



                    cout << "missing return statement in a function with non-void return type.\n";
                    return ToValue( func );
                }

                pFuncLLR->body() = cfg;
                return ToValue( func );
            } );
    }
}







>
|















>
|








|
>
>
>
|








96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
                auto func = BuildFunc( c, ftype, identity, params, make_shared< Vector >(), c );
                const auto& pFuncLLR = func.llr();

                ifstream sourcefile( filename.c_str() );
                if( !sourcefile.good() )
                {
                    pFuncLLR->setInvalid();
                    DiagnosticsManager::GetInstance().emitErrorMessage( 0,
                        format( "can't open '{}'.", filename ) );
                    return ToValue( func );
                }

                auto r = make_shared< parse::Resolver >( make_shared< lex::Lexer >( sourcefile, filename ), c );
                parse::Parser p( r );

                auto cfg = make_shared< llr::CFG >();
                p.setCFG( cfg );
                p.setCurrentBB( cfg->entryBB() );

                p.parseSequence();

                if( !r->eos() )
                {
                    pFuncLLR->setInvalid();
                    DiagnosticsManager::GetInstance().emitErrorMessage(
                        r->getCurrentLocation(), "syntax error." );
                    return ToValue( func );
                }

                if( c.returnType() != GetValueType< void >()
                    && !cfg->areAllBBTerminated() )
                {
                    pFuncLLR->setInvalid();

                    // TODO the return statement should always be optional at the top level of a file,
                    // so we should be passed a default return value as parameter and insert return
                    // statements automatically wherever they may be missing in the cfg.
                    DiagnosticsManager::GetInstance().emitErrorMessage( 0,
                        format( "{}: missing return statement in a function with non-void return type.", filename ) );
                    return ToValue( func );
                }

                pFuncLLR->body() = cfg;
                return ToValue( func );
            } );
    }
}