-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathread.cpp
More file actions
123 lines (97 loc) · 2.83 KB
/
read.cpp
File metadata and controls
123 lines (97 loc) · 2.83 KB
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
115
116
117
118
119
120
121
122
123
#include "read.h"
#include "object.h"
#include "exceptions.h"
#include "nil.h"
#include "doublet.h"
#include "symbolsList.h"
#include "number.h"
#include "lispString.h"
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <string.h>
SymbolsList symbolsList;
Read::Read(std::istream& input): stream(input) { }
Read::~Read() {}
Object * Read::read() {
int rawChar = this->stream.peek();
char peekChar = static_cast<char>(rawChar);
if (peekChar == ')') {
throw TooManyParents();
}
if (peekChar == '(') {
this->stream.get();
return readList(this->stream) ;
}
return readAtom(this->stream);
}
Object * Read::readList(std::istream& stream, bool firstTime) {
Object * first;
int rawChar = stream.peek();
char peekChar = static_cast<char>(rawChar);
cout << peekChar;
if (peekChar == EOF) throw UnterminatedList();
if (peekChar == ')') {
stream.get(peekChar);
return new Nil();
}
if ((not firstTime) and (peekChar == '.')) {
stream.get(peekChar);
peekChar = stream.peek();
if (peekChar == EOF)
throw LackingCdr();
Read * toRead = new Read(stream);
first = toRead->read();
peekChar = stream.peek();
if (peekChar == EOF)
throw UnterminatedCons();
if (not (peekChar == ')'))
throw TooMuchInCdr() ;
stream.get(peekChar);
return first;
}
Read * toRead = new Read(stream);
first = toRead->read();
Doublet * doublet = new Doublet(first, readList(stream, false));
return doublet;
}
Object * Read::readAtom(std::istream& stream) {
std::string stringFromStream(std::istreambuf_iterator<char>(stream), {});;
std::string read = getWord(stringFromStream);
if (isNumber(read)) {
Number * number = new Number(std::stoi(read));
return number;
}
if (isString(read)) {
String * string = new String(read.substr(1, read.size() - 2));
return string;
}
Symbol * symbol = symbolsList.findSymbol(read);
if (symbol)
return symbol;
Symbol * newSymbol = new Symbol(read, NULL);
return newSymbol;
}
std::string Read::getWord(std::string string) {
int i = 0;
char character;
std::string word;
while((character = string[i++])) {
if ((isspace(character) || character == '(' || character == ')') && not word.empty())
return word;
else
word += character;
}
if (not word.empty())
return word;
else
return "";
}
bool Read::isNumber(const std::string& string) {
return(strspn(string.c_str(), "0123456789") == string.size());
}
bool Read::isString(const std::string& string) {
if (string.c_str()[0] != '"' or string[strlen(string.c_str()) - 1] != '"')
return false;
return true;
}