summaryrefslogtreecommitdiff
path: root/src/main/interactive_shell.cpp
blob: 3d37ade43abf9b39bca75c25e275812c0d066734 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*********************                                                        */
/*! \file interactive_shell.cpp
 ** \verbatim
 ** Original author: cconway
 ** Major contributors: 
 ** Minor contributors (to current version): 
 ** This file is part of the CVC4 prototype.
 ** Copyright (c) 2009, 2010  The Analysis of Computer Systems Group (ACSys)
 ** Courant Institute of Mathematical Sciences
 ** New York University
 ** See the file COPYING in the top-level source directory for licensing
 ** information.\endverbatim
 **
 ** \brief Interactive shell for CVC4
 **/

#include <iostream>

#include "interactive_shell.h"
#include "expr/command.h"
#include "parser/parser.h"
#include "parser/parser_builder.h"

using namespace std;

namespace CVC4 {

Command* InteractiveShell::readCommand() {
  /* Don't do anything if the input is closed. */
  if( d_in.eof() ) {
    return NULL;
  }

  /* If something's wrong with the input, there's nothing we can do. */
  if( !d_in.good() ) {
    throw ParserException("Interactive input broken.");
  }

  string input;

  /* Prompt the user for input. */
  d_out << "CVC4> " << flush;
  while(true) {
    stringbuf sb;
    string line;

    /* Read a line */
    d_in.get(sb,'\n');
    line = sb.str();
    // cout << "Input was '" << input << "'" << endl << flush;

    /* If we hit EOF, we're done. */
    if( d_in.eof() ) {
      input += line;
      break;
    }

    /* Check for failure */
    if( d_in.fail() ) {
      /* This should only happen if the input line was empty. */
      Assert( line.empty() );
      d_in.clear();
    }

    /* Extract the newline delimiter from the stream too */
    int c = d_in.get();
    Assert( c == '\n' );

    // cout << "Next char is '" << (char)c << "'" << endl << flush;

    /* Strip trailing whitespace. */
    int n = line.length() - 1;
    while( !line.empty() && isspace(line[n]) ) { 
      line.erase(n,1); 
      n--;
    }

    input += line;
    
    /* If the last char was a backslash, continue on the next line. */
    if( !line.empty() && line[n] == '\\' ) {
      n = input.length() - 1;
      Assert( input[n] == '\\' );
      input[n] = '\n';
      d_out << "... > " << flush;
    } else {
      /* No continuation, we're done. */
      //cout << "Leaving input loop." << endl << flush;
      break;
    }
  }

  Parser *parser = 
    d_parserBuilder
        .withStringInput(input)
        .withStateFrom(d_lastParser)
        .build();

  /* There may be more than one command in the input. Build up a
     sequence. */
  CommandSequence *cmd_seq = new CommandSequence();
  Command *cmd;

  while( (cmd = parser->nextCommand()) ) {
    cmd_seq->addCommand(cmd);
  }

  delete d_lastParser;
  d_lastParser = parser;

  return cmd_seq;
}

} // CVC4 namespace
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback