From 50c6956d99b4ee2cf3d003e5918e84b9d1a08f1b Mon Sep 17 00:00:00 2001
From: Mike Buland <eichlan@xagasoft.com>
Date: Thu, 1 Dec 2016 07:22:35 -0700
Subject: New layout for the parser, it doesn't parse yet.

---
 src/lexer.cpp  |   8 +-
 src/lexer.h    |   2 +-
 src/parser.cpp | 406 ++++++++++++++-------------------------------------------
 src/parser.h   |  10 +-
 src/token.cpp  |   1 +
 5 files changed, 106 insertions(+), 321 deletions(-)

diff --git a/src/lexer.cpp b/src/lexer.cpp
index 55d155d..538e088 100644
--- a/src/lexer.cpp
+++ b/src/lexer.cpp
@@ -24,17 +24,17 @@ Lexer::~Lexer()
 {
 }
 
-void Lexer::nextToken()
+void Lexer::nextToken( int iCount )
 {
-    if( iLookAheadUsed <= 1 )
+    if( iLookAheadUsed-iCount <= 0 )
     {
         iLookAheadUsed = 0;
         iLookAheadStart = 0;
     }
     else
     {
-        iLookAheadStart = (iLookAheadStart+1)%iLookAheadSize;
-        iLookAheadUsed--;
+        iLookAheadStart = (iLookAheadStart+iCount)%iLookAheadSize;
+        iLookAheadUsed -= iCount;
     }
 }
 
diff --git a/src/lexer.h b/src/lexer.h
index 193a22b..1d6ddcb 100644
--- a/src/lexer.h
+++ b/src/lexer.h
@@ -20,7 +20,7 @@ public:
     void setMode( Mode e ) { eMode = e; }
     Mode getMode() const { return eMode; }
 
-    void nextToken();
+    void nextToken( int iCount=1 );
 
     int getScale() const { return iScale; }
     void setScale( int i ) { iScale = i; }
diff --git a/src/parser.cpp b/src/parser.cpp
index 0131ba3..510b471 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -29,7 +29,17 @@ void Parser::parse()
         expr();
 
         Bu::sio << "Final stack:";
-        for( TokenStack::iterator i = tsStack.begin(); i; i++ )
+        for( TokenStack::iterator i = tsParse.begin(); i; i++ )
+        {
+            Bu::sio << " " << (*i).eType;
+            if( (*i).eType == Token::tNumber )
+            {
+                Bu::sio << "(" << (*i).nVal->toString() << ")";
+            }
+        }
+        Bu::sio << Bu::sio.nl;
+        Bu::sio << "Script:";
+        for( TokenStack::iterator i = tsScript.begin(); i; i++ )
         {
             Bu::sio << " " << (*i).eType;
             if( (*i).eType == Token::tNumber )
@@ -67,7 +77,7 @@ void Parser::expr()
             Token t = lex[0];
             lex.nextToken();
             expr();
-            tsStack.push( t );
+            shift( t );
             break;
     }
 }
