This commit is contained in:
grabt 2023-09-11 10:45:05 -05:00
commit 37d4602de2
17 changed files with 451 additions and 0 deletions

BIN
a.out Executable file

Binary file not shown.

7
license.md Normal file
View File

@ -0,0 +1,7 @@
Copyright © 2023 <grantsquires@disroot.org>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

43
src/builtins.cc Normal file
View File

@ -0,0 +1,43 @@
#include "builtins.hh"
namespace builtin {
bool builtin::check_args(lexi l){
if(l.args.size()!=args.size())
return false;
for(int i = 0; i!=l.args.size(); i++){
if(l.args[i].type!=args[i]) return false;
}
return true;
}
std::any a_exit(lexi l){
exit(std::get<int>(l.args[0].value));
}
std::any write(lexi l){
std::cout<<std::get<std::string>(l.args[0].value)<<std::endl;
return 0;
}
std::any _if(lexi l){
if(std::get<int>(l.args[0].value)==1)
interp(l.args[1].to_larray());
else
interp(l.args[2].to_larray());
//std::cout<<batch_format(l.args[1].to_larray(),0);
return 0;
}
std::any __anon(lexi l){
for(object o : l.args)
interp(o.n_value);
return 0;
}
}
void ttest(lexi l){
//std::cout<<write.check_args(l)<<std::endl;
(void)builtins["write"]->exec(l);
//a.exec = tes;
//std::cout<<std::any_cast<typeid(typemap[INT])>(a.exec({5}));
}

46
src/builtins.hh Normal file
View File

@ -0,0 +1,46 @@
#include "parser.hh"
#include <typeinfo>
#include <iostream>
#include <map>
#include <typeindex>
#include <any>
#include <functional>
#include "stdarg.h"
#include "interp.hh"
namespace builtin {
class builtin {
public:
std::string call = "";
std::vector<type> args = {};
type _return = NONE;
std::any(*exec)(lexi);
bool check_args(lexi l);
builtin(std::string _call, std::vector<type> _args, type __return, std::any(*e)(lexi)){
call = _call;
args = _args;
_return = __return;
exec = e;
}
};
std::any a_exit(lexi l);
std::any write(lexi l);
std::any _if(lexi l);
std::any __anon(lexi l);
}
static builtin::builtin _write("write",{STRING},NONE,builtin::write);
static builtin::builtin _exit("exit",{INT},NONE,builtin::a_exit);
static builtin::builtin _if("if",{INT,STATEMENT,STATEMENT},NONE,builtin::_if);
static builtin::builtin __anon("if",{ANY},NONE,builtin::__anon);
static std::map<std::string, builtin::builtin*> builtins = {
{"write",&_write},{"exit",&_exit},{"if",&_if},{"__anon",&__anon}
};
void ttest(lexi);

10
src/files.cc Normal file
View File

@ -0,0 +1,10 @@
#include "files.hh"
std::string f_read(std::string path){
std::stringstream r;
std::ifstream file(path);
if(!file.is_open())
p_ferr("file not found",1);
r << file.rdbuf();
return r.str();
}

12
src/files.hh Normal file
View File

@ -0,0 +1,12 @@
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include "pretty.hh"
#ifndef __files_hh
#define __files_hh
std::string f_read(std::string path);
#endif

14
src/interp.cc Normal file
View File

@ -0,0 +1,14 @@
#include "interp.hh"
#include "pretty.hh"
#include "builtins.hh"
void interp(std::vector<lexi> inp){
//std::cout<<batch_format(inp, 0);
//std::cout<<inp[0].args[0].value.index();
for(lexi l : inp){
if(!builtins.count(l.oper)&&l.oper!="__anon")
p_ferr("undefined refrence to "+l.oper+" on line:"+std::to_string(l.line)+":"+std::to_string(l._char),1);
builtins[l.oper]->exec(l);
}
}

5
src/interp.hh Normal file
View File

@ -0,0 +1,5 @@
#include "parser.hh"
#include <vector>
#include <iostream>
void interp(std::vector<lexi>);

184
src/parser.cc Normal file
View File

