mirror of
https://github.com/sigmasternchen/libargo
synced 2025-03-15 05:08:54 +00:00
codegen looks good
This commit is contained in:
parent
46e6d00b57
commit
e64d22b9d1
1 changed files with 125 additions and 10 deletions
|
@ -3,25 +3,139 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "codegen.h"
|
||||
#include "helper.h"
|
||||
|
||||
struct declarsinfo* declarations;
|
||||
|
||||
extern int yyparse();
|
||||
|
||||
void generateCodeStruct(FILE* output, struct structinfo* info) {
|
||||
fprintf(output, "Struct %s", info->names[0]);
|
||||
if (info->names[1]) {
|
||||
fprintf(output, ", %s", info->names[1]);
|
||||
}
|
||||
void generatePreamble(FILE* output) {
|
||||
fprintf(output, "#include <stdlib.h>\n");
|
||||
fprintf(output, "#include <stdbool.h>\n");
|
||||
fprintf(output, "#include <errno.h>\n");
|
||||
fprintf(output, "#include <alloc.h>\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "#include <json.h>\n");
|
||||
fprintf(output, "#include <marshall.h>\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "extern void _marshallPanic(const char*, const char*);\n");
|
||||
fprintf(output, "extern void _registerMarshaller(int, const char**, (jsonValue_t*)(*)(void*), (void*)(*)(jsonValue_t*));\n");
|
||||
fprintf(output, "\n");
|
||||
}
|
||||
|
||||
char* fixStructName(char* _name) {
|
||||
char* name = strdup(_name);
|
||||
if (name == NULL) {
|
||||
panic("strdup");
|
||||
}
|
||||
|
||||
for (size_t i = 0; name[i] != '\0'; i++) {
|
||||
if (name[i] == ' ') {
|
||||
name[i] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
char* generateMarshallFunction(FILE* output, struct structinfo* info, char* suffix) {
|
||||
#define MARSHALL_FUNCTION_PREFIX "_json_marshall_value_"
|
||||
|
||||
char* functionName = malloc(strlen(MARSHALL_FUNCTION_PREFIX) + strlen(suffix) + 1);
|
||||
if (functionName == NULL) {
|
||||
panic("malloc");
|
||||
}
|
||||
strcpy(functionName, MARSHALL_FUNCTION_PREFIX);
|
||||
strcat(functionName, suffix);
|
||||
|
||||
fprintf(output, "static jsonValue_t* %s(%s* d) {\n", functionName, info->names[0]);
|
||||
fprintf(output, "\tif (d == NULL)\n");
|
||||
fprintf(output, "\t\treturn json_null();\n");
|
||||
fprintf(output, "\tretuen json_object(true, %d\n", info->memberno);
|
||||
|
||||
for (size_t i = 0; i < info->memberno; i++) {
|
||||
struct memberinfo* member = info->members[i];
|
||||
|
||||
fprintf(output, "\t\t\"%s\", ", member->name);
|
||||
|
||||
const char* reference = "";
|
||||
|
||||
if (!member->type->isPointer) {
|
||||
reference = "&";
|
||||
}
|
||||
|
||||
fprintf(output, "_json_marshall_value(\"%s\", %s(d->%s))%s\n", member->type->type, reference, member->name, i == info->memberno - 1 ? "," : "");
|
||||
}
|
||||
|
||||
fprintf(output, "\t);\n");
|
||||
fprintf(output, "}\n\n");
|
||||
|
||||
return functionName;
|
||||
}
|
||||
|
||||
char* generateUnmarshallFunction(FILE* output, struct structinfo* info, char* suffix) {
|
||||
#define UNMARSHALL_FUNCTION_PREFIX "_json_unmarshall_value_"
|
||||
|
||||
char* functionName = malloc(strlen(UNMARSHALL_FUNCTION_PREFIX) + strlen(suffix) + 1);
|
||||
if (functionName == NULL) {
|
||||
panic("malloc");
|
||||
}
|
||||
strcpy(functionName, UNMARSHALL_FUNCTION_PREFIX);
|
||||
strcat(functionName, suffix);
|
||||
|
||||
fprintf(output, "static %s* %s(jsonValue_t* v) {\n", info->names[0], functionName);
|
||||
fprintf(output, "\tif (v->type != JSON_OBJECT) {\n");
|
||||
fprintf(output, "\t\terrno = EINVAL;\n");
|
||||
fprintf(output, "\t\treturn NULL;\n");
|
||||
fprintf(output, "\t}\n");
|
||||
fprintf(output, "\t%s* d = malloc(sizeof(%s));\n", info->names[0], info->names[0]);
|
||||
fprintf(output, "\tif (d == NULL)\n");
|
||||
fprintf(output, "\t\treturn NULL;\n");
|
||||
fprintf(output, "\tvoid* tmp;\n");
|
||||
|
||||
|
||||
for (size_t i = 0; i < info->memberno; i++) {
|
||||
fprintf(output, " Member %s (%s%s)\n",
|
||||
info->members[i]->name,
|
||||
info->members[i]->type->type,
|
||||
info->members[i]->type->isPointer ? " pointer" : ""
|
||||
);
|
||||
struct memberinfo* member = info->members[i];
|
||||
fprintf(output, "\ttmp = _json_unmarshall_value(\"%s\", json_object_get(v, \"%s\");\n", member->type->type, member->name);
|
||||
if (member->type->isPointer) {
|
||||
fprintf(output, "\td->%s = (%s*) tmp;\n", member->name, member->type->type);
|
||||
} else {
|
||||
fprintf(output, "\tif (tmp == NULL) {\n");
|
||||
fprintf(output, "\t\terrno = EINVAL;\n");
|
||||
fprintf(output, "\t\tfree(d);\n");
|
||||
fprintf(output, "\t\treturn NULL;\n");
|
||||
fprintf(output, "\t} else {\n");
|
||||
fprintf(output, "\t\td->%s = *((%s*) tmp);\n", member->name, member->type->type);
|
||||
fprintf(output, "\t\tfree(tmp);\n");
|
||||
fprintf(output, "\t}\n");
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(output, "\treturn d;\n");
|
||||
|
||||
fprintf(output, "}\n\n");
|
||||
|
||||
return functionName;
|
||||
}
|
||||
|
||||
void generateCodeStruct(FILE* output, struct structinfo* info) {
|
||||
char* suffix = fixStructName(info->names[0]);
|
||||
|
||||
char* marshall = generateMarshallFunction(output, info, suffix);
|
||||
char* unmarshall = generateUnmarshallFunction(output, info, suffix);
|
||||
|
||||
fprintf(output, "__attribute__((constructor)) static void _register_marshaller_%s_() {\n", suffix);
|
||||
int namesno = info->names[1] == 0 ? 1 : 2;
|
||||
fprintf(output, "\tchar* tmp = alloca(sizeof(char*) * %d);\n", namesno);
|
||||
fprintf(output, "\ttmp[0] = info->names[0];\n");
|
||||
fprintf(output, "\ttmp[1] = info->names[1];\n");
|
||||
fprintf(output, "\t_registerMarshaller(%d, tmp, &%s, &%s);\n", namesno, marshall, unmarshall);
|
||||
fprintf(output, "}\n\n");
|
||||
|
||||
free(suffix);
|
||||
|
||||
free(marshall);
|
||||
free(unmarshall);
|
||||
}
|
||||
|
||||
void generateCode(FILE* output) {
|
||||
|
@ -36,6 +150,7 @@ int main(void) {
|
|||
return result;
|
||||
}
|
||||
|
||||
generatePreamble(stdout);
|
||||
generateCode(stdout);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue