//lexer functor(Cons, Functor) functor(Token, Functor) functor(Info, Functor) //Info(line,column) functor(Pair, Functor) functor(F, Functor) functor(F2, Functor) /* t={ rel fold(Functor l, pred, Any a, Any result) if(l=Cons(b,tail)) pred(a,b,c) fold(tail, pred, c, result) else l=Cons result=a } */ functor(Tuple, Functor) rel pause() c::read(x) rel debug(e) true //print(e) //parser functor(Eq, Functor) functor(Neq, Functor) functor(Stm, Functor) functor(Stm2, Functor) functor(Inequality, Functor) functor(True, Functor) functor(False, Functor) functor(Pred, Functor) functor(And, Functor) functor(Or, Functor) functor(Bracket, Functor) functor(ObjPred, Functor) functor(If, Functor) functor(Cond, Functor) functor(SoftCut, Functor) functor(Op, Functor) functor(Host, Functor) functor(Once, Functor) functor(Declaration, Functor) functor(Mutable, Functor) functor(Size, Functor) //'world' functor(Rel, Functor) functor(Fact, Functor) //'expression' functor(Num, Functor) functor(Str, Functor) functor(Id, Functor) functor(ObjGet, Functor) functor(ObjGet2, Functor) functor(Func, Functor) functor(Error, Functor) functor(None, Functor) //gen functor(Var, Functor) //Var(name, object|local|args, type) functor(Void, Functor) functor(Local, Functor) functor(Lib, Functor) functor(Cur, Functor) functor(Put, Functor) functor(Num, Functor) functor(Str, Functor) functor(Id, Functor) functor(ObjGet, Functor) functor(Func, Functor) functor(TList, Functor Functor) functor(TArray, Functor List) functor(TTable, Functor Functor) functor(Op, Functor) // misc rel parse_type(l,tail,type) l = [Token(_,type,_)|tail] rel get_info(l,info) l = [Token(_,_,info)|_] rel get_line(l,info1) l = [Token(_,_,info)|_] info=Info(info1,_) rel custom_throw(String msg, Functor info) info=Info(line, col) //logic.throw('(line '+math.integerToString(line)+', col '+math.integerToString(col)+') '+msg) print(info) //c::throw(str(msg+' in line '+line+', col '+col)) //c::throw(msg) throw(str('(line '+line+', col '+col+') '+msg)) // ... Relation parse_exp/**/ rel parse_args(l,tail,f) case parse_exp(l,l1,f1) parse_type(l1,l2,',') parse_args(l2,tail,f2) f=[f1|f2] case parse_exp(l,tail,f1) f=[f1] case f=[] tail=l rel parse_args2(l,tail,f) case parse_exp(l,l1,f1) parse_type(l1,l2,s) if(s='|') parse_exp(l2,tail,f2) f=[f1,Tuple(f2)] elseif(s=',') parse_args2(l2,tail,f2) f=[f1|f2] else false case parse_exp(l,tail,f1) f=[f1] case f=[] tail=l // expression parsing /* rel parse_obj_get(l,tail,f) l = [Token(a,'id',_),Token(_,'.',_)| tail] parse_exp(l2,l3,f1) //l3=[Token(_,']',_)|tail] f=ObjGet(a,f1) */ rel parse_obj_get(l,tail,f) l = [Token(a,'id',_),Token(_,'.',_),Token(b,'id',_)| tail] f=ObjGet(a,b) rel parse_obj_get2(l,tail,f) l = [Token(a,'id',_),Token(_,'[',_)|l2] parse_exp(l2,l3,f1) l3=[Token(_,']',_)|tail] f=ObjGet2(a,f1) rel parse_exp_call(l,tail,f) l = [Token(name,'id',_),Token(_,'(',_)| l2] parse_args(l2,l3,args) l3=[Token(_,')',_)|tail] f=Func(name,args,get_info(l)) rel parse_obj_pred(l,tail,f) l = [Token(obj,'id',_),Token(_,'.',_),Token(a,'id',_),Token(_,'(',_)| l2] parse_args(l2,l3,code_args) l3=[Token(_,')',_)|tail] f=ObjPred(obj,a,code_args,get_info(l)) rel parse_list(l,tail,f) l = [Token(_,'[',_)|l2] parse_args2(l2,l3,args) l3=[Token(_,']',_)|tail] f=TList(args) rel parse_array(l,tail,f) l = [Token(_,'{',_)|l2] parse_args2(l2,l3,args) l3=[Token(_,'}',_)|tail] f=TArray(args) Relation parse_body Relation parse_call rel parse_lambda(l,tail,f) l=Cons(Token(_,'rel',_),Cons(Token(_,'(',_), l2)) parse_args(l2, l3, args) l3=Cons(Token(_,')',_),l4) parse_body(l4, l5, body) l5=Cons(Token(_,';',_), tail) f=Rel(args,body) rel parse_table(l,tail,f) l = Cons(Token(_,'{',_),l2) debug('table') cut debug(l2) //c::break() if(l2=[Token(_,'}',_)|tail]) f=TTable(True) else parse_body(l2,l3,args) //debug('table=') l3=Cons(Token(_,'}',_),tail) //debug(args) f=TTable(args) rel name_list_to_type2(l,l2) if(l=[head]) l2=[[head]] else l=Cons(head, tail) name_list_to_type2(tail, tail2) l2=Cons([head], tail2) //e.g. [Rel, Num] ==> [Rel, [Num]] rel name_list_to_type(l,l2) if(l=[]) l2=l elseif(l=[a]) //atomic type l2=l else //composite type l=Cons(a,tail) name_list_to_type2(tail,tail2) l2=Cons(a,tail2) rel parse_name2(l,tail,type,name) //id or type followed by id case l=[Token(a,'id',_)|l2] //pause() parse_name2(l2,tail,type2,name) type=[a|type2] //many ids -> type is declared debug([name,type]) case l=[Token(a,'id',_)|tail] type=[] name=a rel parse_name(l,tail,type,name) parse_name2(l,tail,name_list,name) //once name_list_to_type(name_list,type) rel parse_value(l,tail,f) //str, number or -number case l=[Token(a,'string',_)| tail] and f=Str(a) case l=[Token(_,'-',_), Token(a,'number',_) | tail] and f=Num('-'+a) case l=[Token(a,'number',_)| tail] and f=Num(a) rel parse_excl(l,tail,code) l = Cons(Token(_,'!',_), Cons(Token(a,'id',_), tail)) //code=Exclamation(a,get_info(l)) code=Mutable(a) rel parse_length(l,tail,code) //l=Cons(Token(_,'#',_), Cons(Token(a,'id',_), tail)) l=[Token(_,'#',_)| l2] parse_exp(l2,tail,a) code=Size(a,get_info(l)) rel match_any(l,l2,f) case f(l,tail,f2) match_any(tail,l2,f1) case l=l2 /* exp = id exp1 | exp2 exp1 = '[' exp ']' | '.' exp | '{' ... '}' | '(' args ')' exp2 = '#' id | ':' id */ rel parse_host(l,tail,code) case l = Cons(Token(obj,'id',_),Cons(Token(_,'::',_),Cons(Token(a,'id',_),Cons(Token(_,'(',_), l2)))) parse_args(l2,l3,code_args) l3=[Token(_,')',_)|tail] code=Host(obj,a,code_args) //debug(code) case l = Cons(Token(obj,'id',_),Cons(Token(_,'::',_), l2)) l2=[Token(str,'string',_)|tail] code=Host(obj, str) case l = [Token(obj,'id',_),Token(_,'::',_)| l2] l2=[Token(obj2,'id',_)|tail] code=Host(obj, obj2) rel parse_host2(l,tail,f) l = [Token(a,'id',_),Token(_,'.',_),Token(b,'id',_)| tail] f=ObjGet(a,b) rel id_exp2(l,tail,f) parse_obj_get(l,tail,f) or parse_obj_get2(l,tail,f) or parse_exp_call(l,tail,f) rel id_exp(l,tail,f) parse_exp_call(l,tail,f) or parse_obj_pred(l,tail,f) or parse_obj_get(l,tail,f) or parse_obj_get2(l,tail,f) or parse_host(l,tail,f) rel c2(l,tail,f) case parse_list(l,tail,f) case parse_array(l,tail,f) case parse_table(l,tail,f) case parse_lambda(l,tail,f) case parse_length(l,tail,f) case parse_excl(l,tail,f) case //get expression within bracket parse_type(l,l2,'(') parse_exp(l2,l3,f1) debug(Tuple(f1,f)) f=f1 parse_type(l3,tail,')') case parse_obj_get(l,tail,f) case parse_obj_get2(l,tail,f) case debug('name-') parse_name(l,tail,type,name) and f=Id(name,type) case parse_value(l, tail,f) rel fget(f2,f,a,f2) if(f2=None) f=a else f=f2 Relation parse_exp2 Relation parse_exp3 /* Relation fget*/ rel op_(op) op='+' or op='-' or op='*' or op='/' //parses expressions joined by math operators rel parse_math2(l,tail,prev,f) parse_type(l,l2,op) choose(op_(op))//todo debug(['op',op]) debug(['exp2',b]) //get_info(l,info) fcur = Op(prev,parse_exp2(l2,l4),op,get_info(l)) parse_math2(l4,tail,fcur,fnext) fget(fnext,f,fcur,fnext) else f=None tail=l rel parse_exp(l,tail,f) parse_exp2(l,l2,a) //c2(l,l2,a) debug(['exp',a]) parse_math2(l2,tail,a,f2) fget(f2,f,a,f2) //parse_math0(l,tail,f) //debug(F(f)) /* statements */ rel parse_elseifs(l,tail,c_) case l = Cons(Token(_,'elseif',_), Cons(Token(_,'(',_), l1)) parse_body(l1, l2, f1) l2=Cons(Token(_,')',_), l3) parse_body(l3, l4, f2) parse_elseifs(l4, tail, c_2) c_=Cons(Pair(f1,f2), c_2) case l = Cons(Token(_,'else',_), l10) parse_body(l10,tail,f1) c_=[f1] case c_=Cons tail=l rel parse_if(l,tail,f) if(l = Cons(Token(_,'if',_), l0)) f=Cond(fbody1,fbody2,c_,'if') elseif(l = Cons(Token(_,'when',_), l0)) f=Cond(fbody1,fbody2,c_,'when') else l = Cons(Token(_,'choose',_), l0) f=SoftCut(fbody1,fbody2,c_) l0 = Cons(Token(_,'(',_), l2) debug('if') parse_body(l2,l3,fbody1) l3=Cons(Token(_,')',_), l4) parse_body(l4,l5,fbody2) debug(['elseif',fbody2]) parse_elseifs(l5,l11,c_) l11=Cons(Token(_,';',_), tail) debug(['end']) //pl::writeln(c_) rel parse_case2(l,l1) l = [Token(_,'case',_)| l1] or l = [Token(_,'cond',_)| l1] rel parse_case1(l,tail,f) case parse_case2(l,l1) parse_body(l1,l2,f1) parse_case1(l2,tail,c_) f=[f1|c_] case f=[] tail=l rel parse_case(l,tail,f) parse_case2(l,l1) parse_body(l1,l2,f1) parse_case1(l2,l3,c_) l3=[Token(_,';',_)| tail] f=Cond(True,f1,c_) debug(f) //pl::writeln(f) /* simple statements */ rel parse_eq(l,tail,f) parse_exp(l,l2,a) parse_type(l2,l3,'=') parse_exp(l3,tail,b) get_info(l,info) f=Eq(a,b,info) rel parse_neq(l,tail,f) parse_exp(l,l2,a) parse_type(l2,l3,'!=') parse_exp(l3,tail,b) f=Neq(a,b) rel parse_true(l,tail,f) l = [Token(a,'true',_)|tail] f=True rel parse_atom(l,tail,f) l = [Token('cut','id',_)|tail] f=Fact(a,[],get_info(l)) rel parse_false(l,tail,f) l = [Token(a,'false',_)|tail] f=False rel parse_once(l,tail,f) l=[Token(name,name,_)| l2] if(name='once')//parse_call(l,l2,s1) true else name='not'//todo case //(name='once' or name='not') parse_call(l2, tail, body) f=Stm(name,[],body,get_info(l)) rel parse_all(l,tail,f) l=[Token(name,'id',_),Token(_,'(',_)| l2] name='forall' parse_body(l2, l3, body1) l3=[Token(_,')',_)|l4] parse_body(l4, l5, body) l5=[Token(_,';',_)|tail] f=Stm2(name,body1,body2,get_info(l)) rel parse_inequality(l,tail,f) parse_exp(l,l2,a) parse_type(l2,l3,op) when(op='<' or op='>' or op='<=' or op='>=') parse_exp(l3,tail,b) f=Inequality(a,b,op,get_info(l)) else false /* composite statements */ rel parse_stm(l,tail,f) l=[Token(name,'id',_),Token(_,'(',_)| l2] name='functor' parse_args(l2, l3, args) l3=[Token(_,')',_)|l4] parse_body(l4, l5, body) l5=[Token(_,';',_)|tail] f=Stm(name,args,body,get_info(l)) rel parse_struct3(l,tail,f) l=[Token(name,'id',_),Token(_,'(',_)| l2] debug('st3') if(name='for') f=Stm(name,[body1,body2,body3],body,get_info(l)) else false parse_body(l2, l3, body1) l3=[Token(_,';',_)|l4] parse_body(l4, l5, body2) l5=[Token(_,';',_)|l6] parse_body(l6, l7, body3) l7=[Token(_,';',_),Token(_,')',_)|l8] debug('st3-for') parse_body(l8, l9, body) l9=[Token(_,';',_)|tail] rel parse_struct(l,tail,f) l=[Token(name,'id',_),Token(_,'(',_)| l2] if(name='while') f=Stm(name,body1,body,get_info(l)) else false parse_body(l2, l3, body1) l3=[Token(_,')',_)|l4] parse_body(l4, l5, body) l5=[Token(_,';',_)|tail] rel parse_pred(l,tail,code) l = Cons(Token(a,'id',_), Cons(Token(_,'(',_), l2)) parse_args(l2,l3,code_args) l3=[Token(_,')',_)|tail] if(a='functor') code=Fact(a,code_args,get_info(l)) elseif(a='throw') code=Fact(a,code_args,get_info(l)) elseif(a='cut') code=Fact(a,code_args,get_info(l)) else code=Pred(a,code_args,get_info(l)) rel parse_declaration(l,tail,code) parse_name(l,tail,type,name) //todo: throw error when type is empty (doesn't work now due to backtracking) code=Declaration(name,type) //Relation parse_definition rel parse_definition(l,tail,f) l=[Token(_,mode,_),Token(name,'id',_),Token(_,'(',_)| l2] if(mode='rel') f=Rel(name,args,body) elseif(mode='fun') f=Rel(name,args,body,mode) else false parse_args(l2, l3, args) l3=[Token(_,')',_)|l4] parse_body(l4, l5, body) l5=[Token(_,';',_)|tail] //parse any simple statement rel parse_call(l,tail,code) parse_true(l,tail,code) or parse_false(l,tail,code) or parse_atom(l,tail,code) or parse_if(l,tail,code) or parse_case(l,tail,code) or parse_once(l,tail,code) or //parse_stm(l,tail,code) or parse_all(l,tail,code) or parse_eq(l,tail,code) or parse_neq(l,tail,code) or parse_inequality(l,tail,code) or parse_pred(l,tail,code) or parse_obj_pred(l,tail,code) or parse_host(l,tail,code) or parse_definition(l,tail,code) or parse_struct(l,tail,code) or parse_struct3(l,tail,code) or parse_declaration(l,tail,code) /* rel parse_call(l,tail,code) parse_true(l,tail,code) */ rel parse_body2(l2,tail,s1,code) if(l2=[Token(conn,'connective',_)| l3]) if(conn='and') get_line(l2,i1) get_line(l3,i2) debug([i1,i2]) //c::def(i1) code=And(s1,s2,Tuple(i2,i2)) elseif(conn='or') code=Or(s1,s2) parse_body(l3,tail,s2) else l2=tail s1=code rel info2(l,t2) print([l,t2]) choose(l=[t|tail] and t=Token(_,'connective',_)) info2(tail,t2) elseif(l=[]) throw('could not get line') else l=[t|_] t=t2 /* exp = id exp1 | exp2 exp1 = '[' exp ']' | '.' exp exp = id exp1 exp1 = '[' exp ']' | '.' exp exp = id exp3 exp1 = '[' exp ']' | '.' exp exp3 = exp1 exp3 | exp1 */ //parses atomic expression rel parse_obj_get_(l,tail,f) l = [Token(a,'id',_),Token(_,'.',_)| l2] parse_exp(l2,l3,f1) l3=[Token(_,']',_)|tail] f=ObjGet(a,f1) rel parse_obj_get__(l,tail,f) l = [Token(a,'id',_),Token(_,'[',_)|l2] parse_exp(l2,l3,f1) l3=[Token(_,']',_)|tail] f=ObjGet2(a,f1) /* rel parse_exp3(l,tail,f) when(l = [Token(name,'id',_)| l2]) debug(['token',name]) id_exp2(l,tail,f) else c2(l,tail,f) */ rel parse_exp3(l,tail,f) when(l = [Token(name,'id',_)| l2]) debug(['token',name]) id_exp2(l,tail,f) else debug(['non-id',name]) c2(l,tail,f) rel parse_exp2(l,tail,f) //parse_exp_obj_call(l,tail,f) or when(parse_type(l,_,'id')) id_exp(l,tail,f) else c2(l,tail,f) fun parse_body(l,tail,code) if(parse_call(l,l2,s1)) parse_body2(l2,tail,s1,code) else //info2(l,t) l=[t|_] debug(F(t)) t=Token(_,_,info) custom_throw('parser error',info) /* rel parse_body(l,tail,code) parse_call(l,l2,s1) parse_body2(l2,tail,s1,code) */ require('lexer2', lexer) require('ws2', ws) rel run2(l,code) parse_body(l,tail,code) //debug(F(tail)) //todo if(tail=[Token('EOF',_,_)]) true else if(tail=Cons(t,Cons(t2,_))) t2=Token(_,_,info) custom_throw('parser error1',info) else tail=[t|_] debug(F2(t)) t=Token(_,_,info) custom_throw('parser error2',info) rel run_lexer(s,l) //lexer.run(s, l) debug("lexer...") lexer.run(s, l) cut debug("whitespace...") ws.run(l,l2) cut rel run_parser(l1,l) run2(l1, l) require('list', list) rel add(x,y,z) c::add(x,y,z) rel each(e,e2) e=Token(tk,_,_) e2=tk rel db_token(l) list.map(l,each,l3)//todo check Object existence print(l3) list.reverse(l3,l4) print(l4) list.join(l3,' ',s2) print(s2) debug('') print(str(s2)) rel run(s,l1) debug("lexer...") lexer.run(s, l) cut debug("whitespace...") ws.run(l,l2) debug(l2) //db_token(l) cut debug('parser...') run2(l2,l1) cut /**/ t2={ 'parse_exp'=parse_exp 'parse_call'=parse_call 'parse_body'=parse_body 'run'=run 'run_ws'=run2 'lexer'=run_lexer 'run_parser'=run2 } export(t2) //debug(t) /*todo export({ 'parse_exp'=parse_exp 'parse_call'=parse_call 'parse_body'=parse_body 'run'=run 'run_ws'=run2 'lexer'=run_lexer 'run_parser'=run2 })*/ require('io', io) //s='x=1 and a=2' //s='functor(Functor,Cons) and x=1+1' //io.readFile('test0.co',s) //io.readFile('test1.co',s) //io.readFile('parser2.co',s) //s='rel p() true;' //s='x=1 and y=2' //s='x+2-3' //s='x=t[2][3]' //s='x=2' /* //s='once !x=2' //s='send=pl::send()' when(run(s,l)) //parse_exp(l,tail,f) print(['l',l]) //db_token(l) //print(f) //print(['l',l]) else true rel to_array(l,String s,i,c,c2,env,env2) when(l=[a|tail]) term(a,sa,env,env1,prefix1) gensym('T',c1) s=prefix1+'set_('+c+','+i+','+sa+','+c_+'),'+prefix2 to_array(tail,prefix2,c1,c2,env1,env2) else l=[] c2=c s='' env2=env */ //s="p(a,1,2,'a')" //parse_eq(l2,l3,f) //parse_name(l2,tail,type,f) //parse_exp(l2,l3,f) //parse_call(l2,l3,f) //parse_body(l2,l3,f) //parse_declaration(l2,l3,f) //print(f) //t.run('once a=b and b=c',l) /* t.run('t[0][1]',l) print(l) t.run('a={1,b}',l) print(l) print(t.run('a=[1,b]')) t.run('a={0=1 and 1=b}',l1) print(l1) */ s='t[0][1]' //s='t.x.y' //require('parser2',t) //s="halt=l.halt" //s="x=o.str(2)" //s='for(x=1;x=2;true;) print(x);' //io.readFile('gen5.co',s) //s="if(pl::ground(info)) throw(str(1+2+q)) else y=2;" //s='x=-2;' //s='while(x=2) true;' //s1='cond x=1 cond x=2;' print(t) //s='x=2' c::clock(t3) //lexer.run(s, l) //t.run(s,l) run(s,l) c::clock(t4) print(['l',l]) print(num(t4-t3))/* //print(run(s)) //print(t.run(s1)) debug("whitespace...") ws.run(l,l2) cut parse_exp3(l2,l3,f) print(f)*/