[MOD/WIP] Start actually parsing unions in j2s.

This commit is contained in:
lda 2023-12-11 21:24:09 +01:00
parent 3cdd227175
commit 8423712c91
Signed by: lda
GPG key ID: 6898757653ABE3E6

View file

@ -45,6 +45,33 @@ Trim(char c, char *str)
return str; return str;
} }
static char *
JsonTypeFunction(JsonType jsonType)
{
char *func;
switch (jsonType)
{
case JSON_STRING:
func = "String";
break;
case JSON_INTEGER:
func = "Integer";
break;
case JSON_FLOAT:
func = "Float";
break;
case JSON_BOOLEAN:
func = "Boolean";
break;
default:
/* Should not happen */
func = NULL;
break;
}
return func;
}
static JsonType static JsonType
TypeToJsonType(char *type) TypeToJsonType(char *type)
{ {
@ -462,6 +489,7 @@ Main(Array * args)
StreamPrintf(headerFile, "#include <Cytoplasm/Array.h>\n"); StreamPrintf(headerFile, "#include <Cytoplasm/Array.h>\n");
StreamPrintf(headerFile, "#include <Cytoplasm/HashMap.h>\n"); StreamPrintf(headerFile, "#include <Cytoplasm/HashMap.h>\n");
StreamPrintf(headerFile, "#include <Cytoplasm/Int64.h>\n"); StreamPrintf(headerFile, "#include <Cytoplasm/Int64.h>\n");
StreamPrintf(headerFile, "#include <Cytoplasm/Json.h>\n");
StreamPutc(headerFile, '\n'); StreamPutc(headerFile, '\n');
@ -514,7 +542,7 @@ Main(Array * args)
StreamPrintf(headerFile, " %s_AS_%s%s", type, key, comma); StreamPrintf(headerFile, " %s_AS_%s%s", type, key, comma);
} }
Free(keys); ArrayFree(keys);
StreamPrintf(headerFile, "} %sType;\n\n", type); StreamPrintf(headerFile, "} %sType;\n\n", type);
} }
info = StrEquals(typeType, "union") ? "Union" : ""; info = StrEquals(typeType, "union") ? "Union" : "";
@ -565,7 +593,6 @@ Main(Array * args)
StreamPrintf(headerFile, "} %s%s;\n\n", type, info); StreamPrintf(headerFile, "} %s%s;\n\n", type, info);
/* TODO: Add extra "type" enum or something*/
if (StrEquals(typeType, "union")) if (StrEquals(typeType, "union"))
{ {
StreamPrintf(headerFile, "typedef struct %s {\n", type); StreamPrintf(headerFile, "typedef struct %s {\n", type);
@ -835,27 +862,7 @@ Main(Array * args)
} }
else else
{ {
char *func; char *func = JsonTypeFunction(jsonType);
switch (jsonType)
{
case JSON_STRING:
func = "String";
break;
case JSON_INTEGER:
func = "Integer";
break;
case JSON_FLOAT:
func = "Float";
break;
case JSON_BOOLEAN:
func = "Boolean";
break;
default:
/* Should not happen */
func = NULL;
break;
}
if (jsonType == JSON_STRING) if (jsonType == JSON_STRING)
{ {
@ -1105,6 +1112,72 @@ Main(Array * args)
StreamPrintf(implFile, "}\n\n"); StreamPrintf(implFile, "}\n\n");
StreamPutc(headerFile, '\n'); StreamPutc(headerFile, '\n');
} }
else if (StrEquals(typeType, "union"))
{
StreamPrintf(headerFile, "extern int %sFromValue(JsonValue *, %s *, char **);\n", type, type);
StreamPrintf(implFile, "int\n%sFromValue(JsonValue *val, %s *out, char **errp)\n{\n", type, type);
StreamPrintf(implFile, " if (!val || !out)\n");
StreamPrintf(implFile, " {\n");
StreamPrintf(implFile, " *errp = \"Invalid values passed to %sFromValue\";\n", type);
StreamPrintf(implFile, " return 0;\n");
StreamPrintf(implFile, " }\n\n");
for (i = 0; i < ArraySize(keys); i++)
{
char *key = ArrayGet(keys, i);
char *fieldType = JsonValueAsString(JsonGet(fields, 2, key, "type"));
int isSimple = StrEquals(fieldType, "string") ||
StrEquals(fieldType, "boolean") ||
StrEquals(fieldType, "integer") ||
StrEquals(fieldType, "float") ;
int ignore = JsonValueAsBoolean(JsonGet(fields, 2, key, "ignore"));
if (isSimple)
{
JsonType actualType = TypeToJsonType(fieldType);
char *func = JsonTypeFunction(actualType);
StreamPrintf(implFile, " if (JsonValueType(val) == %s)\n", JsonTypeToStr(actualType));
StreamPrintf(implFile, " {\n");
StreamPrintf(implFile, " out->type = %s_AS_%s;\n", type, key);
StreamPrintf(implFile, " out->value.%s = JsonValueAs%s(val);\n\n", key, func);
StreamPrintf(implFile, " return 1;\n");
StreamPrintf(implFile, " }\n");
continue;
}
if (StrEquals(fieldType, "array"))
{
StreamPrintf(implFile, " if (JsonValueType(val) == JSON_ARRAY)\n");
StreamPrintf(implFile, " {\n");
StreamPrintf(implFile, " out->type = %s_AS_%s;\n", type, key);
StreamPrintf(implFile, " out->value.%s = JsonValueAsArray(val);\n\n", key);
StreamPrintf(implFile, " return 1;\n");
StreamPrintf(implFile, " }\n");
continue;
}
if (ignore)
{
continue;
}
StreamPrintf(implFile, " if (JsonValueType(val) == JSON_OBJECT)\n");
StreamPrintf(implFile, " {\n");
StreamPrintf(implFile, " HashMap *json = JsonValueAsObject(val);\n");
StreamPrintf(implFile, " if (!%sFromJson(json, &out->value.%s, errp))\n", fieldType, key, fieldType);
StreamPrintf(implFile, " {\n");
StreamPrintf(implFile, " /* errp is already set */\n");
StreamPrintf(implFile, " return 0;\n");
StreamPrintf(implFile, " }\n");
StreamPrintf(implFile, " out->type = %s_AS_%s;\n", type, key);
StreamPrintf(implFile, " return 1;\n");
StreamPrintf(implFile, " }\n");
/* TODO */
}
StreamPrintf(implFile, " \n");
StreamPrintf(implFile, " *errp = \"Invalid type for %s\";\n", type);
StreamPrintf(implFile, " return 0;\n");
StreamPrintf(implFile, "}\n");
}
else if (StrEquals(typeType, "enum")) else if (StrEquals(typeType, "enum"))
{ {
StreamPrintf(headerFile, "extern int %sFromStr(char *);\n", type); StreamPrintf(headerFile, "extern int %sFromStr(char *);\n", type);