diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644
index dfe0770..0000000
--- a/.gitattributes
+++ /dev/null
@@ -1,2 +0,0 @@
-# Auto detect text files and perform LF normalization
-* text=auto
diff --git a/.gitignore b/.gitignore
index 97d22ed..4902fa6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,5 +5,8 @@ out
*.exe
tiny
src
-*.tar.gz
-*.out
\ No newline at end of file
+*.tar*
+*.out
+pkg
+.*/
+src
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..aaa97fa
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,41 @@
+tiny data format and tiny language
+Copyright (C) 2025-2026 Kin Fuyuki
+
+tiny data format and tiny language is free software; You can redistribute it and/or modify it under the terms of:
+ - the GNU Affero General Public License version 3 as published by the Free Software Foundation.
+You don't have to do anything special to accept the license and you don’t have to notify anyone which that you have made that decision.
+
+tiny data format and tiny language is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See your chosen license for more details.
+
+You should have received a copy of both licenses along with tiny data format and tiny language.
+If not, see .
+
+
+There is a strong belief within us that the license we have chosen provides not only the best solution for providing you with the essential freedom necessary to use tiny data format and tiny language within your projects, but also for maintaining enough copyleft strength for us to feel confident and secure with releasing our hard work to the public. For your convenience we've included our own interpretation of the license we chose, which can be seen below.
+
+Our interpretation of the GNU Affero General Public License version 3: (Quoted words are words in which there exists a definition within the license to avoid ambiguity.)
+ 1. You must always provide the source code, copyright and license information of tiny data format and tiny language whenever you "convey" any part of tiny data format and tiny language;
+ be it a verbatim copy or a modified copy.
+ 2. tiny data format and tiny language was developed as a library and has therefore been designed without knowledge of your work; as such the following should be implied:
+ a) tiny data format and tiny language was developed without knowledge of your work; as such the following should be implied:
+ i) tiny data format and tiny language should not fall under a work which is "based on" your work.
+ ii) You should be free to use tiny data format and tiny language in a work covered by the:
+ - GNU General Public License version 2
+ - GNU Lesser General Public License version 2.1
+ This is due to those licenses classifying tiny data format and tiny language as a work which would fall under an "aggregate" work by their terms and definitions;
+ as such it should not be covered by their terms and conditions. The relevant passages start at:
+ - Line 129 of the GNU General Public License version 2
+ - Line 206 of the GNU Lesser General Public License version 2.1
+ b) If you have not "modified", "adapted" or "extended" tiny data format and tiny language then your work should not be bound by this license,
+ as you are using tiny data format and tiny language under the definition of an "aggregate" work.
+ c) If you have "modified", "adapted" or "extended" tiny data format and tiny language then any of those modifications/extensions/adaptations which you have made
+ should indeed be bound by this license, as you are using tiny data format and tiny language under the definition of a "based on" work.
+
+Our hopes is that our own interpretation of license aligns perfectly with your own values and goals for using our work freely and securely. If you have any questions at all about the licensing chosen for tiny data format and tiny language you can email us directly at or you can get in touch with the license authors (the Free Software Foundation) at licensing@fsf.org to gain their opinion too.
+
+Alternatively you can provide feedback and acquire the support you need at our support forum. We'll definitely try and help you as soon as possible, and to the best of our ability; as we understand that user experience is everything, so we want to make you as happy as possible! So feel free to get in touch via our support forum and chat with other users of tiny data format and tiny language here at:
+https://github.com/kin-fuyuki/tiny-cpp/issues
+
+Thanks, and we hope you enjoy using tiny data format and tiny language and that it's everything you ever hoped it could be.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..7be0250
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,7 @@
+CC=clang++
+CFLAGS=-std=c++23
+
+install:
+ rm -rf /usr/include/tiny/
+ mkdir -p /usr/include/tiny/
+ cp inc/*.h /usr/include/tiny/
\ No newline at end of file
diff --git a/PKGBUILD b/PKGBUILD
deleted file mode 100644
index bd94f3a..0000000
--- a/PKGBUILD
+++ /dev/null
@@ -1,19 +0,0 @@
-Maintainer=kin fuyuki
-pkgname=tiny
-pkgver=1.0
-pkgrel=1
-pkgdesc="tiny script runner"
-arch=('any')
-url="https://crystalsoft.neocities.org"
-license=('AGPL3')
-makedepends=('gcc')
-source=("https://github.com/J-K-Tech/${pkgname}/archive/refs/tags/${pkgver}.tar.gz")
-sha256sums=('2af3bfa2937e7452f74895db7e12c60b67000dc9c2e9f1aa1e53f7e1537d2636')
-
-build() {
- g++ -O3 term.cpp main.cpp -o tiny
-}
-
-package() {
- install -Dm755 tiny "$pkgdir/tiny"
-}
\ No newline at end of file
diff --git a/README.md b/README.md
index a2b7974..1fa724b 100644
--- a/README.md
+++ b/README.md
@@ -1,59 +1,3 @@
-# Tiny
+# TINY SOFTWARE SUITE
-A tiny command line interpreter for organizing, you can split huge single line commands into lines and even add comments and variables!
-
-## Features
-
-Multi-command: You can make multiple commands in same `.tmk` file by having a line that starts with `\n`
-
-Comments: You can use comments in the file to your peers or future you remember what you done, also useful to separate sections of a command
-
-Variables: If a line starts with `%` it will get all the name of it until hit the second `%` and to set variables the line has to start with `set`
-
-Ignore space: Add `\` at the start of the line so it will not add an space before it.
-
-(all written in this line after the `\n` and `%var%` will be ignored and be seen as comments)
-
-## example
-
-```
-;set variables
-set flags=-Os
-;compiler
-g++
-%flags%
-
-;files
-main.cpp
-
-;includes
--lstdc++
-
--I/usr/
-;to not add space between /usr/ and include, you add \ so it will be "/usr/include" and not "/usr/ include"
-\include
-
-;output
--o tiny.exe
-
-;end command
-\n
-;run tiny
-tiny.exe
-```
-
-# WARNING, THIS PROGRAM HAS STRICT SYNTAX
-## The line MUST to have `;`,`set` and `%` as first character to be detected as comment, setter and variable, so you can have it in the command (without being interpreted by Tiny) by adding a space before.
-
-
-# Roadmap
-
-- Add variables when loading a Tiny script
-
-- Create functions
-
-- Stuff people ask for
-
-# Compatibility
-
-This is supposed to run anywhere, if it dont work in a platform please warn me (maybe exotic systems with uncommon headers like master system or whatever might not work out of the box... idk.. if it even has a CLI lol)
+[visit the wiki](https://github.com/kin-fuyuki/tiny/wiki)
\ No newline at end of file
diff --git a/build.tmk b/build.tmk
deleted file mode 100644
index ceb5904..0000000
--- a/build.tmk
+++ /dev/null
@@ -1,20 +0,0 @@
-
-clang++ term.cpp main.cpp -m32 --target=i686-w64-mingw32-gcc -O3 -o out/tiny9x.exe -Wl,--major-subsystem-version=4,--minor-subsystem-version=0
-
-\n
-clang++ term.cpp main.cpp -m32 --target=i686-w64-mingw32-gcc -O3 -o out/tiny2k.exe -Wl,--major-subsystem-version=5,--minor-subsystem-version=0
-
-\n
-clang++ term.cpp main.cpp -m64 --target=x86_64-w64-mingw32-gcc -O3 -o out/tinyxp64.exe -Wl,--major-subsystem-version=5,--minor-subsystem-version=1
-
-\n
-clang++ term.cpp main.cpp -m64 --target=x86_64-w64-mingw32-gcc -O3 -o out/tiny.exe -Wl,--major-subsystem-version=10,--minor-subsystem-version=1
-
-\n
-clang++ term.cpp main.cpp -O3 -o out/tiny
-
-\n
-clang++ term.cpp main.cpp -m32 -O3 -o out/tiny32
-
-\n
-;djgpp term.cpp main.cpp -O3 -o out/tiny32
\ No newline at end of file
diff --git a/inc/tdf.h b/inc/tdf.h
new file mode 100644
index 0000000..8a2c297
--- /dev/null
+++ b/inc/tdf.h
@@ -0,0 +1,412 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#ifndef TINYDATAFORMAT_H
+#define TINYDATAFORMAT_H
+#define TINYDEFINEHEADER "0000_TDF_HEADER_DEFINE"
+#include "term.h"
+
+#define GENSTART {int LAST = trimmed.find(' ', 3);if (LAST == std::string::npos) goto FAILTOPARSE;std::string KEY = trimmed.substr(2, LAST - 2);
+#define GENEND (VALUE)};todelete.push_back(DAT.datapointer); (*current)[KEY]=DAT;break;}
+#define GENMID ); if (idx != sub.size()) goto FAILTOPARSE;}catch(const std::invalid_argument&){goto FAILTOPARSE;}TDF_DATA DAT={
+
+#define INTGENSTART GENSTART std::string sub = trimmed.substr(LAST + 1);size_t idx; int VALUE; try{ VALUE=stoi(sub, &idx,
+#define INTGENEND , new int GENEND
+
+#define SETSTART value){boost::unordered_map*current=data;for(size_t i=0;ifind(path[i]);if(it==current->end()){if(i==path.size()-1){TDF_DATA DAT={
+#define SETMID (value)};todelete.push_back(DAT.datapointer);(*current)[path[i]]=DAT;return;}else{\
+ boost::unordered_map*newmap=new boost::unordered_map();TDF_DATA DAT={TDF_CLASS,newmap}\
+ ;todelete.push_back(DAT.datapointer);(*current)[path[i]]=DAT;current=newmap;}}else{if(i==path.size()-1){if(it->second.type!=
+#define SETEND *>(it->second.datapointer)=value;return;}if(it->second.type!=TDF_CLASS)throw TDF_ERR(SET_MISMATCH,filepath,path);\
+ current=(boost::unordered_map*)(it->second.datapointer);}}}
+
+
+#define GETSTART (std::vectorpath){boost::unordered_map*current=data;for(size_t i=0;ifind(path[i]);if(it==current->end())throw TDF_ERR(PATH_NOT_FOUND,filepath,path);if(i==path.size()-1){if(it->second.type!=
+#define GETMID )throw TDF_ERR(GET_MISMATCH,filepath,path);return *static_cast<
+#define GETEND *>(it->second.datapointer);}\
+ if(it->second.type!=TDF_CLASS)throw TDF_ERR(GET_MISMATCH,filepath,path);current=(boost::unordered_map*)(it->second.datapointer);}\
+ throw TDF_ERR(PATH_NOT_FOUND,filepath,path);}
+
+#define DEFAULTGET(TYPE_NAME, ACTUAL_TYPE) ACTUAL_TYPE TYPE_NAME(std::vector path, ACTUAL_TYPE defaultval) {try { return\
+ TYPE_NAME(path); } catch (TDF_ERR &e) { warning((char*)e.what()); return defaultval; } }
+
+namespace tiny {
+enum TDF_ERROR{
+ SET_MISMATCH=1,
+ GET_MISMATCH=2,
+ PATH_NOT_FOUND=3,
+ UNKNOWN_ERROR=-1,
+ FILE_NOT_FOUND=4,
+ FAILED_TO_PARSE=5,
+ NULL_POINTER=6,
+};
+class TDF_ERR : public std::exception
+ {
+ public:
+ std::string message;
+
+ explicit TDF_ERR(TDF_ERROR err,std::string file,std::vectorpath) _GLIBCXX_TXN_SAFE{
+ message="TDF ERROR: ";
+
+ switch(err){
+ case SET_MISMATCH:
+ message+="SET TYPE MISMATCH ";
+ break;
+ case GET_MISMATCH:
+ message+="GET TYPE MISMATCH ";
+ break;
+ case PATH_NOT_FOUND:
+ message+="PATH NOT FOUND ";
+ break;
+ case FILE_NOT_FOUND:
+ message+="FILE NOT FOUND "+file;
+ return;
+ case FAILED_TO_PARSE:
+ message+="FAILED TO PARSE "+file+" AT LINE :"+path[0];
+ return;
+ case NULL_POINTER:
+ message+="NULL POINTER of selector "+path[0];
+ message+="FAILED TO PARSE "+file+" AT LINE :"+path[1];
+ return;
+ default:
+ message+="UNKNOWN ERROR ";
+ break;
+ }
+
+ message+=" ON FILE: "+file+" AT PATH: ";
+ for(size_t i=0;i
+ TDF_CLASS = 9, //class
+};
+struct TDF_DATA {
+ TDF_Type type;
+ void* datapointer;
+};
+struct TDF_FUNCS{
+ boost::unordered_mapfuncs;
+ TDF_DATA(*FUNCS[])(std::string);
+};
+struct TDF_FILE{
+ boost::unordered_map* data=nullptr;
+ char*filepath;
+ TDF_FUNCS FUNCS;
+ std::vector todelete;
+ void close(){
+ for(size_t i=0;i*> (todelete[i]);
+ }
+ }
+ void* read(){
+ char CCHAR=' ';
+ int INDEX=0;
+ std::ifstream file(filepath);
+
+ if (file.is_open()) {
+ if (data!=nullptr)
+ delete data;
+ data=new boost::unordered_map();
+ todelete.push_back(data);
+ boost::unordered_map*current=data;
+
+ std::vector*>stack={};
+ std::vectorpathvec={};
+ bool textblock=false;
+ std::string BLOCK;
+ std::string BLOCKKEY;
+ std::vector *defines=new std::vector();
+ TDF_DATA defdat={TDF_DEFINES,defines};
+ (*current)[TINYDEFINEHEADER]=defdat;
+
+ std::string line;
+ while (std::getline(file, line)) {
+ ++INDEX;
+ if (line.length()==0){continue;}
+ if (textblock){
+ std::string blockline = line;
+ size_t lead = blockline.find_first_not_of(' ');
+ if(lead != std::string::npos){
+ blockline = blockline.substr(lead);
+ }
+ if (blockline=="\\"){
+ textblock=false;
+ TDF_DATA DAT={TDF_BLOCK,new std::string(BLOCK)};
+ todelete.push_back(DAT.datapointer);
+ (*current)[BLOCKKEY]=DAT;
+ }else{
+ BLOCK+=line+"\n";
+ }
+ }
+ else{
+ std::string trimmed = line;
+ size_t lead = trimmed.find_first_not_of(' ');
+ if(lead != std::string::npos){
+ trimmed = trimmed.substr(lead);
+ }else{
+ continue;
+ }
+ if (trimmed.empty() || trimmed[0]=='#'){continue;}
+ if (trimmed.size() > 1 && trimmed[1]==' '){
+ CCHAR=trimmed[0];
+ switch (CCHAR) {
+
+ case '"':GENSTART std::string VALUE; VALUE=trimmed.substr(LAST + 1); TDF_DATA DAT = { TDF_STR, new std::string GENEND
+
+
+ case 'S':{
+ int LAST = trimmed.find(' ', 2);
+ std::string KEY;
+ if (LAST != std::string::npos){
+ KEY = trimmed.substr(2, LAST - 2);
+ }else{
+ KEY = trimmed.substr(2);
+ }
+ BLOCKKEY=KEY;
+ BLOCK="";
+ textblock=true;
+ break;}
+
+
+ case '\'':GENSTART if (LAST + 1 >= trimmed.size()) goto FAILTOPARSE;char VALUE=trimmed.at(LAST + 1);
+ if (LAST + 2 < trimmed.size()) goto FAILTOPARSE;TDF_DATA DAT = { TDF_CHAR, new char GENEND
+
+
+ case 'i': INTGENSTART 0 GENMID TDF_INT INTGENEND
+
+
+ case 'h':INTGENSTART 16 GENMID TDF_HEX INTGENEND
+
+
+ case 'b':INTGENSTART 2 GENMID TDF_BINARY INTGENEND
+
+
+ case 'B': GENSTART if (LAST + 1 >= trimmed.size()) goto FAILTOPARSE; char c=trimmed.at(LAST + 1);
+ bool VALUE = c=='T'; if (LAST + 2 < trimmed.size()) goto FAILTOPARSE; TDF_DATA DAT={TDF_BOOL,new bool GENEND
+
+
+ case 'f':GENSTART std::string sub = trimmed.substr(LAST + 1);size_t idx;float VALUE; try{VALUE=stof(sub, &idx);
+ if (idx != sub.size()) goto FAILTOPARSE;}catch(std::invalid_argument&){goto FAILTOPARSE;}TDF_DATA DAT={TDF_FLOAT,new float GENEND
+
+
+ case '@':GENSTART
+ std::string VALUE=trimmed.substr(LAST + 1);
+ std::vector*ptr=new std::vector();
+ size_t pos=0;
+ std::string token;
+ while((pos=VALUE.find('.'))!=std::string::npos){
+ token=VALUE.substr(0,pos);
+ ptr->push_back(token);
+ VALUE.erase(0,pos+1);
+ }
+ ptr->push_back(VALUE);
+ TDF_DATA DAT={TDF_POINTER,ptr};
+ todelete.push_back(DAT.datapointer);
+ (*current)[KEY]=DAT;
+ break;}
+
+
+ case '{':{
+ int LAST = trimmed.find(' ', 3);
+ std::string KEY;
+ if (LAST != std::string::npos){
+ KEY = trimmed.substr(2, LAST - 2);
+ }else{
+ KEY = trimmed.substr(2);
+ }
+ boost::unordered_map*newmap=new boost::unordered_map();
+ TDF_DATA DAT={TDF_CLASS,newmap};
+ todelete.push_back(DAT.datapointer);
+ (*current)[KEY]=DAT;
+ std::vector *defines=new std::vector();
+ TDF_DATA defdat={TDF_DEFINES,defines};
+ (*newmap)[TINYDEFINEHEADER]=defdat;
+ stack.push_back(current);
+ pathvec.push_back(KEY);
+ current=newmap;
+ break;}
+
+
+ default:{
+ try {
+ int PATH=FUNCS.funcs.at(trimmed[0]);
+ int LAST = trimmed.find(' ', 3);
+ if (LAST == std::string::npos)goto FAILTOPARSE;
+ std::string KEY = trimmed.substr(2, LAST - 2);
+ (*current)[KEY]=FUNCS.FUNCS[PATH](trimmed);
+ todelete.push_back((*current)[KEY].datapointer);
+ if ((*current)[KEY].datapointer==nullptr) goto FAILTOPARSE;
+ }catch(const std::out_of_range&){
+ break;
+ }
+ break;}
+ }
+ }else if(trimmed == "}"){
+ if(stack.empty())goto FAILTOPARSE;
+ current=stack.back();
+ stack.pop_back();
+ if(!pathvec.empty())pathvec.pop_back();
+ }else{
+ auto it = current->find(TINYDEFINEHEADER);
+ if (it == current->end() || it->second.type != TDF_DEFINES) goto FAILTOPARSE;
+ std::vector* defines = static_cast*>(it->second.datapointer);
+ defines->push_back(line);
+ }
+ }
+ }
+ return data;
+ }else{
+ throw TDF_ERR(FILE_NOT_FOUND,filepath,{});
+ }
+ NULLPOINTER:
+ throw TDF_ERR(NULL_POINTER,filepath,{std::string(1,CCHAR),std::to_string(INDEX)});
+ FAILTOPARSE:
+ throw TDF_ERR(FAILED_TO_PARSE,filepath,{std::to_string(INDEX)});
+ delete data;
+ data=nullptr;
+ return nullptr;
+ }
+ //get
+
+ #define ITSNOT it->second.type!=
+ float getfloat GETSTART ITSNOT TDF_FLOAT GETMID float GETEND DEFAULTGET(getfloat, float)
+
+ bool getbool GETSTART ITSNOT TDF_BOOL GETMID bool GETEND DEFAULTGET(getbool, bool)
+
+ int getint GETSTART (ITSNOT TDF_INT)&&(ITSNOT TDF_HEX)&&(ITSNOT TDF_BINARY) GETMID int GETEND DEFAULTGET(getint, int)
+
+ std::string getstring GETSTART (ITSNOT TDF_STR)&&(ITSNOT TDF_BLOCK) GETMID std::string GETEND DEFAULTGET(getstring, std::string)
+
+ std::vector getpointer GETSTART ITSNOT TDF_POINTER GETMID std::vector GETEND DEFAULTGET(getpointer, std::vector)
+
+ char getchar GETSTART ITSNOT TDF_CHAR GETMID char GETEND DEFAULTGET(getchar, char)
+
+ bool defined(std::vectorpath){
+ boost::unordered_map*current=data;
+ for(size_t i=0;ifind(path[i]);
+ if(it==current->end())return false;
+ if(i==path.size()-1)return true;
+ if(it->second.type!=TDF_CLASS)return false;
+ current=(boost::unordered_map*)it->second.datapointer;}
+ return false;}
+ DEFAULTGET(defined, bool)
+
+ boost::unordered_map* getclass(std::vectorpath){
+ boost::unordered_map*current=data;
+ for(size_t i=0;ifind(path[i]);
+ if(it==current->end())throw TDF_ERR(PATH_NOT_FOUND,filepath,path);
+ if(i==path.size()-1){
+ if(ITSNOT TDF_CLASS)throw TDF_ERR(GET_MISMATCH,filepath,path);
+ return (boost::unordered_map*)(it->second.datapointer);
+ }
+ if(ITSNOT TDF_CLASS)throw TDF_ERR(GET_MISMATCH,filepath,path);
+ current=(boost::unordered_map*)(it->second.datapointer);
+ }
+ throw TDF_ERR(PATH_NOT_FOUND,filepath,path);
+ }
+ boost::unordered_map* getclass(std::vectorpath,boost::unordered_map* defaultval){
+ try {
+ return getclass(path);}
+ catch(TDF_ERR e) {
+ warning((char*)e.what());
+ return defaultval;
+ }
+ }
+//set
+
+ void setbool(std::vectorpath, bool SETSTART TDF_BOOL, new bool SETMID TDF_BOOL) throw TDF_ERR(SET_MISMATCH, filepath, path); *static_castpath, int SETSTART TDF_INT, new int SETMID TDF_INT) throw TDF_ERR(SET_MISMATCH, filepath, path); *static_castpath, std::string SETSTART TDF_STR, new std::string SETMID TDF_STR) throw TDF_ERR(SET_MISMATCH, filepath, path); *static_castpath, std::string SETSTART TDF_BLOCK, new std::string SETMID TDF_BLOCK) throw TDF_ERR(SET_MISMATCH, filepath, path); *static_castpath, float SETSTART TDF_FLOAT, new float SETMID TDF_FLOAT) throw TDF_ERR(SET_MISMATCH, filepath, path); *static_castpath, char SETSTART TDF_CHAR, new char SETMID TDF_CHAR) throw TDF_ERR(SET_MISMATCH, filepath, path); *static_castpath, std::vector SETSTART TDF_POINTER, new std::vector SETMID TDF_POINTER) throw TDF_ERR(SET_MISMATCH, filepath, path); *static_cast SETEND
+
+ void define(std::vectordefines,char* name){
+ auto it = data->find(TINYDEFINEHEADER);
+ if (it == data->end() || it->second.type != TDF_DEFINES) {
+ std::vector* newdefines = new std::vector();
+ TDF_DATA defdat = { TDF_DEFINES, newdefines };
+ (*data)[TINYDEFINEHEADER] = defdat;
+ todelete.push_back(defdat.datapointer);
+ it = data->find(TINYDEFINEHEADER);
+ }
+ std::vector* currentdefines = static_cast*>(it->second.datapointer);
+ for (size_t i = 0; i < defines.size(); i++) {
+ currentdefines->push_back(defines[i]);
+ }
+ currentdefines->push_back(std::string("#define ") + name);
+ }
+
+ void save(){
+ std::ofstream file(filepath, std::ios::out | std::ios::trunc);
+ std::string DATA="";
+ crawl(data,&DATA,"");
+ file<*map,std::string*STR,std::string indent){
+ auto it = map->find(TINYDEFINEHEADER);
+ if (it != map->end() && it->second.type == TDF_DEFINES) {
+ std::vector* defines = static_cast*>(it->second.datapointer);
+ for (auto& def : *defines) {
+ *STR += def + "\n";
+ }
+ }
+ for(auto&[key,val]:*map){
+ if(key==TINYDEFINEHEADER)continue;
+ switch(val.type){
+ case TDF_STR:*STR+="\" "+key+" "+*static_cast(val.datapointer)+"\n";break;
+ case TDF_CHAR:*STR+="' "+key+" "+*static_cast(val.datapointer)+"\n";break;
+ case TDF_BLOCK:*STR+="S "+key+"\n"+*static_cast(val.datapointer)+"\n\\\n";break;
+ case TDF_BOOL:*STR+="B "+key+" "+(*static_cast(val.datapointer)?"T":"F")+"\n";break;
+ case TDF_BINARY:*STR+="b "+key+" "+std::to_string(*static_cast(val.datapointer))+"\n";break;
+ case TDF_INT:*STR+="i "+key+" "+std::to_string(*static_cast(val.datapointer))+"\n";break;
+ case TDF_FLOAT:*STR+="f "+key+" "+std::to_string(*static_cast(val.datapointer))+"\n";break;
+ case TDF_HEX:*STR+="h "+key+" "+std::to_string(*static_cast(val.datapointer))+"\n";break;
+
+ case TDF_POINTER:{std::vector*ptr=static_cast*>(val.datapointer);
+ *STR+="@ "+key+" ";for(size_t i=0;isize();i++){*STR+=(*ptr)[i];if(isize()-1)*STR+=".";}*STR+="\n";break;}
+
+ case TDF_CLASS:*STR+="{ "+key+"\n";crawl((boost::unordered_map*)(val.datapointer),STR,"");*STR+="}\n";break;
+ }
+ }
+ }
+};
+
+}
+#endif
\ No newline at end of file
diff --git a/inc/term.h b/inc/term.h
new file mode 100644
index 0000000..d875de5
--- /dev/null
+++ b/inc/term.h
@@ -0,0 +1,108 @@
+#pragma once
+#ifndef TINYTERM_H
+#define TINYTERM_H
+
+#include
+#include
+#include
+#include
+
+namespace tiny {
+
+struct ErrorLevel {
+ int value;
+ ErrorLevel(int var){
+ this->value=var;
+ }
+ void setvalue(int var){
+ this->value=var;
+ }
+};
+
+extern tiny::ErrorLevel level;
+
+inline const char* WHITE = "\033[0m";
+inline const char* BLACK = "\033[30m";
+inline const char* RED = "\033[31m";
+inline const char* GREEN = "\033[32m";
+inline const char* YELLOW = "\033[33m";
+inline const char* BLUE = "\033[34m";
+inline const char* MAGENTA = "\033[35m";
+inline const char* CYAN = "\033[36m";
+inline const char* BGRED = "\033[41m";
+inline const char* BGBLACK = "\033[40m";
+inline const char* BGGREEN = "\033[42m";
+inline const char* BGYELLOW = "\033[43m";
+inline const char* BGBLUE = "\033[44m";
+inline const char* BGMAGENTA ="\033[45m";
+inline const char* BGCYAN = "\033[46m";
+inline const char* BGWHITE = "\033[47m";
+inline const char* BOLDBLACK = "\033[1m\033[30m";
+inline const char* BOLDRED = "\033[1m\033[31m";
+inline const char* BOLDGREEN = "\033[1m\033[32m";
+inline const char* BOLDYELLOW = "\033[1m\033[33m";
+inline const char* BOLDBLUE = "\033[1m\033[34m";
+inline const char* BOLDMAGENTA = "\033[1m\033[35m";
+inline const char* BOLDCYAN = "\033[1m\033[36m";
+inline const char* BOLDWHITE = "\033[1m\033[37m";
+
+#define ending \
+ mixer.append(info); mixer.append("\033[0m\n");\
+ const char * finalinfo=mixer.c_str();\
+ va_start (arg, finalinfo);\
+ vfprintf (stdout, finalinfo, arg);\
+ va_end (arg);
+
+inline void echo(char * info,...){
+ if (level.value==4)
+ {
+ va_list arg;
+ std::string mixer=info;
+ mixer.append("\n");
+ const char * finalinfo=mixer.c_str();
+ va_start (arg, finalinfo);
+ vfprintf (stdout, finalinfo, arg);
+ va_end (arg);}
+}
+inline void warning( char * info,...){
+ if (level.value>=1)
+ {
+ va_list arg;
+ std::string mixer=YELLOW;ending
+}
+}
+inline void fatal( char * info,...){
+ va_list arg;
+ std::string mixer=BOLDWHITE+std::string(BGRED);ending
+}
+inline void error( char * info,...){
+ if (level.value>=0)
+ {
+ va_list arg;
+ std::string mixer=BOLDRED;ending
+}}
+inline void success(char * info , ...){
+ if (level.value>=2)
+ {
+ va_list arg;
+ std::string mixer=GREEN;ending}
+}
+inline void message(char * info , ...){
+ if (level.value>=3)
+ {
+ va_list arg;
+ std::string mixer=BOLDWHITE;ending}
+}
+inline void startup(char* game,char*version){
+int lv=level.value;level.value=6;
+ echo("%s %s",game,version);
+ warning("be warned that");
+ error("ERRORS MIGHT OCCUR!!!");
+ success("but dont worry");
+ message("this is not an error");
+ fatal("I SWEAR");
+level.value=lv;
+}
+
+}
+#endif
\ No newline at end of file
diff --git a/inc/tiny.h b/inc/tiny.h
new file mode 100644
index 0000000..e69de29
diff --git a/main.cpp b/main.cpp
deleted file mode 100644
index 8f75a1c..0000000
--- a/main.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-#include
-#include
-#include
-#include