#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>


int dummymode = 0;

#define fatal() \
do { \
	fprintf(stderr,"fatal error on %d, bye\n", __LINE__); \
	exit(1); \
} while (0)


#define LINEL 128
unsigned char linebuf[LINEL];
unsigned char *line;
unsigned char white[] = " \t\n";

static struct br {
	int buffered;
	int bp;
} brr;
int bl;
unsigned char **b;

#define cc(a,b) strcasecmp(a,b)

unsigned char *tlws(unsigned char *linebuf)
{
	return linebuf ? linebuf + strspn(linebuf, white) : NULL;
}
unsigned char *ttws(unsigned char *line)
{
	while (strlen(line) > 0 && (line[strlen(line)-1] == ' ' || line[strlen(line)-1] == '\t' || line[strlen(line)-1] == ';' || line[strlen(line)-1] == '.' || line[strlen(line)-1] == '\n'))
		line[strlen(line)-1] = 0;
	return line;
}

void getline(void)
{
	if (brr.buffered && brr.bp < bl) {
		line = strcpy(linebuf, b[brr.bp++]);
//		printf("R%d:<%s>\n", dummymode, line);
		return;
	}
	do {
	if (fgets(linebuf, LINEL, stdin) == NULL)
		exit(0);
	line = tlws(linebuf);
	ttws(line);
	if (brr.buffered) {
		b = realloc(b, sizeof(unsigned char *) * ++bl);
		b[bl-1] = strdup(line);
	} else if (!brr.buffered && b) {
		brr.bp = 0;
		while (bl > 0) {
			free(b[--bl]);
		}
		free(b); b = NULL;
	}
	} while (!line[0]);
//	printf("L%d:<%s>\n", dummymode, line);
}


struct var {
	unsigned char *name;
	enum vt { V_STR, V_INT } type;
	union {
		unsigned char *str;
		int i;
	} val;
};

int vars_no = 0;
struct var *vars = NULL;

void add_var(unsigned char *name, enum vt type)
{
	vars = realloc(vars, ++vars_no * sizeof(struct var));
	vars[vars_no-1].name = strdup(name);
	vars[vars_no-1].type = type;
}

struct var *get_var(unsigned char *name)
{
	int i = 0;
	for (; i < vars_no; i++) {
		if (!cc(name, vars[i].name))
			return &vars[i];
	}
	return NULL;
}

char *alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
char *alnum = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_1234597890";
int hit_to = 0;
int loadint(unsigned char **expr) {
	unsigned char *e = *expr;
	int i, j;
	e = tlws(e);
	if (isalpha(*e)) {
		char p, *pp;
		struct var *v;
		pp = e + strspn(e, alpha);
		if (isdigit(*pp)) { pp += strspn(pp, alnum); }
		p = *pp; *pp = 0;
		v = get_var(e);
		if (!v) fatal();
		if (v->type != V_INT) fatal();
		i = v->val.i;
		*pp = p; e = pp;
	} else {
		if (!isdigit(*e)) fatal();
		i = strtol(e, &e, 10);
	}
	e = tlws(e);
	if (!strncasecmp(e, "to ", 3)) {
		e += 3;
		hit_to = 1;
		*expr = e;
		return i;
	}
	if (!(*e == '+' || *e == '-' || *e == '/' || *e == '*' || *e == '<' || *e == '>' || *e == '=')) {
		*expr = e;
		return i;
	}
	switch (*(e++)) {
		case '+':
			j = loadint(&e);
			i += j;
			break;
		case '-':
			j = loadint(&e);
			i -= j;
			break;
		case '/':
			j = loadint(&e);
			i /= j;
			break;
		case '*':
			j = loadint(&e);
			i *= j;
			break;
		case '<':
			j = loadint(&e);
			i = i < j;
			break;
		case '>':
			j = loadint(&e);
			i = i > j;
			break;
		case '=':
			j = loadint(&e);
			i = i == j;
			break;
	}
	*expr = e;
	return i;
}

unsigned char *loadstr(unsigned char **expr) {
	unsigned char *e = *expr;
	unsigned char *s;
	e = tlws(e);
	if (isalpha(*e)) {
		char p, *pp;
		struct var *v;
		pp = e + strspn(e, alpha);
		if (isdigit(*pp)) { pp += strspn(pp, alnum); }
		p = *pp; *pp = 0;
		v = get_var(e);
		if (!v) fatal();
		if (v->type != V_STR) fatal();
		s = strdup(v->val.str);
		*pp = p; e = pp;
	} else {
		if (*e != '\'') fatal(); (e)++;
		s = e;
		e += strcspn(e, "'");
		*e = 0;
		s = strdup(s);
		(e)++;
	}
	e = tlws(e);
	if (*e == '+') {
		unsigned char *sa;
		e++;
		sa = loadstr(&e);
		s = realloc(s, strlen(s) + strlen(sa) + 1);
		strcat(s, sa);
		free(sa);
	}
	*expr = e;
	return s;
}


