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