Phasor 2.2.0
Stack VM based Programming Language
Loading...
Searching...
No Matches
Frontend.cpp
Go to the documentation of this file.
6#include "Frontend.hpp"
7
8#include <version.h>
9
11#include "../sscanf.h"
12#include <fstream>
13#include <iostream>
14#include <sstream>
15#include <string>
16
17#ifdef _WIN32
18#include <Windows.h>
19#define error(msg) MessageBoxA(NULL, std::string(msg).c_str(), "Phasor Runtime Error", MB_OK | MB_ICONERROR)
20#else
21#define error(msg) std::cerr << "Error: " << msg << std::endl
22#endif
23
24bool startsWith(const std::string &input, const std::string &prefix)
25{
26 if (input.size() >= prefix.size() && input.compare(0, prefix.size(), prefix) == 0)
27 {
28 return true;
29 }
30 return false;
31}
32
33void Phasor::Frontend::runScript(const std::string &source, VM *vm)
34{
35 Lexer lexer(source);
36 auto tokens = lexer.tokenize();
37
38 Parser parser(tokens);
39 auto program = parser.parse();
40
41 CodeGenerator codegen;
42 auto bytecode = codegen.generate(*program);
43
44 bool ownVM = false;
45
46 if (vm == nullptr)
47 {
48 ownVM = true;
49 vm = new VM();
51 }
52
53#if defined(_WIN32)
54 FFI ffi("plugins", vm);
55#elif defined(__APPLE__)
56 FFI ffi("/Library/Application Support/org.Phasor.Phasor/plugins", vm);
57#elif defined(__linux__)
58 FFI ffi("/opt/Phasor/plugins", vm);
59#endif
60
61 vm->setImportHandler([](const std::filesystem::path &path) {
62 std::ifstream file(path);
63 if (!file.is_open())
64 {
65 throw std::runtime_error("Could not open imported file: " + path.string());
66 }
67 std::stringstream buffer;
68 buffer << file.rdbuf();
69 runScript(buffer.str());
70 });
71
72 vm->run(bytecode);
73
74 if (ownVM)
75 {
76 delete vm;
77 }
78}
79
81{
82 std::cout << "Phasor v" << PHASOR_VERSION_STRING << " REPL\n(C) 2026 Daniel McGuire\n\n";
83 std::cout << "Type 'exit();' to quit. Function declarations will not work.\n";
84
85 bool ownVM = false;
86 if (vm == nullptr)
87 {
88 ownVM = true;
89 vm = new VM();
91 }
92
93#if defined(_WIN32)
94 FFI ffi("plugins", vm);
95#elif defined(__APPLE__)
96 FFI ffi("/Library/Application Support/org.Phasor.Phasor/plugins", vm);
97#elif defined(__linux__)
98 FFI ffi("/opt/Phasor/plugins", vm);
99#endif
100
101 vm->setImportHandler([](const std::filesystem::path &path) {
102 std::ifstream file(path);
103 if (!file.is_open())
104 {
105 throw std::runtime_error("Could not open imported file: " + path.string());
106 }
107 std::stringstream buffer;
108 buffer << file.rdbuf();
109 runScript(buffer.str());
110 });
111
112 std::map<std::string, int> globalVars;
113 int nextVarIdx = 0;
114 CodeGenerator codegen;
115
116 std::string line;
117 while (true)
118 {
119 try
120 {
121 std::cout << "\n> ";
122 if (!std::getline(std::cin, line))
123 break;
124 if (startsWith(line, "vm_pop"))
125 {
126 line = "let popx = " + vm->pop().toString();
127 continue;
128 }
129 if (startsWith(line, "vm_push"))
130 {
131 vm->push(line.substr(4));
132 continue;
133 }
134 if (startsWith(line, "vm_peek"))
135 {
136 line = "let peekx = " + vm->peek().toString();
137 }
138 if (startsWith(line, "vm_op"))
139 {
140 char instruction[64];
141 unsigned int operand;
142 sscanf(line.c_str(), "vm_op %63s %d", instruction, &operand);
143 vm->operation(PhasorIR::stringToOpCode(std::string(instruction)), operand);
144 continue;
145 }
146 if (startsWith(line, "vm_getvar"))
147 {
148 int index;
149 sscanf(line.c_str(), "vm_getvar %d", &index);
150 line = "let getvarx = " + vm->getVariable(index).toString();
151 }
152 if (startsWith(line, "vm_setvar"))
153 {
154 char value[64];
155 sscanf(line.c_str(), "vm_setvar %63s", value);
156 line = "var setvarx = " + std::to_string(vm->addVariable(value));
157 }
158 if (startsWith(line, "vm_reset"))
159 {
160 vm->reset(true, true, true);
161 continue;
162 }
163 if (startsWith(line, "exit"))
164 break;
165 if (line.empty())
166 {
167 std::cerr << "Empty line\n";
168 continue;
169 }
170
171 Lexer lexer(line);
172 auto tokens = lexer.tokenize();
173
174 Parser parser(tokens);
175 auto program = parser.parse();
176
177 auto bytecode = codegen.generate(*program, globalVars, nextVarIdx, true);
178
179 // Update persistent state
180 globalVars = bytecode.variables;
181 nextVarIdx = bytecode.nextVarIndex;
182
183 vm->run(bytecode);
184 }
185 catch (const std::exception &e)
186 {
187 std::string errorMsg = std::string(e.what()) + " | " + vm->getInformation() + "\n";
188 error(errorMsg);
189 }
190 }
191 if (ownVM)
192 {
193 delete vm;
194 }
195}
#define error(msg)
Definition Frontend.cpp:21
bool startsWith(const std::string &input, const std::string &prefix)
Definition Frontend.cpp:24
Code generator for Phasor VM.
Definition CodeGen.hpp:243
Bytecode generate(const AST::Program &program, const std::map< std::string, int > &existingVars={}, int nextVarIdx=0, bool replMode=false)
Generate bytecode from program.
Definition CodeGen.cpp:7
Manages loading, registering, and unloading native FFI plugins.
Definition ffi.hpp:48
Lexer.
Definition Lexer.hpp:30
std::vector< Token > tokenize()
Definition Lexer.cpp:25
Parser.
Definition Parser.hpp:12
std::unique_ptr< AST::Program > parse()
Definition Parser.cpp:13
static OpCode stringToOpCode(const std::string &str)
Helper to convert string to OpCode.
Definition PhasorIR.cpp:343
static void registerFunctions(VM &vm)
Register all standard library functions.
Definition StdLib.cpp:10
Virtual Machine.
Definition VM.hpp:18
Value pop()
Pop a value from the stack.
Definition VM.cpp:884
size_t addVariable(const Value &value)
Add a variable to the VM.
Definition VM.cpp:923
void push(const Value &value)
Push a value onto the stack.
Definition VM.cpp:879
void setImportHandler(ImportHandler handler)
Definition VM.cpp:874
void run(const Bytecode &bytecode)
Run the virtual machine.
Definition VM.cpp:9
Value getVariable(const size_t index)
Get a variable from the VM.
Definition VM.cpp:946
Value operation(const OpCode &op, const int &operand1=0, const int &operand2=0, const int &operand3=0, const int &operand4=0, const int &operand5=0)
Execute a single operation.
Definition VM.cpp:26
Value peek()
Peek at the top value on the stack.
Definition VM.cpp:895
void reset(const bool &resetStack=true, const bool &resetFunctions=true, const bool &resetVariables=true)
Reset the virtual machine.
Definition VM.cpp:904
std::string getInformation()
Get VM information for debugging.
Definition VM.cpp:980
std::string toString() const
Convert to string for printing.
Definition Value.hpp:362
void runScript(const std::string &source, VM *vm=nullptr)
Run a script.
Definition Frontend.cpp:33
void runRepl(VM *vm=nullptr)
Run an REPL.
Definition Frontend.cpp:80
std::map< std::string, int > variables
Variable name -> index mapping.
Definition CodeGen.hpp:204