25 SetConsoleTitleA(title);
33#define setupConsole() \
34 AttachConsole(ATTACH_PARENT_PROCESS); \
35 { FILE* _f; freopen_s(&_f, "CONOUT$", "w", stdout); } \
36 { FILE* _f; freopen_s(&_f, "CONOUT$", "w", stderr); } \
39std::string getCommandLine(LPSTR &lpszCmdLine) {
40 std::string cmdline = lpszCmdLine;
41 return (cmdline.size() >= 2 && cmdline.starts_with(
'"') && cmdline.ends_with(
'"')) ? cmdline.substr(1, cmdline.size() - 2) : cmdline;
48#define PHASOR_API __declspec(dllexport)
49#elif defined(__GNUC__) || defined(__clang__)
50#define PHASOR_API __attribute__((visibility("default")))
59 return PHASOR_VERSION_STRING;
62 PHASOR_API int exec(
void *vmPtr,
const unsigned char *bytecode,
size_t bytecodeSize,
const char *moduleName,
63 int argc,
const char **argv)
68 std::vector<Phasor::u8> bytecodeData(bytecode, bytecode + bytecodeSize);
71 return NativeRT.
run();
73 catch (
const std::exception &e)
75 msg(std::string(moduleName) +
": " + e.what());
80 PHASOR_API int execFuncInt(
void *vmPtr,
const unsigned char *bytecode,
size_t bytecodeSize,
const char *moduleName,
81 int argc,
const char **argv,
const char *functionName)
86 std::vector<Phasor::u8> bytecodeData(bytecode, bytecode + bytecodeSize);
91 catch (
const std::exception &e)
93 msg(std::string(moduleName) +
": " + e.what());
99 const char *moduleName,
int argc,
const char **argv,
const char *functionName)
102 static std::string ret;
105 std::vector<Phasor::u8> bytecodeData(bytecode, bytecode + bytecodeSize);
115 catch (
const std::exception &e)
117 msg(std::string(moduleName) +
": " + e.what());
130 catch (
const std::exception &e)
132 msg(std::string(moduleName) +
": " + e.what());
144 catch (
const std::exception &e)
146 msg(std::string(moduleName) +
": " + e.what());
152 unsigned char *buffer,
size_t bufferSize,
size_t *outSize)
162 if (modulePath && std::filesystem::exists(modulePath))
167 auto ast = parser.
parse();
169 std::vector<Phasor::u8> data = serializer.
serialize(bc);
172 *outSize = data.size();
177 if (bufferSize < data.size())
180 std::memcpy(buffer, data.data(), data.size());
184 catch (
const std::exception &e)
186 msg(std::string(moduleName) +
": " + e.what());
191 PHASOR_API bool compilePUL(
const char *script,
const char *moduleName,
unsigned char *buffer,
size_t bufferSize,
202 auto ast = parser.
parse();
204 std::vector<Phasor::u8> data = serializer.
serialize(bc);
207 *outSize = data.size();
212 if (bufferSize < data.size())
215 std::memcpy(buffer, data.data(), data.size());
219 catch (
const std::exception &e)
221 msg(std::string(moduleName) +
": " + e.what());
252 vm->
reset(
true, resetFunctions, resetVariables);
265#if defined(_SHARED) && defined(_WIN32)
266 PHASOR_API void CALLBACK PhasorSourceStringEvaluateA(HWND hwnd, HINSTANCE, LPSTR lpszCmdLine,
int)
269 int exitCode =
evaluatePHS(NULL, getCommandLine(lpszCmdLine).c_str(), __func__,
"",
false);
272 std::string message = std::format(
"\nFailed with code {}\n", exitCode);
273 MessageBoxA(hwnd, message.c_str(), __func__, MB_OK | MB_ICONERROR);
277 PHASOR_API void CALLBACK PhasorSourceFileEvaluateA(HWND hwnd, HINSTANCE, LPSTR lpszCmdLine,
int)
280 std::filesystem::path file = getCommandLine(lpszCmdLine);
281 std::string scriptText;
283 if (!std::filesystem::exists(file))
285 std::string message = std::format(
"File \"{}\" does not exist\n", file.filename().string());
286 MessageBoxA(hwnd, message.c_str(), __func__, MB_OK | MB_ICONERROR);
290 std::ifstream fileStream(file);
293 std::string message = std::format(
"File \"{}\" could not be opened\n", file.filename().string());
294 MessageBoxA(hwnd, message.c_str(), __func__, MB_OK | MB_ICONERROR);
298 fileStream.seekg(0, std::ios::end);
299 scriptText.resize(
static_cast<size_t>(fileStream.tellg()));
300 fileStream.seekg(0, std::ios::beg);
302 fileStream.read(scriptText.data(), scriptText.size());
304 int exitCode =
evaluatePHS(NULL, scriptText.c_str(), __func__, file.parent_path().string().c_str(),
false);
307 std::string message = std::format(
"\nFailed with code {}\n", exitCode);
308 MessageBoxA(hwnd, message.c_str(), __func__, MB_OK | MB_ICONERROR);
312 PHASOR_API void CALLBACK PulsarSourceStringEvaluateA(HWND hwnd, HINSTANCE, LPSTR lpszCmdLine,
int)
315 int exitCode =
evaluatePUL(NULL, getCommandLine(lpszCmdLine).c_str(), __func__);
318 std::string message = std::format(
"\nFailed with code {}\n", exitCode);
319 MessageBoxA(hwnd, message.c_str(), __func__, MB_OK | MB_ICONERROR);
323 PHASOR_API void CALLBACK PulsarSourceFileEvaluateA(HWND hwnd, HINSTANCE, LPSTR lpszCmdLine,
int)
326 std::filesystem::path file = getCommandLine(lpszCmdLine);
327 std::string scriptText;
329 if (!std::filesystem::exists(file))
331 std::string message = std::format(
"File \"{}\" does not exist\n", file.filename().string());
332 MessageBoxA(hwnd, message.c_str(), __func__, MB_OK | MB_ICONERROR);
336 std::ifstream fileStream(file);
339 std::string message = std::format(
"File \"{}\" could not be opened\n", file.filename().string());
340 MessageBoxA(hwnd, message.c_str(), __func__, MB_OK | MB_ICONERROR);
344 fileStream.seekg(0, std::ios::end);
345 scriptText.resize(
static_cast<size_t>(fileStream.tellg()));
346 fileStream.seekg(0, std::ios::beg);
348 fileStream.read(scriptText.data(), scriptText.size());
350 int exitCode =
evaluatePUL(NULL, scriptText.c_str(), __func__);
353 std::string message = std::format(
"\nFailed with code {}\n", exitCode);
354 MessageBoxA(hwnd, message.c_str(), __func__, MB_OK | MB_ICONERROR);
358 PHASOR_API void CALLBACK PhasorBytecodeFileExecuteA(HWND hwnd, HINSTANCE, LPSTR lpszCmdLine,
int)
361 std::filesystem::path file = getCommandLine(lpszCmdLine);
362 if (!std::filesystem::exists(file))
364 std::string message = std::format(
"File \"{}\" does not exist\n", file.filename().string());
365 MessageBoxA(hwnd, message.c_str(), __func__, MB_OK | MB_ICONERROR);
368 if (file.extension().string() !=
".phsb")
370 std::string message = std::format(
"File \"{}\" is not a .phsb file\n", file.filename().string());
371 MessageBoxA(hwnd, message.c_str(), __func__, MB_OK | MB_ICONERROR);
376 std::array<const char *, 2> args = {
"phasorrt.dll", __func__};
378 int exitCode = NativeRT.run();
381 std::string message = std::format(
"\nFailed with code {}\n", exitCode);
382 MessageBoxA(hwnd, message.c_str(), __func__, MB_OK | MB_ICONERROR);
PHASOR_API const char * execFuncString(void *vmPtr, const unsigned char *bytecode, size_t bytecodeSize, const char *moduleName, int argc, const char **argv, const char *functionName)
Executes a function from pre-compiled Phasor bytecode, and casts return to an string.
PHASOR_API bool compilePHS(const char *script, const char *moduleName, const char *modulePath, unsigned char *buffer, size_t bufferSize, size_t *outSize)
Compiles a Phasor Programming Language script into Phasor VM bytecode.
PHASOR_API int evaluatePUL(void *vmPtr, const char *script, const char *moduleName)
Executes a Pulsar Scripting Language script.
void set_terminal_title(const char *title)
PHASOR_API bool compilePUL(const char *script, const char *moduleName, unsigned char *buffer, size_t bufferSize, size_t *outSize)
Compiles a Pulsar Scripting Language script into Phasor VM bytecode.
PHASOR_API int evaluatePHS(void *vmPtr, const char *script, const char *moduleName, const char *modulePath, bool verbose)
Executes a Phasor Programming Language script.
PHASOR_API const char * getVersion()
Get the version string for Phasor VM.
PHASOR_API bool freeState(void *vmPtr)
Frees an existing state instance.
PHASOR_API int execFuncInt(void *vmPtr, const unsigned char *bytecode, size_t bytecodeSize, const char *moduleName, int argc, const char **argv, const char *functionName)
Executes a function from pre-compiled Phasor bytecode, and casts return to an integer.
PHASOR_API int exec(void *vmPtr, const unsigned char *bytecode, size_t bytecodeSize, const char *moduleName, int argc, const char **argv)
Executes pre-compiled Phasor bytecode.
PHASOR_API void * createState()
Creates a new state instance.
PHASOR_API void initStdLib(void *vmPtr)
Register standard library to state instance.
PHASOR_API bool resetState(void *vmPtr, bool resetFunctions, bool resetVariables)
Resets the state.
PHASOR_API bool isErrorStatus(void *vmPtr)
Checks if the state is in an error status.
Bytecode binary format deserializer.
Bytecode loadFromFile(const std::filesystem::path &filename)
Load bytecode from .phsb file.
Bytecode binary format serializer.
std::vector< u8 > serialize(const Bytecode &bytecode)
Serialize bytecode to binary buffer.
Code generator for Phasor VM.
Bytecode generate(const AST::Program &program, const std::unordered_map< std::string, int > &existingVars={}, int nextVarIdx=0, bool replMode=false)
Generate bytecode from program.
std::vector< Token > tokenize()
CLI wrapper for running Phasor scripts and bytecode in-process.
int runFunctionInt(std::string functionName)
std::optional< std::string > runFunctionString(std::string functionName)
std::unique_ptr< AST::Program > parse()
void setSourcePath(const std::filesystem::path &path)
static void registerFunctions(VM &vm)
void reset(const bool &resetStack=true, const bool &resetFunctions=true, const bool &resetVariables=true)
Reset the virtual machine.
int runScript(const std::string &source, VM *vm, const std::filesystem::path &path="", bool verbose=false)
Run a script.
int runScript(const std::string &source, Phasor::VM *vm=nullptr)
Run a script.