Skip to content

Commit

Permalink
LibLemon: Implemented a JSON parser, Terminal: Font rendering fix
Browse files Browse the repository at this point in the history
  • Loading branch information
fido2020 committed Jan 5, 2021
1 parent 5519848 commit 83ab725
Show file tree
Hide file tree
Showing 16 changed files with 639 additions and 32 deletions.
88 changes: 88 additions & 0 deletions Applications/JSONDump/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include <lemon/core/json.h>

#include <iostream>
#include <sstream>

using JSONValue = Lemon::JSONValue;

void PrintObject(JSONValue& json);

void PrintArray(JSONValue& json){
std::cout << "Array[ ";
for(auto& v : *json.array){
if(v.IsObject()){
PrintObject(v);
} else if(v.IsArray()){
PrintArray(v);
} else if(v.isFloatingPoint){
std::cout << v.AsFloat();
} else if(v.IsString()){
std::cout << v.AsString();
} else if(v.IsNumber()){
std::cout << v.AsSignedNumber();
} else if(v.IsBool()){
std::cout << (v.AsBool() ? "true" : "false");
} else {
std::cout << "null";
}
std::cout << ", ";
}
std::cout << " ]\n";
}

void PrintObject(JSONValue& json){
std::cout << "Object{ ";
for(auto& v : *json.object){
std::cout << "key: \"" << v.first << "\", value: ";
if(v.second.IsObject()){
PrintObject(v.second);
} else if(v.second.IsArray()){
PrintArray(v.second);
} else if(v.second.isFloatingPoint){
std::cout << v.second.AsFloat();
} else if(v.second.IsString()){
std::cout << v.second.AsString();
} else if(v.second.IsNumber()){
std::cout << v.second.AsSignedNumber();
} else if(v.second.IsBool()){
std::cout << (v.second.AsBool() ? "true" : "false");
} else {
std::cout << "null";
}
std::cout << ",\n";
}
std::cout << " }\n";
}

