aboutsummaryrefslogtreecommitdiffstats
path: root/3rdparty/python-console/ParseHelper.BlockParseState.cpp
diff options
context:
space:
mode:
authorMiodrag Milanovic <mmicko@gmail.com>2018-06-28 13:16:53 +0200
committerMiodrag Milanovic <mmicko@gmail.com>2018-06-28 17:57:26 +0200
commitc63274342f1aaa3d1087c0df5ffdaccfd0afcd56 (patch)
treeb04628f6c8c6768e2d5771737f3f13687cd0ed29 /3rdparty/python-console/ParseHelper.BlockParseState.cpp
parent66670831b89d934ef00c47c0527137f6ec38a0b0 (diff)
downloadnextpnr-c63274342f1aaa3d1087c0df5ffdaccfd0afcd56.tar.gz
nextpnr-c63274342f1aaa3d1087c0df5ffdaccfd0afcd56.tar.bz2
nextpnr-c63274342f1aaa3d1087c0df5ffdaccfd0afcd56.zip
initial import of python-console
Diffstat (limited to '3rdparty/python-console/ParseHelper.BlockParseState.cpp')
-rw-r--r--3rdparty/python-console/ParseHelper.BlockParseState.cpp174
1 files changed, 174 insertions, 0 deletions
diff --git a/3rdparty/python-console/ParseHelper.BlockParseState.cpp b/3rdparty/python-console/ParseHelper.BlockParseState.cpp
new file mode 100644
index 00000000..4dc568b2
--- /dev/null
+++ b/3rdparty/python-console/ParseHelper.BlockParseState.cpp
@@ -0,0 +1,174 @@
+/**
+Copyright (c) 2014 Alex Tsui
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#include "ParseHelper.h"
+
+ParseHelper::BlockParseState::
+BlockParseState( ParseHelper& parent ):
+ ParseState( parent )
+{ }
+
+ParseHelper::BlockParseState::
+BlockParseState( ParseHelper& parent, const std::string& indent_ ):
+ ParseState( parent ),
+ indent( indent_ )
+{ }
+
+bool ParseHelper::BlockParseState::
+process(const std::string& str)
+{
+ bool ok = initializeIndent(str);
+ if ( ! ok )
+ {
+ // finish processing
+ return true;
+ }
+
+ Indent ind;
+ bool isIndented = PeekIndent( str, &ind );
+ if ( isIndented )
+ {
+#ifndef NDEBUG
+ std::cout << "current line indent: ";
+ print( ind );
+#endif
+ // check if indent matches
+ if ( ind.Token != indent.Token )
+ {
+ // dedent until we match or empty the stack
+ bool found = false;
+ while ( !found )
+ {
+ parent.stateStack.pop_back( );
+ if ( !parent.stateStack.size( ) )
+ break;
+ boost::shared_ptr<BlockParseState> parseState =
+ boost::dynamic_pointer_cast<BlockParseState>(
+ parent.stateStack.back( ));
+ found = ( ind.Token == parseState->indent.Token );
+ }
+
+ if ( ! found )
+ {
+#ifndef NDEBUG
+ std::cout << "indent mismatch\n";
+#endif
+ parent.reset( );
+ ParseMessage msg( 1, "IndentationError: unexpected indent");
+ parent.broadcast( msg );
+ return true;
+ }
+ }
+
+ // process command
+
+ // enter indented block state
+ if ( str[str.size()-1] == ':' )
+ {
+ parent.commandBuffer.push_back( str );
+ //parent.inBlock = (boost::dynamic_pointer_cast<BlockParseState>(
+ // parent.stateStack.back()));
+
+ //expectingIndent = true;
+ boost::shared_ptr<ParseState> parseState(
+ new BlockParseState( parent ) );
+ parent.stateStack.push_back( parseState );
+ return true;
+ }
+
+ if ( str[str.size()-1] == '\\' )
+ {
+ parent.commandBuffer.push_back( str );
+ boost::shared_ptr<ParseState> parseState(
+ new ContinuationParseState( parent ) );
+ parent.stateStack.push_back( parseState );
+ return true;
+ }
+
+ if (BracketParseState::HasOpenBrackets( str ))
+ {
+ // FIXME: Every parse state should have its own local buffer
+ boost::shared_ptr<ParseState> parseState(
+ new BracketParseState( parent, str ) );
+ parent.stateStack.push_back( parseState );
+ return true;
+ }
+
+ parent.commandBuffer.push_back( str );
+ return true;
+ }
+ else
+ {
+ if ( str.size() )
+ {
+ {
+#ifndef NDEBUG
+ std::cout << "Expected indented block\n";
+#endif
+ parent.reset( );
+ ParseMessage msg( 1, "IndentationError: expected an indented block" );
+ parent.broadcast( msg );
+ return false;
+ }
+ }
+#ifndef NDEBUG
+ std::cout << "Leaving block\n";
+#endif
+ parent.stateStack.pop_back();
+ parent.flush( );
+ parent.reset( );
+ return true;
+ }
+}
+
+bool ParseHelper::BlockParseState::
+initializeIndent(const std::string& str)
+{
+ bool expectingIndent = (indent.Token == "");
+ if ( !expectingIndent )
+ {
+ std::cout << "already initialized indent: ";
+ print( indent );
+ return true;
+ }
+
+ Indent ind;
+ bool isIndented = parent.PeekIndent( str, &ind );
+ if ( !isIndented )
+ {
+#ifndef NDEBUG
+ std::cout << "Expected indented block\n";
+#endif
+ parent.reset( );
+ ParseMessage msg( 1, "IndentationError: expected an indented block" );
+ parent.broadcast( msg );
+ return false;
+ }
+ indent = ind;
+ //parent.currentIndent = ind;
+ //parent.indentStack.push_back( parent.currentIndent );
+ //parent.expectingIndent = false;
+#ifndef NDEBUG
+ std::cout << "initializing indent: ";
+ print( ind );
+#endif
+ return true;
+}