Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
17
Добавлен:
15.06.2014
Размер:
7.12 Кб
Скачать
#include<string.h>
#include<ctype.h>
#include<stdio.h>

#define cCONST 1
#define cVAR 2
#define cASSIGN 3
#define cSTOP 0
#define cEVAL 5
#define cMUL 6 // *
#define cSUB 7  // -
#define cADD 8 // +
#define cDIV 10 // 
#define cPRINT 9 //начать вывод переменных из стека
#define cPRINTF 11 // начать неформатированный вывод
#define cPRINT_STOP 12 // остановить вывод переменых из стека
#define cINPUT 14 //начать ввод
#define cINPUT_STOP 15 // остановить вывод переменых из стека
#define cWHILE 16 //начало условия цикла
#define cDO 17 // конец условия цикла
#define cENDDO 18 // конец цикла
#define cJE 19 // ==
#define cJNE 20 // !=
#define cJG 21 // >
#define cJL 22 // <
#define cJGE 23 //  >=
#define cJLE 24 //  <=
#define cIF 25
#define cTHEN 26 
#define cELSE 27
#define cENDIF 28


#define MAX_TABLE 128
#define MAX_STR   100

double prog[10000];
double stack[10000];
double stack_p[100]; //стек указателей для возвращения из цикла, позволяет до 100 вложенных циклов
int l_stack_p=0;
int l_stack=0;
int ip=0;

void push_p(double x)
{

	stack_p[l_stack_p++]=x;
}

double pull_p()
{
	double d;
	l_stack_p--;
	d = stack_p[l_stack_p];
	l_stack_p++;
	return d;
}

double pop_p()
{
	double d;
	l_stack_p--;
	d = stack_p[l_stack_p];
	return d;
}


struct
{
  char name[50];
  double value;
}symtable[1000];

struct peremen{
	char name[50];
	double value;
}PR[MAX_TABLE];

int l_per = 0; // счетчик переменных
int last_per =0;

void add_command(double com);

void debug_prog()
{
	
	add_command(cINPUT);
	add_command(1);
	add_command(cVAR);
	
	add_command(cSTOP);

}

//функция поиска переменных в таблице по имени, возвращает положение переменнойв таблице
//если нет то возвращает -1
int poiskperem(char s[]) {
	//printf("\tvar is searching\t");
	int i;
	for(i=l_per;i>0;i--)	
		if(strcmp(symtable[i].name,s) == 0)
			return i;
	return -1;
}


int dobavperem(char s[]) {	
	//printf("\tvar is adding\t");
	if(poiskperem(s)==-1) {
		int len;
		len=strlen(s);
		if(l_per+1>=MAX_TABLE)
			yyerror("table symbol is full");
		if(l_per + len + 1>=MAX_STR)
			yyerror("lexemes size of");
		l_per++;
		//printf("\t%d\t",l_per);
		strcpy(symtable[l_per].name, s);
		return l_per;	
	}else {
		yyerror("not second declarate");
	      }
}




void push(double x)
{
	//printf("push in stack = %.2f\t",x);
	stack[l_stack++]=x;
}

double pop()
{
	double d;
	l_stack--;
	d = stack[l_stack];
	//printf("pop from stack = %.2f",d);
	return d;
}


void pushconst()
{
	push((double)prog[ip++]);
}

void pushvar()
{
	double d;
	d = (double)prog[ip];
	ip++;
	push(d);
}

void eval()
{
	double d; int index;
	d = pop();
	index = (int)d;
	d = symtable[index].value;
	push(d);
}

void toassign()
{
	int index;
	double d1,d2;
	d1 = pop();
	d2 = pop();
	symtable[(int)d1].value=d2;
}

void input_var()
{
	while(prog[ip]!=cINPUT_STOP)
	{
		double d1;
		float d2;
		ip++;
		pushvar();
		d1 = pop();
		char name[50];
		strcpy(name, symtable[(int)d1].name);
		printf("\nInput %s : ",name);
		scanf("%g",&d2);
		//printf("vi vveli %f",d2);
		symtable[(int)d1].value=d2;
	}
	
}

void vivod_print()
{
	double d;
	while(prog[ip]!=cPRINT_STOP)
	{
		ip++;
		pushvar();
		eval();
		d = pop();
		printf("\n OUTPUT = %.0f\n",d);
	}
	
}

void vivod_print_f()
{
	double d;
	while(prog[ip]!=cPRINT_STOP)
	{
		ip++;
		pushvar();
		eval();
		d = pop();
		printf("\n OUTPUT = %f\n",d);
	}
	
}

