moved C/C++ implementation to separate folder

This commit is contained in:
anon
2023-02-11 01:20:21 +01:00
parent ac35005c89
commit 6c0bb83e1d
11 changed files with 0 additions and 0 deletions

35
Cati/Makefile Executable file
View File

@ -0,0 +1,35 @@
CXX:=g++
CFLAGS:=-O0 -ggdb -std=c++17
CPPFLAGS:=-D DEBUG
LDLIBS:=
LDFLAGS:=
COMP:=$(CXX) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(LDLIBS)
OBJD:=obj/
SRCD:=src/
SRC:=main.cpp lexer.cpp algo.cpp
SRC:=$(addprefix ${SRCD},${SRC})
OBJ:=$(subst .cpp,.o,$(subst ${SRCD},${OBJD},${SRC}))
OUTPUT:=ati.out
.PHONY: main clean run
main: ${OBJ}
${COMP} ${OBJ} -o ${OUTPUT}
obj/%.o: src/%.cpp
${COMP} -c $< -o ${OBJD}/$*.o
clean:
-rm ${OBJD}/*
-rm ./${OUTPUT}
run:
./${OUTPUT}
gdb:
sudo gdb --directory=./src -p $(shell pgrep ${OUTPUT})
algo:
make -C debug/

0
Cati/obj/.placeholder Normal file
View File

36
Cati/src/JokerTao.cpp Normal file
View File

@ -0,0 +1,36 @@
#include "JokerTao.h"
unsigned int JokerTao::id_ = JOKERTAO::END;
namespace jt{
inline std::vector<JokerTao> table;
unsigned findf_relationship(int attr_, std::string value_){
unsigned last_id = JOKERTAO::END - 1;
for(auto &&i : table[i]){
if(i.id == last_id){
continue;
}
if(i.attr == attr && i.value == value_){
return i.index;
}
}
return JOKERTAO::INVALID;
}
unsigned find_attribute(unsigned id_, JokerTao* attr_, unsigned index_ = 0){
for(auto &&i : table[i]){
if(i.id != id_){
continue;
}
if(i.attr == attr){
return i.index;
}
}
return JOKERTAO::INVALID;
}
}

33
Cati/src/JokerTao.h Normal file
View File

@ -0,0 +1,33 @@
#pragma once
#include <vector>
enum JOKERTAO{
INVALID,
NAME,
VALUE
END
};
struct JokerTao{
unsigned id;
JokerTao *attr;
unsigned index;
std::string value; //void* value = nullptr;
inline unsigned last_id(){ return id__; }
JokerTao(attr_ = nullptr, value_ = "", id_ = id__++, index_ = 0) :
id(id_), attr(attr_), index(index_), value(value_){
}
delete JokerTao();
private:
static unsigned id__;
};
namespace jt{
extern std::vector<JokerTao> table;
unsigned findf_relationship(unsigned attr_, std::string value_);
unsigned find_attribute(unsigned index_, JokerTao* attr_, unsigned index_ = 0);
}

240
Cati/src/algo.cpp Normal file
View File

@ -0,0 +1,240 @@
#include "algo.h"
namespace algo{
/* VARS */
inline std::stack<struct frame> callstack;
inline std::unordered_map<std::string, std::string> vars;
/**/
bool init(){
const char *const *c = standard_vars-1;
while((c++, *c != NULL)){
vars[*c] = EMPTY_CELL;
}
callstack.emplace();
return true;
}
void assign(const std::string &name, const std::string& val){
vars[name] = val;
//unsigned index = findf_relationship(NAME, v[ALGO::DESTINATION]);
//if(index == JOKERTAO::INVALID){
// jt::table.emplace_back(JOKERTAO::NAME, v[ALGO::DESTINATION]);
// jt::table.emplace_back(JOKERTAO::VALUE, v[ALGO::VALUE], 0);
//}else{
// jt[index].find_attribute()
//}
}
void pop(unsigned &head){
if(callstack.size() == 1){
#ifdef DEBUG
printf(YELLOW "Return on empty callstack: exiting.\n" NORMAL);
#endif
raise(SIGINT);
}
callstack.pop();
head = callstack.top().bp + 1;
}
void push(const unsigned &head){
callstack.top().bp = head;
callstack.emplace();
}
std::string arref(std::string s){
for(int i = s.size()-1, last = i; i >= 0; i--){
if(s[i] == '-'){
s.replace(i+1, last-i, deref(s.substr(i+1, last-i)));
}
}
return s;
}
std::string deref(std::string s){
s = arref(s);
return (vars.find(s) != vars.end()) ? deref(vars[s]) : s;
}
bool jump(unsigned &head, const jmp &do_jump, const std::string &dest, const char &push){
bool ret = false;
switch(do_jump){
case algo::jmp::nop:
break;
case algo::jmp::jmp:
algo::call(head, dest, (push != algo::EMPTY_CELL));
ret = true;
break;
case algo::jmp::je:
if(algo::vars["eval"] == algo::true_){
algo::call(head, dest, (push != algo::EMPTY_CELL));
ret = true;
}
break;
case algo::jmp::jne:
if(algo::vars["eval"] == algo::false_){
algo::call(head, dest, (push != algo::EMPTY_CELL));
ret = true;
}
break;
}
#ifdef DEBUG
if(ret){
printf(MAGENTA "Jumped to '%s' (%s). " NORMAL, dest.c_str(), algo::deref(dest).c_str());
}
printf(MAGENTA "Head at %d. " NORMAL, head);
#endif
return ret;
}
void call(unsigned &head, const std::string &dest, const bool &is_push){
#ifdef DEBUG
long debug_stacklen = algo::callstack.size();
#endif
if(dest == "return"){
pop(head);
goto RETURN;
}
if(is_push){ push(head); }
try{
head = std::stoi(deref(dest));
}catch(...){
#ifdef DEBUG
printf("Invalid jump destination '%s'", dest.c_str());
#endif
goto RETURN;
}
RETURN:
#ifdef DEBUG
if(algo::callstack.size() != debug_stacklen){
printf(YELLOW "[Stack: %ld->%ld] " NORMAL, debug_stacklen, algo::callstack.size());
}
#endif
}
int aint(std::string s){
static const char c[] = "0123456789";
int i = 0;
bool sign = true;
while(true){
switch(s[i]){
case '-':
sign = !(sign xor false);
++i;
continue;
case '+':
sign = !(sign xor true);
++i;
continue;
default:
goto BR;
}
}
BR:
s.erase(0, i);
for(i = 0; i < s.size(); i++){
bool is_any = false;
for(int h = 0, end2 = sizeof(c)-1; h < end2; h++){
if(s[i] == c[h]){
is_any = true;
break;
}
}
if(not is_any){
s.erase(i, 1);
--i;
}
}
if(s == ""){ s = '0'; }
return std::stoi(s) * (sign ? 1 : -1);
}
void do_eval(const std::string &opr1, char oper, const std::string &opr2){ // convert to use assign()
#define CASECHAR(c){ \
case (char)(*#c):\
vars["eval"] = std::to_string(aint(deref(opr1)) c aint(deref(opr2))); \
}
#define CASELCHAR(c){ \
case (char)(*#c):\
aint(deref(opr1)) c aint(deref(opr2)) ? (vars["eval"] = true_) : (vars["eval"] = false_); \
}
//is_cmp = (oper == EMPTY_CELL);
vars["eval"] = "";
switch(oper){
case EMPTY_CELL:
vars["eval"] = deref(opr1);
return;
case '.':
vars["eval"] = deref(opr1) + deref(opr2);
return;
case '\'':
vars["eval"] = deref(opr1).substr(0, opr1.size()-aint(deref(opr2)));
return;
CASECHAR(-)
return;
CASECHAR(+)
return;
CASECHAR(/)
return;
CASECHAR(*)
return;
CASECHAR(%)
return;
CASELCHAR(<)
return;
CASELCHAR(>)
return;
case '=':
aint(deref(opr1)) == aint(deref(opr2)) ? (vars["eval"] = true_) : (vars["eval"] = false_); \
return;
CASELCHAR(|)
return;
CASELCHAR(&)
return;
CASELCHAR(^)
return;
}
}
}
//int aint(std::string s){
// static const char c[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; // ?!
// bool sign = true;
// int roof = 1;
//
// for(int i = 0, int end = s.size(); i < end; i++){
// int h = 0;
// for(int e = sizeof(c)-1; h < e; h++){
// if(c[h] == s[i]){
// while(pow(2, roof) < h){
// ++roof;
// }
// goto CONT;
// }
// }
// switch(s[i]){
// case '-':
// sign = !(sign xor false);
// s.rease(i, 1);
// --i;
// continue;
// case '+':
// sign = !(sign xor true);
// s.rease(i, 1);
// --i;
// continue;
// default:
// s[i] = '0';
// continue;
// }
// CONT:
// }
//}

