header generator: return type determination for scripting engine

This commit is contained in:
nakst 2022-02-09 21:04:45 +00:00
parent a30cb8cd83
commit afdff66710
2 changed files with 156 additions and 6 deletions

View File

@ -2049,7 +2049,7 @@ function void *EsFileStoreReadAll(EsFileStore *file, size_t *fileSize) @heap_buf
function bool EsFileStoreWriteAll(EsFileStore *file, const void *data, size_t dataBytes) @buffer_in(data, dataBytes);
function bool EsFileStoreAppend(EsFileStore *file, const void *data, size_t dataBytes) @buffer_in(data, dataBytes);
function EsFileOffsetDifference EsFileStoreGetSize(EsFileStore *file); // Returns -1 on error.
function void *EsFileStoreMap(EsFileStore *file, size_t *fileSize, uint32_t flags) @buffer_out(return, fileSize*) @out(fileSize);
function void *EsFileStoreMap(EsFileStore *file, size_t *fileSize, uint32_t flags) @native();
// These calls require permission_all_files.
function bool EsMountPointGetVolumeInformation(STRING prefix, EsVolumeInformation *information) @out(information); // Returns false if the mount point does not exist.
@ -2362,7 +2362,7 @@ function int EsCRTvsnprintf(char *buffer, size_t bufferSize, EsCString format, v
function EsError EsClipboardAddText(EsClipboard clipboard, STRING text = BLANK_STRING);
function bool EsClipboardHasFormat(EsClipboard clipboard, EsClipboardFormat format);
function bool EsClipboardHasData(EsClipboard clipboard);
function char *EsClipboardReadText(EsClipboard clipboard, size_t *bytes, uint32_t *flags = ES_NULL) @out(flags) @buffer_out(return, bytes*) @out(bytes); // Free with EsHeapFree.
function char *EsClipboardReadText(EsClipboard clipboard, size_t *bytes, uint32_t *flags = ES_NULL) @out(flags) @heap_buffer_out(return, bytes*) @out(bytes); // Free with EsHeapFree.
function EsFileStore *EsClipboardOpen(EsClipboard clipboard); // Open the clipboard for writing.
function EsError EsClipboardCloseAndAdd(EsClipboard clipboard, EsClipboardFormat format, EsFileStore *fileStore, uint32_t flags = ES_FLAGS_DEFAULT);
@ -2507,7 +2507,7 @@ function EsTextbox *EsTextboxCreate(EsElement *parent, uint64_t flags = ES_FLAGS
function bool EsTextboxFind(EsTextbox *textbox, STRING string, int32_t *line, int32_t *byte, uint32_t flags) @out(line) @out(byte);
function void EsTextboxInsert(EsTextbox *textbox, STRING string = BLANK_STRING, bool sendUpdatedMessage = true); // Deletes existing selection first.
function void EsTextboxAppend(EsTextbox *textbox, STRING string = BLANK_STRING, bool sendUpdatedMessage = true); // Ignores the user's selection.
function char *EsTextboxGetContents(EsTextbox *textbox, size_t *bytes = ES_NULL, uint32_t flags = ES_FLAGS_DEFAULT) @buffer_out(return, bytes*) @out(bytes); // Result will be zero-terminated; free with EsHeapFree.
function char *EsTextboxGetContents(EsTextbox *textbox, size_t *bytes = ES_NULL, uint32_t flags = ES_FLAGS_DEFAULT) @heap_buffer_out(return, bytes*) @out(bytes); // Result will be zero-terminated; free with EsHeapFree.
function double EsTextboxGetContentsAsDouble(EsTextbox *textbox, uint32_t flags = ES_FLAGS_DEFAULT);
function size_t EsTextboxGetLineLength(EsTextbox *textbox, uintptr_t line = 0);
function void EsTextboxGetSelection(EsTextbox *textbox, int32_t *fromLine, int32_t *fromByte, int32_t *toLine, int32_t *toByte) @out(fromLine) @out(fromByte) @out(toLine) @out(toByte);

View File

@ -1291,7 +1291,158 @@ void OutputScript(Entry *root) {
}
}
FilePrintFormat(output, "void %s(", entry->children[0].name);
uintptr_t returnValueCount = 0;
for (int pass = 0; pass < 2; pass++) {
if (pass == 1 && returnValueCount > 1) {
FilePrintFormat(output, "tuple[");
}
returnValueCount = 0;
for (int i = 0; i < arrlen(entry->children); i++) {
Entry argument = entry->children[i];
assert(argument.type == ENTRY_VARIABLE);
bool isVoidReturn = 0 == strcmp(argument.variable.type, "void") && !argument.variable.pointer;
bool isOutput = i == 0 && !isVoidReturn;
for (int i = 0; i < arrlen(entry->annotations); i++) {
if ((0 == strcmp(entry->annotations[i].name, "out")
|| 0 == strcmp(entry->annotations[i].name, "buffer_out"))
&& 0 == strcmp(entry->annotations[i].children[0].name, argument.name)) {
isOutput = true;
}
}
char nameWithAsteriskSuffix[256];
assert(strlen(argument.name) < sizeof(nameWithAsteriskSuffix) - 2);
strcpy(nameWithAsteriskSuffix, argument.name);
strcat(nameWithAsteriskSuffix, "*");
for (int i = 0; i < arrlen(entry->annotations); i++) {
if ((0 == strcmp(entry->annotations[i].name, "heap_array_out")
|| 0 == strcmp(entry->annotations[i].name, "heap_buffer_out"))
&& 0 == strcmp(entry->annotations[i].children[1].name, nameWithAsteriskSuffix)) {
assert(isOutput);
isOutput = false;
}
}
if (!isOutput) {
continue;
}
returnValueCount++;
if (pass == 0) {
continue;
}
if (returnValueCount > 1) {
FilePrintFormat(output, ", ");
}
bool foundType = false;
int pointer = argument.variable.pointer;
for (int i = 0; i < arrlen(entry->annotations); i++) {
if ((0 == strcmp(entry->annotations[i].name, "heap_array_out")
|| 0 == strcmp(entry->annotations[i].name, "heap_buffer_out"))
&& 0 == strcmp(entry->annotations[i].children[1].name, nameWithAsteriskSuffix)) {
assert(isOutput);
isOutput = false;
}
}
for (int i = 0; i < arrlen(entry->annotations); i++) {
if ((0 == strcmp(entry->annotations[i].name, "out"))
&& 0 == strcmp(entry->annotations[i].children[0].name, argument.name)) {
pointer--;
}
}
bool isArray = false;
const char *argumentName = i ? argument.name : "return";
for (int i = 0; i < arrlen(entry->annotations); i++) {
if ((0 == strcmp(entry->annotations[i].name, "heap_array_out")
|| 0 == strcmp(entry->annotations[i].name, "heap_matrix_out")
|| 0 == strcmp(entry->annotations[i].name, "heap_buffer_out")
|| 0 == strcmp(entry->annotations[i].name, "fixed_buffer_out")
|| 0 == strcmp(entry->annotations[i].name, "buffer_out"))
&& 0 == strcmp(entry->annotations[i].children[0].name, argumentName)) {
isArray = 0 == strcmp(entry->annotations[i].name, "heap_array_out");
if (isArray) {
pointer--;
} else {
foundType = true;
FilePrintFormat(output, "str");
}
}
}
if (foundType) {
} else if (pointer == 0) {
if (ScriptWriteBasicType(argument.variable.type)) {
foundType = true;
} else {
for (int k = 0; k < arrlen(root->children); k++) {
if (!root->children[k].name) continue;
if (strcmp(argument.variable.type, root->children[k].name)) continue;
if (root->children[k].type == ENTRY_TYPE_NAME) {
if (ScriptWriteBasicType(root->children[k].variable.type)) {
foundType = true;
}
} else if (root->children[k].type == ENTRY_ENUM) {
FilePrintFormat(output, "%s", root->children[k].name);
foundType = true;
} else if (root->children[k].type == ENTRY_STRUCT) {
FilePrintFormat(output, "%s", root->children[k].name);
foundType = true;
}
}
}
} else if (pointer == 1) {
for (int k = 0; k < arrlen(root->children); k++) {
if (!root->children[k].name) continue;
if (strcmp(argument.variable.type, root->children[k].name)) continue;
if (root->children[k].type == ENTRY_API_TYPE) {
FilePrintFormat(output, "%s", root->children[k].name);
foundType = true;
} else if (root->children[k].type == ENTRY_STRUCT) {
FilePrintFormat(output, "%s", root->children[k].name);
foundType = true;
}
}
if (!foundType && 0 == strcmp(argument.variable.type, "ES_INSTANCE_TYPE")) {
FilePrintFormat(output, "EsInstance");
foundType = true;
}
}
if (isArray) {
FilePrintFormat(output, "[]");
}
if (!foundType) {
assert(false);
}
}
if (pass == 1 && returnValueCount > 1) {
FilePrintFormat(output, "]");
}
}
if (returnValueCount == 0) {
FilePrintFormat(output, "void");
}
FilePrintFormat(output, " %s(", entry->children[0].name);
bool firstArgument = true;
@ -1307,8 +1458,7 @@ void OutputScript(Entry *root) {
&& 0 == strcmp(entry->annotations[i].children[0].name, argument->name)) {
goto skipArgument;
} else if ((0 == strcmp(entry->annotations[i].name, "array_in")
|| 0 == strcmp(entry->annotations[i].name, "buffer_in")
|| 0 == strcmp(entry->annotations[i].name, "buffer_out"))
|| 0 == strcmp(entry->annotations[i].name, "buffer_in"))
&& 0 == strcmp(entry->annotations[i].children[1].name, argument->name)) {
goto skipArgument;
} else if ((0 == strcmp(entry->annotations[i].name, "buffer_in")