Compare commits
5 Commits
735dc2f8ac
...
991625d46b
Author | SHA1 | Date |
---|---|---|
ame | 991625d46b | |
ame | dcdb5634f1 | |
ame | c93df6ed85 | |
ame | cfe1347bf4 | |
ame | 83354f6bc7 |
|
@ -2,9 +2,5 @@ todo:
|
|||
|
||||
* clean header files (please)
|
||||
|
||||
* custom functions can take arguments
|
||||
|
||||
* return
|
||||
|
||||
* loops
|
||||
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
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[0]!=ANY) continue;
|
||||
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)
|
||||
|
@ -92,8 +93,10 @@ namespace builtin {
|
|||
return 0;
|
||||
}
|
||||
std::any __anon(lexi *l,state* s){
|
||||
for(object o : l->args)
|
||||
interp(o.n_value,s);
|
||||
for(object o : l->args){
|
||||
if(s->_break!=BREAK)
|
||||
interp(o.n_value,s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
std::any _def(lexi *l,state *s){
|
||||
|
@ -185,7 +188,7 @@ namespace builtin {
|
|||
f.call = l->args[0].ident;
|
||||
f.args = t;
|
||||
f.argst = tt;
|
||||
f._return = NONE;
|
||||
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;
|
||||
|
@ -224,6 +227,43 @@ namespace builtin {
|
|||
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){
|
||||
|
|
|
@ -76,6 +76,16 @@ namespace builtin {
|
|||
std::any _pp(lexi*, state*);
|
||||
std::any _mm(lexi*, state*);
|
||||
|
||||
//array operations
|
||||
std::any _push(lexi*, state*);
|
||||
std::any _pop(lexi*, state*);
|
||||
std::any _insert(lexi*, state*);
|
||||
std::any _rem(lexi*, state*);
|
||||
std::any _len(lexi*, state*);
|
||||
std::any _tail(lexi*, state*);
|
||||
|
||||
std::any _return(lexi*, state*);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -113,12 +123,23 @@ static builtin::builtin _read("read",{{NONE}},NONE,builtin::_read);
|
|||
static builtin::builtin _pp("++",{{NONE}},NONE,builtin::_pp);
|
||||
static builtin::builtin _mm("--",{{NONE}},INT,builtin::_add);
|
||||
|
||||
static std::map<std::string, builtin::builtin*> builtins = {
|
||||
static builtin::builtin _push("push",{{ARRAY,ANY}},ANY,builtin::_push); //WARN: all of these SHOULD return an array, figure it out
|
||||
static builtin::builtin _pop("seta",{{ARRAY}},ANY,builtin::_pop);
|
||||
static builtin::builtin _insert("insert",{{ARRAY,INT,ANY}},ANY,builtin::_insert);
|
||||
static builtin::builtin _rem("rem",{{ARRAY, INT}},ANY,builtin::_rem); //WARN: up to here
|
||||
|
||||
static builtin::builtin _len("len",{{ARRAY}},INT,builtin::_len);
|
||||
static builtin::builtin _tail("tail",{{ARRAY}},ANY,builtin::_tail);
|
||||
|
||||
static builtin::builtin _return("return",{{ANY},{}},NONE,builtin::_return);
|
||||
|
||||
static std::unordered_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},{"udef",&_udef},{"seta",&_seta},{"++",&_pp},{"--",&_mm}
|
||||
,{"type",&_type},{"read",&_read}
|
||||
,{"type",&_type},{"read",&_read},{"push",&_push},{"pop",&_pop},{"insert",&_insert},{"rem",&_rem},{"len",&_len}
|
||||
,{"tail",&_tail},{"return",&_return}
|
||||
};
|
||||
|
||||
void ttest(lexi);
|
||||
|
|
28
src/cast.cc
28
src/cast.cc
|
@ -2,6 +2,8 @@
|
|||
#include "pretty.hh"
|
||||
|
||||
object cast_o(object i, type t, state* s){
|
||||
std::string out;
|
||||
std::vector<object> oba;
|
||||
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);
|
||||
|
@ -38,6 +40,20 @@ object cast_o(object i, type t, state* s){
|
|||
i.value = std::to_string(std::get<int>(i.value));
|
||||
break;
|
||||
}
|
||||
if(i.type==ARRAY){
|
||||
i.type = STRING;
|
||||
//out = "{ ";
|
||||
for(object o : std::get<std::vector<object>>(i.value)){
|
||||
out += std::get<std::string>(cast_o(o,STRING,s).value);
|
||||
}
|
||||
//if(out!="{ "){
|
||||
// out[out.size()-1] = ' ';
|
||||
// out[out.size()-2] = ' ';
|
||||
//}
|
||||
//out+="}";
|
||||
i.value = out;
|
||||
break;
|
||||
}
|
||||
p_ferr("no avaliable converstion from "+std::to_string(i.type)+" to "+std::to_string(t),1);
|
||||
break;
|
||||
case STATEMENT:
|
||||
|
@ -47,7 +63,19 @@ object cast_o(object i, type t, state* s){
|
|||
case STATEMENTC:
|
||||
case DOUBLE:
|
||||
case REF:
|
||||
break;
|
||||
case ARRAY:
|
||||
if(i.type==STRING){
|
||||
i.type=ARRAY;
|
||||
for(char c : std::get<std::string>(i.value)){
|
||||
std::string a(1,c);
|
||||
oba.push_back(object(a,a,STRING));
|
||||
}
|
||||
i.value = oba;
|
||||
break;
|
||||
}
|
||||
p_ferr("no avaliable converstion from "+std::to_string(i.type)+" to "+std::to_string(t),1);
|
||||
break;
|
||||
case ANON:
|
||||
case ANY:
|
||||
case NUMBER:
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
#include "interp.hh"
|
||||
|
||||
std::any single_ex(lexi l, state*s){
|
||||
//std::cout<<l.format(0);
|
||||
//std::cout<<l.format(0)<<std::endl;
|
||||
if(!builtins.count(l.oper)&&l.oper!="__anon"){
|
||||
if(!s->functions.count(l.oper))
|
||||
p_ferr("undefined refrence to "+l.oper+" on line:"+std::to_string(l.line)+":"+std::to_string(l._char),1);
|
||||
lexi gen = s->gen_args(s->functions[l.oper].argst,l);
|
||||
return s->functions[l.oper].exec(gen,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[sel_args],l);
|
||||
|
|
14
src/state.cc
14
src/state.cc
|
@ -39,14 +39,20 @@ std::any func::exec(lexi l, state*s) {
|
|||
//for(int i = 0; i!=l.args.size();i++)
|
||||
// std::cout<<l.args[i]<<std::endl;
|
||||
//std::cout<<args.size();
|
||||
state os = *s;
|
||||
if(1||args.size()==3){
|
||||
for(int i = 0; i!=l.args.size(); i++)
|
||||
s->names[args[i]] = l.args[i];
|
||||
}
|
||||
s->_return = object("","",STRING);
|
||||
for(lexi ss : calls){
|
||||
if(s->_break==BREAK)break;
|
||||
single_ex(ss,s);
|
||||
}
|
||||
return 0;//single_ex(l,s);
|
||||
s->_break = NO_FN;
|
||||
auto _return = s->_return;
|
||||
*s = os;
|
||||
return _return;//single_ex(l,s);
|
||||
};
|
||||
|
||||
lexi state::gen_args(std::vector<type> b, lexi i){
|
||||
|
@ -62,7 +68,11 @@ lexi state::gen_args(std::vector<type> b, lexi i){
|
|||
i.args[x] = cast_o(names[i.args[x].ident],b[x],this);
|
||||
}
|
||||
} else if(b[x]!=ANON&&i.args[x].type==STATEMENT){
|
||||
i.args[x] = dtype(i.args[x],single_ex(i.args[x].n_value[0],this),builtins[i.args[x].n_value[0].oper]->_return,b[x]);
|
||||
//std::cout<<this->functions[i.args[x].n_value[0].oper]._return<<" "<<i.args.size()<<" "<<i.args[x].n_value.size();
|
||||
if(builtins.count(i.args[x].n_value[0].oper))
|
||||
i.args[x] = dtype(i.args[x],single_ex(i.args[x].n_value[0],this),builtins[i.args[x].n_value[0].oper]->_return,b[x]);
|
||||
else if(this->functions.count(i.args[x].n_value[0].oper))
|
||||
i.args[x] = dtype(i.args[x],single_ex(i.args[x].n_value[0],this),this->functions[i.args[x].n_value[0].oper]._return,b[x]);;
|
||||
if(i.args[x].type!=b[x])
|
||||
i.args[x] = cast_o(i.args[x],b[x],this);
|
||||
} else if(b[x]!=ANY&&b[x]!=i.args[x].type){
|
||||
|
|
|
@ -32,8 +32,14 @@ class func {
|
|||
|
||||
};
|
||||
|
||||
enum st {
|
||||
CONTINUE,BREAK,NO_FN
|
||||
};
|
||||
|
||||
class state {
|
||||
public:
|
||||
st _break;
|
||||
std::any _return;
|
||||
std::map<std::string, object> names;
|
||||
std::map<std::string, func> functions;
|
||||
lexi gen_args(std::vector<type>, lexi);
|
||||
|
|
|
@ -7,7 +7,8 @@ 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)}};
|
||||
state.names = {{"true",object("true",1,INT)},{"true",object("false",0,INT)},
|
||||
{"maybe",object("maybe",1.5,DOUBLE)}};
|
||||
interp(test(f_read(argv[1])),&state);
|
||||
//std::cout<<batch_format(test(f_read(argv[1])),0);
|
||||
//interp(test(f_read("./test/exit.ll")));
|
||||
|
|
|
@ -70,6 +70,10 @@ tests = {
|
|||
file = "./test/rec.ll",
|
||||
ex_return = "0",
|
||||
ex_out = "5\n4\n3\n2\n1",
|
||||
},{
|
||||
file = "./test/fibonacci2.ll",
|
||||
ex_return = "0",
|
||||
ex_out = "34",
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
(defn y {z} ((write z)(if (> z 0) (y (- z 1)))))
|
||||
(y 5)
|
||||
(write z)
|
|
@ -0,0 +1,7 @@
|
|||
(defn recfib {n} (
|
||||
(if (< n 0) (exit -9))
|
||||
(if (== n 0) (return 0))
|
||||
(if (|| (== n 1) (== n 2)) (return 1))
|
||||
(return (+ (recfib (- n 1)) (recfib (- n 2))))
|
||||
))
|
||||
(write (recfib 9))
|
|
@ -0,0 +1,8 @@
|
|||
(def uwu {5,4,3})
|
||||
(def uwu (insert uwu 1 1))
|
||||
(def uwu (rem uwu 0))
|
||||
(write uwu)
|
||||
(write (len uwu))
|
||||
(write (tail uwu))
|
||||
(write (len "uwu wowa"))
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(defn uwut ((write "uwu")(return)(write "nya")))
|
||||
(defn uwu ((uwut)(write "22")(uwut)(return)(write "nya")))
|
||||
(defn t ((write "wowa")(return "HAHAH")))
|
||||
(write (t))
|
||||
(uwu)
|
Loading…
Reference in New Issue