76
Cati/src/algo.h Normal file
View File

@ -0,0 +1,76 @@
#include <math.h>
#include <signal.h>
#include <string>
#include <stack>
#include <unordered_map>
#ifdef DEBUG
# include "debug.h"
#endif
namespace algo{
/* CONST */
enum{
// LINE,
JUMP,
DESTINATION,
ASSIGNMENT,
OPR1,
OPERATOR,
OPR2,
COMMENT
};
enum class jmp{
nop,
jmp,
je,
jne
};
const char EMPTY_CELL = '0';
const char true_[] = "TRUE";
const char false_[] = "FALSE";
struct frame{
unsigned bp;
};
const char* const standard_vars[] = {
"eval",
"ret",
"argv-0",
"argv-1",
"argv-2",
"argv-3",
"argv-4",
"argv-5",
"argv-6",
"argv-7",
"argv-8",
"argv-9",
NULL
};
/**/
/* VARS */
extern std::stack<struct frame> callstack;
extern std::unordered_map<std::string, std::string> vars;
/**/
bool init();
std::string arref(std::string s);
std::string deref(std::string s);
int aint(std::string s);
void assign(const std::string &name, const std::string& val);
void do_eval(const std::string &opr1, char oper, const std::string &opr2);
void pop(unsigned &head);
void push(const unsigned &head);
bool jump(unsigned &head, const jmp &do_jump, const std::string &dest, const char &push);
void call(unsigned &head, const std::string &dest, const bool &is_push);
}

