diff options
| author | Dylan <boss@tehbox.org> | 2026-06-06 19:36:41 +1200 |
|---|---|---|
| committer | Dylan <boss@tehbox.org> | 2026-06-06 19:36:41 +1200 |
| commit | 1d379a5cf34475f66f2ab9359f77dac162c0a40e (patch) | |
| tree | 395d54815331fbcad053001bf5cb28fafb69e9d4 /src/json.cpp | |
| parent | 46c896bcd78d31130321562b0659e28230261b8e (diff) | |
| download | tehjson-1d379a5cf34475f66f2ab9359f77dac162c0a40e.tar.gz tehjson-1d379a5cf34475f66f2ab9359f77dac162c0a40e.zip | |
feat: JSON reading
- Implemented a tokenizer for json
- Implemented a method which will read json from a string using the tokenizer
Diffstat (limited to 'src/json.cpp')
| -rw-r--r-- | src/json.cpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/json.cpp b/src/json.cpp index c11ca6e..9c1c3f9 100644 --- a/src/json.cpp +++ b/src/json.cpp @@ -1,7 +1,10 @@ #include "json.h" +#include "tokenizer.h" #include <cstddef> +#include <iostream> #include <stdexcept> +#include <string> namespace TehJSON { @@ -66,4 +69,62 @@ namespace TehJSON throw std::runtime_error("Node is a leaf!"); return children.size(); } + + Token JSON::consume() + { + if(tokenPos >= tokens.size()) + throw std::out_of_range("No tokens left, but json not finished!"); + return tokens[tokenPos++]; + } + + Token JSON::consume(TokenType type) + { + Token t = consume(); + if(t.type != type) + throw std::runtime_error("Wrong token type, expected: " + getTokenName(type) + ", but got: " + getTokenName(t.type)); + return t; + } + + TokenType JSON::nextTokenType() + { + if(tokenPos >= tokens.size()) + throw std::out_of_range("No tokens left, but json not finished!"); + return tokens[tokenPos].type; + } + + void JSON::readFromString(std::string s) + { + Tokenizer tokenizer; + tokenizer.appendInput(s); + std::vector<Token> stringTokens = tokenizer.tokenize(); + + readFromTokens(stringTokens, 0); + } + + int JSON::readFromTokens(std::vector<Token> tokens, int pos) + { + this->tokens = tokens; + tokenPos = pos; + + consume(TokenType::LBrace); + while(nextTokenType() != TokenType::RBrace) + { + Token childName = consume(TokenType::StringLit); + // std::cout << "Child: " << childName.content << std::endl; + consume(TokenType::Colon); + switch(nextTokenType()) + { + case TokenType::LBrace: tokenPos = children[childName.content].readFromTokens(tokens, tokenPos); 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; + default: throw std::runtime_error("Token type is not a literal!"); + } + if(nextTokenType() != TokenType::RBrace) + consume(TokenType::Comma); + } + consume(TokenType::RBrace); + + return tokenPos; + } } |
