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_SRDParserConfig ovParserConfig;
T_SRDParser ovParser; T_SRDParser ovParser;
T_String curFile;
T_AutoArray< T_String , 32 > inclStack;
T_Visitor< A_Node > visitor{ opast::ASTVisitorBrowser }; T_Visitor< A_Node > visitor{ opast::ASTVisitorBrowser };
T_Visitor< uint32_t , uint32_t > callGraphVisitor{ T_Visitor< uint32_t , uint32_t > callGraphVisitor{
[this]( uint32_t v , uint32_t child ) -> T_Optional< uint32_t > { [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; 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 parseFunction( T_SRDList const& funcList ) noexcept;
void parseFunctionArguments( void parseFunctionArguments(
@ -944,28 +950,71 @@ bool T_ParserImpl_::parseTopLevel(
M_LOGSTR_( "... Generating tree" , 2 ); M_LOGSTR_( "... Generating tree" , 2 );
for ( auto const& t : input ) { for ( auto const& t : input ) {
if ( t.type( ) == E_SRDTokenType::LIST && t.list( ).size( ) > 0 ) { if ( t.type( ) == E_SRDTokenType::LIST && t.list( ).size( ) > 0 ) {
parseFunction( t.list( ) ); parseTLList( t.list( ) );
} else { } else {
errors.addNew( "function, init or frame list expected" , errors.addNew( "top-level list expected" , t.location( ) );
t.location( ) );
} }
} }
return errors.empty( ); return errors.empty( );
} }
void T_ParserImpl_::parseFunction( void T_ParserImpl_::parseTLList(
T_SRDList const& funcList ) noexcept T_SRDList const& input ) noexcept
{ {
assert( funcList.size( ) != 0 ); assert( input.size( ) != 0 );
auto const& ft{ input[ 0 ] };
auto const& fw( funcList[ 0 ] ); if ( ft.type( ) != E_SRDTokenType::WORD ) {
if ( fw.type( ) != E_SRDTokenType::WORD errors.addNew( "word expected" , ft.location( ) );
|| ( fw.stringValue( ) != "init" && fw.stringValue( ) != "frame"
&& fw.stringValue( ) != "fn" ) ) {
errors.addNew( "init, frame or fn expected" , fw.location( ) );
return; 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_String const& ftw( fw.stringValue( ) );
T_OwnPtr< A_FuncNode > fn; T_OwnPtr< A_FuncNode > fn;
if ( ftw == "fn" ) { if ( ftw == "fn" ) {