Скачиваний:
11
Добавлен:
01.05.2014
Размер:
28.46 Кб
Скачать
#ifndef _SEM_OPER_
#define _SEM_OPER_

#define MAX_SIZE_ARRAY 10
#define MAX_VAL_INDEX  255

int get_type(ATTR&, char&);
int int_to_float(FILE*, unsigned char&, unsigned char&);
unsigned char add_to_t_f_const(float);
unsigned char add_to_t_i_const(int);
int	op_s_not_equal(SYMB&, FILE*, FILE*);


unsigned int cur_atom = 0;     // ⥪гйЁ© ­®¬Ґа вҐва ¤л
unsigned int cur_free_addr = 0;// ⥪гйЁ©  ¤аҐб бў®Ў®¤­®© п祩ЄЁ б в Ў«. ЇҐаҐ¬Ґ­­ле
unsigned int temp_addr = 0;    //  ¤аҐб ­ з «  ўаҐ¬Ґ­­®© ®Ў« бвЁ Ї ¬пвЁ
unsigned int max_addr = 0;


struct ARR {
	List<unsigned char>* ind_ptr;
	unsigned char id;
};

// бЁ¬ў®«м­лҐ ®Ў®§­ зҐ­Ёп Є®¤®ў ®ЇҐа жЁ© вҐва ¤
char* str_atom[] = {
"addi  ", // 0
"addf  ", // 1
"addm  ", // 2
"subi  ", // 3
"subf  ", // 4
"subm  ", // 5
"muli  ", // 6
"mulf  ", // 7
"mulm  ", // 8
"divi  ", // 9
"divf  ", // 10
"eei   ", // 11
"eef   ", // 12
"nei   ", // 13
"nef   ", // 14
"li    ", // 15
"lf    ", // 16
"lei   ", // 17
"lef   ", // 18
"det   ", // 19
"transp", // 20
"ftype ", // 21
"printi", // 22
"printf", // 23
"scani ", // 24
"scanf ", // 25
"jmp   ", // 26
"jmpf  ", // 27
"seti  ", // 28
"setf  ", // 29
"setm  ", // 30
};

// ‚лў®¤ вҐва ¤л
void print_atom(char n, FILE* f, FILE* fb, const ATTR& a1, const ATTR& a2, const ATTR& a3)
{
	fprintf(f, "%-3u: %s ", cur_atom++, str_atom[n]);
	fprintf(f, "[%-3u %-3u]  ", a1.val[0], a1.val[1]);
	fprintf(f, "[%-3u %-3u]  ", a2.val[0], a2.val[1]);
	fprintf(f, "[%-3u %-3u]\n", a3.val[0], a3.val[1]);
	fprintf(fb, "%c%c%c%c%c%c%c", n, a1.val[0], a1.val[1], a2.val[0],
			a2.val[1], a3.val[0], a3.val[1]);
}





// ----------------------------
//     ЋЏ…ђЂ–€ЋЌЌ›… ‘€Њ‚Ћ‹›
// ----------------------------

int op_s_mark(SYMB& s, FILE* f, FILE* fb) // {Њ…’ЉЂ}
{
	ATTR a;
	s.get_attr(0, a);
	if (t_id[a.val[1]].cls)
		return 12; // ®иЁЎЄ  (id 㦥 ®Ўкпў«Ґ­)
	t_id[a.val[1]].cls = 3; // Є« бб ¬ҐвЄ 
	t_id[a.val[1]].ptr.val[1] = t_mark.get_qntf();
	t_id[a.val[1]].ptr.val[0] = 7; // в Ў«. ¬Ґв®Є
	t_mark.add(cur_atom);
	return 0;
}

int op_s_init_mark(SYMB& s, FILE* f, FILE* fb) // {€Њ}
{
	ATTR a1;
	s.get_attr(0, a1);
	t_mark[a1.val[1]] = cur_atom;
	return 0;
}

int op_s_add_vmark(SYMB& s, FILE* f, FILE* fb) // {„‚Њ}
{
	int a = -1;
	t_mark.add(a);
	return 0;
}

int op_s_add_mark(SYMB& s, FILE* f, FILE* fb) // {„Њ}
{
	t_mark.add(cur_atom);
	return 0;
}


int op_s_jmpf(SYMB& s, FILE* f, FILE* fb) // {“Џ‹}
{
	ATTR a1, a2, a3 = {0, 0};
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	char e, t;
	e = get_type(a1, t);
	if (e)
		return e;
	if (t == 3)
		return 15;
	if (t == 2) {
		SYMB ts;
		ATTR atmp;
		s.get_attr(0, atmp);
		ts.set_attr(0, atmp);
		unsigned char k = add_to_t_f_const(0.0);
		ts.set_attr(1, 5, k);
		ts.set_attr(2, 6, t_var.get_qntf());
		op_s_not_equal(ts, f, fb);
		ts.get_attr(2, a1);
	}
	print_atom(27, f, fb, a1, a2, a3);

	cur_free_addr = temp_addr;

	return 0;
}


int op_s_goto(SYMB& s, FILE* f, FILE* fb) // {ЃЏ}
{
	ATTR a1, a2 = {0, 0}, a3 = {0, 0};
	s.get_attr(0, a1);
	if (a1.val[0] == 3) {
		if (!t_id[a1.val[1]].cls) return 11; // id ­Ґ ®Ўкпў«Ґ­
		if (t_id[a1.val[1]].cls != 3) return 13; // ®иЁЎЄ  (id ­Ґ ¬ҐвЄ )
		a1 = t_id[a1.val[1]].ptr;
	}
	print_atom(26, f, fb, a1, a2, a3);
	return 0;
}


