📄 chksupport.cpp
字号:
#ifndef __CHKSUPPORT_CPP__
#define __CHKSUPPORT_CPP__
#include <cstdio>
#include <iostream>
#include <algorithm>
#include "common.cpp"
#include "CHKsymtable.cpp"
#include "IDHash.cpp"
extern int PROGRAM_LineNumber;
extern char* PROGRAM_FileName;
struct Tmsg {
int lineno;
int sourcecount;
string msgtxt;
};
vector <Tmsg> error_msgs;
void errormsg(int code, string str1, string str2, string str3);
bool compare_msg(const Tmsg& k1, const Tmsg& k2);
int errormsg_print();
string __int2str(int num);
string __vartype2str(int var_type);
string __vartype2str(TSymbolListVariableEntry& Ventry);
void errormsg(int code, int lineno, string str1 = "UNKNOWN", string str2 = "UNKNOWN", string str3 = "UNKNOWN")
{
string str = "";
for (int i = 0; error_message[code][i]; i++)
{
if (error_message[code][i] == '%')
{
i ++;
switch (error_message[code][i])
{
case '1' : str += str1;
break;
case '2' : str += str2;
break;
case '3' : str += str3;
break;
default : str += error_message[code][i];
}
}
else
{
str += error_message[code][i];
}
}
Tmsg tmpmsg;
tmpmsg.lineno = lineno;
tmpmsg.msgtxt = str;
tmpmsg.sourcecount = error_msgs.size();
error_msgs.push_back(tmpmsg);
}
bool compare_msg(const Tmsg& k1, const Tmsg& k2)
{
if (k1.lineno != k2.lineno)
{
return (k1.lineno < k2.lineno);
}
else
{
return (k1.sourcecount < k2.sourcecount);
}
}
int errormsg_print()
{
sort(error_msgs.begin(), error_msgs.end(), compare_msg);
for (unsigned int i = 0; i < error_msgs.size(); i++)
{
cout << PROGRAM_FileName << ":" << error_msgs[i].lineno << ": Compilation Error " << error_msgs[i].msgtxt << endl;
}
if (error_msgs.size() == 0)
{
return 1;
}
else
{
return 0;
}
}
string __int2str(int num)
{
char s[20];
sprintf(s, "%d", num);
return s;
}
string __vartype2str(int var_type)
{
string res = "null type";
if (var_type == var_type_void) res = "void";
else if (var_type == var_type_int) res = "int";
else if (var_type == var_type_bool) res = "bool";
else if (var_type == var_type_double) res = "double";
else if (var_type == var_type_char) res = "char";
else if (var_type == var_type_notfound) res = "unknown type";
else if (SymbolListType[var_type].type_number == type_number_struct) res = "struct " + IDHash_int2ID(var_type);
else if (SymbolListType[var_type].type_number == type_number_pointer) res = __vartype2str(SymbolListType[var_type].ret_type_id) + "*";
else if (SymbolListType[var_type].type_number == type_number_function)
{
res = __vartype2str(SymbolListType[var_type].ret_type_id) + "()(";
for (list <TSymbolListVariableEntry> :: iterator p = SymbolListType[var_type].field_var.begin(); p != SymbolListType[var_type].field_var.end(); p ++)
{
if (p != SymbolListType[var_type].field_var.begin())
{
res += ",";
}
res += __vartype2str(p->var_type);
}
res += ")";
}
else if (SymbolListType[var_type].type_number == type_number_array)
{
res = __vartype2str(SymbolListType[var_type].ret_type_id);
int i = res.length();
for ( ; i >= 0; i --)
{
if ((i == (int)res.length() || res[i] == '[') && res[i - 1] != ']') break;
}
char buf[20];
sprintf(buf, "[%d]", SymbolListType[var_type].array_size);
res.insert(i, buf);
}
return res;
}
string __vartype2str(TSymbolListVariableEntry& Ventry)
{
return __vartype2str(Ventry.var_type);
}
int __chk_bool_type(TSymbolListVariableEntry& Ventry)
{
return (Ventry.var_type == var_type_bool || Ventry.var_type == var_type_int || Ventry.var_type == var_type_char ||
Ventry.var_type >= 0 && SymbolListType[Ventry.var_type].type_number == type_number_pointer ||
Ventry.var_type >= 0 && SymbolListType[Ventry.var_type].type_number == type_number_function);
}
int __chk_int_type(TSymbolListVariableEntry& Ventry)
{
return (Ventry.var_type == var_type_bool || Ventry.var_type == var_type_int || Ventry.var_type == var_type_char ||
Ventry.var_type >= 0 && SymbolListType[Ventry.var_type].type_number == type_number_pointer ||
Ventry.var_type >= 0 && SymbolListType[Ventry.var_type].type_number == type_number_function);
}
int __chk_comparable_type(TSymbolListVariableEntry& var)
{
return (__chk_int_type(var));
}
int __chk_logical_type(TSymbolListVariableEntry& var)
{
return (__chk_bool_type(var));
}
int __chk_calculational_type(TSymbolListVariableEntry& var)
{
return (__chk_int_type(var));
}
void CheckExprBinaryRelational(TSymbolListVariableEntry& var1, TSymbolListVariableEntry& var2, int op_type, TSymbolListVariableEntry& var)
{
var.var_type = var_type_bool;
var.const_sign = 0;
var.lvalue = 0;
if (var1.var_type == var_type_notfound || var2.var_type == var_type_notfound) return;
if (op_type == SRC_relational_EQL || op_type == SRC_relational_NEQ)
{
if (__chk_bool_type(var1) && __chk_bool_type(var2))
{
var.var_type = var_type_bool;
var.const_sign = 0;
var.lvalue = 0;
return;
}
}
if (op_type == SRC_relational_LES || op_type == SRC_relational_LEQ || op_type == SRC_relational_GTR || op_type == SRC_relational_GEQ ||
op_type == SRC_relational_EQL || SRC_relational_NEQ)
{
if ((var1.var_type >= 0 && SymbolListType[var1.var_type].type_number == type_number_pointer || var1.var_type == var_type_NULL) &&
(var2.var_type >= 0 && SymbolListType[var2.var_type].type_number == type_number_pointer || var2.var_type == var_type_NULL))
{
var.var_type = var_type_bool;
var.const_sign = 0;
var.lvalue = 0;
return;
}
}
if (!__chk_comparable_type(var1) || !__chk_comparable_type(var2))
{
errormsg(7, PROGRAM_LineNumber, __vartype2str(var1), SRC_OP_name[op_type], __vartype2str(var2));
// var.var_type = var_type_notfound;
return;
}
var.var_type = var_type_bool;
var.lvalue = 0;
var.const_sign = 0;
}
void CheckExprBinaryLogical(TSymbolListVariableEntry& var1, TSymbolListVariableEntry& var2, int op_type, TSymbolListVariableEntry& var)
{
var.var_type = var_type_bool;
var.const_sign = 0;
var.lvalue = 0;
if (var1.var_type == var_type_notfound || var2.var_type == var_type_notfound) return;
if (!__chk_logical_type(var1) || !__chk_logical_type(var2))
{
errormsg(7, PROGRAM_LineNumber, __vartype2str(var1), SRC_OP_name[op_type], __vartype2str(var2));
// var.var_type = var_type_notfound;
return;
}
var.var_type = var_type_bool;
var.const_sign = 0;
var.lvalue = 0;
}
void CheckPerformBinaryCalc(TSymbolListVariableEntry& var1, TSymbolListVariableEntry& var2, int op_type, TSymbolListVariableEntry& var)
{
var.var_type = var_type_int;
var.const_sign = 1;
var.lvalue = 0;
if (op_type == SRC_calculational_ADD) var.const_val = var1.const_val + var2.const_val;
else if (op_type == SRC_calculational_MINUS) var.const_val = var1.const_val - var2.const_val;
else if (op_type == SRC_calculational_MUL) var.const_val = var1.const_val * var2.const_val;
else if (op_type == SRC_calculational_DIV)
{
if (var2.const_val == 0)
{
errormsg(37, PROGRAM_LineNumber);
var.var_type = var_type_notfound;
var.const_sign = 0;
return;
}
var.const_val = var1.const_val / var2.const_val;
}
else if (op_type == SRC_calculational_MOD)
{
if (var2.const_val == 0)
{
errormsg(37, PROGRAM_LineNumber);
var.var_type = var_type_notfound;
var.const_sign = 0;
return;
}
var.const_val = var1.const_val % var2.const_val;
}
else if (op_type == SRC_calculational_AND) var.const_val = var1.const_val & var2.const_val;
else if (op_type == SRC_calculational_OR) var.const_val = var1.const_val | var2.const_val;
else if (op_type == SRC_calculational_XOR) var.const_val = var1.const_val ^ var2.const_val;
else if (op_type == SRC_calculational_SHL) var.const_val = var1.const_val << var2.const_val;
else if (op_type == SRC_calculational_SHR) var.const_val = var1.const_val >> var2.const_val;
}
void CheckExprBinaryCalculational(TSymbolListVariableEntry& var1, TSymbolListVariableEntry& var2, int op_type, TSymbolListVariableEntry& var)
{
var.var_type = var_type_notfound;
var.const_sign = 0;
var.lvalue = 0;
if (var1.var_type == var_type_notfound || var2.var_type == var_type_notfound) return;
if (op_type == SRC_calculational_ADD || op_type == SRC_calculational_MINUS)
{
if (var1.var_type >= 0 &&
(SymbolListType[var1.var_type].type_number == type_number_pointer || SymbolListType[var1.var_type].type_number == type_number_array) &&
__chk_int_type(var2))
{
var = var1;
if (SymbolListType[var.var_type].type_number == type_number_array)
{
var.var_type = SymbolListTypeADDStar(SymbolListType[var.var_type].ret_type_id);
}
var.lvalue = 0; var.const_sign = 0;
return;
}
}
if (!__chk_calculational_type(var1) || !__chk_calculational_type(var2))
{
errormsg(7, PROGRAM_LineNumber, __vartype2str(var1), SRC_OP_name[op_type], __vartype2str(var2));
var.var_type = var_type_notfound;
return;
}
if (op_type == SRC_calculational_MOD && (!__chk_int_type(var1) || !__chk_int_type(var2)))
{
errormsg(7, PROGRAM_LineNumber, __vartype2str(var1), SRC_OP_name[op_type], __vartype2str(var2));
var.var_type = var_type_notfound;
return;
}
if (var1.const_sign && var2.const_sign)
{
CheckPerformBinaryCalc(var1, var2, op_type, var);
return;
}
var.var_type = var_type_int;
var.const_sign = 0;
var.lvalue = 0;
}
void CheckExprUnaryNOT(TSymbolListVariableEntry& var1, int op_type, TSymbolListVariableEntry& var)
{
var.var_type = var_type_int;
var.const_sign = 0;
var.lvalue = 0;
if (var1.var_type == var_type_notfound) return;
if (!__chk_logical_type(var1) && !__chk_int_type(var1))
{
errormsg(8, PROGRAM_LineNumber, SRC_OP_name[op_type], __vartype2str(var1));
// var.var_type = var_type_notfound;
return;
}
var.var_type = var1.var_type;
var.lvalue = 0;
if (var1.const_sign)
{
var.const_sign = 0;
var1.const_val = !var.const_val;
}
else
{
var.const_sign = 0;
}
}
void CheckExprUnaryLogical(TSymbolListVariableEntry& var1, int op_type, TSymbolListVariableEntry& var)
{
var.var_type = var_type_bool;
var.const_sign = 0;
var.lvalue = 0;
if (var1.var_type == var_type_notfound) return;
if (!__chk_logical_type(var1))
{
errormsg(8, PROGRAM_LineNumber, SRC_OP_name[op_type], __vartype2str(var1));
// var.var_type = var_type_notfound;
return;
}
var.var_type = var_type_bool;
var.const_sign = 0;
var.lvalue = 0;
}
void CheckPerformUnaryCalc(TSymbolListVariableEntry& var1, int op_type, TSymbolListVariableEntry& var)
{
var.var_type = var_type_int;
var.const_sign = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -