diff --git a/README.md b/README.md index cbb0ae6..371903c 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,22 @@ __`vm_str`__ has 3 formats. The third one is used to declare a character. var s='str'; var s="another string"; var s=`c`; + +# some special characters is allowed in this language: + +'\a'; +'\b'; +'\e'; +'\f'; +'\n'; +'\r'; +'\t'; +'\v'; +'\0'; +'\\'; +'\?'; +'\''; +'\"'; ``` __`vm_vec`__ has unlimited length and can store all types of values. diff --git a/makefile b/makefile index a9a5c44..ec37858 100644 --- a/makefile +++ b/makefile @@ -31,5 +31,5 @@ test:nasal ./nasal -op -e test/scalar.nas ./nasal -op -e test/trait.nas ./nasal -op -t -d test/turingmachine.nas - ./nasal -op -t -d test/ycombinator.nas + ./nasal -op -t -d -o test/ycombinator.nas \ No newline at end of file diff --git a/nasal_builtin.h b/nasal_builtin.h index 8617f63..0ec9666 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -949,7 +949,7 @@ nasal_ref builtin_opendir(nasal_ref* local,nasal_gc& gc) return builtin_err("opendir","\"path\" must be string"); DIR* p=opendir(path.str()->c_str()); if(!p) - return builtin_err("opendir","cannot open dir <"+*path.str()+">"); + return builtin_err("opendir","cannot open dir <"+*path.str()+"> errno "+std::to_string(errno)); nasal_ref ret=gc.alloc(vm_obj); ret.obj()->type=obj_dir; ret.obj()->ptr=(void*)p; @@ -1020,7 +1020,7 @@ nasal_ref builtin_dlopen(nasal_ref* local,nasal_gc& gc) void* ptr=dlopen(dlname.str()->c_str(),RTLD_LOCAL|RTLD_LAZY); #endif if(!ptr) - return builtin_err("dlopen","cannot open dynamic lib \""+*dlname.str()+"\""); + return builtin_err("dlopen","cannot open dynamic lib <"+*dlname.str()+">"); nasal_ref ret=gc.alloc(vm_obj); ret.obj()->type=obj_dylib; ret.obj()->ptr=ptr; diff --git a/test/turingmachine.nas b/test/turingmachine.nas index 86e6a13..5c65025 100644 --- a/test/turingmachine.nas +++ b/test/turingmachine.nas @@ -7,8 +7,44 @@ var table=[ ['q2','0','1','R','q3'], ['q3',nil,nil,'S','q3'] ]; + +var operand={ + new:func(symbol,changed_symbol,move,next_state){ + if(move!='L' and move!='R' and move!='S') + die("invalid move type:"+move); + return { + symbol:symbol, + changed_symbol:changed_symbol, + move:move, + next_state:next_state + }; + } +}; + +var machine={ + states:{}, + add:func(state,operand){ + if(!contains(me.states,state)) + me.states[state]=[operand]; + else{ + foreach(var i;me.states[state]) + if(i.symbol==operand.symbol or i.symbol==nil){ + println(i); + die("conflict operand"); + } + append(me.states[state],operand); + } + }, + load:func(data){ + foreach(var opr;data){ + var (nstat,sym,csym,move,nextstat)=opr; + me.add(nstat,operand.new(sym,csym,move,nextstat)); + } + } +}; + var prt=func(state,pointer,paper,act=nil){ - print(state,':',pointer,':',act!=nil?act:'','\n\t'); + print(act!=nil?act:'','\n\t'); var s=''; foreach(var i;paper) s~=i; @@ -16,37 +52,50 @@ var prt=func(state,pointer,paper,act=nil){ for(var i=0;i'); - state=action[4]; + if(!contains(machine.states,state)) + die("no matching function for state:"~state); + var found=0; + foreach(var action;machine.states[state]){ + var (sym,csym,move,next)=( + action.symbol, + action.changed_symbol, + action.move, + action.next_state + ); + if(sym==paper[pointer] or sym==nil){ + if(sym!=nil) + paper[pointer]=csym; + if(move=='L') pointer-=1; + elsif(move=='R') pointer+=1; + (state,found)=(next,1); break; } - prt(state,pointer,paper,action); + } + + if(!found) + die("no matching function for state:"~state); + + prt(state,pointer,paper,[sym,csym,move,next]); } } -run(table,{},'q0','q3'); \ No newline at end of file +run(table,'q0','q3'); +print('\n'); \ No newline at end of file