diff options
| author | Dylan <boss@tehbox.org> | 2026-06-11 22:11:09 +1200 |
|---|---|---|
| committer | Dylan <boss@tehbox.org> | 2026-06-11 22:11:09 +1200 |
| commit | 49a8dae0f3a6e589dfad65cbbf230137a7b67f4a (patch) | |
| tree | 12eb15246e6e53911a91fde2d715c5d3a78dc614 /src | |
| parent | 79a977bc3bea7777de861e4c1adda6d9f9feec99 (diff) | |
| download | tehjson-49a8dae0f3a6e589dfad65cbbf230137a7b67f4a.tar.gz tehjson-49a8dae0f3a6e589dfad65cbbf230137a7b67f4a.zip | |
feat: Started to add arrays
Only supports arrays of ints so far
Diffstat (limited to 'src')
| -rw-r--r-- | src/json.cpp | 55 | ||||
| -rw-r--r-- | src/json.h | 8 | ||||
| -rw-r--r-- | src/json.hpp | 32 | ||||
| -rw-r--r-- | src/tokenizer.cpp | 4 | ||||
| -rw-r--r-- | src/tokenizer.h | 3 |
5 files changed, 85 insertions, 17 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"; } } @@ -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); |