void save_expr(struct var *v, unsigned char **expr)
{
	if (v->type == V_STR) {
		unsigned char *ss = v->val.str;
		v->val.str = loadstr(expr);
		free(ss);
	} else
		v->val.i = loadint(expr);
}

struct var* assign(unsigned char *vn)
{
	struct var *v = get_var(vn);
	if (!v) fatal();
	if (line[0] != '=') fatal();
	line++;
	save_expr(v, &line);
	return v;
}


void perform_write(int ln, unsigned char *exprs) {
	while(exprs) {
		char *v = tlws(strsep(&exprs, ","));
		ttws(v);
		if (v[strlen(v)-1] == ')') {
			v[strlen(v)-1] = 0;
			if (!*v) break;
		}
		if (isalpha(*v)) {
			unsigned char *pp, p;
			struct var *var;
			pp = v + strspn(v, alnum); p = *pp; *pp = 0; var = get_var(v); *pp = p;
			if (!var) fatal();
			if (var->type == V_INT) goto num; else goto str;
		} else {
			if (*v != '\'') {
num:
				printf("%d", loadint(&v));
			} else {
				unsigned char *ss;
str:
				ss = loadstr(&v);
				printf("%s", ss);
				free(ss);
			}
		}
	}
	if (ln) puts("");
}

void
parse_statement()
{
	int wait_end = 0;
	// line already loaded
	//printf("<A+>\n");
	do {
		if (!cc(line, "begin")) {
			wait_end = 1;
		} else if (!cc(line, "end")) {
			if (!wait_end) fatal();
	//printf("<A-e>\n");
			return;
		} else {
			unsigned char *tok = line;
			char o;
			line += strcspn(line, ":( \t");
			o = line[0]; line[0] = 0; line++;
			while ((o == ' ' || o == '\t')) {
				if (line[0] == ':' || line[0] == '(') {
					o = line[0]; line[0] = 0;
					line++;
					break;
				} else if (*line == ' ' || *line == '\t') {
					line++;
					continue;
				}
				break;
			}
			if (o == ':') {
				if (!dummymode)
				assign(tok);
			} else if (o == '(') {
				if (!dummymode) {
				if (!cc(tok, "write")) {
					perform_write(0, line);
				} else if (!cc(tok, "writeln")) {
					perform_write(1, line);
				} else fatal();
				}
			} else {
				if (dummymode) {
					getline();
					parse_statement();
				} else
				if (!cc(tok, "for")) {
					struct var *i;
					int limit;
					struct br brm;
					tok = line;
					line += strcspn(line, ":"); *line = 0; line++; ttws(tok);
					i = assign(tok);
					if (!hit_to) fatal();
					hit_to = 0;
					limit = loadint(&line);
					line = tlws(line);
					if (cc(line, "do")) fatal();
					if (i->type != V_INT) fatal();
					brm = brr;
					brr.buffered = 1;
					dummymode = 1; getline(); parse_statement(); dummymode = 0; // preload
					brr.bp = brm.bp;
					//printf("+++++++++++\n");
					for (; i->val.i <= limit; i->val.i++) {
						getline();
						parse_statement();
						brr.bp = brm.bp;
					}
					//printf("************\n");
					brr = brm;
				} else if (!cc(tok, "while")) {
					unsigned char *expr, *l = strdup(line);
					struct br brm;
					brm = brr;
					brr.buffered = 1;
					dummymode = 1; getline(); parse_statement(); dummymode = 0; // preload
					brr.bp = brm.bp;
					//printf("++++/++++++\n");
					while (expr = l) {
						int i = loadint(&expr);
					//	printf("<%s>%d\n", l, i);
						if (!i) break;
						expr = tlws(expr);
						if (cc(expr, "do")) fatal();
						getline();
						parse_statement();
						brr.bp = brm.bp;
					}
					free(l);
					//printf("****/*******\n");
					brr = brm;
				} else {
					fatal();
				}
			}
			if (!wait_end) {
	//printf("<A-s>\n");
				return;
			}
		}
		getline();
	} while (1);
}


int main()
{
	getline();
	if (!cc(line, "var")) {
		getline();
		while (cc(line, "begin")) {
			unsigned char *t = strchr(line, ':');
			enum vt type;
			if (!t) fatal();
			t++; t[-1] = 0; t = tlws(t); ttws(line);
			if (!cc(t, "integer")) {
				type = V_INT;
			} else if (!cc(t, "string")) {
				type = V_STR;
			} else {
				printf("%s\n", t);
				fatal();
			}
			while(line) {
				char *v = tlws(strsep(&line, ","));
				ttws(v);
				if (get_var(v))
					fatal();
				add_var(v, type);
			}
			getline();
		}
	}
	if (cc(line, "begin"))
		fatal();
	parse_statement();
	return 0;
}