int op_s_in(SYMB& s, FILE* f, FILE* fb) // {‚‚Ћ„}
{
	ATTR a1, a2 = {0, 0}, a3 = {0, 0};
	s.get_attr(0, a1);
	if (a1.val[0] == 3) {
		if (!t_id[a1.val[1]].cls)
			return 11;
		if (t_id[a1.val[1]].cls != 1)
			return 13;
		a1 = t_id[a1.val[1]].ptr;
	}
	if (a1.val[0] == 6) {
		if (t_var[a1.val[1]].type > 2)
			return 15;
	}
	print_atom(t_var[a1.val[1]].type + 23, f, fb, a1, a2, a3);
	cur_free_addr = temp_addr;
	return 0;
}


int op_s_out(SYMB& s, FILE* f, FILE* fb) // {‚›‚Ћ„}
{
	ATTR a1, a2 = {0, 0}, a3 = {0, 0};
	s.get_attr(0, a1);
	char e, t;
	e = get_type(a1, t);
	if (e)
		return e;
	if (t == 3) // Ґб«Ё вЁЇ - ¬ ваЁж 
		return 15;
	print_atom(t + 21, f, fb, a1, a2, a3);
	cur_free_addr = temp_addr;
	return 0;
}



// -------------------------------------
//              ЋЃљџ‚‹…Ќ€џ
// -------------------------------------

int op_s_list_arr(SYMB& s, FILE* f, FILE* fb) // {‘Џ€‘ЋЉ_ЊЂ‘‘}
{
	ATTR a1, a2, a3;
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	s.get_attr(2, a3);
	ARR tarr;
	tarr.id = a1.val[1];
	tarr.ind_ptr = (List<unsigned char>*)a2.ptr;
	(*((List<ARR>*)a3.ptr)).add(tarr);
	return 0;
}

int op_s_def_array(SYMB& s, FILE* f, FILE* fb) // {ЊЂ‘‘€‚}
{
	ATTR a1, a2;
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	List<ARR>* ptr = (List<ARR>*)a2.ptr;
	int i, j;

	for (i = 0; i < (*ptr).get_qntf(); i++) {
		ARR ta = (*ptr)[i];
		if (t_id[ta.id].cls) return 12; // Ї®ўв®а­®Ґ ®Ўкпў«. Ё¤Ґ­вЁдЁЄ
		List<unsigned char>* ptr1 = ta.ind_ptr;
		if ((*ptr1).get_qntf() > MAX_SIZE_ARRAY)
			return 19; // ­Ґ¤®ЇгбвЁ¬л© а §¬Ґа ¬ ббЁў 
		unsigned long size_var = 1;

		for (j = 0; j < (*ptr1).get_qntf(); j++) {
			if (!(t_i_const[(*ptr1)[j]] > 0 && t_i_const[(*ptr1)[j]] <= MAX_VAL_INDEX))
				return 20;
			(*ptr1)[j] = (unsigned char)t_i_const[(*ptr1)[j]];
			size_var *= (*ptr1)[j];
		}
		size_var *= ((a1.val[1] - 5) == 4) ? 2 : 4;
		if (size_var + cur_free_addr > 65535)
			return 18;
		// ⥯Ґам ind_ptr ᮤҐа¦Ёв бЇЁб®Є Ё­¤ҐЄб®ў ¬ ббЁў 
		// § ¤ Ґ¬ Ї а ¬Ґвал в Ў«. Ё¤Ґ­вЁдЁЄ в®а®ў
		t_id[ta.id].cls = 1; // Є« бб ЇҐаҐ¬Ґ­­ п
		t_id[ta.id].type = a1.val[1] - 5; // § ¤ Ґ¬ вЁЇ (array of int, array of float)
		t_id[ta.id].ptr.val[0] = 6; // в Ў«. ЇҐаҐ¬Ґ­­ле
		t_id[ta.id].ptr.val[1] = t_var.get_qntf(); // Ї®ап¤Є®ў. ­®¬Ґа ЇҐаҐ¬.
		// § ¤ Ґ¬ Ї а ¬Ґвал в Ў«. ЇҐаҐ¬Ґ­­ле

		ELEM_T_VAR tv;
		tv.type = t_id[ta.id].type;
		tv.attr.ptr = ptr1; // гЄ § вҐ«м ­  бЇЁб®Є Ё­¤ҐЄб®ў
		tv.size = size_var;
		tv.addr = cur_free_addr;
		tv.offs.ptr = 0;
		cur_free_addr+= tv.size;
		t_var.add(tv);

//		printf("Array ");
//		for (j = 0; j < (*ptr1).get_qntf(); j++) {
//			printf("[%i]", (*ptr1)[j]);
//		}
//		printf(" defined. SIZE = %i, ADDR = $%i\n", tv.size, tv.addr);

	}
	temp_addr = cur_free_addr;
    max_addr = cur_free_addr;
	delete ptr; // г¤ «Ёвм бЇЁб®Є ¬ ббЁў®ў
// ! “¤ «пвм бЇЁб®Є Ё­¤ҐЄб®ў Ќ…‹њ‡џ !
	return 0;
}


int op_s_list_id(SYMB& s, FILE* f, FILE* fb) // {‘Џ€‘ЋЉ_€„…Ќ’}
{
	ATTR a1, a2;
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	(*((List<unsigned char>*)a2.ptr)).add(a1.val[1]);
	return 0;
}


int op_s_def_variables(SYMB& s, FILE* f, FILE* fb)  // {Џ…ђ…Њ…ЌЌ›…}
{
	ATTR a1, a2;
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	List<unsigned char>* ptr = (List<unsigned char>*)a2.ptr;
	int i;
	for (i = 0; i < (*ptr).get_qntf(); i++) {
		unsigned char j = (*ptr)[i];
		if (t_id[j].cls)
			return 12; // Ї®ўв®а­®Ґ ®Ўкпў«. Ё¤Ґ­вЁдЁЄ
		t_id[j].cls = 1; // Є« бб ЇҐаҐ¬Ґ­­ п
		t_id[j].type = a1.val[1] - 8; // § ¤ Ґ¬ вЁЇ
		t_id[j].ptr.val[0] = 6;       // § ¤ Ґ¬ гЄ § вҐ«м ­  в Ў«Ёжг ЇҐаҐ¬.
		t_id[j].ptr.val[1] = t_var.get_qntf();
		// Ё­Ёж. в Ў«. ЇҐаҐ¬Ґ­­ле
		ELEM_T_VAR tv;
		tv.type = t_id[j].type;
		tv.size = (tv.type == 1) ? 2: 4;
		if (cur_free_addr + tv.size < cur_free_addr)
			return 18;
		tv.addr = cur_free_addr;
		cur_free_addr+= tv.size;
		tv.offs.ptr = 0;
		t_var.add(tv);
//		printf("Var (%i) defined. SIZE = %i, ADDR = $%i\n", j, tv.size, tv.addr);
	}
	temp_addr = cur_free_addr;
	max_addr = cur_free_addr;
	delete ptr; // г¤ «Ёвм бЇЁб®Є Ё§ Ї ¬пвЁ
	return 0;
}



int op_s_def_matrix(SYMB& s, FILE* f, FILE* fb)  // {ЊЂ’ђ€–Ђ}
{
	ATTR a1, a2, a3;
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	s.get_attr(2, a3);
	if (t_id[a1.val[1]].cls) return 12; // Ї®ўв®а­®Ґ ®Ўкпў«. id
	int v1, v2;
	v1 = t_i_const[a2.val[1]];
	v2 = t_i_const[a3.val[1]];
	unsigned long sz = v1 * v2 * 4 + cur_free_addr;
	if (sz > 65535)
		return 18;
	if (!((v1 > 0 && v1 <= MAX_VAL_INDEX) && (v2 > 0 && v2 <= MAX_VAL_INDEX))) {
		return 20;
	}
	t_id[a1.val[1]].cls = 1;
	t_id[a1.val[1]].type = 3; // fmatr
	t_id[a1.val[1]].ptr.val[0] = 6;
	t_id[a1.val[1]].ptr.val[1] = t_var.get_qntf();

	ELEM_T_VAR tv;
	tv.type = 3;
	tv.size = v1 * v2 * 4;
	tv.attr.val[0] = v1;
	tv.attr.val[1] = v2;
	tv.addr = cur_free_addr;
	tv.offs.ptr = 0;
	cur_free_addr+= tv.size;
	t_var.add(tv);
	temp_addr = cur_free_addr;
	max_addr = cur_free_addr;
//	printf("Matrix [%i, %i] defined. SIZE = %i, ADDR = $%i\n", v1, v2, tv.size, tv.addr);
	return 0;
}

int op_s_def_const(SYMB& s, FILE* f, FILE* fb)  // {ЉЋЌ‘’ЂЌ’Ђ}
{
	ATTR a1, a2;
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	if (t_id[a1.val[1]].cls)
		return 12; // Ї®ўв®аҐ­ЁҐ id
	t_id[a1.val[1]].cls = 2; // Є« бб Є®­бв ­в 
	t_id[a1.val[1]].ptr = a2;
	t_id[a1.val[1]].type = a2.val[0] - 3;
	temp_addr = cur_free_addr;
	max_addr = cur_free_addr;
//	printf("Defined const: id[%i, %i], val[%i, %i]\n", a1.val[0], a1.val[1], a2.val[0], a2.val[1]);
	return 0;
}


// ------------------------
// Ђђ€”Њ…’€—…‘Љ€… ЋЏ…ђЂ–€€
// ------------------------


// ‚®§ўа й Ґв вЁЇ н«Ґ¬Ґ­в  ў r: 1 - int; 2 - float; 3 - fmatr;
// Ќ  ўл室Ґ Є®¤ ®иЁЎЄЁ
int get_type(ATTR& a, char& r)
{
	if (a.val[0] == 3) {         // id
		if (!t_id[a.val[1]].cls)
			return 11;
		if (t_id[a.val[1]].cls == 3)
			return 13;
		a = t_id[a.val[1]].ptr;
	}
	if (a.val[0] == 6) {  // var
		r = t_var[a.val[1]].type;
		if (r > 3)
			return 15;
	}
	else {
		r = (a.val[0] == 4) ? 1: 2;
	}
	return 0;
}


// int -> float
int int_to_float(FILE* f, FILE* fb, unsigned char& a1, unsigned char& a2, char nd_var)
{
	ATTR at1;
	at1.val[0] = a1;
	at1.val[1] = a2;

	ELEM_T_VAR tv;
	tv.offs.ptr = 0;
	tv.type = 2;
	tv.size = 4;
	if (nd_var) {
		tv.addr = cur_free_addr;
		cur_free_addr += 4;
		if (cur_free_addr + tv.size < cur_free_addr)
			return 18;
		max_addr = (cur_free_addr > max_addr) ? cur_free_addr : max_addr;
	}
	else {
		tv.addr = t_var[a2].addr;
		cur_free_addr = tv.addr + 4;
	}
	a2 = t_var.get_qntf();
	a1 = 6;
	t_var.add(tv);

	ATTR at3 = {a1, a2}, at2 = {0, 0};
	print_atom(21, f, fb, at1, at2, at3);
	return 0;
}


