Skip to content

Commit

Permalink
add element_type docs and commit further to namer and remove kkeep
Browse files Browse the repository at this point in the history
  • Loading branch information
danlapid committed Sep 20, 2022
1 parent 581ffe1 commit a5278bd
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 57 deletions.
6 changes: 6 additions & 0 deletions src/bfbs_gen.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ class BaseBfbsGenerator : public BfbsGenerator {
}

protected:
// GetObject returns the underlying object struct of the given type
// if element_type is true and GetObject is a list of objects then
// GetObject will correctly return the object struct of the vector's elements
const reflection::Object *GetObject(const reflection::Type *type,
bool element_type = false) const {
const reflection::BaseType base_type =
Expand All @@ -141,6 +144,9 @@ class BaseBfbsGenerator : public BfbsGenerator {
return nullptr;
}

// GetEnum returns the underlying enum struct of the given type
// if element_type is true and GetEnum is a list of enums then
// GetEnum will correctly return the enum struct of the vector's elements
const reflection::Enum *GetEnum(const reflection::Type *type,
bool element_type = false) const {
const reflection::BaseType base_type =
Expand Down
123 changes: 66 additions & 57 deletions src/bfbs_gen_nim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ std::set<std::string> NimKeywords() {
}

Namer::Config NimDefaultConfig() {
return { /*types=*/Case::kKeep,
/*constants=*/Case::kScreamingSnake,
/*methods=*/Case::kUpperCamel,
return { /*types=*/Case::kUpperCamel,
/*constants=*/Case::kUpperCamel,
/*methods=*/Case::kLowerCamel,
/*functions=*/Case::kUpperCamel,
/*fields=*/Case::kLowerCamel,
/*variable=*/Case::kLowerCamel,
/*variants=*/Case::kKeep,
/*variants=*/Case::kUpperCamel,
/*enum_variant_seperator=*/".",
/*escape_keywords=*/Namer::Config::Escape::AfterConvertingCase,
/*namespaces=*/Case::kKeep,
Expand All @@ -85,29 +85,6 @@ const std::set<std::string> builtin_types = {
"float64", "string", "int", "uint", "uoffset", "Builder"
};

// Returns the correct name for the type
// Type:
// MyGame.Example.Monster:
// Current:
// Monster
// Imported:
// MyGame_Example_Monster.Monster
std::string Denamespace(const std::string &s, bool current = false) {
if (builtin_types.find(s) != builtin_types.end()) { return s; }
std::string prefix;
const size_t pos = s.find_last_of(".");
if (pos != std::string::npos) { prefix = s.substr(0, pos); }
std::string suffix = s.substr(pos + 1);
if (current) {
return suffix;
} else {
std::string underscored = prefix;
underscored += underscored.empty() ? "" : "_";
std::replace(underscored.begin(), underscored.end(), '.', '_');
return underscored + suffix + "." + suffix;
}
}

class NimBfbsGenerator : public BaseBfbsGenerator {
public:
explicit NimBfbsGenerator(const std::string &flatc_version)
Expand Down Expand Up @@ -190,13 +167,13 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
base_type == r::Obj || base_type == r::Union) {
GenerateDocumentation(field->documentation(), "", code);

std::string getter_signature = "func " + field_name +
std::string getter_signature = "func " + namer_.Method(field_name) +
"*(self: " + object_name +
"): " + field_type + " =\n";
std::string getter_code;
std::string setter_signature = "func `" + field_name +
"=`*(self: var " + object_name +
", n: " + field_type + "): bool =\n";
std::string setter_signature =
"func `" + namer_.Method(field_name + "=") + "`*(self: var " +
object_name + ", n: " + field_type + "): bool =\n";
std::string setter_code;

if (base_type == r::Obj || base_type == r::Union ||
Expand Down Expand Up @@ -253,14 +230,14 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
}

// Get vector length:
code += "func " + field_name + "Length*(self: " + object_name +
"): int = \n";
code += "func " + namer_.Method(field_name + "Length") +
"*(self: " + object_name + "): int = \n";
code += " " + offset_prefix;
code += " " + offset_prefix_2;
code += " return self.tab.VectorLen(o)\n";

// Get single vector field:
code += "func " + field_name + "*(self: " + object_name +
code += "func " + namer_.Method(field_name) + "*(self: " + object_name +
", j: int): " + GenerateType(field->type(), true) + " = \n";
code += " " + offset_prefix;
code += " " + offset_prefix_2;
Expand All @@ -273,7 +250,7 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
"\n";

// Get entire vector:
code += "func " + field_name + "*(self: " + object_name +
code += "func " + namer_.Method(field_name) + "*(self: " + object_name +
"): " + GenerateType(field->type()) + " = \n";
code += " let len = self." + field_name + "Length\n";
code += " for i in countup(0, len - 1):\n";
Expand All @@ -285,14 +262,16 @@ class NimBfbsGenerator : public BaseBfbsGenerator {

// Create all the builders
if (object->is_struct()) {
code += "proc " + object_name + "Create*(self: var Builder";
code += "proc " + namer_.Function(object_name + "Create") +
"*(self: var Builder";
code += GenerateStructBuilderArgs(object);
code += "): uoffset =\n";
code += AppendStructBuilderBody(object);
code += " return self.Offset()\n";
} else {
// Table builders
code += "proc " + object_name + "Start*(builder: var Builder) =\n";
code += "proc " + namer_.Function(object_name + "Start") +
"*(builder: var Builder) =\n";
code += " builder.StartObject(" + NumToString(object->fields()->size()) +
")\n";

Expand All @@ -303,15 +282,16 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
const std::string variable_name = namer_.Variable(field->name()->str());
const std::string variable_type = GenerateTypeBasic(field->type());

code += "proc " + object_name + "Add" + field_name +
code += "proc " + namer_.Function(object_name + "Add" + field_name) +
"*(builder: var Builder, " + variable_name + ": " +
variable_type + ") =\n";
code += " builder.Prepend" + GenerateMethod(field) + "Slot(" +
NumToString(field->id()) + ", " + variable_name + ", default(" +
variable_type + "))\n";

if (IsVector(field->type()->base_type())) {
code += "proc " + object_name + "Start" + field_name +
code += "proc " +
namer_.Function(object_name + "Start" + field_name) +
"Vector*(builder: var Builder, numElems: uoffset) =\n";

const int32_t element_size = field->type()->element_size();
Expand All @@ -325,7 +305,8 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
}
});

code += "proc " + object_name + "End*(builder: var Builder): uoffset =\n";
code += "proc " + namer_.Function(object_name + "End") +
"*(builder: var Builder): uoffset =\n";
code += " return builder.EndObject()\n";
}
EmitCodeBlock(code, object_name, ns, object->declaration_file()->str());
Expand Down Expand Up @@ -416,15 +397,35 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
}
}

std::string Denamespace(const std::string &s, std::string &importns,
std::string &ns) const {
if (builtin_types.find(s) != builtin_types.end()) { return s; }
std::string type = namer_.Type(namer_.Denamespace(s, ns));
importns = ns.empty() ? type : ns + "." + type;
std::replace(importns.begin(), importns.end(), '.', '_');
return type;
}

std::string Denamespace(const std::string &s, std::string &importns) const {
std::string ns;
return Denamespace(s, importns, ns);
}

std::string Denamespace(const std::string &s) const {
std::string importns;
return Denamespace(s, importns);
}

std::string GenerateType(const r::Type *type, bool element_type = false,
bool enum_inner = false) const {
const r::BaseType base_type =
element_type ? type->element() : type->base_type();
if (IsScalar(base_type) && !enum_inner) {
const r::Enum *type_enum = GetEnum(type, element_type);
if (type_enum != nullptr) {
std::string type_name = type_enum->name()->str();
return Denamespace(namer_.Type(type_name));
std::string importns;
std::string type_name = Denamespace(type_enum->name()->str(), importns);
return importns + "." + type_name;
}
}
if (IsScalar(base_type)) { return Denamespace(GenerateType(base_type)); }
Expand All @@ -436,8 +437,13 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
case r::Union: return "Vtable";
case r::Obj: {
const r::Object *type_obj = GetObject(type, element_type);
std::string type_name = type_obj->name()->str();
return Denamespace(namer_.Type(type_name), type_obj == current_obj_);
std::string importns;
std::string type_name = Denamespace(type_obj->name()->str(), importns);
if (type_obj == current_obj_) {
return type_name;
} else {
return importns + "." + type_name;
}
}
default: return "uoffset";
}
Expand Down Expand Up @@ -559,34 +565,37 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
return new_path;
}

std::string RegisterImports(const r::Object *object, const r::Field *field,
bool use_element = false) {
void RegisterImports(const r::Object *object, const r::Field *field,
bool use_element = false) {
std::string importns;
std::string type_name;

const r::BaseType type =
use_element ? field->type()->element() : field->type()->base_type();

if (IsStructOrTable(type)) {
const r::Object *object = GetObjectByIndex(field->type()->index());
if (object == current_obj_) { return namer_.Denamespace(object); }
type_name = object->name()->str();
const r::Object *object_def = GetObjectByIndex(field->type()->index());
if (object_def == current_obj_) { return; }
std::string ns;
type_name = Denamespace(object_def->name()->str(), importns, ns);
type_name = ns.empty() ? type_name : ns + "." + type_name;
} else {
const r::Enum *enum_def = GetEnumByIndex(field->type()->index());
if (enum_def == current_enum_) { return namer_.Denamespace(enum_def); }
type_name = enum_def->name()->str();
if (enum_def == current_enum_) { return; }
std::string ns;
type_name = Denamespace(enum_def->name()->str(), importns, ns);
type_name = ns.empty() ? type_name : ns + "." + type_name;
}

std::string name = type_name;
std::replace(name.begin(), name.end(), '.', '_');
std::string import_path =
GetRelativePathFromNamespace(object->name()->str(), type_name);
return RegisterImports(import_path, name);
std::replace(type_name.begin(), type_name.end(), '.', '_');
RegisterImports(import_path, importns);
}

std::string RegisterImports(const std::string &local_name,
const std::string &imports_name) {
void RegisterImports(const std::string &local_name,
const std::string &imports_name) {
imports_[local_name] = imports_name;
return local_name;
}

void EmitCodeBlock(const std::string &code_block, const std::string &name,
Expand Down

0 comments on commit a5278bd

Please sign in to comment.