std::stringstream ss;
std::ifstream file;
std::string str;
int main(int argc, char** argv){
if(argc < 2){
std::cout << "Usage: " << argv[0] << " <file>\n";
return 1;
}

file.open(argv[1]);

if(!file.is_open()){
std::cout << "Error opening file " << argv[1] << "!\n";
return 2;
}

ss << file.rdbuf();

str = ss.str();
std::string_view sv = std::string_view(str);
Lemon::JSONParser p = Lemon::JSONParser(sv);

auto json = p.Parse();
if(!json.IsObject()){
std::cout << "Error parsing JSON file!\n";
return 3;
}

PrintObject(json);

return 0;
}
4 changes: 4 additions & 0 deletions Applications/LSh/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ void ParseLine(){
int main(){
printf("Lemon SHell\n");

if(const char* h = getenv("HOME"); h){
chdir(h);
}

getcwd(currentDir, PATH_MAX);
tcgetattr(STDOUT_FILENO, &execAttributes);
readAttributes = execAttributes;
Expand Down
6 changes: 3 additions & 3 deletions Applications/Terminal/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ void Scroll(){
}

void OnPaint(surface_t* surface){
int fontHeight = terminalFont->height;
int fontHeight = terminalFont->lineHeight;

if(/*paintAll*/ true){
for(int i = 0; i < rowCount && (bufferOffset + i) < static_cast<int>(buffer.size()); i++){
Expand Down Expand Up @@ -497,7 +497,7 @@ int main(int argc, char** argv){
terminalFont = Lemon::Graphics::GetFont("default");
}

rowCount = 480 / terminalFont->height - 1;
rowCount = 480 / terminalFont->lineHeight - 1;
columnCount = 720 / 8;

curPos = {0, 0};
Expand Down Expand Up @@ -570,7 +570,7 @@ int main(int argc, char** argv){
window->Resize(ev.resizeBounds);

columnCount = window->GetSize().x / 8;
rowCount = window->GetSize().y / terminalFont->height;
rowCount = window->GetSize().y / terminalFont->lineHeight;

wSz.ws_col = static_cast<unsigned short>(columnCount);
wSz.ws_row = static_cast<unsigned short>(rowCount);
Expand Down
6 changes: 6 additions & 0 deletions Applications/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ lemonmonitor_src = [
ipctest_src = [
'IPCTest/main.cpp'
]

jsondump_src = [
'JSONDump/main.cpp'
]

minesweeper_src = [
'Minesweeper/main.cpp'
]
Expand All @@ -80,4 +85,5 @@ executable('guitest.lef', guitest_src, cpp_args : application_cpp_args, link_arg
executable('run.lef', run_src, cpp_args : application_cpp_args, link_args : ['-llemon', '-lfreetype', '-lz', '-lpng'], install : true)
executable('lemonmonitor.lef', lemonmonitor_src, cpp_args : application_cpp_args, link_args : ['-llemon', '-lfreetype', '-lz', '-lpng'], install : true)
executable('ipctest.lef', ipctest_src, cpp_args : application_cpp_args, install : true)
executable('jsondump.lef', jsondump_src, cpp_args : application_cpp_args, install : true, link_args : ['-llemon'])
executable('minesweeper.lef', minesweeper_src, cpp_args : application_cpp_args, link_args : ['-llemon', '-lfreetype', '-lz', '-lpng'], install : true)
1 change: 1 addition & 0 deletions Base/lemon/lemond.cfg
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[Environment]
HOME=/system
PATH=/initrd:/system/bin
LC_ALL=C
167 changes: 153 additions & 14 deletions LibLemon/include/lemon/core/json.h
Original file line number Diff line number Diff line change
@@ -1,35 +1,174 @@
#pragma once

#include <fstream>
#include <nlohmann/json.hpp>
#include <string>
#include <vector>
#include <map>
#include <cassert>

#include <lemon/core/lexer.h>

namespace Lemon{
class JSONConfig{
protected:
nlohmann::json j;
using JSONKey = std::string;

public:
JSONConfig();
struct JSONValue{
enum {
TypeString,
TypeArray,
TypeObject,
TypeNumber,
TypeBoolean,
TypeNull,
};

int type;
bool isFloatingPoint = false;
bool isSigned = true;

template<typename T>
T& GetItem(std::string path){
union{
std::string* str = nullptr;
std::vector<JSONValue>* array;
std::map<JSONKey, JSONValue>* object;
unsigned long uLong;
long sLong;
float fl;
double dbl;
bool boolean;
};

JSONValue(){
type = TypeNull;
}

bool IsArray(std::string path){

JSONValue(const std::string& s){
type = TypeString;

str = new std::string(s);
}

JSONValue(std::string&& s){
type = TypeString;

str = new std::string(s);
}

JSONValue(const std::vector<JSONValue>& v){
type = TypeArray;

array = new std::vector<JSONValue>(v);
}

JSONValue(std::vector<JSONValue>&& v){
type = TypeArray;

array = new std::vector<JSONValue>(v);
}

JSONValue(const std::map<JSONKey, JSONValue>& o){
type = TypeObject;

object = new std::map<JSONKey, JSONValue>(o);
}

JSONValue(std::map<JSONKey, JSONValue>&& o){
type = TypeObject;

object = new std::map<JSONKey, JSONValue>(o);
}

JSONValue(unsigned long ul){
type = TypeNumber;

uLong = ul;
isSigned = false;
}

JSONValue(long l){
type = TypeNumber;

sLong = l;
isSigned = true;
}

JSONValue(float f){
type = TypeNumber;

fl = f;
isFloatingPoint = true;
}

bool IsNumber(std::string path){
JSONValue(bool b){
type = TypeBoolean;

boolean = b;
}

bool IsString(std::string path){
inline const JSONValue& operator[](const std::string& s){
assert(type == TypeObject && object);

return object->at(s);
}

bool IsBoolean(std::string path){

inline bool IsString(){
return type == TypeString;
}

inline bool IsNumber(){
return type == TypeNumber;
}

inline bool IsBool(){
return type == TypeBoolean;
}

inline bool IsArray(){
return type == TypeArray;
}

inline bool IsObject(){
return type == TypeObject;
}

inline bool IsNull(){
return type == TypeNull;
}

std::string AsString(){
return *str;
}

template<typename I = long>
inline I AsSignedNumber(){
return static_cast<I>(sLong);
}

template<typename I = unsigned long>
inline I AsUnsignedNumber(){
return static_cast<I>(uLong);
}

template<typename I = float>
inline I AsFloat(){
return static_cast<I>(fl);
}

inline bool AsBool(){
return boolean;
}
};

class JSONParser : protected BasicLexer{
protected:
std::string ParseString();

int ParseValue(JSONValue& val);

JSONValue ParseObject();
JSONValue ParseArray();

public:
JSONParser(std::string_view& v);

JSONValue Parse();
};
}
52 changes: 52 additions & 0 deletions LibLemon/include/lemon/core/lexer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once

#include <string_view>
#include <vector>
#include <cctype>

namespace Lemon{
// Provides a simple base for a more complex lexer
class BasicLexer {
protected:
int line = 0;
std::string_view sv;
const char* it;
public:
BasicLexer(std::string_view& v);

inline bool End(){ return it >= sv.end(); }

char Eat();

bool EatWord(const char* word);

template<typename C>
std::string_view EatWhile(C cond){
auto start = it;
size_t count = 0;
char c;
while(!End() && cond(c = Peek())){
count++;

if(c == '\n'){
line++;
}
Eat();
}

return sv.substr(static_cast<size_t>(start - sv.begin()), count);
}

int EatOne(char c);

inline void EatWhitespace(bool includeBreaks = true) {
if(includeBreaks){
EatWhile([](char c) -> bool { return isspace(c) || isblank(c) || c == '\t' || c == '\n' || c == '\r'; });
} else {
EatWhile([](char c) -> bool { return isspace(c) || isblank(c) || c == '\t'; });
}
}

char Peek(size_t ahead = 0) const;
};
}
Loading

0 comments on commit 83ab725

Please sign in to comment.