void MUL()
{	double d1,d2;
	d1=pop();
	d2=pop();
	d1*=d2;
	push(d1);
}

void add()
{
	double d1,d2;
	d1=pop();
	d2=pop();
	d1+=d2;
	push(d1);
}

void sub()
{
	double d1,d2;
	d1=pop();
	d2=pop();
	d1=d2-d1;
	push(d1);
}

void div()
{
	double d1,d2;
	d1=pop();
	d2=pop();
	if(d2==0)yyerror("division by zero!"); 
	d1=d2/d1;
	push(d1);
}

void je()
{
	double d1,d2;
	d1=pop();
	d2=pop();
	if(d2==d1){
		push(1);
	}else
	{
		push(0);
	}	
}
void jne()
{
	double d1,d2;
	d1=pop();
	d2=pop();
	if(d2!=d1){
		push(1);
	}else
	{
		push(0);
	}	
}

void jg()
{
	double d1,d2;
	d1=pop();
	d2=pop();
	if(d2>d1){
		push(1);
	}else
	{
		push(0);
	}	
}
void jl()
{
	double d1,d2;
	d1=pop();
	d2=pop();
	if(d2<d1){
		push(1);
	}else
	{
		push(0);
	}	
}
void jge()
{
	double d1,d2;
	d1=pop();
	d2=pop();
	if(d2>=d1){
		push(1);
	}else
	{
		push(0);
	}	
}
void jle()
{
	double d1,d2;
	d1=pop();
	d2=pop();
	if(d2<=d1){
		push(1);
	}else
	{
		push(0);
	}	
}

void f_while()
{
	push_p(ip);
}

void f_do()
{
	double d1;
	d1 = pop();
	if(d1==0) 
	{
		while(prog[ip++]!=cENDDO){}
		pop_p();
	}
}
void f_enddo()
{
	ip = pull_p();
}


void f_then()
{
	double d1;
	d1 = pop();
	int per=0;
	if(d1==0) 
	{
		while(1)
		{
			if(prog[ip]==cIF)
			{
				per++;
			}else 
			{
				if(per==0)
				{
					if(prog[ip]==cELSE)
					{
							ip++;
							break;

					}
					if(prog[ip]==cENDIF)
					{
						ip++;
						break;
					}
				}else
				{
					if(prog[ip]==cENDIF)
					{
						per--;
					}
				}
			}
			ip++;
		};
	}
}

void f_else()
{
	int per=0;
	while(1)
	{
			if(prog[ip]==cIF)
			{
				per++;
			}else 
			{
				if(per==0)
				{
					if(prog[ip]==cENDIF)
					{
						ip++;
						break;
					}
				}else
				{
					if(prog[ip]==cENDIF)
					{
						per--;
					}
				}
			}
			ip++;
	};
}

///блок работы с управляющей памятью
int last_com=0;
void add_command(double com)
{
	//printf("\nnew commant is = %f.1",com);
	prog[last_com]=com;
	last_com++;
}

void vipolni(int ipp)
{
	int code;
	ip=ipp;
	while(prog[ip]!=cSTOP)
	{
		code = prog[ip++];
		switch(code)
		{
			case cCONST:
			{
				pushconst();
				break;
			}
			case cVAR:
			{
				pushvar();
				break;
			}
			case cMUL:
			{
				MUL();
				break;
			}
			case cASSIGN:
			{
				toassign();
				break;
			}
			case cEVAL:
			{
				eval();
				break;
			}
			case cPRINT:
			{
				vivod_print();
				break;
			}
			case cPRINTF:
			{
				vivod_print_f();
				break;
			}
			case cINPUT:
			{
				input_var();
				break;
			}
			case cADD:
			{
				add();
				break;
			}
			case cSUB:
			{
				sub();
				break;
			}
			case cDIV:
			{
				div();
				break;
			}
			case cJE:
			{
				je();
				break;
			}
			case cJNE:
			{
				jne();
				break;
			}
			case cJGE:
			{
				jge();
				break;
			}
			case cJLE:
			{
				jle();
				break;
			}
			case cJG:
			{
				jg();
				break;
			}
			case cJL:
			{
				jl();
				break;
			}
			case cWHILE:
			{
				f_while();
				break;
			}
			case cDO:
			{
				f_do();
				break;
			}
			case cENDDO:
			{
				f_enddo();
				break;
			}
			case cIF:
			{
				break;
			}
			case cTHEN:
			{
				f_then();
				break;
			}
			case cELSE:
			{
				f_else();
				break;
			}
			case cENDIF:
			{
				break;
			}
		};
	}
}





Соседние файлы в папке c_compile(флор_курса)