int check_size_matrix_add(const ATTR& a1, const ATTR& a2)
{
	if (t_var[a1.val[1]].attr.val[0] == t_var[a2.val[1]].attr.val[0] &&
		t_var[a1.val[1]].attr.val[1] == t_var[a2.val[1]].attr.val[1])
		return 0;
	else
		return 16;
}

int check_size_matrix_mul(const ATTR& a1, const ATTR& a2)
{
	if (t_var[a1.val[1]].attr.val[1] == t_var[a2.val[1]].attr.val[0])
		return 0;
	else
		return 16;
}

unsigned int get_new_addr(ATTR a1, ATTR a2)
{
	unsigned int new_addr, addr1, addr2;
	if (a1.val[0] < 6 && a2.val[0] < 6) { // ¤®Ў®ў«пҐ¬ ўа. ЇҐаҐ¬Ґ­­го
		new_addr = cur_free_addr;
	}
	else {
		if (a1.val[0] == 6 && a2.val[0] == 6) {
			addr1 = t_var[a1.val[1]].addr;
			addr2 = t_var[a2.val[1]].addr;
			if (addr1 >= temp_addr && addr2 >= temp_addr)
				new_addr = (addr1 < addr2) ? addr1 : addr2;
			else {
				if (addr1 < temp_addr && addr2 < temp_addr)
					new_addr = cur_free_addr;
				else {
					if (addr1 < temp_addr)
						new_addr = t_var[a2.val[1]].addr;
					else
						new_addr = t_var[a1.val[1]].addr;
				}
			}
		}
		else {
			if (a1.val[0] == 6) {
				if (t_var[a1.val[1]].addr >= temp_addr)
					new_addr = t_var[a1.val[1]].addr;
				else
					new_addr = cur_free_addr;
			}
			else
				if (t_var[a2.val[1]].addr >= temp_addr)
					new_addr = t_var[a2.val[1]].addr;
				else
					new_addr = cur_free_addr;
		}
	}
	return new_addr;
}


int op_s_add(SYMB& s, FILE* f, FILE* fb)  // {+}
{
	char types_op_add[3][3] = {
		{1, 2, 0},
		{3, 4, 0},
		{0, 0, 5}
	};

	ATTR a1, a2, a3;
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	s.get_attr(2, a3);

	char nd_var1 = (a1.val[0] < 6); //|| (t_var[a1.val[1]].offs.ptr); // last
	char nd_var2 = (a2.val[0] < 6); //|| (t_var[a2.val[1]].offs.ptr);
	unsigned int n_addr = get_new_addr(a1, a2);

	char tl, tr;
	int e;
	e = get_type(a1, tl); // Ї®«гзЁвм вЁЇ «Ґў®Ј®  аЈг¬Ґ­в 
	if (e)
		return e;
	e = get_type(a2, tr); // Ї®«гзЁвм вЁЇ Їа ў®Ј®  аЈг¬Ґ­в 
	if (e)
		return e;
	e = types_op_add[tl - 1][tr - 1];
	if (!e)  // ­Ґў®§¬®¦­®бвм б«®¦Ёвм вЁЇл
		return 15;

//	char ba;

	ELEM_T_VAR tv;


	switch(e) {
		case 1:
			print_atom(0, f, fb, a1, a2, a3);
			tv.size = 2;
			break;
		case 2:
			int err = int_to_float(f, fb, a1.val[0], a1.val[1], nd_var1);
			if (err)
				return err;
			s.set_attr(2, 6, ++a3.val[1]);
			print_atom(1, f, fb, a1, a2, a3);

			ATTR pa;
			s.get_attr(1, pa);
			n_addr = get_new_addr(a1, pa);

			tv.size = 4;
			tl = 2;
			break;
		case 3:
			err = int_to_float(f, fb, a2.val[0], a2.val[1], nd_var2);
			if (err)
				return err;
			s.set_attr(2, 6, ++a3.val[1]);
			print_atom(1, f, fb, a1, a2, a3);

			s.get_attr(0, pa);
			n_addr = get_new_addr(pa, a2);

			tv.size = 4;
			tr = 2;
			break;
		case 5:
			int e1 = check_size_matrix_add(a1, a2);
			if (e1)
				return e1;
			tv.attr = t_var[a1.val[1]].attr;
			tv.size = t_var[a1.val[1]].size;
			print_atom(2, f, fb, a1, a2, a3);
			break;
		default:
			print_atom(1, f, fb, a1, a2, a3);
			tv.size = 4;
			break;
	}
	tv.type = tl;
	tv.addr = n_addr;
	if (n_addr + tv.size < n_addr)
		return 18;

	cur_free_addr = tv.addr + tv.size;
	max_addr = (cur_free_addr > max_addr) ? cur_free_addr : max_addr;
	tv.offs.ptr = 0;
	t_var.add(tv);

	return 0;
}


