275 lines
8.4 KiB
C++
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}));
|
|
}
|