Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Курсовая работа. Вариант 16 / kurs / SEM_OPER
.CPP#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