int op_s_sub(SYMB& s, FILE* f, FILE* fb)  // {-}
{
	char types_op_sub[3][3] = {
		{1, 2, 0},
		{3, 4, 0},
		{0, 0, 5}
	};
	ATTR a1, a2, a3;
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	s.get_attr(2, a3);

	char nd_var1 = (a1.val[0] < 6);
	char nd_var2 = (a2.val[0] < 6);
	unsigned int n_addr = get_new_addr(a1, a2);

	char tl, tr;
	int e;
	e = get_type(a1, tl); // Ї®«гзЁвм вЁЇ «Ґў®Ј®  аЈг¬Ґ­в 
	if (e)
		return e;
	e = get_type(a2, tr); // Ї®«гзЁвм вЁЇ Їа ў®Ј®  аЈг¬Ґ­в 
	if (e)
		return e;
	e = types_op_sub[tl - 1][tr - 1];

	if (!e)  // ­Ґў®§¬®¦­®бвм б«®¦Ёвм вЁЇл
		return 15;

	ELEM_T_VAR tv;
	switch(e) {
		case 1:
			print_atom(3, f, fb, a1, a2, a3);
			tv.size = 2;
			break;
		case 2:
			int err = int_to_float(f, fb, a1.val[0], a1.val[1], nd_var1);
			if (err)
				return err;
			s.set_attr(2, 6, ++a3.val[1]);
			print_atom(4, f, fb, a1, a2, a3);

			ATTR pa;
			s.get_attr(1, pa);
			n_addr = get_new_addr(a1, pa);

			tv.size = 4;
			tl = 2;
			break;
		case 3:
			err = int_to_float(f, fb, a2.val[0], a2.val[1], nd_var2);
			if (err)
				return err;
			s.set_attr(2, 6, ++a3.val[1]);
			print_atom(4, f, fb, a1, a2, a3);

			s.get_attr(0, pa);
			n_addr = get_new_addr(pa, a2);

			tv.size = 4;
			tr = 2;
			break;
		case 5:
			int e1 = check_size_matrix_add(a1, a2);
			if (e1)
				return e1;
			tv.attr = t_var[a1.val[1]].attr;
			tv.size = t_var[a1.val[1]].size;
			print_atom(5, f, fb, a1, a2, a3);
			break;
		default:
			print_atom(4, f, fb, a1, a2, a3);
			break;
	}
	tv.type = tl;
	tv.addr = n_addr;
	if (n_addr + tv.size < n_addr)
		return 18;
	cur_free_addr = tv.addr + tv.size;
	max_addr = (cur_free_addr > max_addr) ? cur_free_addr : max_addr;
	tv.offs.ptr = 0;
	t_var.add(tv);

	return 0;
}



int op_s_mul(SYMB& s, FILE* f, FILE* fb)  // {*}
{
	char types_op_mul[3][3] = {
		{1, 2, 0},
		{3, 4, 0},
		{0, 0, 5}
	};
	ATTR a1, a2, a3;
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	s.get_attr(2, a3);

	char nd_var1 = (a1.val[0] < 6);
	char nd_var2 = (a2.val[0] < 6);
	unsigned int n_addr = get_new_addr(a1, a2);

	char tl, tr;
	int e;
	e = get_type(a1, tl); // Ї®«гзЁвм вЁЇ «Ґў®Ј®  аЈг¬Ґ­в 
	if (e)
		return e;
	e = get_type(a2, tr); // Ї®«гзЁвм вЁЇ Їа ў®Ј®  аЈг¬Ґ­в 
	if (e)
		return e;
	e = types_op_mul[tl - 1][tr - 1];
	if (!e)  // ­Ґў®§¬®¦­®бвм б«®¦Ёвм вЁЇл
		return 15;

	ELEM_T_VAR tv;
	switch(e) {
		case 1:
			print_atom(6, f, fb, a1, a2, a3);
			tv.size = 2;
			break;
		case 2:
			int err = int_to_float(f, fb, a1.val[0], a1.val[1], nd_var1);
			if (err)
				return err;
			s.set_attr(2, 6, ++a3.val[1]);

			ATTR pa;
			s.get_attr(1, pa);
			n_addr = get_new_addr(a1, pa);

			print_atom(7, f, fb, a1, a2, a3);
			tv.size = 4;
			tl = 2;
			break;
		case 3:
			err = int_to_float(f, fb, a2.val[0], a2.val[1], nd_var2);
			if (err)
				return err;
			s.set_attr(2, 6, ++a3.val[1]);

			s.get_attr(0, pa);
			n_addr = get_new_addr(pa, a2);

			print_atom(7, f, fb, a1, a2, a3);
			tv.size = 4;
			tr = 2;
			break;
		case 5:
			int e1 = check_size_matrix_mul(a1, a2);
			if (e1)
				return e1;

			int n = t_var[a1.val[1]].attr.val[0];
			int m = t_var[a2.val[1]].attr.val[1];
			tv.attr.val[0] = n;
			tv.attr.val[1] = m;
			tv.size = n * m * 4;
			n_addr = cur_free_addr;
			print_atom(8, f,fb,  a1, a2, a3);
			break;
		default:
			print_atom(7, f, fb, a1, a2, a3);
			tv.size = 4;
			break;
	}
	tv.type = tl;
	tv.addr = n_addr;
	if (n_addr + tv.size < n_addr)
		return 18;
	cur_free_addr = tv.addr + tv.size;
	max_addr = (cur_free_addr > max_addr) ? cur_free_addr : max_addr;
	tv.offs.ptr = 0;
	t_var.add(tv);

	return 0;
}