@ -0,0 +1,184 @@
#include "parser.hh"
void object::clear(){
ident="";
value = NULL;
type = NONE;
}
std::vector<lexi> object::to_larray(){
std::vector<lexi> r;
if(n_value[0].oper!="__anon") return n_value;
for(object ii : n_value[0].args){
for(lexi s : ii.n_value){
r.push_back(s);
}
}
return r;
}
void object::gen_value(){
switch(type){
case INT:
value = std::stoi(ident);
break;
case DOUBLE:
value = std::stod(ident);
break;
case CHAR:
value = ident[0];
break;
case NONE:
case STRING:
value = ident;
case STATEMENT:
case STATEMENT_UNEX:
case REF:
case ANON:
case ARRAY:
case ANY:
break;
}
}
std::string lexi::format(int indent){
indent+=INDENT_ITER;
std::string indent_s = "";
for(int i = 0; i<indent;i++){
indent_s+=" ";
}
std::string argv = "[ ";
for(object a : args){
if(a.type!=STATEMENT)
argv+="'"+a.ident+"'"+":"+std::to_string(a.type)+", ";
else{
argv+="\n"+indent_s+batch_format(a.n_value, indent+INDENT_ITER)+indent_s+":"+std::to_string(a.type)+",";
//std::cout<<a.n_value.size();
}
//argv+="[object]:"+std::to_string(a.type)+", ";
}
argv[argv.size()-1] = ' ';
argv[argv.size()-2] = ' ';
argv+="]";
return "call: '"+oper+"' | argv: "+argv;
}
void lexi::clear(){
oper = "";
args = {};
}
std::map<char, char> matching = {{'"','"'},{'(',')'},{'[',']'}};
std::vector<char> matching_keys = {'"','(','['};
std::map<char, type> matching_types = {{'"',STRING},{'(',STATEMENT_UNEX},{'[',ARRAY}};
std::string batch_format(std::vector<lexi> a,int indent){
std::string r = "";
for(lexi b : a){
r+=b.format(indent)+"\n";
}
return r;
}
std::vector<lexi> test(std::string input){
int open = 0;
reading_symbol read = LOOKING;
lexi tob;
char last_con;
int con_level;
std::vector<lexi> all;
object carg;
tob.line = 0;
tob._char = 0;
for(int i = 0; i!=input.size(); i++){
tob._char++;
if(input[i]=='\n') tob.line++;
if(input[i]=='('){
open++;
if(read==LOOKING){
read = READING_O;
continue;
}
}
else if(input[i]==')'){
open--;
if(open==0){
if(read==READING_A||read==READING_CON){
if(carg.ident!=""){
//std::cout<<carg.ident<<std::endl;
tob.args.push_back(carg);
}
}
carg.clear();
all.push_back(tob);
tob.clear();
read = LOOKING;
}
}
if(read==READING_O){
if(input[i]==' ')
read=READING_A;
else if(tob.oper==""&&input[i]=='('){
tob.oper="__anon";
read = READING_CON;
carg.clear();
carg.type = ANON;
con_level = 0;
last_con = input[i];
}
else
tob.oper+=input[i];
} else if(read==READING_A){
if(input[i]==' '&&carg.ident!=""&&carg.ident!="\n"){
tob.args.push_back(carg);
carg.clear();
} else if(std::find(matching_keys.begin(),matching_keys.end(),input[i]) != matching_keys.end()){
con_level = 0;
carg.clear();
last_con = input[i];
carg.type = matching_types[last_con];
if(tob.oper=="__anon")
carg.type = ANON;
read = READING_CON;
}
else if(input[i]!=' '){
carg.ident+=input[i];
if(carg.type==NONE){
if(isdigit(input[i]))
carg.type=INT;//do other types:3
} else if(carg.type==INT&&input[i]=='.'){
carg.type=DOUBLE;
}
}
} else if(read==READING_CON){
if(input[i]==matching[last_con]&&con_level==0){
tob.args.push_back(carg);
carg.clear();
read = READING_A;
} else {
if(input[i]==last_con)
con_level++;
else if(input[i]==matching[last_con])
con_level--;
carg.ident+=input[i];
}
}
}
for(int i = 0; i!=all.size(); i++){
for(int y = 0; y!=all[i].args.size(); y++){
if(all[i].args[y].type==STATEMENT_UNEX||all[i].args[y].type==ANON){
all[i].args[y].ident = "("+all[i].args[y].ident+")";
all[i].args[y].n_value = test(all[i].args[y].ident);
all[i].args[y].type = STATEMENT;
}
all[i].args[y].gen_value();
}
}
//std::cout<<tob.format()<<std::endl;
return all;
}

54
src/parser.hh Normal file
View File

