summaryrefslogtreecommitdiff
path: root/engine.cpp
blob: 7e178ffc0811d3202186d0efcfcca23542ba2c5d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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){
	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);
	}
}