Compare commits
4 Commits
1b4af50038
...
f248989ac1
Author | SHA1 | Date |
---|---|---|
ame | f248989ac1 | |
ame | e9270a7ff8 | |
ame | 20bae619b5 | |
ame | 1219edb49f |
|
@ -2,4 +2,9 @@ todo:
|
|||
|
||||
* clean header files (please)
|
||||
|
||||
* generics D:
|
||||
* custom functions can take arguments
|
||||
|
||||
* return
|
||||
|
||||
* loops
|
||||
|
||||
|
|
|
@ -2,7 +2,42 @@
|
|||
#include "pretty.hh"
|
||||
#include "cast.hh"
|
||||
namespace builtin {
|
||||
bool builtin::check_args(lexi l, state* s){
|
||||
int builtin::check_args(lexi l, state* s){
|
||||
//for(std::vector<type> a : args){
|
||||
for(int z = 0; z!=args.size(); z++){
|
||||
std::vector<type> a = args[z];
|
||||
bool should_continue = 0;
|
||||
|
||||
if(l.args.size()!=a.size()&&a[0]!=ANY) continue;
|
||||
for(int i = 0; i!=l.args.size(); i++){
|
||||
if(a[i]==ANY) return z;
|
||||
//handle implicit type conversion & variables (dynamic casting! woo:3)
|
||||
if(l.args[i].type!=a[i]&&l.args[i].type!=STATEMENT){
|
||||
//variables
|
||||
if(l.args[i].type==NONE){
|
||||
if(!s->names.count(l.args[i].ident)) p_ferr("undefined refrence to "+l.args[i].ident,1);
|
||||
if(s->names[l.args[i].ident].type==a[i]) continue;
|
||||
object tt = cast_o(s->names[l.args[i].ident],a[i],s);
|
||||
if(tt.type!=a[i]){
|
||||
should_continue = 1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
object tt = cast_o(l.args[i],a[i],s);
|
||||
if(tt.type!=a[i]){
|
||||
should_continue = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if(should_continue)continue;
|
||||
return z;
|
||||
}
|
||||
return -1;
|
||||
/*
|
||||
if(l.args.size()!=args.size()&&args[0]!=ANY)
|
||||
return false;
|
||||
for(int i = 0; i!=l.args.size(); i++){
|
||||
|
@ -32,6 +67,7 @@ namespace builtin {
|
|||
};
|
||||
}
|
||||
return true;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -139,10 +175,36 @@ namespace builtin {
|
|||
f.call = l->args[0].ident;
|
||||
f.args = {};
|
||||
f._return = NONE;
|
||||
f.calls = l->args[2].n_value;
|
||||
f.calls = l->args[l->args.size()==3?2:1].n_value;
|
||||
s->functions.insert({l->args[0].ident,f});
|
||||
return 0;
|
||||
}
|
||||
std::any _udef(lexi *l,state *s){
|
||||
s->names.erase(l->args[0].ident);
|
||||
return 0;
|
||||
}
|
||||
std::any _seta(lexi *l, state* s){
|
||||
//std::cout<<l->args[0].ident<<std::endl;
|
||||
//exit(0);
|
||||
auto bb = std::get<std::map<std::string,object>>(s->names[l->args[0].ident].value);
|
||||
bb[std::get<std::string>(l->args[1].value)] = l->args[2];
|
||||
s->names[l->args[0].ident].value = bb;//[std::get<int>(l->args[1].value)];
|
||||
return 0;
|
||||
//auto ob = std::get<std::vector<object>>(l->args[0].value);
|
||||
//if(std::get<int>(l->args[1].value)>ob.size()) p_ferr("out of range",1);
|
||||
//return ob[std::get<int>(l->args[1].value)];
|
||||
}
|
||||
std::any _pp(lexi*l,state*s){
|
||||
s->names[l->args[0].ident].value = std::get<int>(s->names[l->args[0].ident].value) + 1;
|
||||
return 0;
|
||||
}
|
||||
std::any _mm(lexi*l,state*s){
|
||||
s->names[l->args[0].ident].value = std::get<int>(s->names[l->args[0].ident].value) - 1;
|
||||
return 0;
|
||||
}
|
||||
std::any _type(lexi*l,state*s){
|
||||
return (int)l->args[0].type;
|
||||
}
|
||||
}
|
||||
|
||||
void ttest(lexi l){
|
||||
|
|
|
@ -27,13 +27,13 @@ namespace builtin {
|
|||
class builtin {
|
||||
public:
|
||||
std::string call = "";
|
||||
std::vector<type> args = {};
|
||||
std::vector<std::vector<type>> args = {};
|
||||
type _return = NONE;
|
||||
std::any(*exec)(lexi*, state*);
|
||||
|
||||
bool check_args(lexi, state*);
|
||||
int check_args(lexi, state*);
|
||||
|
||||
builtin(std::string _call, std::vector<type> _args, type __return, std::any(*e)(lexi*, state*)){
|
||||
builtin(std::string _call, std::vector<std::vector<type>> _args, type __return, std::any(*e)(lexi*, state*)){
|
||||
call = _call;
|
||||
args = _args;
|
||||
_return = __return;
|
||||
|
@ -67,43 +67,55 @@ namespace builtin {
|
|||
std::any _xor(lexi*, state*);
|
||||
|
||||
std::any _defn(lexi*, state*);
|
||||
std::any _udef(lexi*, state*);
|
||||
std::any _seta(lexi*, state*);
|
||||
std::any _type(lexi*, state*);
|
||||
//shorthands
|
||||
std::any _pp(lexi*, state*);
|
||||
std::any _mm(lexi*, state*);
|
||||
|
||||
}
|
||||
|
||||
|
||||
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,ANON,ANON},NONE,builtin::_if);
|
||||
static builtin::builtin __anon("if",{ANY},NONE,builtin::__anon);
|
||||
static builtin::builtin _def("def",{NONE,ANY},NONE,builtin::_def);
|
||||
static builtin::builtin _add("+",{INT,INT},INT,builtin::_add);
|
||||
static builtin::builtin _sub("-",{INT,INT},INT,builtin::_sub);
|
||||
static builtin::builtin _mul("*",{INT,INT},INT,builtin::_mul);
|
||||
static builtin::builtin _div("/",{INT,INT},INT,builtin::_div);
|
||||
static builtin::builtin _mod("%",{INT,INT},INT,builtin::_mod);
|
||||
static builtin::builtin _get("get",{ARRAY,INT},ANY,builtin::_get);
|
||||
static builtin::builtin _geta("geta",{MAP,STRING},ANY,builtin::_geta);
|
||||
static builtin::builtin _set("set",{NONE,INT,ANY},NONE,builtin::_set);
|
||||
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,ANON},{INT,ANON,ANON}},NONE,builtin::_if);
|
||||
static builtin::builtin __anon("if",{{ANY}},NONE,builtin::__anon);
|
||||
static builtin::builtin _def("def",{{NONE,ANY}},NONE,builtin::_def);
|
||||
static builtin::builtin _add("+",{{INT,INT}},INT,builtin::_add);
|
||||
static builtin::builtin _sub("-",{{INT,INT}},INT,builtin::_sub);
|
||||
static builtin::builtin _mul("*",{{INT,INT}},INT,builtin::_mul);
|
||||
static builtin::builtin _div("/",{{INT,INT}},INT,builtin::_div);
|
||||
static builtin::builtin _mod("%",{{INT,INT}},INT,builtin::_mod);
|
||||
static builtin::builtin _get("get",{{ARRAY,INT}},ANY,builtin::_get);
|
||||
static builtin::builtin _geta("geta",{{MAP,STRING}},ANY,builtin::_geta);
|
||||
static builtin::builtin _set("set",{{NONE,INT,ANY}},NONE,builtin::_set);
|
||||
|
||||
static builtin::builtin _equ("==",{INT,INT},INT,builtin::_equ);
|
||||
static builtin::builtin _great(">",{INT,INT},INT,builtin::_great);
|
||||
static builtin::builtin _less("<",{INT,INT},INT,builtin::_less);
|
||||
static builtin::builtin _great_o_equ(">=",{INT,INT},INT,builtin::_great_o_equ);
|
||||
static builtin::builtin _less_o_equ("<=",{INT,INT},INT,builtin::_less_o_equ);
|
||||
static builtin::builtin _nequ("!=",{INT,INT},INT,builtin::_nequ);
|
||||
static builtin::builtin _and("&&",{INT,INT},INT,builtin::_and);
|
||||
static builtin::builtin _not("!",{INT},INT,builtin::_not);
|
||||
static builtin::builtin _or("||",{INT,INT},INT,builtin::_or);
|
||||
static builtin::builtin _xor("^",{INT,INT},INT,builtin::_xor);
|
||||
static builtin::builtin _equ("==",{{INT,INT}},INT,builtin::_equ);
|
||||
static builtin::builtin _great(">",{{INT,INT}},INT,builtin::_great);
|
||||
static builtin::builtin _less("<",{{INT,INT}},INT,builtin::_less);
|
||||
static builtin::builtin _great_o_equ(">=",{{INT,INT}},INT,builtin::_great_o_equ);
|
||||
static builtin::builtin _less_o_equ("<=",{{INT,INT}},INT,builtin::_less_o_equ);
|
||||
static builtin::builtin _nequ("!=",{{INT,INT}},INT,builtin::_nequ);
|
||||
static builtin::builtin _and("&&",{{INT,INT}},INT,builtin::_and);
|
||||
static builtin::builtin _not("!",{{INT}},INT,builtin::_not);
|
||||
static builtin::builtin _or("||",{{INT,INT}},INT,builtin::_or);
|
||||
static builtin::builtin _xor("^",{{INT,INT}},INT,builtin::_xor);
|
||||
|
||||
static builtin::builtin _defn("defn",{NONE,INT,ANON},ANY,builtin::_defn);
|
||||
static builtin::builtin _defn("defn",{{NONE,ANON},{NONE,INT,ANON}},ANY,builtin::_defn);
|
||||
static builtin::builtin _udef("udef",{{NONE}},NONE,builtin::_udef);
|
||||
static builtin::builtin _seta("seta",{{NONE,STRING,ANY}},NONE,builtin::_seta);
|
||||
static builtin::builtin _type("type",{{ANY}},INT,builtin::_type);
|
||||
|
||||
static builtin::builtin _pp("++",{{NONE}},NONE,builtin::_pp);
|
||||
static builtin::builtin _mm("--",{{NONE}},INT,builtin::_add);
|
||||
|
||||
static std::map<std::string, builtin::builtin*> builtins = {
|
||||
{"write",&_write},{"exit",&_exit},{"if",&_if},{"__anon",&__anon},{"def",&_def},{"+",&_add}
|
||||
,{"-",&_sub},{"*",&_mul},{"/",&_div},{"%",&_mod},{"get",&_get},{"geta",&_geta},{"set",&_set},{"==",&_equ},
|
||||
{">",&_great},{"<",&_less},{">=",&_great_o_equ},{"<=",&_less_o_equ},{"!=",&_nequ},{"&&",&_and},
|
||||
{"!",&_not},{"||",&_or},{"^",&_xor},{"defn",&_defn}
|
||||
{"!",&_not},{"||",&_or},{"^",&_xor},{"defn",&_defn},{"udef",&_udef},{"seta",&_seta},{"++",&_pp},{"--",&_mm}
|
||||
,{"type",&_type}
|
||||
};
|
||||
|
||||
void ttest(lexi);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "pretty.hh"
|
||||
|
||||
object cast_o(object i, type t, state* s){
|
||||
if(t==i.type) return i;
|
||||
if(i.type==STATEMENT&&t!=STATEMENT&&t!=ANON&&i.ident!="__anon"){
|
||||
i = dtype(i,single_ex(i.n_value[0],s),builtins[i.n_value[0].oper]->_return,t);
|
||||
//i.type = STATEMENTC;
|
||||
|
|
|
@ -8,9 +8,10 @@ std::any single_ex(lexi l, state*s){
|
|||
lexi gen = s->gen_args(s->functions[l.oper].args,l);
|
||||
return s->functions[l.oper].exec(gen,s);
|
||||
}
|
||||
if(!builtins[l.oper]->check_args(l,s))
|
||||
int sel_args = builtins[l.oper]->check_args(l,s);
|
||||
if(sel_args==-1)
|
||||
p_ferr("incorrect usage on "+l.oper,1);
|
||||
lexi gen = s->gen_args(builtins[l.oper]->args,l);
|
||||
lexi gen = s->gen_args(builtins[l.oper]->args[sel_args],l);
|
||||
return builtins[l.oper]->exec(&gen,s);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,12 @@ class object {
|
|||
val value = NULL;
|
||||
std::vector<lexi> n_value;
|
||||
type type = NONE;
|
||||
|
||||
object(){};
|
||||
object(std::string ident,val value, enum type type){
|
||||
this->ident = ident;
|
||||
this->value = value;
|
||||
this->type = type;
|
||||
}
|
||||
std::vector<lexi> to_larray();
|
||||
void gen_value();
|
||||
void clear();
|
||||
|
|
|
@ -7,6 +7,7 @@ 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);
|
||||
state state;
|
||||
state.names = {{"true",object("true",1,INT)},{"true",object("false",0,INT)}};
|
||||
interp(test(f_read(argv[1])),&state);
|
||||
//std::cout<<batch_format(test(f_read(argv[1])),0);
|
||||
//interp(test(f_read("./test/exit.ll")));
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
|
||||
local green = "\27[32m"
|
||||
local red = "\27[31m"
|
||||
local reset = "\27[0m"
|
||||
|
||||
|
||||
binary = "./a.out"
|
||||
tests = {
|
||||
{
|
||||
|
@ -15,7 +21,7 @@ tests = {
|
|||
},{
|
||||
file = "./test/if.ll",
|
||||
ex_return = "0",
|
||||
ex_out = "no",
|
||||
ex_out = "test\nno",
|
||||
},{
|
||||
file = "./test/mul.ll",
|
||||
ex_return = "110",
|
||||
|
@ -46,8 +52,20 @@ tests = {
|
|||
ex_out = "6\n5\n2222\n5",
|
||||
},{
|
||||
file = "./test/assoc.ll",
|
||||
ex_return = "5",
|
||||
ex_return = "2",
|
||||
ex_out = "wowa wowa",
|
||||
},{
|
||||
file = "./test/fibonacci.ll",
|
||||
ex_return = "0",
|
||||
ex_out = "1\n2\n3\n5\n8\n13\n21\n34\n55\n89\nend",
|
||||
},{
|
||||
file = "./test/defn.ll",
|
||||
ex_return = "0",
|
||||
ex_out = "5\n4\n3\n2\n1\nmeow",
|
||||
},{
|
||||
file = "./test/types.ll",
|
||||
ex_return = "5",
|
||||
ex_out = "4\n1\n8\n13\n0",
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -74,32 +92,42 @@ function run_test(test)
|
|||
if(exit==test.ex_return) then
|
||||
return true
|
||||
end
|
||||
print("\nwrong exit code "..exit.."!="..test.ex_return)
|
||||
print("\n\nwrong exit code "..exit.."!="..test.ex_return)
|
||||
return false
|
||||
end
|
||||
print("wrong output '"..output.."'!='"..test.ex_out.."'")
|
||||
print("\nwrong output '"..output.."'!='"..test.ex_out.."'")
|
||||
return false
|
||||
end
|
||||
|
||||
local pass = 0
|
||||
local fail = 0
|
||||
|
||||
local green = "\27[32m"
|
||||
local red = "\27[31m"
|
||||
local reset = "\27[0m"
|
||||
local filest = {}
|
||||
|
||||
local dir = io.popen("ls test")
|
||||
local test_count = 0
|
||||
local rtest_count = 0
|
||||
for t in dir:read("*all"):gmatch("[^\n]+") do
|
||||
table.insert(filest,"./test/"..t)
|
||||
test_count = test_count + 1
|
||||
end
|
||||
for _,t in pairs(tests) do
|
||||
function rfromt(tab,target)
|
||||
for i,t in pairs(tab) do
|
||||
if(t==target) then
|
||||
table.remove(tab,i)
|
||||
return tab
|
||||
end
|
||||
end
|
||||
return tab
|
||||
end
|
||||
for ind,t in pairs(tests) do
|
||||
--table.remove(filest,ind);
|
||||
filest = rfromt(filest,t.file)
|
||||
rtest_count = rtest_count + 1
|
||||
print("--- *** "..t.file)--.."\n\n"..binary.." "..t.file.."\n")
|
||||
io.write("--- *** "..t.file)--.."\n\n"..binary.." "..t.file.."\n")
|
||||
local res = run_test(t)
|
||||
if(res) then
|
||||
--print("--- "..green.." PASSED\n"..reset)
|
||||
print(green.." [✓] "..reset)
|
||||
pass = pass + 1
|
||||
else
|
||||
print("--- "..red.."FAILED\n"..reset)
|
||||
|
@ -108,7 +136,10 @@ for _,t in pairs(tests) do
|
|||
end
|
||||
|
||||
if(test_count>rtest_count) then
|
||||
print(red.."missing "..test_count - rtest_count.." tests (from ./test/)")
|
||||
print(red.."missing "..test_count - rtest_count.." test(s) (from ./test/), missing:")
|
||||
for _,t in pairs(filest) do
|
||||
print(" --"..t)
|
||||
end
|
||||
end
|
||||
if(fail==0) then
|
||||
print(green.."all "..pass.." test(s) passed, all good:3"..reset)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
(def a 20)
|
||||
(def a "20")
|
||||
(def a (+ (+ a 20) 20))
|
||||
(exit a)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
(def hello {"a":"ww", "b":"wowa wowa", "exit":5})
|
||||
(write (geta hello "b"))
|
||||
(seta hello "exit" 2)
|
||||
(exit (geta hello "exit"))
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
(def hi 5)
|
||||
(defn name 1
|
||||
((write hi)
|
||||
(defn name ((write hi)
|
||||
(def hi (- hi 1))
|
||||
(if (> hi 0) (name) (write "meow"))))
|
||||
(name)
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
(def start 10)
|
||||
(def numone 0)
|
||||
(def numtwo 1)
|
||||
(def next_num numtwo)
|
||||
(def count 1)
|
||||
(defn fibon 1
|
||||
((write next_num)
|
||||
(++ count)
|
||||
(def numone numtwo)
|
||||
(def numtwo next_num)
|
||||
(def next_num (+ numone numtwo))
|
||||
(if (>= start count) (fibon) (write "end"))))
|
||||
|
||||
(fibon)
|
|
@ -1,3 +1,4 @@
|
|||
(if 1 (write "test"))
|
||||
(if 1
|
||||
((if 1 ((write "no")) ((exit 5))))
|
||||
((write "nya")))
|
||||
|
|
|
@ -1 +1 @@
|
|||
(write (&& 1 1))
|
||||
(write (! (|| (&& 1 1) 0)))
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
(def meow "nya")
|
||||
(def whar (+ 5 5))
|
||||
(def huhr {5,4,3})
|
||||
(def nahr {"h":meow})
|
||||
(defn uwu (exit 5))
|
||||
(write (type meow))
|
||||
(write (type whar))
|
||||
(write (type huhr))
|
||||
(write (type nahr))
|
||||
(write (type uwu))
|
||||
(uwu)
|
|
@ -0,0 +1,3 @@
|
|||
(def meow 5)
|
||||
(udef meow)
|
||||
(write meow)
|
Loading…
Reference in New Issue