From 3e838627dce1faaac5bd75dc4bade3a4474d69f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Mon, 25 Dec 2017 22:40:55 +0100 Subject: [PATCH] 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. --- c-opparser.cc | 73 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/c-opparser.cc b/c-opparser.cc index d19cc78..6847ced 100644 --- a/c-opparser.cc +++ b/c-opparser.cc @@ -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" ) {