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;