cgen.hpp (2249B)
1 // Code generator 2 3 // Copyright (C) 2022, Mohammad-Reza Nabipoor 4 // SPDX-License-Identifier: GPL-3.0-or-later 5 6 #pragma once 7 8 #include <memory> 9 10 #include "ast.hpp" 11 #include "env.hpp" 12 13 // Use the VM generated by Jitter 14 extern "C" 15 { 16 #define restrict 17 #include "vm/toctave-vm.h" 18 #undef restrict 19 } 20 21 namespace cgen { 22 23 // Generates S-Expression equivalent of input AST 24 std::string 25 sexpr(ast::NodesIter first, ast::NodesIter last); 26 27 //--- Jittery VM 28 29 class JExecRoutine; 30 class JRoutine; 31 32 std::string 33 disasm(const JExecRoutine& er); 34 std::string 35 disasm(const JRoutine& r); 36 37 // Jitter Executable Routine 38 class JExecRoutine 39 { 40 private: 41 std::unique_ptr<struct toctave_executable_routine, 42 void (*)(struct toctave_executable_routine*)> 43 er; 44 std::unique_ptr<struct toctave_state, void (*)(struct toctave_state*)> state; 45 46 public: 47 JExecRoutine() = default; 48 JExecRoutine(struct toctave_mutable_routine*); 49 50 friend std::string disasm(const JExecRoutine& er); 51 52 // Execute the VM code with the given environment. 53 // Returns true when done (reached the done instruction). 54 bool exec(env::Env&); 55 56 // Result of the computation 57 double result(); 58 }; 59 60 class JRoutine 61 { 62 private: 63 std::unique_ptr<struct toctave_mutable_routine, 64 void (*)(struct toctave_mutable_routine*)> 65 r; 66 67 public: 68 using label_t = toctave_label; 69 70 JRoutine(); 71 72 friend std::string disasm(const JRoutine& r); // Disassemble 73 JExecRoutine mkexec(); // Make executable routine 74 75 //--- label manipulation 76 77 label_t mklabel(); 78 label_t label(label_t l); 79 label_t label(); 80 81 //--- instructions 82 83 // stack manipulation 84 void push(double d); 85 void pushnan(); 86 void pop(); 87 void drop(); 88 89 // arithmetic 90 void pow(); 91 void mul(); 92 void div(); 93 void add(); 94 void sub(); 95 96 // branching 97 // ... 98 99 // Pointer should stay valid until the end of execution 100 void call(const char* func); 101 void pushvar(const char* var); // move value from variable to stack 102 void popvar(const char* var); // move value from stack to variable 103 104 // control flow 105 void yield(label_t l); 106 void done(); 107 }; 108 109 // Generates code for the VM generated by Jitter 110 JRoutine 111 jitter(ast::NodesIter first, ast::NodesIter last); 112 113 } // namespace cgen