diff options
Diffstat (limited to 'engine.cpp')
-rw-r--r-- | engine.cpp | 73 |
1 files changed, 72 insertions, 1 deletions
@@ -1,9 +1,80 @@ #include <iostream> +#include <vector> +#include <string> +#include <cstring> +#include <cmath> +#include <cctype> +#include <cassert> +#include "flogo.h" #include "engine.h" using namespace std; +bool iswordstartchar(char c){return isalpha(c)||c=='_'||c=='.'||c==':';} +bool iswordchar(char c){return iswordstartchar(c)||isdigit(c);} +bool isoperator(char c){return strchr("+-*/=<>()[]",c)!=NULL;} + +vector<string> tokenise(const char *str){ + vector<string> tkns; + const char *p=str; + while(true){ + while(*p&&isspace(*p))p++; + if(!*p)break; + if(*p==';'){ + while(*p&&*p!='\n')p++; + continue; + } + string s; + if(iswordstartchar(*p)){ + do s+=*p++; + while(*p&&iswordchar(*p)); + } else if(isdigit(*p)){ + bool havedot=false; + do { + if(*p=='.'){ + if(!havedot)havedot=true; + else break; + } else if(!isdigit(*p))break; + s+=*p++; + } while(*p); + } else if(*p=='"'){ + while(*p&&!isspace(*p))s+=*p++; + } else if(isoperator(*p))s+=*p++; + else { + cerr<<"UNKNOWN CHAR <"<<*p<<'>'<<endl; + p++; + } + tkns.push_back(move(s)); + } + return tkns; +} + void logocommand(const char *str){ - cout<<str<<endl; + int i; + vector<string> tkns=tokenise(str); + const int ntkns=tkns.size(); + for(i=0;i<ntkns;i++){ + if(tkns[i]=="forward"||tkns[i]=="fd"){ + if(i+1>=ntkns)assert(false); + const int n=stoi(tkns[i+1]); + const int newx=turtle.x+n*sin(turtle.dir*M_PI/180),newy=turtle.y-n*cos(turtle.dir*M_PI/180); + drawline(turtle.x,turtle.y,newx,newy); + turtle.x=newx; turtle.y=newy; + drawturtle(); + i++; + } else if(tkns[i]=="left"||tkns[i]=="lt"){ + if(i+1>=ntkns)assert(false); + const int n=stoi(tkns[i+1]); + turtle.dir-=n; + drawturtle(); + i++; + } else if(tkns[i]=="right"||tkns[i]=="rt"){ + if(i+1>=ntkns)assert(false); + const int n=stoi(tkns[i+1]); + turtle.dir+=n; + drawturtle(); + i++; + } else if(tkns[i]=="bye")exit(0); + } } |