Phasor 3.1.1
Stack VM based Programming Language
Loading...
Searching...
No Matches
Frontend.cpp
Go to the documentation of this file.
6
7#include <fstream>
8#include <print>
9#include <sstream>
10#include <string>
11#include <version.h>
12#include <sscanf.h>
13
14#include "Frontend.hpp"
15#include <nativeerror.h>
16
17bool startsWith(const std::string &input, const std::string &prefix)
18{
19 if (input.size() >= prefix.size() && input.compare(0, prefix.size(), prefix) == 0)
20 {
21 return true;
22 }
23 return false;
24}
25
26int pulsar::Frontend::runScript(const std::string &source, Phasor::VM *vm)
27{
28 int status = 0;
29 bool ownVM = false;
30 CodeGenerator codegen;
31 Lexer lexer(source);
32 Parser parser(lexer.tokenize());
33 auto program = parser.parse();
34 auto bytecode = codegen.generate(*program);
35
36 if (vm == nullptr)
37 {
38 ownVM = true;
39 vm = new VM();
41 }
42
43#if defined(_WIN32)
44 vm->initFFI("plugins");
45#elif defined(__APPLE__)
46 vm->initFFI("/Library/Application Support/org.Phasor.Phasor/plugins");
47#elif defined(__linux__)
48 vm->initFFI("/usr/lib/phasor/plugins/");
49#endif
50
51 vm->setImportHandler([](const std::filesystem::path &path) {
52 std::ifstream file(path);
53 if (!file.is_open())
54 {
55 throw std::runtime_error("Could not open imported file: " + path.string());
56 }
57 std::stringstream buffer;
58 buffer << file.rdbuf();
59 runScript(buffer.str());
60 });
61
62 if (status != 0) {
63 if (ownVM) delete vm;
64 return status;
65 }
66
67 status = vm->run(bytecode);
68
69 if (ownVM)
70 {
71 delete vm;
72 }
73
74 return status;
75}
76
78{
79 int status = 0;
80 bool ownVM = false;
81 CodeGenerator codegen;
82
83 if (vm == nullptr)
84 {
85 ownVM = true;
86 vm = new VM();
88 }
89
90#if defined(_WIN32)
91 vm->initFFI("plugins");
92#elif defined(__APPLE__)
93 vm->initFFI("/Library/Application Support/org.Phasor.Phasor/plugins");
94#elif defined(__linux__)
95 vm->initFFI("/usr/lib/phasor/plugins/");
96#endif
97
98 vm->setImportHandler([](const std::filesystem::path &path) {
99 std::ifstream file(path);
100 if (!file.is_open())
101 {
102 throw std::runtime_error("Could not open imported file: " + path.string());
103 }
104 std::stringstream buffer;
105 buffer << file.rdbuf();
106 runScript(buffer.str());
107 });
108
109 if (status != 0) {
110 if (ownVM) delete vm;
111 std::println(std::cerr, "Failed to create FFI handler!");
112 return status;
113 }
114
115 std::map<std::string, int> globalVars;
116 int nextVarIdx = 0;
117 std::string line;
118 bool cleanExit = false;
119
120 std::println("Pulsar REPL (using Phasor VM v{})\n"
121 "(C) 2026 Daniel McGuire\n\n"
122 "Type 'exit();' to quit. Function declarations will not work.", PHASOR_VERSION_STRING);
123
124
125 while (true)
126 {
127 try
128 {
129 std::print("\n> ");
130 if (!std::getline(std::cin, line))
131 break;
132
133 if (startsWith(line, "exit"))
134 {
135 cleanExit = true;
136 break;
137 }
138 if (line.empty())
139 {
140 std::println(std::cerr, "Empty line");
141 continue;
142 }
143
144 Lexer lexer(line);
145 Parser parser(lexer.tokenize());
146
147 auto program = parser.parse();
148 auto bytecode = codegen.generate(*program, globalVars, nextVarIdx, true);
149
150 globalVars = bytecode.variables;
151 nextVarIdx = bytecode.nextVarIndex;
152
153 status = vm->run(bytecode);
154 }
155 catch (const std::exception &e)
156 {
157 std::string errorMsg = std::string(e.what()) + " | " + vm->getInformation() + "\n";
158 error(errorMsg);
159 }
160 }
161
162 if (ownVM)
163 delete vm;
164
165 if (cleanExit)
166 return 0;
167
168 return status;
169}
bool startsWith(const std::string &input, const std::string &prefix)
Definition Frontend.cpp:17
Code generator for Phasor VM.
Definition CodeGen.hpp:90
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
Lexer.
Definition Lexer.hpp:13
std::vector< Token > tokenize()
Definition Lexer.cpp:26
Parser.
Definition Parser.hpp:13
std::unique_ptr< AST::Program > parse()
Definition Parser.cpp:73
static void registerFunctions(VM &vm)
Definition StdLib.hpp:28
Virtual Machine.
Definition VM.hpp:30
void setImportHandler(const ImportHandler &handler)
Set the import handler for importing modules.
Definition Utility.cpp:67
void initFFI(const std::filesystem::path &path)
Definition VM.hpp:66
int run(const Bytecode &bytecode)
Run the virtual machine Exits -1 on uncaught exception.
Definition Utility.cpp:13
std::string getInformation()
Get VM information for debugging.
Definition Utility.cpp:111
int runRepl(Phasor::VM *vm=nullptr)
Run an REPL.
Definition Frontend.cpp:77
int runScript(const std::string &source, Phasor::VM *vm=nullptr)
Run a script.
Definition Frontend.cpp:26
#define error(msg)
Definition nativeerror.h:11
std::map< std::string, int > variables
Variable name -> index mapping.
Definition CodeGen.hpp:50