upd: include exception info in return value

This commit is contained in:
2023-11-10 08:43:57 +08:00
parent fb9acd28bf
commit 169969dc8a
5 changed files with 103 additions and 91 deletions

View File

@ -14,24 +14,30 @@
class InterpretException : public std::exception { class InterpretException : public std::exception {
public: public:
InterpretException() {} InterpretException() {}
InterpretException(const char *message) : m_message(message) {} InterpretException(const char *__message, int __code)
: message(__message), code(__code) {}
const char *what() const noexcept override { return m_message; } const char *what() const noexcept override { return message.c_str(); }
const int GetCode() const noexcept { return code; }
~InterpretException() noexcept override {} ~InterpretException() noexcept override {}
private: private:
const char *m_message; std::string message;
int code;
}; };
class FatalError : public std::exception { class FatalError : public std::exception {
public: public:
FatalError(const char *message) : m_message(message) {} FatalError(const char *__message, int __code)
: message(__message), code(__code) {}
const char *what() const noexcept override { return m_message; } const char *what() const noexcept override { return message.c_str(); }
const int GetCode() const noexcept { return code; }
private: private:
const char *m_message; std::string message;
int code;
}; };
enum FlowControlStatusType { BREAK, CONTINUE, RETURN }; enum FlowControlStatusType { BREAK, CONTINUE, RETURN };
struct FlowType { struct FlowType {

View File

@ -80,7 +80,8 @@ std::any EvalVisitor::visitExpr_stmt(Python3Parser::Expr_stmtContext *ctx) {
if (!ptr_var && !ptr_vec) if (!ptr_var && !ptr_vec)
throw InterpretException( throw InterpretException(
"visitExpr_stmt: Expect left value or tuple at the left of " "visitExpr_stmt: Expect left value or tuple at the left of "
"augassign"); "augassign",
1);
if (ptr_var) { if (ptr_var) {
std::any old_val = DeQuate(*ptr_var, Variables); std::any old_val = DeQuate(*ptr_var, Variables);
if (ctx->augassign()->ADD_ASSIGN()) if (ctx->augassign()->ADD_ASSIGN())
@ -96,17 +97,17 @@ std::any EvalVisitor::visitExpr_stmt(Python3Parser::Expr_stmtContext *ctx) {
else if (ctx->augassign()->MOD_ASSIGN()) else if (ctx->augassign()->MOD_ASSIGN())
SelfMod(old_val, right_value); SelfMod(old_val, right_value);
else else
throw FatalError("visitExpr_stmt: Unknown operator at augassign"); throw FatalError("visitExpr_stmt: Unknown operator at augassign", 2);
Variables.WriteVariable(ptr_var->name, old_val); Variables.WriteVariable(ptr_var->name, old_val);
} else { } else {
if (ptr_vec->size() != if (ptr_vec->size() !=
std::any_cast<std::vector<std::any>>(right_value).size()) std::any_cast<std::vector<std::any>>(right_value).size())
throw InterpretException("visitExpr_stmt: Tuple size not match"); throw InterpretException("visitExpr_stmt: Tuple size not match", 3);
for (int i = 0; i < ptr_vec->size(); i++) { for (int i = 0; i < ptr_vec->size(); i++) {
ptr_var = std::any_cast<RawVarible>(&(*ptr_vec)[i]); ptr_var = std::any_cast<RawVarible>(&(*ptr_vec)[i]);
if (!ptr_var) if (!ptr_var)
throw InterpretException( throw InterpretException(
"visitExpr_stmt: Expect left value at the left of augassign"); "visitExpr_stmt: Expect left value at the left of augassign", 4);
std::any old_val = DeQuate(*ptr_var, Variables); std::any old_val = DeQuate(*ptr_var, Variables);
if (ctx->augassign()->ADD_ASSIGN()) if (ctx->augassign()->ADD_ASSIGN())
SelfAdd(old_val, SelfAdd(old_val,
@ -127,7 +128,7 @@ std::any EvalVisitor::visitExpr_stmt(Python3Parser::Expr_stmtContext *ctx) {
SelfMod(old_val, SelfMod(old_val,
std::any_cast<std::vector<std::any>>(right_value)[i]); std::any_cast<std::vector<std::any>>(right_value)[i]);
else else
throw FatalError("visitExpr_stmt: Unknown operator at augassign"); throw FatalError("visitExpr_stmt: Unknown operator at augassign", 5);
Variables.WriteVariable(ptr_var->name, old_val); Variables.WriteVariable(ptr_var->name, old_val);
} }
} }
@ -146,31 +147,32 @@ std::any EvalVisitor::visitExpr_stmt(Python3Parser::Expr_stmtContext *ctx) {
else if (ptr_dest_tuple) { else if (ptr_dest_tuple) {
if (ptr_dest_tuple->size() != if (ptr_dest_tuple->size() !=
std::any_cast<std::vector<std::any>>(val).size()) std::any_cast<std::vector<std::any>>(val).size())
throw InterpretException("visitExpr_stmt: Tuple size not match"); throw InterpretException("visitExpr_stmt: Tuple size not match", 6);
for (int j = 0; j < ptr_dest_tuple->size(); j++) { for (int j = 0; j < ptr_dest_tuple->size(); j++) {
ptr_dest_single = std::any_cast<RawVarible>(&(*ptr_dest_tuple)[j]); ptr_dest_single = std::any_cast<RawVarible>(&(*ptr_dest_tuple)[j]);
if (!ptr_dest_single) if (!ptr_dest_single)
throw InterpretException( throw InterpretException(
"visitExpr_stmt: Expect left value at the left of assign"); "visitExpr_stmt: Expect left value at the left of assign", 7);
Variables.WriteVariable(ptr_dest_single->name, Variables.WriteVariable(ptr_dest_single->name,
std::any_cast<std::vector<std::any>>(val)[j]); std::any_cast<std::vector<std::any>>(val)[j]);
} }
} else } else
throw InterpretException( throw InterpretException(
"visitExpr_stmt: Expect left value or tuple at the left of assign"); "visitExpr_stmt: Expect left value or tuple at the left of assign",
8);
} }
return NoneType(); return NoneType();
} }
std::any EvalVisitor::visitAugassign(Python3Parser::AugassignContext *ctx) { std::any EvalVisitor::visitAugassign(Python3Parser::AugassignContext *ctx) {
throw FatalError("Function visitAugassign Shouldn't be called"); throw FatalError("Function visitAugassign Shouldn't be called", 9);
} }
std::any EvalVisitor::visitFlow_stmt(Python3Parser::Flow_stmtContext *ctx) { std::any EvalVisitor::visitFlow_stmt(Python3Parser::Flow_stmtContext *ctx) {
if (ctx->break_stmt()) return visitBreak_stmt(ctx->break_stmt()); if (ctx->break_stmt()) return visitBreak_stmt(ctx->break_stmt());
if (ctx->continue_stmt()) return visitContinue_stmt(ctx->continue_stmt()); if (ctx->continue_stmt()) return visitContinue_stmt(ctx->continue_stmt());
if (ctx->return_stmt()) return visitReturn_stmt(ctx->return_stmt()); if (ctx->return_stmt()) return visitReturn_stmt(ctx->return_stmt());
throw FatalError("Unknown flow statement"); throw FatalError("Unknown flow statement", 10);
return NoneType(); return NoneType();
} }
@ -200,7 +202,7 @@ std::any EvalVisitor::visitCompound_stmt(
if (ctx->if_stmt()) return visitIf_stmt(ctx->if_stmt()); if (ctx->if_stmt()) return visitIf_stmt(ctx->if_stmt());
if (ctx->while_stmt()) return visitWhile_stmt(ctx->while_stmt()); if (ctx->while_stmt()) return visitWhile_stmt(ctx->while_stmt());
if (ctx->funcdef()) return visitFuncdef(ctx->funcdef()); if (ctx->funcdef()) return visitFuncdef(ctx->funcdef());
throw FatalError("Unknown compound statement"); throw FatalError("Unknown compound statement", 11);
return NoneType(); return NoneType();
} }
@ -209,7 +211,7 @@ std::any EvalVisitor::visitIf_stmt(Python3Parser::If_stmtContext *ctx) {
auto suite_list = ctx->suite(); auto suite_list = ctx->suite();
if (test_list.size() - suite_list.size() != -1 && if (test_list.size() - suite_list.size() != -1 &&
test_list.size() - suite_list.size() != 0) test_list.size() - suite_list.size() != 0)
throw InterpretException("test and suite doesn't match in If_stmt"); throw InterpretException("test and suite doesn't match in If_stmt", 12);
for (int i = 0; i < test_list.size(); i++) for (int i = 0; i < test_list.size(); i++)
if (Any2Bool(DeQuate(visitTest(test_list[i]), Variables))) if (Any2Bool(DeQuate(visitTest(test_list[i]), Variables)))
return visitSuite(suite_list[i]); return visitSuite(suite_list[i]);
@ -303,7 +305,7 @@ std::any EvalVisitor::visitComparison(Python3Parser::ComparisonContext *ctx) {
else if (op_list[i]->LT_EQ()) else if (op_list[i]->LT_EQ())
ok = LessEqual(last_val, cur); ok = LessEqual(last_val, cur);
else else
throw InterpretException("visitComparison: Unknown operator"); throw InterpretException("visitComparison: Unknown operator", 13);
if (!ok) return false; if (!ok) return false;
last_val = cur; last_val = cur;
} }
@ -311,7 +313,7 @@ std::any EvalVisitor::visitComparison(Python3Parser::ComparisonContext *ctx) {
} }
std::any EvalVisitor::visitComp_op(Python3Parser::Comp_opContext *ctx) { std::any EvalVisitor::visitComp_op(Python3Parser::Comp_opContext *ctx) {
throw FatalError("Function visitComp_op Shouldn't be called"); throw FatalError("Function visitComp_op Shouldn't be called", 14);
} }
std::any EvalVisitor::visitArith_expr(Python3Parser::Arith_exprContext *ctx) { std::any EvalVisitor::visitArith_expr(Python3Parser::Arith_exprContext *ctx) {
@ -328,13 +330,13 @@ std::any EvalVisitor::visitArith_expr(Python3Parser::Arith_exprContext *ctx) {
else if (op_list[i]->MINUS()) else if (op_list[i]->MINUS())
SelfSub(ans, cur); SelfSub(ans, cur);
else else
throw FatalError("visitArith_expr: Unknown operator"); throw FatalError("visitArith_expr: Unknown operator", 15);
} }
return ans; return ans;
} }
std::any EvalVisitor::visitAddorsub_op(Python3Parser::Addorsub_opContext *ctx) { std::any EvalVisitor::visitAddorsub_op(Python3Parser::Addorsub_opContext *ctx) {
throw FatalError("Function visitAddorsub_op Shouldn't be called"); throw FatalError("Function visitAddorsub_op Shouldn't be called", 16);
} }
std::any EvalVisitor::visitTerm(Python3Parser::TermContext *ctx) { std::any EvalVisitor::visitTerm(Python3Parser::TermContext *ctx) {
@ -355,14 +357,14 @@ std::any EvalVisitor::visitTerm(Python3Parser::TermContext *ctx) {
else if (op_list[i]->MOD()) else if (op_list[i]->MOD())
SelfMod(ans, cur); SelfMod(ans, cur);
else else
throw FatalError("visitTerm: Unknown operator"); throw FatalError("visitTerm: Unknown operator", 17);
} }
return ans; return ans;
} }
std::any EvalVisitor::visitMuldivmod_op( std::any EvalVisitor::visitMuldivmod_op(
Python3Parser::Muldivmod_opContext *ctx) { Python3Parser::Muldivmod_opContext *ctx) {
throw FatalError("Function visitMuldivmod_op Shouldn't be called"); throw FatalError("Function visitMuldivmod_op Shouldn't be called", 18);
} }
std::any EvalVisitor::visitFactor(Python3Parser::FactorContext *ctx) { std::any EvalVisitor::visitFactor(Python3Parser::FactorContext *ctx) {
@ -399,7 +401,7 @@ std::any EvalVisitor::visitArglist(Python3Parser::ArglistContext *ctx) {
std::any EvalVisitor::visitArgument(Python3Parser::ArgumentContext *ctx) { std::any EvalVisitor::visitArgument(Python3Parser::ArgumentContext *ctx) {
auto arg_list = ctx->test(); auto arg_list = ctx->test();
if (arg_list.size() != 1 && arg_list.size() != 2) if (arg_list.size() != 1 && arg_list.size() != 2)
throw FatalError("visitArgument: arg_list.size()!=1&&arg_list!=2"); throw FatalError("visitArgument: arg_list.size()!=1&&arg_list!=2", 19);
if (arg_list.size() == 1) if (arg_list.size() == 1)
return ParaArguItemType("", DeQuate(visitTest(arg_list[0]), Variables)); return ParaArguItemType("", DeQuate(visitTest(arg_list[0]), Variables));
else else

View File

@ -1,34 +1,32 @@
#include <iostream>
#include "Evalvisitor.h" #include "Evalvisitor.h"
#include "Python3Lexer.h" #include "Python3Lexer.h"
#include "Python3Parser.h" #include "Python3Parser.h"
#include "antlr4-runtime.h" #include "antlr4-runtime.h"
#include <iostream>
#include "clipp/clipp.h" #include "clipp/clipp.h"
using namespace antlr4; using namespace antlr4;
// TODO: regenerating files in directory named "generated" is dangerous. // TODO: regenerating files in directory named "generated" is dangerous.
// if you really need to regenerate,please ask TA for help. // if you really need to regenerate,please ask TA for help.
int main(int argc, char *argv[]) int main(int argc, char *argv[]) {
{ // TODO: please don't modify the code below the construction of ifs if you
// TODO: please don't modify the code below the construction of ifs if you want to use visitor mode // want to use visitor mode
std::string input_file; std::string input_file;
bool need_help = false; bool need_help = false;
auto cli = (clipp::option("-h", "--help").set(need_help).doc("show help") | auto cli = (clipp::option("-h", "--help").set(need_help).doc("show help") |
clipp::opt_value("input file", input_file)); clipp::opt_value("input file", input_file));
if (!clipp::parse(argc, argv, cli)) if (!clipp::parse(argc, argv, cli)) {
{
std::cout << clipp::make_man_page(cli, argv[0]); std::cout << clipp::make_man_page(cli, argv[0]);
return 0; return 0;
} }
if (need_help) if (need_help) {
{
std::cout << clipp::make_man_page(cli, argv[0]); std::cout << clipp::make_man_page(cli, argv[0]);
return 0; return 0;
} }
ANTLRInputStream *input_p; ANTLRInputStream *input_p;
if (input_file.length() == 0) if (input_file.length() == 0)
input_p = new ANTLRInputStream(std::cin); input_p = new ANTLRInputStream(std::cin);
else else {
{
std::ifstream ifs(input_file); std::ifstream ifs(input_file);
input_p = new ANTLRInputStream(ifs); input_p = new ANTLRInputStream(ifs);
} }
@ -38,25 +36,22 @@ int main(int argc, char *argv[])
Python3Parser parser(&tokens); Python3Parser parser(&tokens);
tree::ParseTree *tree = parser.file_input(); tree::ParseTree *tree = parser.file_input();
EvalVisitor visitor; EvalVisitor visitor;
try try {
{
visitor.visit(tree); visitor.visit(tree);
} } catch (const InterpretException &e) {
catch (const InterpretException &e)
{
std::cerr << "[Interpret Error] " << e.what() << std::endl; std::cerr << "[Interpret Error] " << e.what() << std::endl;
} return e.GetCode();
catch (const FatalError &e) } catch (const FatalError &e) {
{ std::cerr << "\e[7m\e[31m[Fatal Error] " << e.what() << "\e[0m"
std::cerr << "\e[7m\e[31m[Fatal Error] " << e.what() << "\e[0m" << std::endl; << std::endl;
} return e.GetCode();
catch (const std::exception &e) } catch (const std::exception &e) {
{ std::cerr << "\e[7m\e[31m[other std::exception] " << e.what() << "\e[0m"
std::cerr << "\e[7m\e[31m[other std::exception] " << e.what() << "\e[0m" << std::endl; << std::endl;
} return 255;
catch (...) } catch (...) {
{
std::cerr << "\e[7m\e[31m[Unknown Exception]\e[0m" << std::endl; std::cerr << "\e[7m\e[31m[Unknown Exception]\e[0m" << std::endl;
return 255;
} }
delete input_p; delete input_p;
return 0; return 0;

View File

@ -6,7 +6,7 @@ inline void VariableContainer::CreateFrame() {
StackScopes.push(std::unordered_map<std::string, std::any>()); StackScopes.push(std::unordered_map<std::string, std::any>());
} }
void VariableContainer::DestroyFrame() { void VariableContainer::DestroyFrame() {
if (StackScopes.empty()) throw FatalError("DestroyFrame: empty stack"); if (StackScopes.empty()) throw FatalError("DestroyFrame: empty stack", 20);
StackScopes.pop(); StackScopes.pop();
} }
std::any VariableContainer::ReadVariable(const std::string &name) { std::any VariableContainer::ReadVariable(const std::string &name) {
@ -15,7 +15,7 @@ std::any VariableContainer::ReadVariable(const std::string &name) {
if (top.find(name) != top.end()) return top[name]; if (top.find(name) != top.end()) return top[name];
} }
if (GlobalScope.find(name) != GlobalScope.end()) return GlobalScope[name]; if (GlobalScope.find(name) != GlobalScope.end()) return GlobalScope[name];
throw InterpretException(("ReadVariable: not found")); throw InterpretException(("ReadVariable: not found"), 21);
} }
void VariableContainer::WriteVariable(const std::string &name, void VariableContainer::WriteVariable(const std::string &name,
const std::any &value, bool cover) { const std::any &value, bool cover) {
@ -41,7 +41,7 @@ void VariableContainer::WriteVariable(const std::string &name,
void FucntionContainer::AddFunction(const std::string &name, void FucntionContainer::AddFunction(const std::string &name,
const FunctionItem &item) { const FunctionItem &item) {
if (FunctionIndex.find(name) != FunctionIndex.end()) { if (FunctionIndex.find(name) != FunctionIndex.end()) {
throw InterpretException("AddFunction: function already exists"); throw InterpretException("AddFunction: function already exists", 22);
} }
FunctionIndex[name] = item; FunctionIndex[name] = item;
} }
@ -66,32 +66,32 @@ std::any FucntionContainer::CallFunction(const std::string &name,
} else if (name == "str") { } else if (name == "str") {
if (args.size() != 1) if (args.size() != 1)
throw InterpretException( throw InterpretException(
"CallFunction: str() should take exactly one argument"); "CallFunction: str() should take exactly one argument", 23);
return Any2String(args[0].value); return Any2String(args[0].value);
} else if (name == "int") { } else if (name == "int") {
if (args.size() == 1) { if (args.size() == 1) {
return Any2Int(args[0].value); return Any2Int(args[0].value);
} else { } else {
throw InterpretException( throw InterpretException(
"CallFunction: int() should take exactly one argument"); "CallFunction: int() should take exactly one argument", 24);
} }
} else if (name == "float") { } else if (name == "float") {
if (args.size() == 1) { if (args.size() == 1) {
return Any2Float(args[0].value); return Any2Float(args[0].value);
} else { } else {
throw InterpretException( throw InterpretException(
"CallFunction: float() should take exactly one argument"); "CallFunction: float() should take exactly one argument", 25);
} }
} else if (name == "bool") { } else if (name == "bool") {
if (args.size() == 1) { if (args.size() == 1) {
return Any2Bool(args[0].value); return Any2Bool(args[0].value);
} else { } else {
throw InterpretException( throw InterpretException(
"CallFunction: bool() should take exactly one argument"); "CallFunction: bool() should take exactly one argument", 26);
} }
} }
if (FunctionIndex.find(name) == FunctionIndex.end()) { if (FunctionIndex.find(name) == FunctionIndex.end()) {
throw InterpretException("CallFunction: function not found"); throw InterpretException("CallFunction: function not found", 27);
} }
const FunctionItem &func = FunctionIndex[name]; const FunctionItem &func = FunctionIndex[name];
std::unordered_set<std::string> args_with_data; std::unordered_set<std::string> args_with_data;
@ -121,7 +121,8 @@ std::any FucntionContainer::CallFunction(const std::string &name,
i++; i++;
if (i >= func.para_list.size()) break; if (i >= func.para_list.size()) break;
if (!func.para_list[i].value.has_value()) if (!func.para_list[i].value.has_value())
throw InterpretException("CallFunction: function parameter not found"); throw InterpretException("CallFunction: function parameter not found",
28);
Variables.WriteVariable(func.para_list[i].name, func.para_list[i].value, Variables.WriteVariable(func.para_list[i].name, func.para_list[i].value,
true); true);
args_with_data.insert(func.para_list[i].name); args_with_data.insert(func.para_list[i].name);

View File

@ -25,7 +25,7 @@ inline ZYM::int2048 Any2Int(const std::any &value) {
return std::move(ZYM::int2048(0)); return std::move(ZYM::int2048(0));
else { else {
std::cerr << value.type().name() << std::endl; std::cerr << value.type().name() << std::endl;
throw FatalError("Any2Int2048: unknown type"); throw FatalError("Any2Int2048: unknown type", 29);
} }
} }
@ -48,7 +48,7 @@ double Any2Float(const std::any &value) {
else if (auto ptr = std::any_cast<std::string>(&value)) else if (auto ptr = std::any_cast<std::string>(&value))
return std::stod(*ptr); return std::stod(*ptr);
else else
throw FatalError("Any2Float: unknown type"); throw FatalError("Any2Float: unknown type", 30);
} }
std::string Any2String(const std::any &value) { std::string Any2String(const std::any &value) {
@ -68,7 +68,7 @@ std::string Any2String(const std::any &value) {
else if (auto ptr = std::any_cast<NoneType>(&value)) else if (auto ptr = std::any_cast<NoneType>(&value))
buf << "None"; buf << "None";
else else
throw FatalError("Any2String: unknown type"); throw FatalError("Any2String: unknown type", 31);
std::getline(buf, res); std::getline(buf, res);
return res; return res;
} }
@ -83,7 +83,7 @@ bool Any2Bool(const std::any &value) {
} else if (auto ptr = std::any_cast<std::string>(&value)) { } else if (auto ptr = std::any_cast<std::string>(&value)) {
return (*ptr) != ""; return (*ptr) != "";
} else } else
throw FatalError("Any2Bool: unknown type"); throw FatalError("Any2Bool: unknown type", 32);
} }
std::any DeQuate(std::any val, VariableContainer &Variables) { std::any DeQuate(std::any val, VariableContainer &Variables) {
@ -115,16 +115,19 @@ int ConverToSameArithType(std::any &a, std::any &b,
if ((!allow_string_operation) && (ptr_a_string || ptr_b_string)) if ((!allow_string_operation) && (ptr_a_string || ptr_b_string))
throw InterpretException( throw InterpretException(
"ConverToSameArithType: string operation not allowed in this " "ConverToSameArithType: string operation not allowed in this "
"situation"); "situation",
33);
if (allow_string_operation && (ptr_a_string || ptr_b_string)) { if (allow_string_operation && (ptr_a_string || ptr_b_string)) {
if (!(ptr_a_string || ptr_a_int2048)) if (!(ptr_a_string || ptr_a_int2048))
throw InterpretException( throw InterpretException(
"ConverToSameArithType: string operation not allowed in this " "ConverToSameArithType: string operation not allowed in this "
"situation"); "situation",
34);
if (!(ptr_b_string || ptr_b_int2048)) if (!(ptr_b_string || ptr_b_int2048))
throw InterpretException( throw InterpretException(
"ConverToSameArithType: string operation not allowed in this " "ConverToSameArithType: string operation not allowed in this "
"situation"); "situation",
35);
return 1; return 1;
} }
int level_a = (ptr_a_bool != nullptr ? 1 : 0) + int level_a = (ptr_a_bool != nullptr ? 1 : 0) +
@ -146,7 +149,7 @@ int ConverToSameArithType(std::any &a, std::any &b,
b = Any2Float(b); b = Any2Float(b);
break; break;
default: default:
throw FatalError("ConverToSameArithType: unknown type"); throw FatalError("ConverToSameArithType: unknown type", 36);
} }
return 0; return 0;
} }
@ -164,7 +167,7 @@ std::any Add(std::any a, std::any b) {
if ((ptr_a_string != nullptr ? 1 : 0) + (ptr_b_string != nullptr ? 1 : 0) == if ((ptr_a_string != nullptr ? 1 : 0) + (ptr_b_string != nullptr ? 1 : 0) ==
1) { 1) {
throw InterpretException( throw InterpretException(
"Add: string operation not allowed in this situation"); "Add: string operation not allowed in this situation", 37);
} }
if ((ptr_a_string != nullptr ? 1 : 0) + (ptr_b_string != nullptr ? 1 : 0) == if ((ptr_a_string != nullptr ? 1 : 0) + (ptr_b_string != nullptr ? 1 : 0) ==
2) 2)
@ -176,7 +179,7 @@ std::any Add(std::any a, std::any b) {
else if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) else if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr))
return (*ptr_a_float) + (*ptr_b_float); return (*ptr_a_float) + (*ptr_b_float);
else else
throw FatalError("Add: Type Error"); throw FatalError("Add: Type Error", 38);
} }
std::any Sub(std::any a, std::any b) { std::any Sub(std::any a, std::any b) {
ConverToSameArithType(a, b); ConverToSameArithType(a, b);
@ -193,7 +196,7 @@ std::any Sub(std::any a, std::any b) {
else if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) else if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr))
return (*ptr_a_float) - (*ptr_b_float); return (*ptr_a_float) - (*ptr_b_float);
else else
throw FatalError("Sub: Type Error"); throw FatalError("Sub: Type Error", 39);
return a; return a;
} }
std::any Mul(std::any a, std::any b) { std::any Mul(std::any a, std::any b) {
@ -209,7 +212,7 @@ std::any Mul(std::any a, std::any b) {
if ((ptr_a_string != nullptr ? 1 : 0) + (ptr_b_string != nullptr ? 1 : 0) == if ((ptr_a_string != nullptr ? 1 : 0) + (ptr_b_string != nullptr ? 1 : 0) ==
2) { 2) {
throw InterpretException( throw InterpretException(
"Mul: string operation not allowed in this situation"); "Mul: string operation not allowed in this situation", 40);
} else if ((ptr_a_string != nullptr ? 1 : 0) + } else if ((ptr_a_string != nullptr ? 1 : 0) +
(ptr_b_string != nullptr ? 1 : 0) == (ptr_b_string != nullptr ? 1 : 0) ==
1) { 1) {
@ -220,7 +223,7 @@ std::any Mul(std::any a, std::any b) {
std::swap(ptr_a_float, ptr_b_float); std::swap(ptr_a_float, ptr_b_float);
} }
if (ptr_b_float != nullptr) if (ptr_b_float != nullptr)
throw InterpretException("Mul: string*float not allowed"); throw InterpretException("Mul: string*float not allowed", 41);
if (ptr_b_bool != nullptr) { if (ptr_b_bool != nullptr) {
if (*ptr_b_bool) { if (*ptr_b_bool) {
return *ptr_a_string; return *ptr_a_string;
@ -241,7 +244,7 @@ std::any Mul(std::any a, std::any b) {
else if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) else if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr))
return (*ptr_a_float) * (*ptr_b_float); return (*ptr_a_float) * (*ptr_b_float);
else else
throw FatalError("Mul: Type Error"); throw FatalError("Mul: Type Error", 42);
} }
std::any Div(std::any a, std::any b) { std::any Div(std::any a, std::any b) {
bool *ptr_a_bool = std::any_cast<bool>(&a); bool *ptr_a_bool = std::any_cast<bool>(&a);
@ -254,10 +257,10 @@ std::any Div(std::any a, std::any b) {
std::string *ptr_b_string = std::any_cast<std::string>(&b); std::string *ptr_b_string = std::any_cast<std::string>(&b);
if ((ptr_a_string != nullptr) || (ptr_b_string != nullptr)) if ((ptr_a_string != nullptr) || (ptr_b_string != nullptr))
throw InterpretException( throw InterpretException(
"Div: string operation not allowed in this situation"); "Div: string operation not allowed in this situation", 43);
double t_a = Any2Float(a); double t_a = Any2Float(a);
double t_b = Any2Float(b); double t_b = Any2Float(b);
if (t_b == 0) throw InterpretException("Div: divided by zero"); if (t_b == 0) throw InterpretException("Div: divided by zero", 44);
t_a = t_a / t_b; t_a = t_a / t_b;
return a; return a;
} }
@ -270,17 +273,19 @@ std::any Divv(std::any a, std::any b) {
double *ptr_a_float = std::any_cast<double>(&a); double *ptr_a_float = std::any_cast<double>(&a);
double *ptr_b_float = std::any_cast<double>(&b); double *ptr_b_float = std::any_cast<double>(&b);
if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) { if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) {
if ((*ptr_b_float) == 0) throw InterpretException("Divv: divided by zero"); if ((*ptr_b_float) == 0)
throw InterpretException("Divv: divided by zero", 45);
return ZYM::int2048(std::floor((*ptr_a_float) / (*ptr_b_float))); return ZYM::int2048(std::floor((*ptr_a_float) / (*ptr_b_float)));
} else if ((ptr_a_int2048 != nullptr) && (ptr_b_int2048 != nullptr)) { } else if ((ptr_a_int2048 != nullptr) && (ptr_b_int2048 != nullptr)) {
if ((*ptr_b_int2048) == 0) if ((*ptr_b_int2048) == 0)
throw InterpretException("Divv: divided by zero"); throw InterpretException("Divv: divided by zero", 46);
return (*ptr_a_int2048) / (*ptr_b_int2048); return (*ptr_a_int2048) / (*ptr_b_int2048);
} else if ((ptr_a_bool != nullptr) && (ptr_b_bool != nullptr)) { } else if ((ptr_a_bool != nullptr) && (ptr_b_bool != nullptr)) {
if ((*ptr_b_bool) == 0) throw InterpretException("Divv: divided by zero"); if ((*ptr_b_bool) == 0)
throw InterpretException("Divv: divided by zero", 47);
return ZYM::int2048((*ptr_a_bool) / (*ptr_b_bool)); return ZYM::int2048((*ptr_a_bool) / (*ptr_b_bool));
} else } else
throw FatalError("Divv: Type Error"); throw FatalError("Divv: Type Error", 48);
} }
std::any Mod(std::any a, std::any b) { std::any Mod(std::any a, std::any b) {
ConverToSameArithType(a, b); ConverToSameArithType(a, b);
@ -291,18 +296,21 @@ std::any Mod(std::any a, std::any b) {
double *ptr_a_float = std::any_cast<double>(&a); double *ptr_a_float = std::any_cast<double>(&a);
double *ptr_b_float = std::any_cast<double>(&b); double *ptr_b_float = std::any_cast<double>(&b);
if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) { if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) {
if ((*ptr_b_float) == 0) throw InterpretException("Mod: divided by zero"); if ((*ptr_b_float) == 0)
throw InterpretException("Mod: divided by zero", 49);
return ZYM::int2048((*ptr_a_float) - return ZYM::int2048((*ptr_a_float) -
(*ptr_b_float) * (*ptr_b_float) *
std::floor((*ptr_a_float) / (*ptr_b_float))); std::floor((*ptr_a_float) / (*ptr_b_float)));
} else if ((ptr_a_int2048 != nullptr) && (ptr_b_int2048 != nullptr)) { } else if ((ptr_a_int2048 != nullptr) && (ptr_b_int2048 != nullptr)) {
if ((*ptr_b_int2048) == 0) throw InterpretException("Mod: divided by zero"); if ((*ptr_b_int2048) == 0)
throw InterpretException("Mod: divided by zero", 50);
return (*ptr_a_int2048) % (*ptr_b_int2048); return (*ptr_a_int2048) % (*ptr_b_int2048);
} else if ((ptr_a_bool != nullptr) && (ptr_b_bool != nullptr)) { } else if ((ptr_a_bool != nullptr) && (ptr_b_bool != nullptr)) {
if ((*ptr_b_bool) == 0) throw InterpretException("Mod: divided by zero"); if ((*ptr_b_bool) == 0)
throw InterpretException("Mod: divided by zero", 51);
return ZYM::int2048((*ptr_a_bool) % (*ptr_b_bool)); return ZYM::int2048((*ptr_a_bool) % (*ptr_b_bool));
} else } else
throw FatalError("Mod: Type Error"); throw FatalError("Mod: Type Error", 52);
} }
std::any &SelfAdd(std::any &a, std::any b) { std::any &SelfAdd(std::any &a, std::any b) {
a = Add(a, b); a = Add(a, b);
@ -339,7 +347,7 @@ std::any Neg(std::any a) {
else if (ptr_a_float != nullptr) else if (ptr_a_float != nullptr)
return -(*ptr_a_float); return -(*ptr_a_float);
else else
throw FatalError("Neg: Type Error"); throw FatalError("Neg: Type Error", 53);
} }
bool Greater(std::any a, std::any b) { bool Greater(std::any a, std::any b) {
@ -361,7 +369,7 @@ bool Greater(std::any a, std::any b) {
else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr)) else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr))
return (*ptr_a_string) > (*ptr_b_string); return (*ptr_a_string) > (*ptr_b_string);
else else
throw FatalError("Greater: Type Error"); throw FatalError("Greater: Type Error", 54);
} }
bool Less(std::any a, std::any b) { bool Less(std::any a, std::any b) {
ConverToSameArithType(a, b, true); ConverToSameArithType(a, b, true);
@ -382,7 +390,7 @@ bool Less(std::any a, std::any b) {
else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr)) else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr))
return (*ptr_a_string) < (*ptr_b_string); return (*ptr_a_string) < (*ptr_b_string);
else else
throw FatalError("Less: Type Error"); throw FatalError("Less: Type Error", 55);
} }
bool Equal(std::any a, std::any b) { bool Equal(std::any a, std::any b) {
ConverToSameArithType(a, b, true); ConverToSameArithType(a, b, true);
@ -403,7 +411,7 @@ bool Equal(std::any a, std::any b) {
else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr)) else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr))
return (*ptr_a_string) == (*ptr_b_string); return (*ptr_a_string) == (*ptr_b_string);
else else
throw FatalError("Equal: Type Error"); throw FatalError("Equal: Type Error", 56);
} }
bool NotEqual(std::any a, std::any b) { bool NotEqual(std::any a, std::any b) {
ConverToSameArithType(a, b, true); ConverToSameArithType(a, b, true);
@ -424,7 +432,7 @@ bool NotEqual(std::any a, std::any b) {
else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr)) else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr))
return (*ptr_a_string) != (*ptr_b_string); return (*ptr_a_string) != (*ptr_b_string);
else else
throw FatalError("NotEqual: Type Error"); throw FatalError("NotEqual: Type Error", 57);
} }
bool GreaterEqual(std::any a, std::any b) { bool GreaterEqual(std::any a, std::any b) {
ConverToSameArithType(a, b, true); ConverToSameArithType(a, b, true);
@ -445,7 +453,7 @@ bool GreaterEqual(std::any a, std::any b) {
else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr)) else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr))
return (*ptr_a_string) >= (*ptr_b_string); return (*ptr_a_string) >= (*ptr_b_string);
else else
throw FatalError("GreaterEqual: Type Error"); throw FatalError("GreaterEqual: Type Error", 58);
} }
bool LessEqual(std::any a, std::any b) { bool LessEqual(std::any a, std::any b) {
ConverToSameArithType(a, b, true); ConverToSameArithType(a, b, true);
@ -466,5 +474,5 @@ bool LessEqual(std::any a, std::any b) {
else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr)) else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr))
return (*ptr_a_string) <= (*ptr_b_string); return (*ptr_a_string) <= (*ptr_b_string);
else else
throw FatalError("LessEqual: Type Error"); throw FatalError("LessEqual: Type Error", 59);
} }