23
Cati/src/debug.h Normal file
View File

@ -0,0 +1,23 @@
#define DEBUG_COLOR
#ifdef DEBUG_COLOR
# define NORMAL "\033[0m"
# define BOLD "\033[1m"
# define RED "\033[31m"
# define GREEN "\033[32m"
# define YELLOW "\033[33m"
# define BLUE "\033[34m"
# define MAGENTA "\033[35m"
# define CYAN "\033[36m"
# define WHITE "\033[37m"
#else
# define NORMAL ""
# define BOLD ""
# define RED ""
# define GREEN ""
# define YELLOW ""
# define BLUE ""
# define MAGENTA ""
# define CYAN ""
# define WHITE ""
#endif

87
Cati/src/lexer.cpp Normal file
View File

@ -0,0 +1,87 @@
#include "lexer.h"
#include "rapidcsv.h"
#include "algo.h"
inline unsigned long long instruction_counter = 1;
void lex_file(const char* const f){
rapidcsv::Document doc(f, rapidcsv::LabelParams(-1, -1),
rapidcsv::SeparatorParams(';')
);
std::vector<std::string> buf;
for(unsigned head = 1, end = doc.GetRowCount()+1; head < end; head++){
#ifdef DEBUG
printf(BOLD BLUE "%0#6llx" NORMAL "|", instruction_counter++);
printf(BOLD "%s:%d: " NORMAL, f, head);
#endif
const std::string c = doc.GetCell<std::string>(0, head-1);
if(c[0] == '"'){ // skip comments
#ifdef DEBUG
printf(GREEN "Comment: %s\n" NORMAL, c.c_str());
#endif
continue;
}
buf = doc.GetRow<std::string>(head-1);
lex_row(buf, head);
}
}
void lex_row(std::vector<std::string> &v, unsigned &head){
/* --- MUST COMPUTE --- */
algo::do_eval(v[algo::OPR1], v[algo::OPERATOR][0], v[algo::OPR2]);
/* --- */
/* --- INSTRUCTION BREANCHING --- */
/* Is jump*/
if(v[algo::JUMP][0] != algo::EMPTY_CELL){
algo::jmp j;
try{
j = (algo::jmp)(stoi(v[algo::JUMP]));
}catch(...){
puts(RED "Non sensical jump condition." NORMAL);
return;
}
#ifdef DEBUG
printf(MAGENTA "Jump condition %s (%s) %s %s (%s) with %d. " NORMAL,
v[algo::OPR1].c_str(),
algo::deref(v[algo::OPR1]).c_str(),
v[algo::OPERATOR].c_str(),
algo::deref(v[algo::OPR2]).c_str(),
v[algo::OPR2].c_str(),
(int)j
);
#endif
if(algo::jump(head, j, v[algo::DESTINATION], v[algo::ASSIGNMENT][0])){
--head;
#ifdef DEBUG
puts(MAGENTA "Continueing." NORMAL);
#endif
}else{
#ifdef DEBUG
puts(MAGENTA "Falling through." NORMAL);
#endif
}
return;
}
/* Is assignemt */
if(v[algo::ASSIGNMENT][0] != algo::EMPTY_CELL){
algo::assign(algo::arref(v[algo::DESTINATION]), algo::vars["eval"]);
#ifdef DEBUG
printf(CYAN "Assigned '%s' to '%s' (%s). (%s %s %s %c %s)\n" NORMAL,
algo::vars["eval"].c_str(),
v[algo::DESTINATION].c_str(),
algo::arref(v[algo::DESTINATION]).c_str(),
//
v[algo::DESTINATION].c_str(),
v[algo::ASSIGNMENT].c_str(),
v[algo::OPR1].c_str(),
v[algo::OPERATOR][0],
v[algo::OPR2].c_str());
#endif
return;
}
/* --- */
}