int op_s_div(SYMB& s, FILE* f, FILE* fb)  // {/}
{
	char types_op_div[3][3] = {
		{1, 2, 0},
		{3, 4, 0},
		{0, 0, 0}
	};
	ATTR a1, a2, a3;
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	s.get_attr(2, a3);

	char nd_var1 = (a1.val[0] < 6);
	char nd_var2 = (a2.val[0] < 6);
	unsigned int n_addr = get_new_addr(a1, a2);

	char tl, tr;
	int e;
	e = get_type(a1, tl); // Ї®«гзЁвм вЁЇ «Ґў®Ј®  аЈг¬Ґ­в 
	if (e)
		return e;
	e = get_type(a2, tr); // Ї®«гзЁвм вЁЇ Їа ў®Ј®  аЈг¬Ґ­в 
	if (e)
		return e;
	e = types_op_div[tl - 1][tr - 1];
	if (!e)  // ­Ґў®§¬®¦­®бвм б«®¦Ёвм вЁЇл
		return 15;

	ELEM_T_VAR tv;
	switch(e) {
		case 1:
			print_atom(9, f, fb, a1, a2, a3);
			tv.size = 2;
			break;
		case 2:
			int err = int_to_float(f, fb, a1.val[0], a1.val[1], nd_var1);
			if (err)
				return err;
			s.set_attr(2, 6, ++a3.val[1]);

			ATTR pa;
			s.get_attr(1, pa);
			n_addr = get_new_addr(a1, pa);

			print_atom(10, f, fb, a1, a2, a3);
			tv.size = 4;
			tl = 2;
			break;
		case 3:
			err = int_to_float(f, fb, a2.val[0], a2.val[1], nd_var2);
			if (err)
				return err;
			s.set_attr(2, 6, ++a3.val[1]);

			s.get_attr(0, pa);
			n_addr = get_new_addr(pa, a2);

			print_atom(10, f, fb, a1, a2, a3);
			tv.size = 4;
			tr = 2;
			break;
		default:
			print_atom(10, f, fb, a1, a2, a3);
			tv.size = 4;
			break;
	}
	tv.type = tl;
	tv.addr = n_addr;
	if (n_addr + tv.size < n_addr)
		return 18;
	cur_free_addr = tv.addr + tv.size;
	max_addr = (cur_free_addr > max_addr) ? cur_free_addr : max_addr;
	tv.offs.ptr = 0;
	t_var.add(tv);

	return 0;
}



int op_s_det(SYMB& s, FILE* f, FILE* fb) // {„…’}
{
	ATTR a1, a2, a3 = {0, 0};
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	char to;
	char nd_var = (a1.val[0] < 6);
	int e = get_type(a1, to);
	if (e)
		return e;
	if (to != 3) // ­Ґ ¬ ваЁж 
		return 15;
	if (t_var[a1.val[1]].attr.val[0] != t_var[a1.val[1]].attr.val[1])
		return 16; // Ґб«Ё ¬ ваЁж  ­Ґ Єў ¤а в­ п
	print_atom(19, f, fb, a1, a3, a2);

	ELEM_T_VAR tv;

	tv.size = 4;
	tv.type = 2;
	if (nd_var) {
		if (cur_free_addr + tv.size < cur_free_addr)
			return 18;
		tv.addr = cur_free_addr;
	}
	else
		tv.addr = t_var[a1.val[1]].addr;

	cur_free_addr = tv.addr + tv.size;
	max_addr = (cur_free_addr > max_addr) ? cur_free_addr : max_addr;
	tv.offs.ptr = 0;
	t_var.add(tv);

	return 0;
}


int op_s_transpose(SYMB& s, FILE* f, FILE* fb) // {’ђЂЌ‘ЏЋЌ€ђ}
{
	ATTR a1, a2, a3 = {0, 0};
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	char to;
	int e = get_type(a1, to);
	if (e)
		return e;
	if (to != 3) // ­Ґ ¬ ваЁж 
		return 15;
	print_atom(20, f, fb, a1, a3, a2);

	ELEM_T_VAR tv;
	tv.type = 3;
	tv.addr = cur_free_addr;
	tv.size = t_var[a1.val[1]].size;
	if (cur_free_addr + tv.size < cur_free_addr)
		return 18;
	cur_free_addr += tv.size;
	max_addr = (cur_free_addr > max_addr) ? cur_free_addr : max_addr;
	tv.attr.val[0] = t_var[a1.val[1]].attr.val[1];
	tv.attr.val[1] = t_var[a1.val[1]].attr.val[0];
	tv.offs.ptr = 0;
	t_var.add(tv);

	return 0;
}


int op_s_set_vars(SYMB& s, FILE* f, FILE* fb) // {=}
{
	char types_op_eq[3][3] = {{1, 0, 0}, {4, 2, 0}, {0, 0, 3}};
	ATTR a1, a2, a3 = {0, 0};
	s.get_attr(0, a1);
	s.get_attr(1, a2);

	char nd_var = (a2.val[0] < 6);
	char e, t1, t2;
	e = get_type(a1, t1);
	if (e)
		return e;
	if (a1.val[0] < 6)
		return 14;
	e = get_type(a2, t2);
	if (e)
		return e;
	e = types_op_eq[t1 - 1][t2 - 1];
	if (!e)
		return 10;
	if (e == 3)
		if (!(t_var[a1.val[1]].attr.val[0] == t_var[a2.val[1]].attr.val[0] &&
			t_var[a1.val[1]].attr.val[1] == t_var[a2.val[1]].attr.val[1]))
			return 21;
	if (e == 4) {
		int err = int_to_float(f, fb, a2.val[0], a2.val[1], nd_var);
		if (err)
			return err;
		e = 2;
	}
	print_atom(e + 27, f, fb, a1, a2, a3);

	cur_free_addr = temp_addr;

	return 0;
}



