diff --git a/f.py b/f.py new file mode 100644 index 0000000..8d8c514 --- /dev/null +++ b/f.py @@ -0,0 +1,10 @@ +def fib(n): + if n < 0: + return + + if n == 0: + return 0 + if n==1 or n==2: + return 1 + return fib(n-1)+fib(n-2) +fib(9) diff --git a/src/builtins.cc b/src/builtins.cc index ec10220..98284e7 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -4,11 +4,12 @@ namespace builtin { int builtin::check_args(lexi l, state* s){ //for(std::vector a : args){ + for(int z = 0; z!=args.size(); z++){ std::vector 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; @@ -255,6 +258,12 @@ namespace builtin { auto ob = std::get>(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){ diff --git a/src/builtins.hh b/src/builtins.hh index 28a5e21..d270ee4 100644 --- a/src/builtins.hh +++ b/src/builtins.hh @@ -82,7 +82,9 @@ namespace builtin { std::any _insert(lexi*, state*); std::any _rem(lexi*, state*); std::any _len(lexi*, state*); - std::any _tail(lexi*, state*); + std::any _tail(lexi*, state*); + + std::any _return(lexi*, state*); } @@ -129,13 +131,15 @@ static builtin::builtin _rem("rem",{{ARRAY, INT}},ANY,builtin::_rem); //WARN: up 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 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},{"push",&_push},{"pop",&_pop},{"insert",&_insert},{"rem",&_rem},{"len",&_len} - ,{"tail",&_tail} + ,{"tail",&_tail},{"return",&_return} }; void ttest(lexi); diff --git a/src/interp.cc b/src/interp.cc index 7e7e696..01f612a 100644 --- a/src/interp.cc +++ b/src/interp.cc @@ -1,14 +1,16 @@ #include "interp.hh" std::any single_ex(lexi l, state*s){ - //std::cout<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); diff --git a/src/state.cc b/src/state.cc index fa3047c..6bc7015 100644 --- a/src/state.cc +++ b/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<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 b, lexi i){ @@ -62,7 +68,11 @@ lexi state::gen_args(std::vector 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<functions[i.args[x].n_value[0].oper]._return<<" "<_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){ diff --git a/src/state.hh b/src/state.hh index b8d88bb..706d663 100644 --- a/src/state.hh +++ b/src/state.hh @@ -32,8 +32,14 @@ class func { }; +enum st { + CONTINUE,BREAK,NO_FN +}; + class state { public: + st _break; + std::any _return; std::map names; std::map functions; lexi gen_args(std::vector, lexi); diff --git a/src/tests.lua b/src/tests.lua index b3b014b..af5d0c3 100644 --- a/src/tests.lua +++ b/src/tests.lua @@ -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", }, } diff --git a/test/arr_unal.ll b/test/arr_unal.ll new file mode 100644 index 0000000..73f0b6a --- /dev/null +++ b/test/arr_unal.ll @@ -0,0 +1,3 @@ +(defn y {z} ((write z)(if (> z 0) (y (- z 1))))) +(y 5) +(write z) diff --git a/test/fibonacci2.ll b/test/fibonacci2.ll new file mode 100644 index 0000000..006dafb --- /dev/null +++ b/test/fibonacci2.ll @@ -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)) diff --git a/test/return.ll b/test/return.ll new file mode 100644 index 0000000..d07e80d --- /dev/null +++ b/test/return.ll @@ -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)