@ -0,0 +1,54 @@
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <variant>
#include <any>
#ifndef __parser_cc
#define __parser_cc
#define INDENT_ITER 5
enum symbols {
P_OPENING = '(',
P_CLOSING = ')',
};
enum type {
NONE, INT, DOUBLE, CHAR, STRING, STATEMENT_UNEX, STATEMENT, REF, ARRAY, ANON, ANY
};
enum reading_symbol {
LOOKING, READING_O, READING_A, READING_CON
};
class lexi;
class object;
class object {
public:
std::string ident = "";
std::variant<int, double, char, std::string, bool, long> value = NULL;
std::vector<lexi> n_value;
type type = NONE;
std::vector<lexi> to_larray();
void gen_value();
void clear();
};
class lexi {
public:
int _char;
int line;
std::string oper;
std::vector<object> args;
std::string format(int);
void clear();
};
static std::map<type, std::any> typemap = {
{NONE,NULL}, {INT,(int)1}, {DOUBLE,(double)5.5}, {CHAR,(char)'5'},
{STRING,(std::string)"a"},{STATEMENT,new lexi}};
std::string batch_format(std::vector<lexi>, int);
std::vector<lexi> test(std::string);
#endif

16
src/pretty.cc Normal file
View File

@ -0,0 +1,16 @@
#include <iostream>
#include "pretty.hh"
void _p_log(std::string s, int l, std::string f){
std::cout<<color_gray<<"[ log ] "<<f<<":"<<l<<" "<<s<<color_reset<<std::endl;
}
void _p_warn(std::string s, int l, std::string f){
std::cout<<color_lyellow<<"[ wrn ] "<<f<<":"<<l<<" "<<s<<color_reset<<std::endl;
}
void _p_err(std::string s, int l, std::string f){
std::cout<<color_red<<"[ err ] "<<color_gray<<f<<":"<<l<<" "<<s<<color_reset<<std::endl;
}
void _p_ferr(std::string s,int i, int l, std::string f){
std::cout<<color_red<<"[!err ] "<<color_red<<f<<":"<<l<<" "<<s<<color_reset<<std::endl;
exit(i);
}

36
src/pretty.hh Normal file
View File

@ -0,0 +1,36 @@
#include <string>
#ifndef __pretty_cc
#define __pretty_cc
#define color_black "\e[30m"
#define color_red "\e[31m"
#define color_green "\e[32m"
#define color_yellow "\e[33m"
#define color_blue "\e[34m"
#define color_magenta "\e[35m"
#define color_cyan "\e[36m"
#define color_lgray "\e[37m"
#define color_gray "\e[90m"
#define color_lred "\e[91m"
#define color_lgreen "\e[92m"
#define color_lyellow "\e[93m"
#define color_lblue "\e[94m"
#define color_lmagenta "\e[95m"
#define color_lcyan "\e[96m"
#define color_white "\e[97m"
#define color_reset "\e[0m"
#define p_log(X) _p_log(X, __LINE__, __FILE__);
void _p_log(std::string, int, std::string);
#define p_warn(X) _p_warn(X, __LINE__, __FILE__);
void _p_warn(std::string, int, std::string);
#define p_err(X) _p_err(X, __LINE__, __FILE__);
void _p_err(std::string, int, std::string);
#define p_ferr(X,Y) _p_ferr(X, Y, __LINE__, __FILE__);
void _p_ferr(std::string, int, int, std::string);
#endif

14
src/test.cc Normal file
View File

@ -0,0 +1,14 @@
#include <iostream>
#include "parser.hh"
#include "files.hh"
#include "pretty.hh"
#include "interp.hh"
#include "builtins.hh"
#include <string>
int main(int argc, char* argv[]){
//std::cout<<batch_format(test("(exit 5 22)(meow \"wharrrr\" (a 5 (aaa 5.5) ) 445)"),0);
//std::cout<<batch_format(test(f_read("./test/if.ll")),0);
interp(test(f_read(argv[1])));
//interp(test(f_read("./test/exit.ll")));
return 0;
}

2
test/exit.ll Normal file
View File

@ -0,0 +1,2 @@
(write "no aaa")
(exit 5)

4
test/if.ll Normal file
View File

@ -0,0 +1,4 @@
(if 1
((if 1 ((write "no")) ((exit 5))))
((write "nya")))

1
test/nested.ll Normal file
View File

@ -0,0 +1 @@
((((write "meow")(write "nya"))(write "uwu")))(exit 5)

3
test/test.ll Normal file
View File

@ -0,0 +1,3 @@
(what)
(write "hi uwu")
(exit 12)