Compare commits

...

No commits in common. "main" and "1.0" have entirely different histories.

13 changed files with 342 additions and 575 deletions

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

5
.gitignore vendored
View file

@ -5,8 +5,5 @@ out
*.exe
tiny
src
*.tar*
*.tar.gz
*.out
pkg
.*/
src

41
LICENSE
View file

@ -1,41 +0,0 @@
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 dont 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 <http://www.gnu.org/licenses/>.
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 <project support email> 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.

View file

@ -1,7 +0,0 @@
CC=clang++
CFLAGS=-std=c++23
install:
rm -rf /usr/include/tiny/
mkdir -p /usr/include/tiny/
cp inc/*.h /usr/include/tiny/

19
PKGBUILD Normal file
View file

@ -0,0 +1,19 @@
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"
}

View file

@ -1,3 +1,59 @@
# TINY SOFTWARE SUITE
# Tiny
[visit the wiki](https://github.com/kin-fuyuki/tiny/wiki)
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)

20
build.tmk Normal file
View file

@ -0,0 +1,20 @@
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

412
inc/tdf.h
View file

@ -1,412 +0,0 @@
#include <boost/unordered/unordered_map_fwd.hpp>
#include <boost/unordered_map.hpp>
#include <boost/array.hpp>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <fstream>
#include <stdexcept>
#include <vector>
#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<std::string,TDF_DATA>*current=data;for(size_t i=0;i<path.size();i++){\
auto it=current->find(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<std::string,TDF_DATA>*newmap=new boost::unordered_map<std::string,TDF_DATA>();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<std::string,TDF_DATA>*)(it->second.datapointer);}}}
#define GETSTART (std::vector<std::string>path){boost::unordered_map<std::string,TDF_DATA>*current=data;for(size_t i=0;i<path.size();i++){\
auto it=current->find(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<std::string,TDF_DATA>*)(it->second.datapointer);}\
throw TDF_ERR(PATH_NOT_FOUND,filepath,path);}
#define DEFAULTGET(TYPE_NAME, ACTUAL_TYPE) ACTUAL_TYPE TYPE_NAME(std::vector<std::string> 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::vector<std::string>path) _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<path.size();i++){
message+=path[i];
if(i!=path.size()-1)
message+=" . ";
}
}
virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW{
return message.c_str();
}
};
enum TDF_Type : unsigned char {
TDF_DEFINES = 10, //bool
TDF_BOOL = 3, //bool
TDF_CHAR = 1, //char
TDF_BINARY = 4, //int
TDF_INT = 5, //int
TDF_HEX = 7, //int
TDF_STR = 0, //string
TDF_BLOCK = 200, //string
TDF_FLOAT = 6, //float
TDF_POINTER = 8, //vector<string>
TDF_CLASS = 9, //class
};
struct TDF_DATA {
TDF_Type type;
void* datapointer;
};
struct TDF_FUNCS{
boost::unordered_map<char,int>funcs;
TDF_DATA(*FUNCS[])(std::string);
};
struct TDF_FILE{
boost::unordered_map<std::string,TDF_DATA>* data=nullptr;
char*filepath;
TDF_FUNCS FUNCS;
std::vector<void*> todelete;
void close(){
for(size_t i=0;i<todelete.size();i++){
delete static_cast<boost::unordered_map<std::string,TDF_DATA>*> (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<std::string,TDF_DATA>();
todelete.push_back(data);
boost::unordered_map<std::string,TDF_DATA>*current=data;
std::vector<boost::unordered_map<std::string,TDF_DATA>*>stack={};
std::vector<std::string>pathvec={};
bool textblock=false;
std::string BLOCK;
std::string BLOCKKEY;
std::vector<std::string> *defines=new std::vector<std::string>();
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<std::string>*ptr=new std::vector<std::string>();
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<std::string,TDF_DATA>*newmap=new boost::unordered_map<std::string,TDF_DATA>();
TDF_DATA DAT={TDF_CLASS,newmap};
todelete.push_back(DAT.datapointer);
(*current)[KEY]=DAT;
std::vector<std::string> *defines=new std::vector<std::string>();
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<std::string>* defines = static_cast<std::vector<std::string>*>(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<std::string> getpointer GETSTART ITSNOT TDF_POINTER GETMID std::vector<std::string> GETEND DEFAULTGET(getpointer, std::vector<std::string>)
char getchar GETSTART ITSNOT TDF_CHAR GETMID char GETEND DEFAULTGET(getchar, char)
bool defined(std::vector<std::string>path){
boost::unordered_map<std::string,TDF_DATA>*current=data;
for(size_t i=0;i<path.size();i++){auto it=current->find(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<std::string,TDF_DATA>*)it->second.datapointer;}
return false;}
DEFAULTGET(defined, bool)
boost::unordered_map<std::string,TDF_DATA>* getclass(std::vector<std::string>path){
boost::unordered_map<std::string,TDF_DATA>*current=data;
for(size_t i=0;i<path.size();i++){
auto it=current->find(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<std::string,TDF_DATA>*)(it->second.datapointer);
}
if(ITSNOT TDF_CLASS)throw TDF_ERR(GET_MISMATCH,filepath,path);
current=(boost::unordered_map<std::string,TDF_DATA>*)(it->second.datapointer);
}
throw TDF_ERR(PATH_NOT_FOUND,filepath,path);
}
boost::unordered_map<std::string,TDF_DATA>* getclass(std::vector<std::string>path,boost::unordered_map<std::string,TDF_DATA>* defaultval){
try {
return getclass(path);}
catch(TDF_ERR e) {
warning((char*)e.what());
return defaultval;
}
}
//set
void setbool(std::vector<std::string>path, bool SETSTART TDF_BOOL, new bool SETMID TDF_BOOL) throw TDF_ERR(SET_MISMATCH, filepath, path); *static_cast<bool SETEND
void setint(std::vector<std::string>path, int SETSTART TDF_INT, new int SETMID TDF_INT) throw TDF_ERR(SET_MISMATCH, filepath, path); *static_cast<int SETEND
void setstring(std::vector<std::string>path, std::string SETSTART TDF_STR, new std::string SETMID TDF_STR) throw TDF_ERR(SET_MISMATCH, filepath, path); *static_cast<std::string SETEND
void setblock(std::vector<std::string>path, std::string SETSTART TDF_BLOCK, new std::string SETMID TDF_BLOCK) throw TDF_ERR(SET_MISMATCH, filepath, path); *static_cast<std::string SETEND
void setfloat(std::vector<std::string>path, float SETSTART TDF_FLOAT, new float SETMID TDF_FLOAT) throw TDF_ERR(SET_MISMATCH, filepath, path); *static_cast<float SETEND
void setchar(std::vector<std::string>path, char SETSTART TDF_CHAR, new char SETMID TDF_CHAR) throw TDF_ERR(SET_MISMATCH, filepath, path); *static_cast<char SETEND
void setpointer(std::vector<std::string>path, std::vector<std::string> SETSTART TDF_POINTER, new std::vector<std::string> SETMID TDF_POINTER) throw TDF_ERR(SET_MISMATCH, filepath, path); *static_cast<std::vector<std::string> SETEND
void define(std::vector<std::string>defines,char* name){
auto it = data->find(TINYDEFINEHEADER);
if (it == data->end() || it->second.type != TDF_DEFINES) {
std::vector<std::string>* newdefines = new std::vector<std::string>();
TDF_DATA defdat = { TDF_DEFINES, newdefines };
(*data)[TINYDEFINEHEADER] = defdat;
todelete.push_back(defdat.datapointer);
it = data->find(TINYDEFINEHEADER);
}
std::vector<std::string>* currentdefines = static_cast<std::vector<std::string>*>(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<<DATA;
file.close();
}
private:
void crawl(boost::unordered_map<std::string,TDF_DATA>*map,std::string*STR,std::string indent){
auto it = map->find(TINYDEFINEHEADER);
if (it != map->end() && it->second.type == TDF_DEFINES) {
std::vector<std::string>* defines = static_cast<std::vector<std::string>*>(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<std::string*>(val.datapointer)+"\n";break;
case TDF_CHAR:*STR+="' "+key+" "+*static_cast<char*>(val.datapointer)+"\n";break;
case TDF_BLOCK:*STR+="S "+key+"\n"+*static_cast<std::string*>(val.datapointer)+"\n\\\n";break;
case TDF_BOOL:*STR+="B "+key+" "+(*static_cast<bool*>(val.datapointer)?"T":"F")+"\n";break;
case TDF_BINARY:*STR+="b "+key+" "+std::to_string(*static_cast<int*>(val.datapointer))+"\n";break;
case TDF_INT:*STR+="i "+key+" "+std::to_string(*static_cast<int*>(val.datapointer))+"\n";break;
case TDF_FLOAT:*STR+="f "+key+" "+std::to_string(*static_cast<float*>(val.datapointer))+"\n";break;
case TDF_HEX:*STR+="h "+key+" "+std::to_string(*static_cast<int*>(val.datapointer))+"\n";break;
case TDF_POINTER:{std::vector<std::string>*ptr=static_cast<std::vector<std::string>*>(val.datapointer);
*STR+="@ "+key+" ";for(size_t i=0;i<ptr->size();i++){*STR+=(*ptr)[i];if(i<ptr->size()-1)*STR+=".";}*STR+="\n";break;}
case TDF_CLASS:*STR+="{ "+key+"\n";crawl((boost::unordered_map<std::string,TDF_DATA>*)(val.datapointer),STR,"");*STR+="}\n";break;
}
}
}
};
}
#endif

View file

@ -1,108 +0,0 @@
#pragma once
#ifndef TINYTERM_H
#define TINYTERM_H
#include <cstdio>
#include <cstring>
#include <stdarg.h>
#include <string>
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

View file

132
main.cpp Normal file
View file

@ -0,0 +1,132 @@
#include <sstream>
#include <string>
#include <fstream>
#include <map>
std::string get(std::string);
std::map<std::string,std::string> variables;
std::map<std::string,int> functions;
#define CALL ""
#ifdef _WIN32
#undef CALL
#define CALL "call"
#endif
#ifdef linux
#undef CALL
#define CALL "exec"
#endif
#ifdef __APPLE__
#undef CALL
#define CALL "exec"
#endif
#include "term.h"
int call(
std::string lines){
std::string com;
com.append(CALL);
success("command:%s\nexecuting\n\n",lines.c_str());
com.append(lines.c_str());
system(com.c_str());
success("\n\n");
return 0;
}
ErrorLevel level(1);
int set(std::string setter){
std::string name=setter.substr(setter.find_first_of(" ")+1,setter.find("=")-4);
std::string value=setter.substr(setter.find("=")+1);
variables[name]=value;
warning("key %s set as value %s\n\n",name.c_str(),value.c_str());
//success("\nvar: %s\n",variables[name].c_str());
return 0;
}
int fn(std::string setter,int pos){
std::string name=setter.substr(setter.find_first_of(":")+1);
functions[name]=pos;
warning("function %s set in position %i\n\n",name.c_str(),pos);
//success("\nvar: %s\n",variables[name].c_str());
return 0;
}
std::string get(std::string key){
std::string k=key.substr(key.find_first_of('%')+1,key.find_last_of('%')-1);
std::string var=variables[k];
if (var==""){
error("\ncould not get variable with key \"%s\"\n",k.c_str());
exit(1);
}
//success("\ngetting variable \"%s\" with key \"%s\"\n",var.c_str(),k.c_str());
return var;
}
#define A lines.append
int main(int argc, char *argv[]){
for (int i=2;i<argc;i++){
if (argv[i][0]=='-'&&argv[i][1]=='w'){i++;
level= std::stoi(argv[i]);
}else{
std::string key="set ";
key.append(std::to_string(i-2)).append("=").append(argv[i]);
set(key);
}}
warning("tiny runner v0.8\n\n\n");
std::fstream fileStream;
fileStream.open(argv[1]);
if (!fileStream.fail()){
std::ifstream infile(argv[1]);
std::string line;
std::string lines;
int mode=-1;
bool infunc=false;
while (std::getline(infile, line))
{
const char * l=line.c_str();
error((char *)l);
if (line.length()!=0){
switch (l[0])
{
case '\\':
if (l[1]=='n'){
call(lines);
lines.clear();}
else{
A(++l);
}
break;
case '%':
lines.append(get(line));
break;
case ';':
break;
case 's':
if (l[1]=='e'&&l[2]=='t'){
call(lines);
lines.clear();
set(line);}
else{
A(" "+line);
}
break;
case ':':
fn(line, infile.cur);
/* code */
default:
A(" "+line);
break;
}
}
}
call(lines);
return 0;
}
error("could not locate file %s",argv[1]);
return 1;
}

