lojix/interpreter/src/main/com/thesett/aima/logic/fol/interpreter/ResolutionInterpreter.java
public void interpreterLoop() throws IOException
    {
        // Display the welcome message.
        printIntroduction();

        // Initialize the JLine console.
        consoleReader = initializeCommandLineReader();

        // Used to buffer input, and only feed it to the parser when a PERIOD is encountered.
        TokenBuffer tokenBuffer = new TokenBuffer();

        // Used to hold the currently buffered lines of input, for the purpose of presenting this back to the user
        // in the event of a syntax or other error in the input.
        ArrayList<String> inputLines = new ArrayList<String>();

        // Used to count the number of lines entered.
        int lineNo = 0;

        while (true)
        {
            String line = null;

            try
            {
                line = consoleReader.readLine(mode.prompt);
                inputLines.add(line);

                // JLine returns null if CTRL-D is pressed. Exit program mode back to query mode, or exit the
                // interpreter completely from query mode.
                if ((line == null) && ((mode == Mode.Query) || (mode == Mode.QueryMultiLine)))
                {
                    /*log.fine("CTRL-D in query mode, exiting.");*/

                    System.out.println();

                    break;
                }
                else if ((line == null) && ((mode == Mode.Program) || (mode == Mode.ProgramMultiLine)))
                {
                    /*log.fine("CTRL-D in program mode, returning to query mode.");*/

                    System.out.println();
                    mode = Mode.Query;

                    continue;
                }

                // Check the input to see if a system directive was input. This is only allowed in query mode, and is
                // handled differently to normal queries.
                if (mode == Mode.Query)
                {
                    Source<Token> tokenSource =
                        new OffsettingTokenSource(TokenSource.getTokenSourceForString(line), lineNo);
                    parser.setTokenSource(tokenSource);

                    PrologParser.Directive directive = parser.peekAndConsumeDirective();

                    if (directive != null)
                    {
                        switch (directive)
                        {
                        case Trace:

                            /*log.fine("Got trace directive.");*/
                            break;

                        case Info:

                            /*log.fine("Got info directive.");*/
                            break;

                        case User:

                            /*log.fine("Got user directive, entering program mode.");*/
                            mode = Mode.Program;
                            break;
                        }

                        inputLines.clear();

                        continue;
                    }
                }

                // For normal queries, the query functor '?-' begins every statement, this is not passed back from
                // JLine even though it is used as the command prompt.
                if (mode == Mode.Query)
                {
                    line = QUERY_PROMPT + line;
                    inputLines.set(inputLines.size() - 1, line);
                }

                // Buffer input tokens until EOL is reached, of the input is terminated with a PERIOD.
                Source<Token> tokenSource =
                    new OffsettingTokenSource(TokenSource.getTokenSourceForString(line), lineNo);
                Token nextToken;

                while (true)
                {
                    nextToken = tokenSource.poll();

                    if (nextToken == null)
                    {
                        break;
                    }

                    if (nextToken.kind == PrologParserConstants.PERIOD)
                    {
                        /*log.fine("Token was PERIOD.");*/
                        mode = (mode == Mode.QueryMultiLine) ? Mode.Query : mode;
                        mode = (mode == Mode.ProgramMultiLine) ? Mode.Program : mode;

                        tokenBuffer.offer(nextToken);

                        break;
                    }
                    else if (nextToken.kind == PrologParserConstants.EOF)
                    {
                        /*log.fine("Token was EOF.");*/
                        mode = (mode == Mode.Query) ? Mode.QueryMultiLine : mode;
                        mode = (mode == Mode.Program) ? Mode.ProgramMultiLine : mode;

                        lineNo++;

                        break;
                    }

                    tokenBuffer.offer(nextToken);
                }

                // Evaluate the current token buffer, whenever the input is terminated with a PERIOD.
                if ((nextToken != null) && (nextToken.kind == PrologParserConstants.PERIOD))
                {
                    parser.setTokenSource(tokenBuffer);

                    // Parse the next clause.
                    Sentence<Clause> nextParsing = parser.parse();

                    /*log.fine(nextParsing.toString());*/
                    evaluate(nextParsing);

                    inputLines.clear();
                }
            }
            catch (SourceCodeException e)
            {
                SourceCodePosition sourceCodePosition = e.getSourceCodePosition().asZeroOffsetPosition();
                int startLine = sourceCodePosition.getStartLine();
                int endLine = sourceCodePosition.getEndLine();
                int startColumn = sourceCodePosition.getStartColumn();
                int endColumn = sourceCodePosition.getEndColumn();

                System.out.println("[(" + startLine + ", " + startColumn + "), (" + endLine + ", " + endColumn + ")]");

                for (int i = 0; i < inputLines.size(); i++)
                {
                    String errorLine = inputLines.get(i);
                    System.out.println(errorLine);

                    // Check if the line has the error somewhere in it, and mark the part of it that contains the error.
                    int pos = 0;

                    if (i == startLine)
                    {
                        for (; pos < startColumn; pos++)
                        {
                            System.out.print(" ");
                        }
                    }

                    if (i == endLine)
                    {
                        for (; pos <= endColumn; pos++)
                        {
                            System.out.print("^");
                        }

                        System.out.println();
                    }

                    if ((i > startLine) && (i < endLine))
                    {
                        for (; pos < errorLine.length(); pos++)
                        {
                            System.out.print("^");
                        }

                        System.out.println();
                    }
                }

                System.out.println();
                System.out.println(e.getMessage());
                System.out.println();

                inputLines.clear();
                tokenBuffer.clear();
            }
        }
    }
