Phasor 2.2.0
Stack VM based Programming Language
Loading...
Searching...
No Matches
ScriptingRuntime.cpp
Go to the documentation of this file.
9#include <filesystem>
10#include <fstream>
11#include <iostream>
12#include <sstream>
13
14#ifdef _WIN32
15#include <Windows.h>
16#define error(msg) MessageBoxA(NULL, std::string(msg).c_str(), "Phasor Runtime Error", MB_OK | MB_ICONERROR)
17#else
18#define error(msg) std::cerr << "Error: " << msg << std::endl
19#endif
20
21namespace Phasor
22{
23
24ScriptingRuntime::ScriptingRuntime(int argc, char *argv[], char *envp[])
25{
26 m_args.envp = envp;
27 parseArguments(argc, argv);
28}
29
31{
32 if (m_args.inputFile.empty())
33 return 0;
34
35 return runSource();
36}
37
39{
40 std::ifstream file(m_args.inputFile);
41 if (!file.is_open())
42 {
43 std::cerr << "Could not open file: " << m_args.inputFile << "\n";
44 return 1;
45 }
46
47 std::stringstream buffer;
48 buffer << file.rdbuf();
49 std::string source = buffer.str();
50
51 try
52 {
53 auto vm = createVm();
54 runSourceString(source, *vm);
55 }
56 catch (const std::exception &e)
57 {
58 std::string errorMsg = std::string(e.what()) + "\n";
59 error(errorMsg);
60 return 1;
61 }
62
63 return 0;
64}
65
66void ScriptingRuntime::runSourceString(const std::string &source, VM &vm)
67{
68 Lexer lexer(source);
69 auto tokens = lexer.tokenize();
70 Parser parser(tokens);
71 auto program = parser.parse();
72
73 if (m_args.verbose)
74 {
75 std::cout << "AST:\n";
76 program->print();
77 std::cout << "\n";
78 }
79
80 CodeGenerator codegen;
81 auto bytecode = codegen.generate(*program);
82
83 vm.run(bytecode);
84}
85
86std::unique_ptr<VM> ScriptingRuntime::createVm()
87{
88 auto vm = std::make_unique<VM>();
90 StdLib::argv = m_args.scriptArgv;
91 StdLib::argc = m_args.scriptArgc;
92 StdLib::envp = m_args.envp;
93
94#if defined(_WIN32)
95 FFI ffi("plugins", vm.get());
96#elif defined(__APPLE__)
97 FFI ffi("/Library/Application Support/org.Phasor.Phasor/plugins", vm.get());
98#elif defined(__linux__)
99 FFI ffi("/opt/Phasor/plugins", vm.get());
100#endif
101
102 vm->setImportHandler([this, vm_ptr = vm.get()](const std::filesystem::path &path) {
103 std::ifstream file(path);
104 if (!file.is_open())
105 throw std::runtime_error("Could not open imported file: " + path.string());
106 std::stringstream buffer;
107 buffer << file.rdbuf();
108 runSourceString(buffer.str(), *vm_ptr);
109 });
110
111 return vm;
112}
113
114void ScriptingRuntime::parseArguments(int argc, char *argv[])
115{
116 int defaultArgLocation = 1;
117 for (int i = 1; i < argc; i++)
118 {
119 std::string arg = argv[i];
120
121 if (arg == "-v" || arg == "--verbose")
122 {
123 m_args.verbose = true;
124 }
125 else if (arg == "-h" || arg == "--help")
126 {
127 showHelp(argv[0]);
128 exit(0);
129 }
130 else
131 {
132 defaultArgLocation = i;
133 m_args.inputFile = arg;
134 break; // Stop parsing after finding the input file
135 }
136 }
137 m_args.scriptArgv = argv + defaultArgLocation;
138 m_args.scriptArgc = argc - defaultArgLocation;
139}
140
141void ScriptingRuntime::showHelp(const std::string &programName)
142{
143 std::string filename = std::filesystem::path(programName).filename().string();
144 std::cout << "Phasor Scripting Runtime\n\n";
145 std::cout << "Usage:\n";
146 std::cout << " " << filename << " [options] [file.phs] [...script args]\n\n";
147 std::cout << "Options:\n";
148 std::cout << " -v, --verbose Enable verbose output (print AST)\n";
149 std::cout << " -h, --help Show this help message\n";
150}
151
152} // namespace Phasor
#define error(msg)
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
std::unique_ptr< VM > createVm()
void showHelp(const std::string &programName)
struct Phasor::ScriptingRuntime::Args m_args
void runSourceString(const std::string &source, VM &vm)
ScriptingRuntime(int argc, char *argv[], char *envp[])
void parseArguments(int argc, char *argv[])
static void registerFunctions(VM &vm)
Register all standard library functions.
Definition StdLib.cpp:10
static char ** argv
Command line arguments.
Definition StdLib.hpp:30
static int argc
Number of command line arguments.
Definition StdLib.hpp:31
static char ** envp
Environment variables.
Definition StdLib.hpp:32
Virtual Machine.
Definition VM.hpp:18
void run(const Bytecode &bytecode)
Run the virtual machine.
Definition VM.cpp:9
The Phasor Programming Language and Runtime.
Definition AST.hpp:8