8
Cati/src/lexer.h Normal file
View File

@ -0,0 +1,8 @@
#include <vector>
#include <string>
#include <iostream>
void lex_file(const char* const f);
void lex_row(std::vector<std::string> &v, unsigned &head);
extern unsigned long long instruction_counter;

68
Cati/src/main.cpp Normal file
View File

@ -0,0 +1,68 @@
#include <string.h>
#include <signal.h>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
//#include "JokerTao.h"
#include <unordered_map>
//
#include "algo.h"
#include "lexer.h"
using namespace std;
char* f;
[[ noreturn ]] void end(int ignore = 0){
#ifdef DEBUG
printf(NORMAL);
#endif
#ifdef DEBUG
printf(GREEN "\" Standard variables\n" NORMAL);
const char *const *c = algo::standard_vars-1;
while((c++, *c != NULL)){
printf("%s: %s\n", *c, algo::vars[*c].c_str());
algo::vars.erase(*c);
}
printf(GREEN "\" User variables\n" NORMAL);
vector<char*> vpbuf;
for(auto &&i : algo::vars){
char *a;
asprintf(&a, "%s: %s\n", i.first.c_str(), i.second.c_str());
vpbuf.push_back(a);
}
std::sort(vpbuf.begin(), vpbuf.end(), [](char* a, char* b){ return (strcmp(a, b) < 1); });
for(auto &&i : vpbuf){
cout << i;
}
#endif
exit(2);
}
bool init(){
ios::sync_with_stdio(true);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
signal(SIGINT, end);
printf("[init] ");
algo::init();
puts("");
return true;
}
signed main(int argc, char* argv[]){
if(argc < 2){ return 0; }
init();
f = argv[1];
lex_file(f);
end();
}

1821
Cati/src/rapidcsv.h Normal file

File diff suppressed because it is too large Load Diff