int op_s_ratio(SYMB& s, FILE* f, FILE* fb, char nba)
{
	char types_op_ratio[2][2] = {{1, 2}, {3, 4}};
	ATTR a1, a2, a3;
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	s.get_attr(2, a3);

	char nd_var1 = (a1.val[0] < 6);
	char nd_var2 = (a2.val[0] < 6);
	unsigned int n_addr = get_new_addr(a1, a2);

	char tl, tr;
	int e;
	e = get_type(a1, tl);
	if (e)
		return e;
	e = get_type(a2, tr);
	if (e)
		return e;
	if (tl == 3 || tr == 3)
		return 15;
	e = types_op_ratio[tl - 1][tr - 1];

	if (e == 1) {
		print_atom(nba, f, fb, a1, a2, a3);
	}
	else {
		if (e == 2) {
			int err = int_to_float(f, fb, a1.val[0], a1.val[1], nd_var1);
			if (err)
				return err;
			s.set_attr(2, 6, ++a3.val[1]);

			ATTR pa;
			s.get_attr(1, pa);
			n_addr = get_new_addr(a1, pa);
		}
		if (e == 3) {
			int err = int_to_float(f, fb, a2.val[0], a2.val[1], nd_var2);
			if (err)
				return err;
			s.set_attr(2, 6, ++a3.val[1]);

			ATTR pa;
			s.get_attr(0, pa);
			n_addr = get_new_addr(pa, a2);
		}
		print_atom(nba + 1, f, fb, a1, a2, a3);
	}

	ELEM_T_VAR tv;
	tv.size = 2;
	tv.addr = n_addr;
	if (n_addr + tv.size < n_addr)
		return 18;
	cur_free_addr = tv.addr + tv.size;
	max_addr = (cur_free_addr > max_addr) ? cur_free_addr : max_addr;
	tv.type = 1;
	tv.offs.ptr = 0;
	t_var.add(tv);

	return 0;
}


int op_s_not_equal(SYMB& s, FILE* f, FILE* fb)  // {!=}
{
	return (op_s_ratio(s, f, fb, 13));
}


int op_s_equal_equal(SYMB& s, FILE* f, FILE* fb) // {==}
{
	return (op_s_ratio(s, f, fb, 11));
}


int op_s_less(SYMB& s, FILE* f, FILE* fb) // {<}
{
	return (op_s_ratio(s, f, fb, 15));
}

int op_s_less_equal(SYMB& s, FILE* f, FILE* fb) // {<=}
{
	return (op_s_ratio(s, f, fb, 17));
}



// ------------------------------------
//             Џ…ђ…Њ…ЌЌ›…
// ------------------------------------

int op_s_list_attr(SYMB& s, FILE* f, FILE* fb)
{
	ATTR a1, a2;
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	(*((List<ATTR>*)a2.ptr)).add(a1);
	return 0;
}


unsigned char add_to_t_f_const(float val)
{
	int find = 0;
	unsigned char k = 0;
	while (k < t_f_const.get_qntf() && !find) {
		find = (t_f_const[k++] == val);
	}
	if (find)
		k--;
	else
		t_f_const.add(val); // ¤®Ў®ў«пҐ¬ ­®ўго Є®­бв ­вг
	return k;
}


unsigned char add_to_t_i_const(int val)
{
	int find = 0;
	unsigned char k = 0;
	while (k < t_i_const.get_qntf() && !find) {
		find = (t_i_const[k++] == val);
	}
	if (find)
		k--;
	else
		t_i_const.add(val); // ¤®Ў®ў«пҐ¬ ­®ўго Є®­бв ­вг
	return k;
}


int op_s_elem_arr(SYMB& s, FILE* f, FILE* fb)
{
	ATTR a1, a2;
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	if (!t_id[a1.val[1]].cls)
		return 11;
	if (t_id[a1.val[1]].cls != 1)
		return 13;
	if (t_id[a1.val[1]].type < 4) // ­Ґ ¬ ббЁў
		return 15;
	List<ATTR>* ptrl = (List<ATTR>*)a2.ptr;
	List<unsigned char>* ptra = (List<unsigned char>*)t_var[t_id[a1.val[1]].ptr.val[1]].attr.ptr;
	if ((*ptrl).get_qntf() != (*ptra).get_qntf())
		return 17; // ­Ґб®®вўҐвбвўЁҐ а §¬Ґа­®б⥩ ¬ ббЁў 
	int i, j;
	char e, r;
	for (i = 0; i < (*ptrl).get_qntf(); i++) {
		e = get_type((*ptrl)[i], r);
		if (e)
			return e;
		if (r != 1) // Ё­¤ҐЄб ­Ґ int
			return 20;
	}

	ATTR old_var;

	for (i = 0; i < (*ptrl).get_qntf(); i++) {
		int offs = 1;
		for (j = i + 1; j < (*ptra).get_qntf(); j++)
			offs *= (*ptra)[j];
		offs *= (t_id[a1.val[1]].type == 4) ? 2: 4;
// ЁйҐ¬ Є®­бв ­вг ў в Ў«. 楫ле Є®­бв ­в
		unsigned char k = add_to_t_i_const(offs);

		SYMB ts;
		ts.set_attr(0, (*ptrl)[i].val[0], (*ptrl)[i].val[1]);
		ts.set_attr(1, 4, k);
		ts.set_attr(2, 6, t_var.get_qntf());
		int err = op_s_mul(ts, f, fb); // г¬­®¦ Ґ¬ i-© Ё­¤ҐЄб ­  ᬥ饭ЁҐ ў ¬ ббЁўҐ
		if (err)
			return err;

		ATTR cur_var;
		ts.get_attr(2, cur_var);

		if (i) {
			ts.set_attr(0, old_var);
			ts.set_attr(1, cur_var);
			ts.set_attr(2, 6, t_var.get_qntf());
			int err = op_s_add(ts, f, fb);
			if (err)
				return err;
		}
		ts.get_attr(2, old_var);
	}
// ⥯Ґам old_var ᮤҐа¦Ёв  ваЁЎгвл ЇҐаҐ¬Ґ­­®© ᬥ饭Ёп

	ELEM_T_VAR av;
	av.type = t_id[a1.val[1]].type - 3;
	av.size = (av.type == 1) ? 2 : 4;
	av.addr = t_var[t_id[a1.val[1]].ptr.val[1]].addr;
	av.offs = old_var;
	t_var.add(av);
	s.set_attr(2, 6, t_var.get_qntf() - 1);

	delete ptrl; // г¤ «Ёвм бЇЁб®Є Ё­¤ҐЄб®ў
	return 0;
}


