llisp/src/builtins.cc

275 lines
8.4 KiB
C++

#include "builtins.hh"
#include "pretty.hh"
#include "cast.hh"
namespace builtin {
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.size()>0&&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++){
if(args[i]==ANY) break;
if(args[i]==NUMBER&&(l.args[i].type==INT||l.args[i].type==DOUBLE)) continue;
if(l.args[i].type!=args[i]&&l.args[i].type!=STATEMENT){
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==args[i])//||args[i]==NUMBER&&(s->names[l.args[i].ident].type==INT||s->names[l.args[i].ident].type==DOUBLE))
continue;
else {
object tt = cast_o(s->names[l.args[i].ident],args[i],s);
if(tt.type==args[i]){
continue;
}
}
std::cout<<s->names[l.args[i].ident].type;
return false;
} else {
object tt = cast_o(l.args[i],args[i],s);
if(tt.type==args[i]){
continue;
}
}
return false;
};
}
return true;
*/
}
std::any a_exit(lexi *l, state* s){
int ex;
//if(l.args[0].type==NONE)
// ex = std::get<int>(s->names[l.args[0].ident].value);
//else
ex = std::get<int>(l->args[0].value);
exit(ex);
}
std::any write(lexi *l, state* s){
std::cout<<std::get<std::string>(l->args[0].value)<<std::endl;
return 0;
}
std::any _if(lexi *l, state* s){
if(std::get<int>(l->args[0].value)==1)
interp(l->args[1].to_larray(),s);
else if(l->args.size()>2) //only do the second if there is one
interp(l->args[2].to_larray(),s);
return 0;
}
std::any __anon(lexi *l,state* s){
for(object o : l->args){
if(s->_break!=BREAK)
interp(o.n_value,s);
}
return 0;
}
std::any _def(lexi *l,state *s){
s->names[l->args[0].ident] = l->args[1];
return 0;
}
std::any _add(lexi *l, state* s){
return std::get<int>(l->args[0].value) + std::get<int>(l->args[1].value);
}
std::any _sub(lexi *l, state* s){
return std::get<int>(l->args[0].value) - std::get<int>(l->args[1].value);
}
std::any _mul(lexi *l, state* s){
return std::get<int>(l->args[0].value) * std::get<int>(l->args[1].value);
}
std::any _div(lexi *l, state* s){
return std::get<int>(l->args[0].value) / std::get<int>(l->args[1].value);
}
std::any _mod(lexi *l, state* s){
return std::get<int>(l->args[0].value) % std::get<int>(l->args[1].value);
}
std::any _get(lexi *l, state* s){
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 _geta(lexi *l, state* s){
auto ob = std::get<std::map<std::string,object>>(l->args[0].value);
if(!ob.count(std::get<std::string>(l->args[1].value))) p_ferr("key not found",1);
return ob[std::get<std::string>(l->args[1].value)];
}
std::any _set(lexi *l, state* s){
//std::cout<<l->args[0].ident<<std::endl;
//exit(0);
auto bb = std::get<std::vector<object>>(s->names[l->args[0].ident].value);
bb[std::get<int>(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 _equ(lexi*l,state*s){
return (int)(std::get<int>(l->args[0].value)==std::get<int>(l->args[1].value));
}
std::any _great(lexi*l,state*s){
return (int)(std::get<int>(l->args[0].value)>std::get<int>(l->args[1].value));
}
std::any _less(lexi*l,state*s){
return (int)(std::get<int>(l->args[0].value)<std::get<int>(l->args[1].value));
}
std::any _great_o_equ(lexi*l,state*s){
return (int)(std::get<int>(l->args[0].value)>=std::get<int>(l->args[1].value));
}
std::any _less_o_equ(lexi*l,state*s){
return (int)(std::get<int>(l->args[0].value)<=std::get<int>(l->args[1].value));
}
std::any _nequ(lexi*l,state*s){
return (int)(std::get<int>(l->args[0].value)!=std::get<int>(l->args[1].value));
}
std::any _and(lexi*l,state*s){
return (int)(std::get<int>(l->args[0].value)&&std::get<int>(l->args[1].value));
}
std::any _not(lexi*l,state*s){
return (int)!std::get<int>(l->args[0].value);
}
std::any _or(lexi*l,state*s){
return (int)(std::get<int>(l->args[0].value)||std::get<int>(l->args[1].value));
}
std::any _xor(lexi*l,state*s){
return (int)(std::get<int>(l->args[0].value)^std::get<int>(l->args[1].value));
}
std::any _defn(lexi*l, state*s){
std::vector<std::string> t;
std::vector<type> tt;
if(l->args.size()==3){
//for(int i = 1; i!=l->args.size()-1; i++){
std::vector<object> aa = std::get<std::vector<object>>(l->args[1].value);
for(object o : aa){
t.push_back(o.ident);
tt.push_back(STRING);
}
//}
}
func f;
f.call = l->args[0].ident;
f.args = t;
f.argst = tt;
f._return = ANY;
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;
}
std::any _read(lexi *l,state *s){
object o;
std::cin>>o.ident;
o.value = o.ident;
o.type = STRING;
s->names[l->args[0].ident] = o;
return 0;
}
std::any _push(lexi *l,state *s){
auto ob = std::get<std::vector<object>>(l->args[0].value);
ob.push_back(l->args[1]);
l->args[0].value = ob;
return l->args[0];
}
std::any _pop(lexi *l,state *s){
auto ob = std::get<std::vector<object>>(l->args[0].value);
ob.pop_back();
l->args[0].value = ob;
return l->args[0];
}
std::any _insert(lexi *l,state *s){
auto ob = std::get<std::vector<object>>(l->args[0].value);
ob.insert(ob.begin()+std::get<int>(l->args[1].value),l->args[2]);
l->args[0].value = ob;
return l->args[0];
}
std::any _rem(lexi *l,state *s){
auto ob = std::get<std::vector<object>>(l->args[0].value);
ob.erase(ob.begin()+std::get<int>(l->args[1].value));
l->args[0].value = ob;
return l->args[0];
}
std::any _len(lexi *l,state *s){
return (int)std::get<std::vector<object>>(l->args[0].value).size();
}
std::any _tail(lexi *l, state* s){
auto ob = std::get<std::vector<object>>(l->args[0].value);
return ob[ob.size()-1];
}
std::any _return(lexi *l, state* s){
if(l->args.size()==1) s->_return=l->args[0];
//s->_return = object("wowa","wowa",STRING);
s->_break=BREAK;
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}));
}