Пример #1
0
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");
}
Пример #2
0
void pool_add(lky_mempool *pool, void *obj)
{
    struct poolnode *next = gen_node(obj);
    append_to_list(&(pool->head), &(pool->tail), next);
}