A Hugo incarnation of the blog.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

global_scope.cpp 2.8KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #include "global_scope.hpp"
  2. #include "ast.hpp"
  3. void global_function::compile() {
  4. env_ptr new_env = env_ptr(new env_offset(0, nullptr));
  5. for(auto it = params.rbegin(); it != params.rend(); it++) {
  6. new_env = env_ptr(new env_var(*it, new_env));
  7. }
  8. body->compile(new_env, instructions);
  9. instructions.push_back(instruction_ptr(new instruction_update(params.size())));
  10. instructions.push_back(instruction_ptr(new instruction_pop(params.size())));
  11. }
  12. void global_function::declare_llvm(llvm_context& ctx) {
  13. generated_function = ctx.create_custom_function(name, params.size());
  14. }
  15. void global_function::generate_llvm(llvm_context& ctx) {
  16. ctx.builder.SetInsertPoint(&generated_function->getEntryBlock());
  17. for(auto& instruction : instructions) {
  18. instruction->gen_llvm(ctx, generated_function);
  19. }
  20. ctx.builder.CreateRetVoid();
  21. }
  22. void global_constructor::generate_llvm(llvm_context& ctx) {
  23. auto new_function =
  24. ctx.create_custom_function(name, arity);
  25. std::vector<instruction_ptr> instructions;
  26. instructions.push_back(instruction_ptr(new instruction_pack(tag, arity)));
  27. instructions.push_back(instruction_ptr(new instruction_update(0)));
  28. ctx.builder.SetInsertPoint(&new_function->getEntryBlock());
  29. for (auto& instruction : instructions) {
  30. instruction->gen_llvm(ctx, new_function);
  31. }
  32. ctx.builder.CreateRetVoid();
  33. }
  34. global_function& global_scope::add_function(std::string n, std::vector<std::string> ps, ast_ptr b) {
  35. global_function* new_function = new global_function(mangle_name(n), std::move(ps), std::move(b));
  36. functions.push_back(global_function_ptr(new_function));
  37. return *new_function;
  38. }
  39. global_constructor& global_scope::add_constructor(std::string n, int8_t t, size_t a) {
  40. global_constructor* new_constructor = new global_constructor(mangle_name(n), t, a);
  41. constructors.push_back(global_constructor_ptr(new_constructor));
  42. return *new_constructor;
  43. }
  44. void global_scope::compile() {
  45. for(auto& function : functions) {
  46. function->compile();
  47. }
  48. }
  49. void global_scope::generate_llvm(llvm_context& ctx) {
  50. for(auto& constructor : constructors) {
  51. constructor->generate_llvm(ctx);
  52. }
  53. for(auto& function : functions) {
  54. function->declare_llvm(ctx);
  55. }
  56. for(auto& function : functions) {
  57. function->generate_llvm(ctx);
  58. }
  59. }
  60. std::string global_scope::mangle_name(const std::string& n) {
  61. auto occurence_it = occurence_count.find(n);
  62. int occurence = 0;
  63. if(occurence_it != occurence_count.end()) {
  64. occurence = occurence_it->second + 1;
  65. }
  66. occurence_count[n] = occurence;
  67. std::string final_name = n;
  68. if (occurence != 0) {
  69. final_name += "_";
  70. final_name += std::to_string(occurence);
  71. }
  72. return final_name;
  73. }