57
term.cpp Normal file
View file

@ -0,0 +1,57 @@
#include "term.h"
#include <cstdio>
#include <cstring>
#include <stdarg.h>
#include <string>
#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);
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);}
}
void warning( char * info,...){
if (level.value>=1)
{
va_list arg;
std::string mixer=YELLOW;ending
}
}
void error( char * info,...){
if (level.value>=0)
{
va_list arg;
std::string mixer=BOLDRED;ending
}}
void success(char * info , ...){
if (level.value>=2)
{
va_list arg;
std::string mixer=GREEN;ending}
}
void message(char * info , ...){
if (level.value>=3)
{
va_list arg;
std::string mixer=BOLDWHITE;ending}
}
void startup(char* game,char*version){
echo("%s %s",game,version);
warning("be warned that");
error("ERRORS MIGHT OCCUR!!!");
success("but dont worry");
message("this is not an error");
}

52
term.h Normal file
View file

@ -0,0 +1,52 @@
#pragma once
void echo(char* info,...);
void warning( char * info,...);
void error( char * info,...);
void success(char * info , ...);
void message(char * info , ...);
void startup(char* game,char*version);
struct ErrorLevel {
int value;
ErrorLevel(int var){
this->value=var;
}
void setvalue(int var){
this->value=var;
}
};
extern ErrorLevel level;
/*
-1: none
0: error
1: success
2: warning
3: message
4: echo
*/
#define WHITE "\033[0m" /* White */
#define BLACK "\033[30m" /* Black */
#define RED "\033[31m" /* Red */
#define GREEN "\033[32m" /* Green */
#define YELLOW "\033[33m" /* Yellow */
#define BLUE "\033[34m" /* Blue */
#define MAGENTA "\033[35m" /* Magenta */
#define CYAN "\033[36m" /* Cyan */
#define WHITE "\033[37m" /* White */
#define BOLDBLACK "\033[1m\033[30m" /* Bold Black */
#define BOLDRED "\033[1m\033[31m" /* Bold Red */
#define BOLDGREEN "\033[1m\033[32m" /* Bold Green */
#define BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */
#define BOLDBLUE "\033[1m\033[34m" /* Bold Blue */
#define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */
#define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */
#define BOLDWHITE "\033[1m\033[37m" /* Bold White */