symbol-processor/src/cpp.ts

110 lines
3.0 KiB
TypeScript

import { INDENT } from './common';
import { SimpleProperty } from './property';
// List Of Supported C++ Types
const CPP_TYPES = [
'std::string',
'std::vector<',
'std::map<'
];
const CPP_HEADERS = [
'string',
'vector',
'map'
];
// Get Fake Type Name
function isGeneric(type: string) {
return type.endsWith('<');
}
function removeGeneric(type: string) {
if (isGeneric(type)) {
// Remove Generic Parameters
type = type.substring(0, type.length - 1);
}
return type;
}
function getFakeName(type: string) {
return removeGeneric(type).replaceAll('std::', '_std_');
}
// Generate C Type Definition
function generateStruct(type: string) {
// Get Information
const property = new SimpleProperty(0, type, 'fake');
const size = property.propertySize();
const alignment = property.propertyAlignment();
// Generate
let struct = '';
struct += `typedef struct __attribute__((aligned(${alignment}))) __attribute__((packed)) {\n`;
struct += `${INDENT}uchar data[${size}];\n`;
struct += `} ${getFakeName(type)};\n`;
return struct;
}
// Turn A C++ Header Into A C/C++ Headeer
export function fixupCpp(data: string) {
// Replace Types
for (const type of CPP_TYPES) {
// Check If Type Is Generic
if (isGeneric(type)) {
// Generic
while (data.includes(type)) {
// Find Type
let index = data.indexOf(type);
// Replace Type
data = data.substring(0, index) + getFakeName(type) + '(' + data.substring(index + type.length);
// Replace > With (
index = data.indexOf('>', index);
if (index !== -1) {
data = data.substring(0, index) + ')' + data.substring(index + 1);
}
}
} else {
// Normal
data = data.replaceAll(type, getFakeName(type));
}
}
// Setup Macros
let header = '';
header += '// C++ Types\n';
// C++ Support
header += '#ifdef __cplusplus\n';
for (const headerFile of CPP_HEADERS) {
header += `#include <${headerFile}>\n`;
}
for (const type of CPP_TYPES) {
const fakeName = getFakeName(type);
if (isGeneric(type)) {
header += `#define ${fakeName}(...) ${type}__VA_ARGS__>\n`;
} else {
header += `#define ${fakeName} ${type}\n`;
}
}
// C Support
header += '#else\n';
for (let type of CPP_TYPES) {
const fakeName = getFakeName(type);
header += generateStruct(type);
// Strip Generic Information
if (isGeneric(type)) {
type = removeGeneric(type);
header += `#define ${fakeName}(...) ${fakeName}\n`;
}
}
header += '#endif\n';
// Cleanup Macros
let footer = '';
footer += '// Cleanup C++ Types\n';
for (const type of CPP_TYPES) {
const fakeName = getFakeName(type);
footer += `#undef ${fakeName}\n`;
}
// Return
return header + '\n' + data + '\n' + footer;
}