public void interpreterLoop() throws IOException
    {
        // Display the welcome message.
        printIntroduction();

        // Initialize the JLine console.
        consoleReader = initializeCommandLineReader();

        // Used to buffer input, and only feed it to the parser when a PERIOD is encountered.
        TokenBuffer tokenBuffer = new TokenBuffer();

        // Used to hold the currently buffered lines of input, for the purpose of presenting this back to the user
        // in the event of a syntax or other error in the input.
        ArrayList<String> inputLines = new ArrayList<String>();

        // Used to count the number of lines entered.
        int lineNo = 0;

        while (true)
        {
            String line = null;

            try
            {
                line = consoleReader.readLine(mode.prompt);
                inputLines.add(line);

                // JLine returns null if CTRL-D is pressed. Exit program mode back to query mode, or exit the
                // interpreter completely from query mode.
                if ((line == null) && ((mode == Mode.Query) || (mode == Mode.QueryMultiLine)))
                {
                    /*log.fine("CTRL-D in query mode, exiting.");*/

                    System.out.println();

                    break;
                }
                else if ((line == null) && ((mode == Mode.Program) || (mode == Mode.ProgramMultiLine)))
                {
                    /*log.fine("CTRL-D in program mode, returning to query mode.");*/

                    System.out.println();
                    mode = Mode.Query;

                    continue;
                }

                // Check the input to see if a system directive was input. This is only allowed in query mode, and is
                // handled differently to normal queries.
                if (mode == Mode.Query)
                {
                    Source<Token> tokenSource =
                        new OffsettingTokenSource(TokenSource.getTokenSourceForString(line), lineNo);
                    parser.setTokenSource(tokenSource);

                    PrologParser.Directive directive = parser.peekAndConsumeDirective();

                    if (directive != null)
                    {
                        switch (directive)
                        {
                        case Trace:

                            /*log.fine("Got trace directive.");*/
                            break;

                        case Info:

                            /*log.fine("Got info directive.");*/
                            break;

                        case User:

                            /*log.fine("Got user directive, entering program mode.");*/
                            mode = Mode.Program;
                            break;
                        }

                        inputLines.clear();

                        continue;
                    }
                }

                // For normal queries, the query functor '?-' begins every statement, this is not passed back from
                // JLine even though it is used as the command prompt.
                if (mode == Mode.Query)
                {
                    line = QUERY_PROMPT + line;
                    inputLines.set(inputLines.size() - 1, line);
                }

                // Buffer input tokens until EOL is reached, of the input is terminated with a PERIOD.
                Source<Token> tokenSource =
                    new OffsettingTokenSource(TokenSource.getTokenSourceForString(line), lineNo);
                Token nextToken;

                while (true)
                {
                    nextToken = tokenSource.poll();

                    if (nextToken == null)
                    {
                        break;
                    }

                    if (nextToken.kind == PrologParserConstants.PERIOD)
                    {
                        /*log.fine("Token was PERIOD.");*/
                        mode = (mode == Mode.QueryMultiLine) ? Mode.Query : mode;
                        mode = (mode == Mode.ProgramMultiLine) ? Mode.Program : mode;

                        tokenBuffer.offer(nextToken);

                        break;
                    }
                    else if (nextToken.kind == PrologParserConstants.EOF)
                    {
                        /*log.fine("Token was EOF.");*/
                        mode = (mode == Mode.Query) ? Mode.QueryMultiLine : mode;
                        mode = (mode == Mode.Program) ? Mode.ProgramMultiLine : mode;

                        lineNo++;

                        break;
                    }

                    tokenBuffer.offer(nextToken);
                }

                // Evaluate the current token buffer, whenever the input is terminated with a PERIOD.
                if ((nextToken != null) && (nextToken.kind == PrologParserConstants.PERIOD))
                {
                    parser.setTokenSource(tokenBuffer);

                    // Parse the next clause.
                    Sentence<Clause> nextParsing = parser.parse();

                    /*log.fine(nextParsing.toString());*/
                    evaluate(nextParsing);

                    inputLines.clear();
                }
            }
            catch (SourceCodeException e)
            {
                SourceCodePosition sourceCodePosition = e.getSourceCodePosition().asZeroOffsetPosition();
                int startLine = sourceCodePosition.getStartLine();
                int endLine = sourceCodePosition.getEndLine();
                int startColumn = sourceCodePosition.getStartColumn();
                int endColumn = sourceCodePosition.getEndColumn();

                System.out.println("[(" + startLine + ", " + startColumn + "), (" + endLine + ", " + endColumn + ")]");

                for (int i = 0; i < inputLines.size(); i++)
                {
                    String errorLine = inputLines.get(i);
                    System.out.println(errorLine);

                    // Check if the line has the error somewhere in it, and mark the part of it that contains the error.
                    int pos = 0;

                    if (i == startLine)
                    {
                        for (; pos < startColumn; pos++)
                        {
                            System.out.print(" ");
                        }
                    }

                    if (i == endLine)
                    {
                        for (; pos <= endColumn; pos++)
                        {
                            System.out.print("^");
                        }

                        System.out.println();
                    }

                    if ((i > startLine) && (i < endLine))
                    {
                        for (; pos < errorLine.length(); pos++)
                        {
                            System.out.print("^");
                        }

                        System.out.println();
                    }
                }

                System.out.println();
                System.out.println(e.getMessage());
                System.out.println();

                inputLines.clear();
                tokenBuffer.clear();
            }
        }
    }
