Phasor 2.2.0
Stack VM based Programming Language
Loading...
Searching...
No Matches
binding_generator.cpp
Go to the documentation of this file.
1#include <iostream>
2#include <fstream>
3#include <sstream>
4#include <vector>
5#include <string>
6#include <algorithm>
7
8const std::vector<std::string> PATCHES = {
9 "#pragma warning(disable:4996)",
10 "#pragma warning(disable:4244)"
11};
12
13struct Param
14{
15 std::string type;
16 std::string name;
17};
18
20{
21 std::string returnType;
22 std::string name;
23 std::vector<Param> params;
24 std::string rawLine;
25 int lineNumber = 0;
26};
27
28bool isHandleType(const std::string& type)
29{
30 return type == "HANDLE" || type == "HMODULE" || type == "HWND" ||
31 type == "HINSTANCE" || type == "HDC";
32}
33
34bool isSupportedParam(const std::string& type)
35{
36 if (isHandleType(type))
37 return true;
38
39 std::string t = type;
40 t.erase(std::remove(t.begin(), t.end(), ' '), t.end());
41 return t == "BOOL" || t == "DWORD" || t == "int" || t == "LONG" ||
42 t == "UINT" || t == "ULONG" || t == "float" || t == "double" ||
43 t == "LPCSTR" || t == "LPSTR" || t == "constchar*" ||
44 t == "LPCWSTR" || t == "LPWSTR" || t == "constwchar_t*";
45}
46
47std::string trim(const std::string& str)
48{
49 size_t start = str.find_first_not_of(" \t\r\n");
50 if (start == std::string::npos)
51 return "";
52 size_t end = str.find_last_not_of(" \t\r\n");
53 return str.substr(start, end - start + 1);
54}
55
56Function parseFunction(const std::string& line, int lineNumber)
57{
58 Function f;
59 f.rawLine = line;
60 f.lineNumber = lineNumber;
61
62 std::string clean = line;
63 clean.erase(std::remove(clean.begin(), clean.end(), ';'), clean.end());
64
65 size_t paren = clean.find('(');
66 if (paren == std::string::npos)
67 return f;
68
69 std::string retAndName = clean.substr(0, paren);
70 std::string paramStr = clean.substr(paren + 1, clean.find(')') - paren - 1);
71
72 std::istringstream iss(retAndName);
73 iss >> f.returnType >> f.name;
74
75 paramStr = trim(paramStr);
76 if (paramStr.empty() || paramStr == "void")
77 return f;
78
79 std::istringstream pstream(paramStr);
80 std::string param;
81 while (std::getline(pstream, param, ','))
82 {
83 param = trim(param);
84 if (param.empty())
85 continue;
86
87 std::istringstream ps(param);
88 Param p;
89 ps >> p.type >> p.name;
90
91 if (!isSupportedParam(p.type))
92 {
93 f.returnType.clear();
94 break;
95 }
96
97 f.params.push_back(p);
98 }
99
100 return f;
101}
102
103void generateWrapper(const Function& f, std::ostream& out)
104{
105 if (f.returnType.empty())
106 return;
107
108 out << "// " << f.rawLine << " @ln:" << f.lineNumber << "\n";
109 out << "static PhasorValue win32_" << f.name
110 << "(PhasorVM* vm, int argc, const PhasorValue* argv) {\n";
111
112 for (size_t i = 0; i < f.params.size(); ++i)
113 {
114 const auto& p = f.params[i];
115
116 if (isHandleType(p.type))
117 {
118 out << " " << p.type << " " << p.name
119 << " = HandleSystem::resolve<" << p.type
120 << ">(phasor_to_int(argv[" << i << "]));\n";
121 continue;
122 }
123
124 std::string conv;
125 if (p.type == "BOOL")
126 conv = "phasor_to_bool(argv[" + std::to_string(i) + "])";
127 else if (p.type == "DWORD" || p.type == "int" || p.type == "LONG" ||
128 p.type == "UINT" || p.type == "ULONG")
129 conv = "(" + p.type + ")phasor_to_int(argv[" + std::to_string(i) + "])";
130 else if (p.type == "float" || p.type == "double")
131 conv = "(" + p.type + ")phasor_to_float(argv[" + std::to_string(i) + "])";
132 else if (p.type == "LPCSTR" || p.type == "constchar*")
133 conv = "(const char*)phasor_to_string(argv[" + std::to_string(i) + "])";
134 else if (p.type == "LPSTR")
135 conv = "(char*)phasor_to_string(argv[" + std::to_string(i) + "])";
136 else if (p.type == "LPCWSTR" || p.type == "constwchar_t*")
137 conv = "(const wchar_t*)phasor_to_string(argv[" + std::to_string(i) + "])";
138 else
139 conv = "(wchar_t*)phasor_to_string(argv[" + std::to_string(i) + "])";
140
141 out << " " << p.type << " " << p.name << " = " << conv << ";\n";
142 }
143
144 out << " auto result = " << f.name << "(";
145 for (size_t i = 0; i < f.params.size(); ++i)
146 {
147 if (i)
148 out << ", ";
149 out << f.params[i].name;
150 }
151 out << ");\n";
152
154 {
155 out << " auto id = HandleSystem::store(result);\n";
156 out << " return phasor_make_int(id);\n";
157 }
158 else if (f.returnType == "BOOL")
159 out << " return phasor_make_bool(result);\n";
160 else if (f.returnType == "float" || f.returnType == "double")
161 out << " return phasor_make_float(result);\n";
162 else if (f.returnType == "DWORD" || f.returnType == "int" ||
163 f.returnType == "LONG" || f.returnType == "UINT" ||
164 f.returnType == "ULONG")
165 out << " return phasor_make_int(result);\n";
166 else
167 out << " return phasor_make_null();\n";
168
169 out << "}\n\n";
170}
171
172int main(int argc, char** argv)
173{
174 std::string inputFile = "winapi.h";
175 std::string outputFile = "phasor_winapi.cpp";
176
177 if (argc >= 2)
178 inputFile = argv[1];
179 if (argc >= 4 && std::string(argv[2]) == "-o")
180 outputFile = argv[3];
181
182 std::ifstream infile(inputFile);
183 std::ofstream outfile(outputFile);
184
185 outfile << "#define PHASOR_FFI_BUILD_DLL\n";
186 outfile << "#include <PhasorFFI.h>\n";
187 outfile << "#include <windows.h>\n";
188 outfile << "#include \"../src/Bindings/win32/handle.hpp\"\n\n";
189 outfile << "// =====BEGIN PATCHES=====\n";
190 for (const auto& patch : PATCHES)
191 {
192 outfile << patch << "\n";
193 }
194 outfile << "// ======END PATCHES======\n\n";
195
196 std::string line;
197 int lineNumber = 0;
198 std::vector<Function> funcs;
199
200 while (std::getline(infile, line))
201 {
202 lineNumber++;
203 if (line.empty())
204 continue;
205
206 Function f = parseFunction(line, lineNumber);
207 if (!f.returnType.empty())
208 funcs.push_back(f);
209 }
210
211 for (const auto& f : funcs)
212 generateWrapper(f, outfile);
213
214 outfile << "PHASOR_FFI_EXPORT void phasor_plugin_entry(const PhasorAPI* api, PhasorVM* vm) {\n";
215 for (const auto& f : funcs)
216 {
217 outfile << " api->register_function(vm, \"win32_" << f.name
218 << "\", win32_" << f.name << ");\n";
219 }
220 outfile << "}\n";
221}
fn main()
The main execution loop of the Phasor Shell.
Definition Shell.dox:38
bool isSupportedParam(const std::string &type)
std::string trim(const std::string &str)
const std::vector< std::string > PATCHES
bool isHandleType(const std::string &type)
Function parseFunction(const std::string &line, int lineNumber)
void generateWrapper(const Function &f, std::ostream &out)
std::string name
std::string rawLine
std::vector< Param > params
std::string returnType
std::string name
std::string type