int op_s_elem_matr(SYMB& s, FILE* f, FILE* fb)
{
	ATTR a1, a2, a3;
	s.get_attr(0, a1);
	s.get_attr(1, a2);
	s.get_attr(2, a3);
	char e, t;
	e = get_type(a1, t);
	if (e)
		return e;
	if (t != 3) // ­Ґ ¬ ваЁж 
		return 15;

	e = get_type(a2, t);
	if (e)
		return e;
	if (t != 1) // Ё­¤ҐЄб ­Ґ int
		return 20;
	e = get_type(a3, t);
	if (e)
		return e;
	if (t != 1)  // Ё­¤ҐЄб ­Ґ int
		return 20;

	unsigned int offs = t_var[a1.val[1]].attr.val[1] * 4;
	unsigned char k;
	k = add_to_t_i_const(offs);

	SYMB ts;
	ts.set_attr(0, a2);
	ts.set_attr(1, 4, k);
	ts.set_attr(2, 6, t_var.get_qntf());
	op_s_mul(ts, f, fb); // г¬­®¦ Ґ¬ 1-© Ё­¤ҐЄб ­  ᬥ饭ЁҐ ў ¬ ббЁўҐ

	ATTR ta1;
	ts.get_attr(2, ta1);

	k = add_to_t_i_const(4);
	ts.set_attr(0, a3);
	ts.set_attr(1, 4, k);
	ts.set_attr(2, 6, t_var.get_qntf());
	int err = op_s_mul(ts, f, fb); // г¬­®¦ Ґ¬ 2-© Ё­¤ҐЄб ­  4
	if (err)
		return err;

	ATTR ta2;
	ts.get_attr(2, ta2);

	ts.set_attr(0, ta1);
	ts.set_attr(1, ta2);
	ts.set_attr(2, 6, t_var.get_qntf());
	err = op_s_add(ts, f, fb);
	if (err)
		return err;

	ts.get_attr(2, ta2);

	ELEM_T_VAR av;
	av.type = 2;
	av.size = 4;
	av.addr = t_var[a1.val[1]].addr; //  ¤аҐбб ¬ ваЁжл
	av.offs = ta2; // § ¤ Ґ¬ ᬥ饭ЁҐ
	t_var.add(av);

	s.set_attr(3, 6, t_var.get_qntf() - 1);

	return 0;
}


// ------------------------------------------------------------------
// ”г­ЄжЁЁ ўлзЁб«Ґ­Ёп ᨭ⥧Ёа®ў ­­ле  ваЁЎгв®ў ®ЇҐа жЁ®­­ле бЁ¬ў®«®ў
// ------------------------------------------------------------------

ATTR new_list_id() //
{
	List<unsigned char>* ptr = new (List<unsigned char>);
	ATTR t;
	t.ptr = ptr;
//	printf("created list_id, ADDR = %p\n", ptr);
	return t;
}

ATTR new_list_arr() // {ЌЋ‚_‘Џ€‘ЋЉ_ЊЂ‘‘}
{
	List<ARR>* ptr = new(List<ARR>);
	ATTR ta;
	ta.ptr = ptr;
//	printf("created list_arr, ADDR = %p\n", ptr);
	return ta;
}

ATTR new_list_attr()
{
	List<ATTR>* ptr = new(List<ATTR>);
	ATTR ta;
	ta.ptr = ptr;
	return ta;
}

ATTR new_mark() // {ЌЋ‚Њ…’}
{
	ATTR ta;
	ta.val[0] = 7;
	ta.val[1] = t_mark.get_qntf();
	return ta;
}


ATTR new_element() // ЌЋ‚ќ‹’
{
	ATTR ta;
	ta.val[0] = 6;
	ta.val[1] = t_var.get_qntf();
	return ta;
}


// Њ ббЁў ᥬ ­вЁзҐбЄЁе дг­ЄжЁ©
const char n_fun_ops = 28;
int (*arr_fun_ops[n_fun_ops])(SYMB&, FILE*, FILE*) = {
op_s_mark,
op_s_goto,
op_s_in,
op_s_out,
op_s_list_arr,
op_s_list_id,
op_s_def_array,
op_s_def_variables,
op_s_def_matrix,
op_s_def_const,
op_s_init_mark,
op_s_add_vmark,
op_s_add_mark,
op_s_jmpf,
op_s_add,
op_s_sub,
op_s_mul,
op_s_div,
op_s_transpose,
op_s_det,
op_s_set_vars,
op_s_not_equal,
op_s_equal_equal,
op_s_less,
op_s_less_equal,
op_s_list_attr,
op_s_elem_arr,
op_s_elem_matr
};


// Њ ббЁў дг­ЄжЁ© ўлзЁб«Ґ­Ёп ᨭ⥧Ёа®ў ­­ле  ваЁЎгв®ў ®ЇҐа жЁ®­­ле бЁ¬ў®«®ў
const char n_fun_synth_attr = 5;
ATTR (*arr_fun_synth_attr[n_fun_synth_attr])() = {
new_list_id,
new_list_arr,
new_mark,
new_element,
new_list_attr
};


#endif
Соседние файлы в папке kurs