@@ -78,7 +88,7 @@ void Parser::exprP()
     {
         case Token::tNumber:
         case Token::tVariable:
-            tsStack.push( lex[0] );
+           shift( lex[0] );
             lex.nextToken();
             break;
 
@@ -95,306 +105,107 @@ void Parser::exprP()
         case Token::tMinus:
             lex.nextToken();
             exprP();
-            tsStack.push( Token( Token::tNegate ) );            
+            shift( Token( Token::tNegate ) );            
             break;
     }
 }
 /*
-    for(;;)
+case Token::tCommand:
+    lex.setMode( Lexer::modeCommand );
+    if( *t.sVal == "exit" || *t.sVal == "quit" )
+        return;
+    else if( *t.sVal == "scale" )
     {
-        Token t = lex.nextToken();
-        switch( t.eType )
+        Token t2 = lex.nextToken();
+        if( t2.eType == Token::tEndOfLine )
         {
-            case Token::tEndOfInput:
-                while( !tsNonTerminal.isEmpty() )
-                    unwind();
-                return;
-
-            case Token::tEndOfLine:
-                while( !tsNonTerminal.isEmpty() )
-                    unwind();
-                if( !tsTerminal.isEmpty() )
-                {
-                    Bu::println( rOut, "%1").arg( deref( tsTerminal.peek() ) );
-                    hVars.insert("ans", deref( tsTerminal.peek() ) );
-                }
-                tsTerminal.clear();
-                lex.setMode( Lexer::modeNormal );
-                break;
-
-            case Token::tCommand:
-                lex.setMode( Lexer::modeCommand );
-                if( *t.sVal == "exit" || *t.sVal == "quit" )
-                    return;
-                else if( *t.sVal == "scale" )
-                {
-                    Token t2 = lex.nextToken();
-                    if( t2.eType == Token::tEndOfLine )
-                    {
-                        Bu::println( rOut, "Current scale: %1").
-                            arg( lex.getScale() );
-                    }
-                    else if( t2.eType == Token::tString )
-                    {
-                        int32_t i = strtol( t2.sVal->getStr(), 0, 10 );
-                        lex.setScale( i );
-                        if( i < 0 )
-                        {
-                            Bu::println( rOut, "ERROR: You must provide a "
-                                "positive integer or zero as the parameter "
-                                "to scale.");
-                        }
-                        else
-                        {
-                            Bu::println( rOut, "Scale changed to: %1").
-                                arg( lex.getScale() );
-                            for( VarHash::iterator i = hVars.begin(); i; i++ )
-                                (*i).setScale( lex.getScale() );
-                            nZero = Number( lex.getScale(), lex.getRadix() );
-                        }
-                    }
-                    else
-                    {
-                        Bu::println( rOut, "ERROR: You must provide a number "
-                            "as the parameter to scale.");
-                    }
-                }
-                else if( *t.sVal == "radix" )
-                {
-                    Token t2 = lex.nextToken();
-                    if( t2.eType == Token::tEndOfLine )
-                    {
-                        Bu::println( rOut, "Current radix: %1").
-                            arg( lex.getRadix() );
-                    }
-                    else if( t2.eType == Token::tString )
-                    {
-                        int32_t i = strtol( t2.sVal->getStr(), 0, 10 );
-                        if( i < 2 || i > 36 )
-                            Bu::println( rOut, "ERROR: Radix must be between "
-                                    "2 and 36 inclusive");
-                        else
-                        {
-                            lex.setRadix( i );
-                            Bu::println( rOut, "Radix changed to: %1").
-                                arg( lex.getRadix() );
-                            hVars.clear();
-                            nZero = Number( lex.getScale(), lex.getRadix() );
-                        }
-                    }
-                    else
-                    {
-                        Bu::println( rOut, "You must provide a number as "
-                                "the parameter to radix.");
-                    }
-                }
-                else if( *t.sVal == "vars" )
-                {
-                    Bu::println( rOut, "Declared variables:");
-                    for( VarHash::iterator i = hVars.begin(); i; i++ )
-                    {
-                        Bu::println( rOut, " - %1 = %2").
-                            arg( i.getKey() ).arg( *i );
-                    }
-                    Bu::println( rOut, "");
-                }
-                else if( *t.sVal == "help" || *t.sVal == "h" || *t.sVal == "?" )
-                {
-                    Bu::println( rOut, Datafiles::getString("parserhelp.txt") );
-                }
-                else
-                {
-                    Bu::println( rOut, "ERROR: Unknown command '%1'").
-                        arg( *t.sVal );
-                }
-                lex.setMode( Lexer::modeNormal );
-                break;
-
-            case Token::tNumber:
-            case Token::tVariable:
-                tsTerminal.push( t );
-                break;
-
-            default:
-                if( tsNonTerminal.getSize() == 0 || 
-                    getPriority( tsNonTerminal.peek().eType ) <
-                    getPriority( t.eType ) )
-                {
-                    DBS( PARSE,
-                        Bu::println("Pushing non-terminal: %1").arg( t.eType )
-                        );
-                    tsNonTerminal.push( t );
-                }
-                else
-                {
-                    DBS( PARSE,
-                        Bu::println("Unwinding stack before pushing: %1")
-                        .arg( t.eType )
-                        );
-                    unwind();
-                    tsNonTerminal.push( t );
-                }
-                break;
+            Bu::println( rOut, "Current scale: %1").
+                arg( lex.getScale() );
+        }
+        else if( t2.eType == Token::tString )
+        {
+            int32_t i = strtol( t2.sVal->getStr(), 0, 10 );
+            lex.setScale( i );
+            if( i < 0 )
+            {
+                Bu::println( rOut, "ERROR: You must provide a "
+                    "positive integer or zero as the parameter "
+                    "to scale.");
+            }
+            else
+            {
+                Bu::println( rOut, "Scale changed to: %1").
+                    arg( lex.getScale() );
+                for( VarHash::iterator i = hVars.begin(); i; i++ )
+                    (*i).setScale( lex.getScale() );
+                nZero = Number( lex.getScale(), lex.getRadix() );
+            }
+        }
+        else
+        {
+            Bu::println( rOut, "ERROR: You must provide a number "
+                "as the parameter to scale.");
         }
     }
-}
-*/
-
-Number Parser::getVariable( const Bu::String &sName )
-{
-    return hVars.get( sName );
-}
-
-void Parser::setVariable( const Bu::String &sName, const Number &rValue )
-{
-    hVars.insert( sName, rValue );
-}
-
-void Parser::reduce()
-{
-    /*
-    for(;;)
+    else if( *t.sVal == "radix" )
     {
-        DBS_START( PARSE );
-        for( TokenStack::iterator i = tsTerminal.begin(); i; i++ )
+        Token t2 = lex.nextToken();
+        if( t2.eType == Token::tEndOfLine )
         {
-            if( (*i).eType == Token::tNumber )
-                Bu::print(" [%1]").arg( *(*i).nVal );
+            Bu::println( rOut, "Current radix: %1").
+                arg( lex.getRadix() );
+        }
+        else if( t2.eType == Token::tString )
+        {
+            int32_t i = strtol( t2.sVal->getStr(), 0, 10 );
+            if( i < 2 || i > 36 )
+                Bu::println( rOut, "ERROR: Radix must be between "
+                        "2 and 36 inclusive");
             else
-                Bu::print(" [%1]").arg( *(*i).sVal );
+            {
+                lex.setRadix( i );
+                Bu::println( rOut, "Radix changed to: %1").
+                    arg( lex.getRadix() );
+                hVars.clear();
+                nZero = Number( lex.getScale(), lex.getRadix() );
+            }
         }
-        Bu::println("");
-        for( TokenStack::iterator i = tsNonTerminal.begin(); i; i++ )
-            Bu::print(" <%1>").arg( (*i).eType );
-        Bu::println("");
-        DBS_END();
-
-        if( tsNonTerminal.isEmpty() )
-            return;
-
-        if( tsTerminal.getSize() < reqTokens( tsNonTerminal.peek().eType ) )
+        else
         {
-            return;
+            Bu::println( rOut, "You must provide a number as "
+                    "the parameter to radix.");
         }
-        
-        Token t = tsNonTerminal.peekPop();
-        switch( t.eType )
+    }
+    else if( *t.sVal == "vars" )
+    {
+        Bu::println( rOut, "Declared variables:");
+        for( VarHash::iterator i = hVars.begin(); i; i++ )
         {
-            case Token::tPlus:
-                {
-                    Token b = tsTerminal.peekPop();
-                    Token a = tsTerminal.peekPop();
-                    tsTerminal.push(
-                        Token( Token::tNumber,
-                            new Number( deref(a) + deref(b) )
-                            )
-                        );
-                }
-                break;
-            
-            case Token::tMinus:
-                {
-                    Token b = tsTerminal.peekPop();
-                    Token a = tsTerminal.peekPop();
-                    tsTerminal.push(
-                        Token( Token::tNumber,
-                            new Number( deref(a) - deref(b) )
-                            )
-                        );
-                }
-                break;
-            
-            case Token::tMultiply:
-                {
-                    Token b = tsTerminal.peekPop();
-                    Token a = tsTerminal.peekPop();
-                    Number *pProduct = new Number( deref(a) * deref(b) );
-                    pProduct->setScale( lex.getScale() );
-                    tsTerminal.push(
-                        Token( Token::tNumber,
-                            pProduct
-                            )
-                        );
-                }
-                break;
-            
-            case Token::tDivide:
-                {
-                    Token b = tsTerminal.peekPop();
-                    Token a = tsTerminal.peekPop();
-                    tsTerminal.push(
-                        Token( Token::tNumber,
-                            new Number( deref(a) / deref(b) )
-                            )
-                        );
-                }
-                break;
-            
-            case Token::tModulus:
-                {
-                    Token b = tsTerminal.peekPop();
-                    Token a = tsTerminal.peekPop();
-                    tsTerminal.push(
-                        Token( Token::tNumber,
-                            new Number( deref(a) % deref(b) )
-                            )
-                        );
-                }
-                break;
-
-            case Token::tOpenParen:
-                tsNonTerminal.push( t );
-                return;
-
-            case Token::tCloseParen:
-                unwind();
-                if( tsNonTerminal.peek().eType == Token::tOpenParen )
-                {
-
-                    tsNonTerminal.pop();
-                    unwind();
-                }
-                else
-                {
-                    throw Bu::ExceptionBase("Close paren found without open paren.");
-                }
-                break;
-
-            case Token::tEquals:
-                {
-                    Token b = tsTerminal.peekPop();
-                    Token a = tsTerminal.peekPop();
-                    if( a.eType != Token::tVariable )
-                    {
-                        Bu::println("The left hand side of a = must be a variable.");
-                        tsTerminal.clear();
-                        tsNonTerminal.clear();
-                        return;
-                    }
-                    hVars.insert( *a.sVal, deref( b ) );
-                    tsTerminal.push(
-                        Token( Token::tNumber,
-                            new Number( deref( b ) )
-                            )
-                        );
-                }
-                break;
-
-            case Token::tNumber:
-            case Token::tVariable:
-            case Token::tCommand:
-            case Token::tString:
-            case Token::tEndOfLine:
-            case Token::tEndOfInput:
-                // These should never show up at all
-                break;
+            Bu::println( rOut, " - %1 = %2").
+                arg( i.getKey() ).arg( *i );
         }
-        if( !tsNonTerminal.isEmpty() && 
-            getPriority( tsNonTerminal.peek().eType ) <
-            getPriority( t.eType ) )
-            return;
+        Bu::println( rOut, "");
+    }
+    else if( *t.sVal == "help" || *t.sVal == "h" || *t.sVal == "?" )
+    {
+        Bu::println( rOut, Datafiles::getString("parserhelp.txt") );
     }
-    */
+    else
+    {
+        Bu::println( rOut, "ERROR: Unknown command '%1'").
+            arg( *t.sVal );
+    }
+    lex.setMode( Lexer::modeNormal );
+    break;
+*/
+
+void Parser::shift( const Token &t )
+{
+    tsParse.push( t );
+}
+
+void Parser::reduce()
+{
 }
 
 int Parser::reqTokens( Token::Type eType )
@@ -452,26 +263,3 @@ int Parser::getPriority( Token::Type eType )
     }
 }
 
