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