// See the file "COPYING" in the main distribution directory for copyright. #include "pac_func.h" #include "pac_embedded.h" #include "pac_expr.h" #include "pac_output.h" #include "pac_param.h" #include "pac_type.h" Function::Function(ID* id, Type* type, ParamList* params) : id_(id), type_(type), params_(params), expr_(nullptr), code_(nullptr) { analyzer_decl_ = nullptr; env_ = nullptr; } Function::~Function() { delete id_; delete type_; delete_list(ParamList, params_); delete env_; delete expr_; delete code_; } void Function::Prepare(Env* env) { env->AddID(id_, FUNC_ID, type_); env->SetEvaluated(id_); env_ = new Env(env, this); foreach (i, ParamList, params_) { Param* p = *i; env_->AddID(p->id(), FUNC_PARAM, p->type()); env_->SetEvaluated(p->id()); } } void Function::GenForwardDeclaration(Output* out_h) { // Do nothing } void Function::GenCode(Output* out_h, Output* out_cc) { out_h->println("%s %s(%s);", type_->DataTypeStr().c_str(), id_->Name(), ParamDecls(params_).c_str()); string class_str = ""; if ( analyzer_decl_ ) class_str = strfmt("%s::", analyzer_decl_->id()->Name()); string proto_str = strfmt("%s %s%s(%s)", type_->DataTypeStr().c_str(), class_str.c_str(), id_->Name(), ParamDecls(params_).c_str()); ASSERT(! (expr_ && code_)); if ( expr_ ) { out_cc->println("%s {", proto_str.c_str()); out_cc->inc_indent(); out_cc->println("return static_cast<%s>(%s);", type_->DataTypeStr().c_str(), expr_->EvalExpr(out_cc, env_)); out_cc->dec_indent(); out_cc->println("}"); } else if ( code_ ) { out_cc->println("%s {", proto_str.c_str()); out_cc->inc_indent(); code_->GenCode(out_cc, env_); out_cc->dec_indent(); out_cc->println("}"); } out_cc->println(""); } FuncDecl::FuncDecl(Function* function) : Decl(function->id()->clone(), FUNC), function_(function) { function_->Prepare(global_env()); } FuncDecl::~FuncDecl() { delete function_; } void FuncDecl::Prepare() {} void FuncDecl::GenForwardDeclaration(Output* out_h) { function_->GenForwardDeclaration(out_h); } void FuncDecl::GenCode(Output* out_h, Output* out_cc) { function_->GenCode(out_h, out_cc); } AnalyzerFunction::AnalyzerFunction(Function* function) : AnalyzerElement(FUNCTION), function_(function) {}