Parser - Preliminary work in (include)

The parser accepts (include "some file") at top level. It does nothing
so far, however, and having it do anything will require some new code
for file name / path handling.
This commit is contained in:
Emmanuel BENOîT 2017-12-25 22:40:55 +01:00
parent 19ae316ad0
commit 3e838627dc

View file

@ -172,6 +172,9 @@ struct T_ParserImpl_
T_SRDParserConfig ovParserConfig;
T_SRDParser ovParser;
T_String curFile;
T_AutoArray< T_String , 32 > inclStack;
T_Visitor< A_Node > visitor{ opast::ASTVisitorBrowser };
T_Visitor< uint32_t , uint32_t > callGraphVisitor{
[this]( uint32_t v , uint32_t child ) -> T_Optional< uint32_t > {
@ -218,6 +221,9 @@ struct T_ParserImpl_
// ---------------------------------------------------------------------
bool parseTopLevel( T_SRDList const& list ) noexcept;
void parseTLList( T_SRDList const& funcList ) noexcept;
void handleInclude( T_SRDToken const& tFileName ) noexcept;
void parseFunction( T_SRDList const& funcList ) noexcept;
void parseFunctionArguments(
@ -944,28 +950,71 @@ bool T_ParserImpl_::parseTopLevel(
M_LOGSTR_( "... Generating tree" , 2 );
for ( auto const& t : input ) {
if ( t.type( ) == E_SRDTokenType::LIST && t.list( ).size( ) > 0 ) {
parseFunction( t.list( ) );
parseTLList( t.list( ) );
} else {
errors.addNew( "function, init or frame list expected" ,
t.location( ) );
errors.addNew( "top-level list expected" , t.location( ) );
}
}
return errors.empty( );
}
void T_ParserImpl_::parseFunction(
T_SRDList const& funcList ) noexcept
void T_ParserImpl_::parseTLList(
T_SRDList const& input ) noexcept
{
assert( funcList.size( ) != 0 );
auto const& fw( funcList[ 0 ] );
if ( fw.type( ) != E_SRDTokenType::WORD
|| ( fw.stringValue( ) != "init" && fw.stringValue( ) != "frame"
&& fw.stringValue( ) != "fn" ) ) {
errors.addNew( "init, frame or fn expected" , fw.location( ) );
assert( input.size( ) != 0 );
auto const& ft{ input[ 0 ] };
if ( ft.type( ) != E_SRDTokenType::WORD ) {
errors.addNew( "word expected" , ft.location( ) );
return;
}
auto const& fw{ ft.stringValue( ) };
if ( fw == "include" ) {
// TODO
if ( input.size( ) == 1 ) {
errors.addNew( "file name expected" ,
ft.location( ) );
} else {
handleInclude( input[ 1 ] );
if ( input.size( ) > 2 ) {
errors.addNew( "too many arguments" ,
input[ 2 ].location( ) );
}
}
} else if ( fw == "init" || fw == "frame" || fw == "fn" ) {
parseFunction( input );
} else {
errors.addNew( "function or include expected" , ft.location( ) );
}
}
/*----------------------------------------------------------------------------*/
void T_ParserImpl_::handleInclude(
T_SRDToken const& tFileName ) noexcept
{
if ( tFileName.type( ) != E_SRDTokenType::STRING ) {
errors.addNew( "file name expected" ,
tFileName.location( ) );
return;
}
if ( !curFile ) {
curFile = tFileName.location( ).source( );
}
// TODO: resolve included file path
// TODO: check for recursive includes
// TODO: load file
// TODO: parse it
}
/*----------------------------------------------------------------------------*/
void T_ParserImpl_::parseFunction(
T_SRDList const& funcList ) noexcept
{
auto const& fw( funcList[ 0 ] );
T_String const& ftw( fw.stringValue( ) );
T_OwnPtr< A_FuncNode > fn;
if ( ftw == "fn" ) {