mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 20:41:20 +00:00
[vkgen] Add support for directly scripted parsing
It's very early, but it does the job for what I needed (storing the string item and line number).
This commit is contained in:
parent
cd1b20dc22
commit
345aa8e094
1 changed files with 186 additions and 97 deletions
|
@ -7,6 +7,7 @@
|
||||||
#include <PropertyList.h>
|
#include <PropertyList.h>
|
||||||
|
|
||||||
#include "vkfielddef.h"
|
#include "vkfielddef.h"
|
||||||
|
#include "vkfieldtype.h"
|
||||||
#include "vkgen.h"
|
#include "vkgen.h"
|
||||||
#include "vkstruct.h"
|
#include "vkstruct.h"
|
||||||
|
|
||||||
|
@ -106,33 +107,124 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
write_function_head (Struct *self)
|
||||||
|
{
|
||||||
|
fprintf (output_file, "static int %s (const plfield_t *field,"
|
||||||
|
" const plitem_t *item, void *data, plitem_t *messages,"
|
||||||
|
" void *context)\n",
|
||||||
|
[self parseFunc]);
|
||||||
|
fprintf (output_file, "{\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
write_function_tail (Struct *self)
|
||||||
|
{
|
||||||
|
fprintf (output_file, "}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
write_type (Struct *self, PLItem *field_dict, string type)
|
||||||
|
{
|
||||||
|
string key = nil;
|
||||||
|
switch (type) {
|
||||||
|
case "QFDictionary": key = ".dictionary"; break;
|
||||||
|
case "QFArray": key = ".array"; break;
|
||||||
|
case "QFBinary": key = ".binary"; break;
|
||||||
|
case "QFString": key = ".string"; break;
|
||||||
|
}
|
||||||
|
PLItem *type_obj = [field_dict getObjectForKey:key];
|
||||||
|
int count = [type_obj numKeys];
|
||||||
|
if (!count) {
|
||||||
|
//FIXME errors
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fprintf (output_file, "\tif (type == %s) {\n", type);
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
string field = [type_obj keyAtIndex:i];
|
||||||
|
PLItem *item = [type_obj getObjectForKey:field];
|
||||||
|
string str = [item string];
|
||||||
|
|
||||||
|
switch (str) {
|
||||||
|
case "$item.string":
|
||||||
|
str = "vkstrdup (context, PL_String (item))";
|
||||||
|
break;
|
||||||
|
case "$item.line":
|
||||||
|
str = "PL_Line (item)";
|
||||||
|
break;
|
||||||
|
case "$name":
|
||||||
|
str = "vkstrdup (context, field->name)";
|
||||||
|
break;
|
||||||
|
case "$index":
|
||||||
|
str = "field->offset";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf (output_file, "\t\t((%s *) data)->%s = %s;\n", [self outname],
|
||||||
|
field, str);
|
||||||
|
}
|
||||||
|
fprintf (output_file, "\t\treturn 1;\n");
|
||||||
|
fprintf (output_file, "\t}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
write_cexpr (Struct *self, Array *field_defs)
|
||||||
|
{
|
||||||
|
fprintf (output_file, "static exprsym_t %s_symbols[] = {\n",
|
||||||
|
[self outname]);
|
||||||
|
if (field_defs) {
|
||||||
|
PLItem *field_def;
|
||||||
|
qfot_var_t *field;
|
||||||
|
|
||||||
|
for (int i = [field_defs count]; i-- > 0; ) {
|
||||||
|
FieldDef *field_def = [field_defs objectAtIndex:i];
|
||||||
|
[field_def writeSymbol];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < self.type.strct.num_fields; i++) {
|
||||||
|
qfot_var_t *field = &self.type.strct.fields[i];
|
||||||
|
if (field.name == "sType" || field.name == "pNext") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Type *field_type = [Type findType: field.type];
|
||||||
|
fprintf (output_file,
|
||||||
|
"\t{\"%s\", &%s, (void *) field_offset (%s, %s)},\n",
|
||||||
|
field.name, [field_type cexprType], [self outname],
|
||||||
|
field.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf (output_file, "\t{ }\n");
|
||||||
|
fprintf (output_file, "};\n");
|
||||||
|
|
||||||
|
fprintf (output_file, "static exprtab_t %s_symtab = {\n", [self outname]);
|
||||||
|
fprintf (output_file, "\t%s_symbols,\n", [self outname]);
|
||||||
|
fprintf (output_file, "};\n");
|
||||||
|
|
||||||
|
fprintf (output_file, "exprtype_t %s_type = {\n", [self outname]);
|
||||||
|
fprintf (output_file, "\t.name = \"%s\",\n", [self outname]);
|
||||||
|
fprintf (output_file, "\t.size = sizeof (%s),\n", [self outname]);
|
||||||
|
fprintf (output_file, "\t.binops = cexpr_struct_binops,\n");
|
||||||
|
fprintf (output_file, "\t.unops = 0,\n");
|
||||||
|
fprintf (output_file, "\t.data = &%s_symtab,\n", [self outname]);
|
||||||
|
fprintf (output_file, "};\n");
|
||||||
|
fprintf (output_file, "\n");
|
||||||
|
fprintf (header_file, "extern exprtype_t %s_type;\n", [self outname]);
|
||||||
|
}
|
||||||
|
|
||||||
-(void) writeTable
|
-(void) writeTable
|
||||||
{
|
{
|
||||||
PLItem *field_dict = [parse getObjectForKey:[self name]];
|
|
||||||
PLItem *new_name = [field_dict getObjectForKey:".name"];
|
|
||||||
PLItem *only = [field_dict getObjectForKey:".only"];
|
|
||||||
Array *field_defs = [Array array];
|
|
||||||
int have_sType = 0;
|
|
||||||
int have_pNext = 0;
|
|
||||||
int readonly = [field_dict string] == "readonly";
|
|
||||||
|
|
||||||
if ([parse string] == "skip") {
|
if ([parse string] == "skip") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PLItem *field_dict = [parse getObjectForKey:[self name]];
|
||||||
|
|
||||||
|
PLItem *new_name = [field_dict getObjectForKey:".name"];
|
||||||
if (new_name) {
|
if (new_name) {
|
||||||
outname = str_hold ([new_name string]);
|
outname = str_hold ([new_name string]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < type.strct.num_fields; i++) {
|
Array *field_defs = [Array array];
|
||||||
qfot_var_t *field = &type.strct.fields[i];
|
PLItem *only = [field_dict getObjectForKey:".only"];
|
||||||
if (field.name == "sType") {
|
|
||||||
have_sType = 1;
|
|
||||||
}
|
|
||||||
if (field.name == "pNext") {
|
|
||||||
have_pNext = 1;
|
|
||||||
write_symtab = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (only) {
|
if (only) {
|
||||||
string field_name = [only string];
|
string field_name = [only string];
|
||||||
qfot_var_t *field = nil;
|
qfot_var_t *field = nil;
|
||||||
|
@ -182,6 +274,44 @@
|
||||||
[field_defs addObject: field_def];
|
[field_defs addObject: field_def];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ([field_dict getObjectForKey:".type"]) {
|
||||||
|
PLItem *type = [field_dict getObjectForKey:".type"];
|
||||||
|
string str = [type string];
|
||||||
|
|
||||||
|
write_function_head (self);
|
||||||
|
fprintf (output_file, "\tpltype_t type = PL_Type (item);\n");
|
||||||
|
if (str) {
|
||||||
|
write_type (self, field_dict, str);
|
||||||
|
} else {
|
||||||
|
for (int i = [type count]; i-- > 0; ) {
|
||||||
|
str = [[type getObjectAtIndex:i] string];
|
||||||
|
write_type (self, field_dict, str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf (output_file,
|
||||||
|
"\tPL_TypeMismatch (messages, item, field->name, %s, type);\n",
|
||||||
|
parseItemType (type));
|
||||||
|
fprintf (output_file, "\treturn 0;\n");
|
||||||
|
write_function_tail (self);
|
||||||
|
write_cexpr (self, field_defs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int have_sType = 0;
|
||||||
|
int have_pNext = 0;
|
||||||
|
int readonly = [field_dict string] == "readonly";
|
||||||
|
|
||||||
|
for (int i = 0; i < type.strct.num_fields; i++) {
|
||||||
|
qfot_var_t *field = &type.strct.fields[i];
|
||||||
|
if (field.name == "sType") {
|
||||||
|
have_sType = 1;
|
||||||
|
}
|
||||||
|
if (field.name == "pNext") {
|
||||||
|
have_pNext = 1;
|
||||||
|
write_symtab = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (int i = [field_defs count]; i-- > 0; ) {
|
for (int i = [field_defs count]; i-- > 0; ) {
|
||||||
FieldDef *field_def = [field_defs objectAtIndex:i];
|
FieldDef *field_def = [field_defs objectAtIndex:i];
|
||||||
[field_def writeParseData];
|
[field_def writeParseData];
|
||||||
|
@ -206,90 +336,49 @@
|
||||||
fprintf (output_file, "\t{ }\n");
|
fprintf (output_file, "\t{ }\n");
|
||||||
fprintf (output_file, "};\n");
|
fprintf (output_file, "};\n");
|
||||||
|
|
||||||
fprintf (output_file, "static int %s (const plfield_t *field,"
|
write_function_head (self);
|
||||||
" const plitem_t *item, void *data, plitem_t *messages,"
|
if (have_sType) {
|
||||||
" void *context)\n",
|
fprintf (output_file, "\t((%s *) data)->sType", [self outname]);
|
||||||
[self parseFunc]);
|
fprintf (output_file, " = %s;\n", [self sTypeName]);
|
||||||
fprintf (output_file, "{\n");
|
|
||||||
if (have_sType) {
|
|
||||||
fprintf (output_file, "\t((%s *) data)->sType", [self outname]);
|
|
||||||
fprintf (output_file, " = %s;\n", [self sTypeName]);
|
|
||||||
}
|
|
||||||
if (label_field) {
|
|
||||||
fprintf (output_file, "\t((%s *) data)->%s", [self outname],
|
|
||||||
label_field);
|
|
||||||
fprintf (output_file, " = vkstrdup (context, field->name);\n");
|
|
||||||
}
|
|
||||||
if (only) {
|
|
||||||
fprintf (output_file, "\tplfield_t *f = &%s_fields[0];\n",
|
|
||||||
[self outname]);
|
|
||||||
fprintf (output_file,
|
|
||||||
"\tif (!PL_CheckType (PL_Type (item), f->type)) {\n"
|
|
||||||
"\t\tPL_TypeMismatch (messages, item, "
|
|
||||||
"f->name, f->type, PL_Type (item));\n"
|
|
||||||
"\t\treturn 0;\n"
|
|
||||||
"\t}\n"
|
|
||||||
"\tvoid *flddata = (byte *)data + f->offset;\n"
|
|
||||||
"\treturn f->parser (f, item, flddata, messages, "
|
|
||||||
"context);\n");
|
|
||||||
} else {
|
|
||||||
fprintf (output_file,
|
|
||||||
"\tif (PL_Type (item) == QFString\n"
|
|
||||||
"\t\t&& !(item = parse_reference (item, \"%s\", "
|
|
||||||
"messages, context))) {\n"
|
|
||||||
"\t\treturn 0;\n"
|
|
||||||
"\t}\n"
|
|
||||||
"\treturn PL_ParseStruct (%s_fields, item, data, "
|
|
||||||
"messages, context);\n",
|
|
||||||
[self outname], [self outname]);
|
|
||||||
}
|
|
||||||
fprintf (output_file, "}\n");
|
|
||||||
if (have_pNext) {
|
|
||||||
fprintf (output_file, "static parserref_t %s_parser = ",
|
|
||||||
[self outname]);
|
|
||||||
fprintf (output_file, "{\"%s\", %s, sizeof(%s)};\n",
|
|
||||||
[self outname], [self parseFunc], [self outname]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf (output_file, "static exprsym_t %s_symbols[] = {\n", [self outname]);
|
|
||||||
if (field_defs) {
|
|
||||||
PLItem *field_def;
|
|
||||||
qfot_var_t *field;
|
|
||||||
|
|
||||||
for (int i = [field_defs count]; i-- > 0; ) {
|
|
||||||
FieldDef *field_def = [field_defs objectAtIndex:i];
|
|
||||||
[field_def writeSymbol];
|
|
||||||
}
|
}
|
||||||
} else {
|
if (label_field) {
|
||||||
for (int i = 0; i < type.strct.num_fields; i++) {
|
fprintf (output_file, "\t((%s *) data)->%s", [self outname],
|
||||||
qfot_var_t *field = &type.strct.fields[i];
|
label_field);
|
||||||
if (field.name == "sType" || field.name == "pNext") {
|
fprintf (output_file, " = vkstrdup (context, field->name);\n");
|
||||||
continue;
|
}
|
||||||
}
|
if (only) {
|
||||||
Type *field_type = [Type findType: field.type];
|
fprintf (output_file, "\tplfield_t *f = &%s_fields[0];\n",
|
||||||
|
[self outname]);
|
||||||
fprintf (output_file,
|
fprintf (output_file,
|
||||||
"\t{\"%s\", &%s, (void *) field_offset (%s, %s)},\n",
|
"\tif (!PL_CheckType (PL_Type (item), f->type)) {\n"
|
||||||
field.name, [field_type cexprType], [self outname],
|
"\t\tPL_TypeMismatch (messages, item, "
|
||||||
field.name);
|
"f->name, f->type, PL_Type (item));\n"
|
||||||
|
"\t\treturn 0;\n"
|
||||||
|
"\t}\n"
|
||||||
|
"\tvoid *flddata = (byte *)data + f->offset;\n"
|
||||||
|
"\treturn f->parser (f, item, flddata, messages, "
|
||||||
|
"context);\n");
|
||||||
|
} else {
|
||||||
|
fprintf (output_file,
|
||||||
|
"\tif (PL_Type (item) == QFString\n"
|
||||||
|
"\t\t&& !(item = parse_reference (item, \"%s\", "
|
||||||
|
"messages, context))) {\n"
|
||||||
|
"\t\treturn 0;\n"
|
||||||
|
"\t}\n"
|
||||||
|
"\treturn PL_ParseStruct (%s_fields, item, data, "
|
||||||
|
"messages, context);\n",
|
||||||
|
[self outname], [self outname]);
|
||||||
|
}
|
||||||
|
write_function_tail (self);
|
||||||
|
if (have_pNext) {
|
||||||
|
fprintf (output_file, "static parserref_t %s_parser = ",
|
||||||
|
[self outname]);
|
||||||
|
fprintf (output_file, "{\"%s\", %s, sizeof(%s)};\n",
|
||||||
|
[self outname], [self parseFunc], [self outname]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf (output_file, "\t{ }\n");
|
|
||||||
fprintf (output_file, "};\n");
|
|
||||||
|
|
||||||
fprintf (output_file, "static exprtab_t %s_symtab = {\n", [self outname]);
|
write_cexpr (self, field_defs);
|
||||||
fprintf (output_file, "\t%s_symbols,\n", [self outname]);
|
|
||||||
fprintf (output_file, "};\n");
|
|
||||||
|
|
||||||
fprintf (output_file, "exprtype_t %s_type = {\n", [self outname]);
|
|
||||||
fprintf (output_file, "\t.name = \"%s\",\n", [self outname]);
|
|
||||||
fprintf (output_file, "\t.size = sizeof (%s),\n", [self outname]);
|
|
||||||
fprintf (output_file, "\t.binops = cexpr_struct_binops,\n");
|
|
||||||
fprintf (output_file, "\t.unops = 0,\n");
|
|
||||||
fprintf (output_file, "\t.data = &%s_symtab,\n", [self outname]);
|
|
||||||
fprintf (output_file, "};\n");
|
|
||||||
fprintf (output_file, "\n");
|
|
||||||
fprintf (header_file, "extern exprtype_t %s_type;\n", [self outname]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void) writeSymtabInit
|
-(void) writeSymtabInit
|
||||||
|
|
Loading…
Reference in a new issue