36 class ReadStream :
public SerialisationStream<false> {
39 const std::map<std::string, std::string>& rwOperation, SymbolTable& symTab, RecordTable& recTab)
63 RamDomain readRecord(
const std::string& source,
const std::string& recordTypeName,
size_t pos = 0,
64 size_t* charactersRead =
nullptr) {
65 const size_t initial_position = pos;
68 auto&& recordInfo =
types[
"records"][recordTypeName];
69 if (recordInfo.is_null()) {
70 throw std::invalid_argument(
"Missing record type information: " + recordTypeName);
75 if (source.substr(pos, 3) ==
"nil") {
76 if (charactersRead !=
nullptr) {
82 auto&& recordTypes = recordInfo[
"types"];
83 const size_t recordArity = recordInfo[
"arity"].long_value();
85 std::vector<RamDomain> recordValues(recordArity);
89 for (
size_t i = 0;
i < recordArity; ++
i) {
90 const std::string& recordType = recordTypes[
i].string_value();
97 switch (recordType[0]) {
115 recordValues[
i] =
readRecord(source, recordType, pos, &consumed);
119 recordValues[
i] =
readADT(source, recordType, pos, &consumed);
122 default:
fatal(
"Invalid type attribute");
128 if (charactersRead !=
nullptr) {
129 *charactersRead = pos - initial_position;
132 return recordTable.pack(recordValues.data(), recordValues.size());
135 RamDomain readADT(
const std::string& source,
const std::string& adtName,
size_t pos = 0,
136 size_t* charactersRead =
nullptr) {
137 const size_t initial_position = pos;
145 auto&& adtInfo =
types[
"ADTs"][adtName];
146 const auto& branches = adtInfo[
"branches"];
148 if (adtInfo.is_null() || !branches.is_array()) {
149 throw std::invalid_argument(
"Missing ADT information: " + adtName);
157 for (
auto branch : branches.array_items()) {
159 if (branch[
"name"].string_value() == constructor) {
164 throw std::invalid_argument(
"Missing branch information: " + constructor);
167 assert(branchInfo[
"types"].is_array());
168 auto branchTypes = branchInfo[
"types"].
array_items();
171 if (branchTypes.empty()) {
172 if (charactersRead !=
nullptr) {
173 *charactersRead = pos - initial_position;
176 if (adtInfo[
"enum"].bool_value()) {
181 return recordTable.pack(toVector<RamDomain>(branchIdx, emptyArgs).
data(), 2);
186 std::vector<RamDomain> branchArgs(branchTypes.size());
188 for (
size_t i = 0;
i < branchTypes.size(); ++
i) {
189 auto argType = branchTypes[
i].string_value();
190 assert(!argType.empty());
199 switch (argType[0]) {
217 branchArgs[
i] =
readRecord(source, argType, pos, &consumed);
221 branchArgs[
i] =
readADT(source, argType, pos, &consumed);
224 default:
fatal(
"Invalid type attribute");
231 if (charactersRead !=
nullptr) {
232 *charactersRead = pos - initial_position;
237 if (branchArgs.size() != 1) {
238 return recordTable.pack(branchArgs.data(), branchArgs.size());
240 return branchArgs[0];
244 return recordTable.pack(toVector<RamDomain>(branchIdx, branchValue).data(), 2);
254 if (pos >= source.length()) {
255 throw std::invalid_argument(
"Unexpected end of input");
258 const size_t bgn = pos;
259 while (pos < source.length() && std::isalnum(
static_cast<unsigned char>(source[pos]))) {
263 return source.substr(bgn, pos - bgn);
266 std::string
readUntil(
const std::string& source,
const std::string stopChars,
const size_t pos,
267 size_t* charactersRead) {
268 size_t endOfSymbol = source.find_first_of(stopChars, pos);
270 if (endOfSymbol == std::string::npos) {
271 throw std::invalid_argument(
"Unexpected end of input");
274 *charactersRead = endOfSymbol - pos;
276 return source.substr(pos, *charactersRead);
284 if (pos >=
str.length()) {
285 throw std::invalid_argument(
"Unexpected end of input");
288 std::stringstream error;
289 error <<
"Expected: \'" << c <<
"\', got: " <<
str[pos];
290 throw std::invalid_argument(error.str());
299 while (pos <
str.length() && std::isspace(
static_cast<unsigned char>(
str[pos]))) {
311 virtual const std::string&
getName()
const = 0;