void jvmcodegen::gen_function_decl(const ast::node_ptr &node) { auto func = ast::to_function_decl(node); auto curr_scope = m_stack.top(); auto& sym = curr_scope->get(func->name); if (!sym.is_valid()) { throw jvmcodegen_error(fmt::sprintf("%s simbolo nao encontrado!", func->name)); } // empilha o escopo da função m_stack.push(m_symtable->get_scope(sym.scope_id)); reset_locals(); reset_labels(); m_out << fmt::sprintf(".method public static "); std::stringstream ss; if (func->is_main()) { m_out << fmt::sprintf("main([Ljava/lang/String;)V\n"); } else { ss << fmt::sprintf("%s(", func->name); for (size_t i = 0; i < func->arguments.size(); i++) { auto arg = ast::to_argument(func->arguments[i]); auto& asym = m_stack.top()->get(arg->name); ss << fmt::sprintf("%s", jvm_type(asym.c_type())); if (i != func->arguments.size() - 1) ss << m_out << fmt::sprintf(","); } ss << fmt::sprintf(")%s", jvm_type(sym.type & ~types::function)); // salva a assinatura para realizar chamadas.. sym.signature = ss.str(); m_out << fmt::sprintf(ss.str()); m_out << fmt::sprintf("\n"); } int locals = compute_locals(node); if (func->is_main()) locals += 1; m_out << fmt::sprintf(".limit locals %d\n", locals); m_out << fmt::sprintf(".limit stack 15\n"); for (const auto& arg : func->arguments) { gen_node(arg); } for (const auto& stmt : func->statements) { gen_node(stmt); } m_stack.pop(); if (!func->is_main()) { if (sym.c_type() == types::integer) { m_out << fmt::sprintf("ireturn\n"); } else if (sym.c_type() == types::voidt) { m_out << fmt::sprintf("return\n"); } else if (sym.c_type() == types::string) { m_out << fmt::sprintf("areturn\n"); } } else { m_out << fmt::sprintf("return\n"); } m_out << fmt::sprintf(".end method\n\n"); }
void pool_add(lky_mempool *pool, void *obj) { struct poolnode *next = gen_node(obj); append_to_list(&(pool->head), &(pool->tail), next); }