Phasor 2.2.0
Stack VM based Programming Language
Loading...
Searching...
No Matches
CppCodeGenerator.cpp
Go to the documentation of this file.
4#include <fstream>
5#include <iomanip>
6#include <sstream>
7
8namespace Phasor
9{
10
11bool CppCodeGenerator::generate(const Bytecode &bc, const std::filesystem::path &outputPath, const std::string &modName)
12{
13 try
14 {
15 bytecode = &bc;
16 output.str("");
17 output.clear();
18
19 // Determine module name
20 if (modName.empty())
21 {
22 moduleName = sanitizeModuleName(outputPath.stem().string());
23 }
24 else
25 {
27 }
28
29 // Serialize bytecode to binary format
30 BytecodeSerializer serializer;
31 serializedBytecode = serializer.serialize(bc);
32
33 // Generate header file with module name, bytecode, and size
37
38 // Write to file
39 std::ofstream file(outputPath);
40 if (!file.is_open())
41 {
42 return false;
43 }
44
45 file << output.str();
46 file.close();
47
48 return true;
49 }
50 catch (const std::exception &)
51 {
52 return false;
53 }
54}
55
57{
58 std::vector<unsigned char> bytecodeData = parseEmbeddedBytecode(input);
59 BytecodeDeserializer deserializer;
60 return deserializer.deserialize(bytecodeData);
61}
62
64{
65 output << "// Phasor VM Program\n";
66 output << "// Module: " << moduleName << "\n";
67 output << "#pragma once\n";
68 output << "#include <cstddef>\n";
69 output << "#include <string>\n\n";
70}
71
73{
74 output << "std::string moduleName = \"" << moduleName << "\";\n\n";
75}
76
78{
79 output << "inline const unsigned char embeddedBytecode[] = {\n";
80
81 // Write bytecode as hex array
82 for (size_t i = 0; i < serializedBytecode.size(); i++)
83 {
84 if (i % 16 == 0)
85 output << "\t";
86
87 output << "0x" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(serializedBytecode[i]);
88
89 if (i < serializedBytecode.size() - 1)
90 output << ",";
91
92 if (i % 16 == 15)
93 output << "\n";
94 else if (i < serializedBytecode.size() - 1)
95 output << " ";
96 }
97
98 output << std::dec << "\n};\n";
99 output << "inline const size_t embeddedBytecodeSize = " << serializedBytecode.size() << ";\n";
100}
101
102std::vector<unsigned char> CppCodeGenerator::parseEmbeddedBytecode(const std::string &input)
103{
104 std::vector<unsigned char> result;
105 std::istringstream stream(input);
106 std::string token;
107
108 while (stream >> token)
109 {
110 // Only process tokens starting with "0x"
111 if (token.size() >= 3 && token[0] == '0' && (token[1] == 'x' || token[1] == 'X'))
112 {
113 unsigned int byte;
114 std::istringstream hexStream(token);
115 hexStream >> std::hex >> byte;
116 result.push_back(static_cast<unsigned char>(byte));
117 }
118 }
119
120 return result;
121}
122
123std::string CppCodeGenerator::escapeString(const std::string &str)
124{
125 std::ostringstream escaped;
126 for (char c : str)
127 {
128 switch (c)
129 {
130 case '\\':
131 escaped << "\\\\";
132 break;
133 case '\"':
134 escaped << "\\\"";
135 break;
136 case '\n':
137 escaped << "\\n";
138 break;
139 case '\r':
140 escaped << "\\r";
141 break;
142 case '\t':
143 escaped << "\\t";
144 break;
145 default:
146 if (c >= 32 && c <= 126)
147 escaped << c;
148 else
149 escaped << "\\x" << std::hex << std::setw(2) << std::setfill('0')
150 << static_cast<int>(static_cast<unsigned char>(c));
151 break;
152 }
153 }
154 return escaped.str();
155}
156
158{
159 switch (type)
160 {
161 case ValueType::Null:
162 return "Null";
163 case ValueType::Bool:
164 return "Bool";
165 case ValueType::Int:
166 return "Int";
167 case ValueType::Float:
168 return "Float";
170 return "String";
171 default:
172 return "Unknown";
173 }
174}
175
176std::string CppCodeGenerator::sanitizeModuleName(const std::string &name)
177{
178 std::string result;
179 for (char c : name)
180 {
181 if (std::isalnum(c) || c == '_')
182 result += c;
183 else
184 result += '_';
185 }
186
187 // Ensure it starts with a letter or underscore
188 if (!result.empty() && std::isdigit(result[0]))
189 result = "_" + result;
190
191 return result.empty() ? "PhasorModule" : result;
192}
193
194} // namespace Phasor
Bytecode binary format deserializer.
Bytecode deserialize(const std::vector< uint8_t > &data)
Deserialize bytecode from binary buffer.
Bytecode binary format serializer.
std::vector< uint8_t > serialize(const Bytecode &bytecode)
Serialize bytecode to binary buffer.
std::vector< uint8_t > serializedBytecode
Serialized bytecode in .phsb format.
std::string getValueTypeString(ValueType type)
bool generate(const Bytecode &bytecode, const std::filesystem::path &outputPath, const std::string &moduleName="")
Generate C++ header file from bytecode.
std::string escapeString(const std::string &str)
std::vector< unsigned char > parseEmbeddedBytecode(const std::string &input)
std::ostringstream output
Output stream for generated code.
std::string sanitizeModuleName(const std::string &name)
Bytecode generateBytecodeFromEmbedded(const std::string &input)
Generate Bytecode object from embedded bytecode string.
The Phasor Programming Language and Runtime.
Definition AST.hpp:8
ValueType
Runtime value types for the VM.
Definition Value.hpp:17
Complete bytecode structure.
Definition CodeGen.hpp:201