aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/json.cpp55
-rw-r--r--src/json.h8
-rw-r--r--src/json.hpp32
-rw-r--r--src/tokenizer.cpp4
-rw-r--r--src/tokenizer.h3
-rw-r--r--test/main.cpp8
6 files changed, 91 insertions, 19 deletions
diff --git a/src/json.cpp b/src/json.cpp
index c566c2b..0232a8a 100644
--- a/src/json.cpp
+++ b/src/json.cpp
@@ -2,7 +2,6 @@
#include "tokenizer.h"
#include <cstddef>
-#include <iostream>
#include <stdexcept>
#include <string>
@@ -98,13 +97,13 @@ namespace TehJSON
tokenizer.appendInput(s);
std::vector<Token> stringTokens = tokenizer.tokenize();
- readFromTokens(stringTokens, 0);
+ readFromTokens(stringTokens);
}
- int JSON::readFromTokens(std::vector<Token> tokens, int pos)
+ void JSON::readFromTokens(std::vector<Token> tokens)
{
this->tokens = tokens;
- tokenPos = pos;
+ tokenPos = 0;
consume(TokenType::LBrace);
while(nextTokenType() != TokenType::RBrace)
@@ -114,31 +113,61 @@ namespace TehJSON
consume(TokenType::Colon);
switch(nextTokenType())
{
- case TokenType::LBrace: tokenPos = children[childName.content].readFromTokens(tokens, tokenPos); break;
+ case TokenType::LBrace:
+ {
+ std::vector<Token> childTokens;
+ while(nextTokenType() != TokenType::RBrace)
+ {
+ childTokens.push_back(consume());
+ }
+ childTokens.push_back(consume(TokenType::RBrace));
+ children[childName.content].readFromTokens(childTokens);
+ break;
+ }
case TokenType::StringLit: children[childName.content].set<std::string>(consume(TokenType::StringLit).content); break;
case TokenType::IntLit: children[childName.content].set<int>(std::stoi(consume(TokenType::IntLit).content)); break;
case TokenType::FloatLit: children[childName.content].set<float>(std::stof(consume(TokenType::FloatLit).content)); break;
+ case TokenType::LSquare:
+ {
+ consume(TokenType::LSquare);
+ std::vector<int> vec;
+ while(nextTokenType() != TokenType::RSquare)
+ {
+ if(nextTokenType() != TokenType::IntLit)
+ throw std::runtime_error("Only int arrays are supported so far");
+ vec.push_back(std::stoi(consume(TokenType::IntLit).content));
+ if(nextTokenType() == TokenType::Comma)
+ {
+ consume(TokenType::Comma);
+ }
+ }
+ consume(TokenType::RSquare);
+ children[childName.content].set<int>(vec);
+ break;
+ };
default: throw std::runtime_error("Token type is not a literal!");
}
if(nextTokenType() != TokenType::RBrace)
consume(TokenType::Comma);
}
consume(TokenType::RBrace);
-
- return tokenPos;
}
// Serializers for basic types
- template <> std::string TehJSON::JSON::serializeData<int>(std::shared_ptr<void> data)
+ template <> std::string TehJSON::JSON::serializeData<int>(int *data)
+ {
+ return std::to_string(*data);
+ }
+ template <> std::string TehJSON::JSON::serializeData<float>(float *data)
{
- return std::to_string(*static_cast<int*>(data.get()));
+ return std::to_string(*data);
}
- template <> std::string TehJSON::JSON::serializeData<float>(std::shared_ptr<void> data)
+ template <> std::string TehJSON::JSON::serializeData<std::string>(std::string *data)
{
- return std::to_string(*static_cast<float*>(data.get()));
+ return '"' + *data + '"';
}
- template <> std::string TehJSON::JSON::serializeData<std::string>(std::shared_ptr<void> data)
+ template <> std::string TehJSON::JSON::serializeData<bool>(bool *data)
{
- return '"' + *static_cast<std::string*>(data.get()) + '"';
+ return (*data)?"true":"false";
}
}
diff --git a/src/json.h b/src/json.h
index efde542..0e616e3 100644
--- a/src/json.h
+++ b/src/json.h
@@ -28,10 +28,14 @@ namespace TehJSON
template <typename T>
T& get();
template <typename T>
+ void set(std::vector<T> value);
+ template <typename T>
void set(T value);
std::string leafType();
template <typename T>
- static std::string serializeData(std::shared_ptr<void> data);
+ static std::string serializeData(std::vector<T> *data);
+ template <typename T>
+ static std::string serializeData(T *data);
// Non leaf methods
JSON& operator[](std::string name);
@@ -46,7 +50,7 @@ namespace TehJSON
Token consume();
Token consume(TokenType type);
TokenType nextTokenType();
- int readFromTokens(std::vector<Token> tokens, int pos);
+ void readFromTokens(std::vector<Token> tokens);
// Leaf data fields
std::shared_ptr<void> data;
diff --git a/src/json.hpp b/src/json.hpp
index 6f19ddd..8ecd947 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -16,13 +16,41 @@ namespace TehJSON
}
template<typename T>
+ std::string TehJSON::JSON::serializeData(std::vector<T>* data)
+ {
+ std::string res = "[";
+ for(int i = 0; i < data->size(); i++)
+ {
+ T x = data->at(i);
+ // res += "inty";
+ res += TehJSON::JSON::serializeData<T>(&x);
+ if(i != data->size() - 1)
+ res += ", ";
+ }
+ res += "]";
+ return res;
+ }
+
+ template<typename T>
+ void TehJSON::JSON::set(std::vector<T> value)
+ {
+ if(children.size() != 0)
+ throw std::runtime_error("Node is not a leaf (has children already)!");
+ isLeaf = true;
+ dataSerializer = [](std::shared_ptr<void> data) -> std::string {
+ return TehJSON::JSON::serializeData<T>((std::vector<T>*)(data.get()));
+ };
+ data = std::make_shared<std::vector<T>>(value);
+ }
+ template<typename T>
void JSON::set(T value)
{
if(children.size() != 0)
throw std::runtime_error("Node is not a leaf (has children already)!");
isLeaf = true;
- dataSerializer = JSON::serializeData<T>;
+ dataSerializer = [](std::shared_ptr<void> data) -> std::string {
+ return JSON::serializeData<T>((T*)(data.get()));
+ };
data = std::make_shared<T>(value);
}
-
}
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index ac7c215..a32879e 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -9,6 +9,8 @@ namespace TehJSON
{
case TokenType::LBrace: return "LBrace";
case TokenType::RBrace: return "RBrace";
+ case TokenType::LSquare: return "LSquare";
+ case TokenType::RSquare: return "RSquare";
case TokenType::Colon: return "Colon";
case TokenType::Comma: return "Comma";
case TokenType::StringLit: return "StringLit";
@@ -78,6 +80,8 @@ namespace TehJSON
}
case '{': tokens.push_back({TokenType::LBrace, std::string{c}}); break;
case '}': tokens.push_back({TokenType::RBrace, std::string{c}}); break;
+ case '[': tokens.push_back({TokenType::LSquare, std::string{c}}); break;
+ case ']': tokens.push_back({TokenType::RSquare, std::string{c}}); break;
case ':': tokens.push_back({TokenType::Colon, std::string{c}}); break;
case ',': tokens.push_back({TokenType::Comma, std::string{c}}); break;
default: throw std::runtime_error("Unexpected character: '" + std::string{c} + "'");
diff --git a/src/tokenizer.h b/src/tokenizer.h
index 3322553..d0362a3 100644
--- a/src/tokenizer.h
+++ b/src/tokenizer.h
@@ -9,11 +9,14 @@ namespace TehJSON
{
LBrace,
RBrace,
+ LSquare,
+ RSquare,
Colon,
Comma,
StringLit,
IntLit,
FloatLit,
+ BoolLit,
};
std::string getTokenName(TokenType t);
diff --git a/test/main.cpp b/test/main.cpp
index 00fca03..456810b 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -1,19 +1,23 @@
+#include "json.h"
#include <json.hpp>
#include <tokenizer.h>
#include <iostream>
#include <memory>
+#include <vector>
using std::cout, std::endl;
int main()
{
TehJSON::JSON jsonWriter;
- // TestClass test1;
- // json["test1"].set(test1);
jsonWriter["test_string"].set<std::string>("stringy");
jsonWriter["test_int"].set<int>(123);
jsonWriter["test_float"].set<float>(51.8);
+ jsonWriter["test_vecs"]["int"].set<int>({1, 2, 3});
+ // jsonWriter["test_vecs"]["float"].set<float>({0.1, 0.2, 0.3});
+ // jsonWriter["test_true"].set(true);
+ // jsonWriter["test_false"].set(false);
jsonWriter["test_object"]["test_int"].set<int>(100);
jsonWriter["test_object"]["test_float"].set<float>(100);