public void interpreterLoop ( ) throws IOException { // Display the welcome message. printIntroduction ( ) ; // Initialize the JLine console. consoleReader = initializeCommandLineReader ( ) ; // Used to buffer input, and only feed it to the parser when a PERIOD is encountered. TokenBuffer tokenBuffer = new TokenBuffer ( ) ; // Used to hold the currently buffered lines of input, for the purpose of presenting this back to the user // in the event of a syntax or other error in the input. ArrayList < String > inputLines = new ArrayList < String > ( ) ; // Used to count the number of lines entered. int lineNo = 0 ; while ( true ) { String line = null ; try { line = consoleReader . readLine ( mode . prompt ) ; inputLines . add ( line ) ; // JLine returns null if CTRL-D is pressed. Exit program mode back to query mode, or exit the // interpreter completely from query mode. if ( ( line == null ) && ( ( mode == Mode . Query ) || ( mode == Mode . QueryMultiLine ) ) ) { /*log.fine("CTRL-D in query mode, exiting.");*/ System . out . println ( ) ; break ; } else if ( ( line == null ) && ( ( mode == Mode . Program ) || ( mode == Mode . ProgramMultiLine ) ) ) { /*log.fine("CTRL-D in program mode, returning to query mode.");*/ System . out . println ( ) ; mode = Mode . Query ; continue ; } // Check the input to see if a system directive was input. This is only allowed in query mode, and is // handled differently to normal queries. if ( mode == Mode . Query ) { Source < Token > tokenSource = new OffsettingTokenSource ( TokenSource . getTokenSourceForString ( line ) , lineNo ) ; parser . setTokenSource ( tokenSource ) ; PrologParser . Directive directive = parser . peekAndConsumeDirective ( ) ; if ( directive != null ) { switch ( directive ) { case Trace : /*log.fine("Got trace directive.");*/ break ; case Info : /*log.fine("Got info directive.");*/ break ; case User : /*log.fine("Got user directive, entering program mode.");*/ mode = Mode . Program ; break ; } inputLines . clear ( ) ; continue ; } } // For normal queries, the query functor '?-' begins every statement, this is not passed back from // JLine even though it is used as the command prompt. if ( mode == Mode . Query ) { line = QUERY_PROMPT + line ; inputLines . set ( inputLines . size ( ) - 1 , line ) ; } // Buffer input tokens until EOL is reached, of the input is terminated with a PERIOD. Source < Token > tokenSource = new OffsettingTokenSource ( TokenSource . getTokenSourceForString ( line ) , lineNo ) ; Token nextToken ; while ( true ) { nextToken = tokenSource . poll ( ) ; if ( nextToken == null ) { break ; } if ( nextToken . kind == PrologParserConstants . PERIOD ) { /*log.fine("Token was PERIOD.");*/ mode = ( mode == Mode . QueryMultiLine ) ? Mode . Query : mode ; mode = ( mode == Mode . ProgramMultiLine ) ? Mode . Program : mode ; tokenBuffer . offer ( nextToken ) ; break ; } else if ( nextToken . kind == PrologParserConstants . EOF ) { /*log.fine("Token was EOF.");*/ mode = ( mode == Mode . Query ) ? Mode . QueryMultiLine : mode ; mode = ( mode == Mode . Program ) ? Mode . ProgramMultiLine : mode ; lineNo ++ ; break ; } tokenBuffer . offer ( nextToken ) ; } // Evaluate the current token buffer, whenever the input is terminated with a PERIOD. if ( ( nextToken != null ) && ( nextToken . kind == PrologParserConstants . PERIOD ) ) { parser . setTokenSource ( tokenBuffer ) ; // Parse the next clause. Sentence < Clause > nextParsing = parser . parse ( ) ; /*log.fine(nextParsing.toString());*/ evaluate ( nextParsing ) ; inputLines . clear ( ) ; } } catch ( SourceCodeException e ) { SourceCodePosition sourceCodePosition = e . getSourceCodePosition ( ) . asZeroOffsetPosition ( ) ; int startLine = sourceCodePosition . getStartLine ( ) ; int endLine = sourceCodePosition . getEndLine ( ) ; int startColumn = sourceCodePosition . getStartColumn ( ) ; int endColumn = sourceCodePosition . getEndColumn ( ) ; System . out . println ( "[(" + startLine + ", " + startColumn + "), (" + endLine + ", " + endColumn + ")]" ) ; for ( int i = 0 ; i < inputLines . size ( ) ; i ++ ) { String errorLine = inputLines . get ( i ) ; System . out . println ( errorLine ) ; // Check if the line has the error somewhere in it, and mark the part of it that contains the error. int pos = 0 ; if ( i == startLine ) { for ( ; pos < startColumn ; pos ++ ) { System . out . print ( " " ) ; } } if ( i == endLine ) { for ( ; pos <= endColumn ; pos ++ ) { System . out . print ( "^" ) ; } System . out . println ( ) ; } if ( ( i > startLine ) && ( i < endLine ) ) { for ( ; pos < errorLine . length ( ) ; pos ++ ) { System . out . print ( "^" ) ; } System . out . println ( ) ; } } System . out . println ( ) ; System . out . println ( e . getMessage ( ) ) ; System . out . println ( ) ; inputLines . clear ( ) ; tokenBuffer . clear ( ) ; } } }
Implements the top-level interpreter loop. This will parse and evaluate sentences until it encounters an CTRL-D
in query mode, at which point the interpreter will terminate.

@throws SourceCodeException If malformed code is encountered.
@throws IOException         If an IO error is encountered whilst reading the source code.
Implements the top - level interpreter loop . This will parse and evaluate sentences until it encounters an CTRL - D in query mode at which point the interpreter will terminate .