-Number &Parser::deref( Token &t )
-{
-    if( t.eType == Token::tNumber )
-    {
-        return *t.nVal;
-    }
-    else if( t.eType == Token::tVariable )
-    {
-        try
-        {
-            return hVars.get( *t.sVal );
-        }
-        catch(...)
-        {
-            return nZero;
-        }
-    }
-    else
-    {
-        throw Bu::ExceptionBase("Element was not a number or variable.");
-    }
-}
-
diff --git a/src/parser.h b/src/parser.h
index 05fab0b..1caa229 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -49,14 +49,13 @@ public:
     virtual ~Parser();
 
     void parse();
-    Number getVariable( const Bu::String &sName );
-    void setVariable( const Bu::String &sName, const Number &rValue );
 
 private:
     void expr();
     void exprP();
 
 private:
+    void shift( const Token &t );
     void reduce();
     int reqTokens( Token::Type eType );
     int getPriority( Token::Type eType );
@@ -66,11 +65,8 @@ private:
     Lexer &lex;
     Bu::Stream &rOut;
     typedef Bu::List<Token> TokenStack;
-    typedef Bu::Hash<Bu::String, Number> VarHash;
-    TokenStack tsStack;
-//    TokenStack tsNonTerminal;
-    Number nZero;
-    VarHash hVars;
+    TokenStack tsParse;
+    TokenStack tsScript;
 };
 
 #endif
diff --git a/src/token.cpp b/src/token.cpp
index c591e6a..1eaa92a 100644
--- a/src/token.cpp
+++ b/src/token.cpp
@@ -99,6 +99,7 @@ Bu::Formatter &operator<<( Bu::Formatter &f, Token::Type eType )
         case Token::tString:        return f << "str";
         case Token::tEndOfLine:     return f << "eol";
         case Token::tEndOfInput:    return f << "eoi";
+        case Token::tNegate:        return f << "neg";
 
         default:                    return f << "???";
     }
-- 
cgit v1.2.3