mirror of
https://github.com/Relintai/broken_seals.git
synced 2024-11-13 20:47:19 +01:00
Move the parser code to a new file.
This commit is contained in:
parent
2bf13be369
commit
0b7964f01b
749
game/addons/gdc_converter/gdsparser.gd
Normal file
749
game/addons/gdc_converter/gdsparser.gd
Normal file
@ -0,0 +1,749 @@
|
||||
tool
|
||||
extends Reference
|
||||
|
||||
enum GDScopeType {
|
||||
GDSCOPE_TYPE_GENERIC = 0,
|
||||
GDSCOPE_TYPE_CLASS,
|
||||
GDSCOPE_TYPE_IF,
|
||||
GDSCOPE_TYPE_ELIF,
|
||||
GDSCOPE_TYPE_ELSE,
|
||||
GDSCOPE_TYPE_FUNC,
|
||||
GDSCOPE_TYPE_FOR,
|
||||
GDSCOPE_TYPE_WHILE,
|
||||
GDSCOPE_TYPE_ENUM,
|
||||
};
|
||||
|
||||
class GDSScope:
|
||||
var type : int = GDScopeType.GDSCOPE_TYPE_GENERIC
|
||||
var scope_data : String = ""
|
||||
var raw_scope_data : String = ""
|
||||
var scope_data_alt : String = ""
|
||||
var raw_scope_data_alt : String = ""
|
||||
var subscopes : Array = Array()
|
||||
var scope_lines : PoolStringArray = PoolStringArray()
|
||||
|
||||
func parse(contents : PoolStringArray, current_index : int = 0, current_indent : int = 0) -> int:
|
||||
while current_index < contents.size():
|
||||
var cl : String = contents[current_index]
|
||||
|
||||
if cl == "tool":
|
||||
scope_lines.append("#" + cl)
|
||||
current_index += 1
|
||||
continue
|
||||
|
||||
if cl.begins_with("class_name "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_CLASS
|
||||
raw_scope_data = cl
|
||||
scope_data = cl.trim_prefix("class_name ")
|
||||
current_index += 1
|
||||
continue
|
||||
|
||||
if cl.begins_with("extends "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_CLASS
|
||||
raw_scope_data_alt = cl
|
||||
scope_data_alt = cl.trim_prefix("extends ")
|
||||
current_index += 1
|
||||
continue
|
||||
|
||||
if cl.begins_with("#"):
|
||||
scope_lines.append(cl)
|
||||
current_index += 1
|
||||
continue
|
||||
|
||||
var curr_line_indent : int = get_indent_count(cl)
|
||||
var clstripped : String = cl.strip_edges(true, false)
|
||||
|
||||
if curr_line_indent < current_indent:
|
||||
return current_index
|
||||
|
||||
if cl.ends_with(":") || cl.begins_with("enum "):
|
||||
var scope : GDSScope = GDSScope.new()
|
||||
scope.parse_scope_data(clstripped)
|
||||
current_index += 1
|
||||
current_index = scope.parse(contents, current_index, curr_line_indent + 1)
|
||||
subscopes.append(scope)
|
||||
|
||||
#don't
|
||||
#current_index += 1
|
||||
continue
|
||||
|
||||
scope_lines.append(clstripped)
|
||||
current_index += 1
|
||||
|
||||
return current_index
|
||||
|
||||
func parse_scope_data(s : String) -> void:
|
||||
raw_scope_data = s
|
||||
|
||||
if raw_scope_data.begins_with("if "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_IF
|
||||
scope_data = raw_scope_data.trim_prefix("if ").trim_suffix(":")
|
||||
elif raw_scope_data.begins_with("elif "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_ELIF
|
||||
scope_data = raw_scope_data.trim_prefix("elif ").trim_suffix(":")
|
||||
elif raw_scope_data.begins_with("else"):
|
||||
type = GDScopeType.GDSCOPE_TYPE_ELSE
|
||||
elif raw_scope_data.begins_with("class "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_CLASS
|
||||
scope_data = raw_scope_data.trim_prefix("class ").trim_suffix(":")
|
||||
elif raw_scope_data.begins_with("enum "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_ENUM
|
||||
scope_data = raw_scope_data.trim_prefix("enum ").trim_suffix("{")
|
||||
elif raw_scope_data.begins_with("func "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_FUNC
|
||||
scope_data = raw_scope_data.trim_prefix("func ").trim_suffix(":")
|
||||
elif raw_scope_data.begins_with("for "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_FOR
|
||||
scope_data = raw_scope_data.trim_prefix("for ").trim_suffix(":")
|
||||
elif raw_scope_data.begins_with("while "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_WHILE
|
||||
scope_data = raw_scope_data.trim_prefix("while ").trim_suffix(":")
|
||||
|
||||
func get_indent_count(s : String) -> int:
|
||||
var c : int = 0
|
||||
|
||||
for ch in s:
|
||||
if ch == "\t":
|
||||
c += 1
|
||||
else:
|
||||
break
|
||||
|
||||
return c
|
||||
|
||||
func convert_to_string(current_scope_level : int = 0) -> String:
|
||||
var indents : String = ""
|
||||
|
||||
for i in range(current_scope_level):
|
||||
indents += " "
|
||||
|
||||
var s : String = indents + "---GDSScope---\n"
|
||||
|
||||
s += indents + raw_scope_data + " -- " + type_to_print_string() + " "
|
||||
s += scope_data
|
||||
|
||||
if scope_data_alt != "":
|
||||
s += " " + scope_data_alt
|
||||
|
||||
s += "\n"
|
||||
|
||||
indents += " "
|
||||
|
||||
for l in scope_lines:
|
||||
s += indents + l + "\n"
|
||||
|
||||
for subs in subscopes:
|
||||
s += "\n"
|
||||
s += subs.convert_to_string(current_scope_level + 1)
|
||||
|
||||
s += "\n"
|
||||
|
||||
return s
|
||||
|
||||
func type_to_print_string() -> String:
|
||||
if type == GDScopeType.GDSCOPE_TYPE_CLASS:
|
||||
return "(CLASS)"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_IF:
|
||||
return "(IF)"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ELIF:
|
||||
return "(ELIF)"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ELSE:
|
||||
return "(ELSE)"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_FUNC:
|
||||
return "(FUNC)"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_FOR:
|
||||
return "(FOR)"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_WHILE:
|
||||
return "(WHILE)"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ENUM:
|
||||
return "(ENUM)"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_GENERIC:
|
||||
return "(GEN)"
|
||||
|
||||
return "(UNKN)"
|
||||
|
||||
func type_to_cpp_entity() -> String:
|
||||
if type == GDScopeType.GDSCOPE_TYPE_CLASS:
|
||||
return "class "
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_IF:
|
||||
return "if "
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ELIF:
|
||||
return "else if "
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ELSE:
|
||||
return "else "
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_FUNC:
|
||||
return ""
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_FOR:
|
||||
return "for "
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_WHILE:
|
||||
return "while "
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ENUM:
|
||||
return "enum "
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_GENERIC:
|
||||
return ""
|
||||
|
||||
return ""
|
||||
|
||||
func get_cpp_header_string(current_scope_level : int = 0) -> String:
|
||||
if type == GDScopeType.GDSCOPE_TYPE_IF:
|
||||
return ""
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ELIF:
|
||||
return ""
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ELSE:
|
||||
return ""
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_FOR:
|
||||
return ""
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_WHILE:
|
||||
return ""
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_GENERIC:
|
||||
return ""
|
||||
|
||||
var indents : String = ""
|
||||
|
||||
for i in range(current_scope_level):
|
||||
indents += " "
|
||||
|
||||
var s : String = ""
|
||||
|
||||
s += indents + type_to_cpp_entity()
|
||||
|
||||
if type == GDScopeType.GDSCOPE_TYPE_CLASS:
|
||||
s += scope_data
|
||||
|
||||
if scope_data_alt != "":
|
||||
s += " : public " + scope_data_alt
|
||||
|
||||
s += " {\n"
|
||||
|
||||
if scope_data_alt != "":
|
||||
s += indents + " GDCLASS(" + scope_data + ", " + scope_data_alt + ");\n\n"
|
||||
|
||||
s += indents + " public:\n"
|
||||
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_FUNC:
|
||||
s += transform_method_to_cpp() + ";"
|
||||
return s
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ENUM:
|
||||
s += scope_data + " {"
|
||||
|
||||
s += "\n"
|
||||
|
||||
indents += " "
|
||||
|
||||
if type == GDScopeType.GDSCOPE_TYPE_CLASS:
|
||||
for l in scope_lines:
|
||||
var gs : String = create_cpp_getter_setter(l, true, indents)
|
||||
|
||||
if gs != "":
|
||||
s += gs + "\n"
|
||||
|
||||
for subs in subscopes:
|
||||
var scstr : String = subs.get_cpp_header_string(current_scope_level + 1)
|
||||
|
||||
if scstr != "":
|
||||
s += scstr
|
||||
s += "\n"
|
||||
|
||||
if type == GDScopeType.GDSCOPE_TYPE_CLASS:
|
||||
s += "\n"
|
||||
s += indents + scope_data + "();\n"
|
||||
s += indents + "~" + scope_data + "();\n"
|
||||
s += "\n"
|
||||
s += indents + "protected:\n"
|
||||
s += indents + "static void _bind_methods();\n"
|
||||
|
||||
s += "\n"
|
||||
|
||||
if type != GDScopeType.GDSCOPE_TYPE_ENUM:
|
||||
for l in scope_lines:
|
||||
if l.begins_with("#"):
|
||||
l = l.replace("#", "//")
|
||||
s += indents + l + "\n"
|
||||
continue
|
||||
|
||||
if l.begins_with("var "):
|
||||
s += indents + transform_variable_to_cpp(l) + ";\n"
|
||||
else:
|
||||
s += indents + l + ";\n"
|
||||
else:
|
||||
for l in scope_lines:
|
||||
if l.begins_with("#"):
|
||||
l = l.replace("#", "//")
|
||||
s += indents + l + "\n"
|
||||
continue
|
||||
|
||||
s += indents + l + "\n"
|
||||
|
||||
if type == GDScopeType.GDSCOPE_TYPE_CLASS || type == GDScopeType.GDSCOPE_TYPE_ENUM:
|
||||
s += "};"
|
||||
else:
|
||||
s += "}"
|
||||
|
||||
s += "\n"
|
||||
|
||||
return s
|
||||
|
||||
func get_cpp_impl_string(current_scope_level : int = 0, owner_class_name : String = "") -> String:
|
||||
if type == GDScopeType.GDSCOPE_TYPE_ENUM:
|
||||
return ""
|
||||
|
||||
var indents : String = ""
|
||||
|
||||
for i in range(current_scope_level):
|
||||
indents += " "
|
||||
|
||||
var s : String = ""
|
||||
|
||||
s += indents
|
||||
|
||||
if type == GDScopeType.GDSCOPE_TYPE_IF:
|
||||
s += "if (" + scope_data + ") {"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ELIF:
|
||||
s += "if (" + scope_data + ") {"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ELSE:
|
||||
s += "else {"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_FOR:
|
||||
s += "for (" + scope_data + ") {"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_WHILE:
|
||||
s += "while (" + scope_data + ") {"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_GENERIC:
|
||||
s += scope_data + " {"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_FUNC:
|
||||
s += transform_method_to_cpp(owner_class_name) + " {"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_CLASS:
|
||||
owner_class_name = scope_data + "::"
|
||||
|
||||
for l in scope_lines:
|
||||
var gs : String = create_cpp_getter_setter(l, false, indents, owner_class_name)
|
||||
|
||||
if gs != "":
|
||||
s += gs + "\n"
|
||||
|
||||
s += "\n"
|
||||
indents += " "
|
||||
|
||||
for subs in subscopes:
|
||||
var scstr : String = subs.get_cpp_impl_string(current_scope_level + 1, owner_class_name)
|
||||
|
||||
if scstr != "":
|
||||
s += scstr
|
||||
s += "\n"
|
||||
|
||||
if type == GDScopeType.GDSCOPE_TYPE_CLASS:
|
||||
s += "\n"
|
||||
s += indents + scope_data + "::" + scope_data + "() {\n"
|
||||
|
||||
for l in scope_lines:
|
||||
if l.find("preload") != -1:
|
||||
s += indents + "//" + l + ";\n"
|
||||
elif l.begins_with("var "):
|
||||
var vcpp : String = transform_variable_to_cpp(l)
|
||||
var index_fs : int = vcpp.find(" ")
|
||||
if index_fs != -1:
|
||||
vcpp = vcpp.substr(index_fs + 1)
|
||||
|
||||
s += indents + " " + vcpp + ";\n"
|
||||
|
||||
s += indents + "}\n\n"
|
||||
s += indents + scope_data + "::~" + scope_data + "() {\n"
|
||||
s += indents + "}\n\n"
|
||||
s += "\n"
|
||||
s += indents + "static void " + scope_data + "::_bind_methods() {\n"
|
||||
s += indents + "/*\n"
|
||||
|
||||
for l in scope_lines:
|
||||
var gs : String = create_cpp_getter_setter(l, true, indents + " ")
|
||||
|
||||
if gs != "":
|
||||
s += gs + "\n"
|
||||
|
||||
for subs in subscopes:
|
||||
var scstr : String = subs.get_cpp_header_string(indents.length() + 1)
|
||||
|
||||
if scstr != "":
|
||||
s += scstr + "\n"
|
||||
|
||||
s += indents + "*/\n"
|
||||
s += indents + "}\n\n"
|
||||
|
||||
s += "\n"
|
||||
|
||||
if type != GDScopeType.GDSCOPE_TYPE_CLASS:
|
||||
for l in scope_lines:
|
||||
if l.begins_with("#"):
|
||||
l = l.replace("#", "//")
|
||||
s += indents + l + ";\n"
|
||||
continue
|
||||
|
||||
s += indents + l + ";\n"
|
||||
s += "}\n"
|
||||
|
||||
return s
|
||||
|
||||
func create_cpp_getter_setter(line : String, header : bool, indent : String, class_prefix : String = "") -> String:
|
||||
if !line.begins_with("var "):
|
||||
return ""
|
||||
|
||||
var cpp_var : String = transform_variable_to_cpp(line)
|
||||
|
||||
var equals_index = cpp_var.find("=")
|
||||
if equals_index != -1:
|
||||
cpp_var = cpp_var.substr(0, equals_index)
|
||||
|
||||
cpp_var = cpp_var.strip_edges()
|
||||
|
||||
var name_start_index : int = cpp_var.find_last(" ")
|
||||
var var_type : String = cpp_var.substr(0, name_start_index).strip_edges()
|
||||
var var_name : String = cpp_var.substr(name_start_index + 1).strip_edges()
|
||||
|
||||
var ret_final : String = ""
|
||||
|
||||
if var_type == "int" || var_type == "float" || var_type == "bool" || var_type == "RID":
|
||||
ret_final += indent + var_type + " " + class_prefix + "get_" + var_name + "() const"
|
||||
|
||||
if !header:
|
||||
ret_final += " {\n";
|
||||
ret_final += indent + " return " + var_name + ";\n"
|
||||
ret_final += indent + "}\n\n";
|
||||
else:
|
||||
ret_final += ";\n"
|
||||
|
||||
ret_final += indent + "void " + class_prefix + "set_" + var_name + "(const " + var_type + " val)"
|
||||
|
||||
if !header:
|
||||
ret_final += " {\n";
|
||||
ret_final += indent + var_name + " = val;\n"
|
||||
ret_final += indent + "}\n\n";
|
||||
else:
|
||||
ret_final += ";\n"
|
||||
else:
|
||||
ret_final += indent + var_type + " " + class_prefix + "get_" + var_name + "()"
|
||||
|
||||
if !header:
|
||||
ret_final += " {\n";
|
||||
ret_final += indent + " return " + var_name + ";\n"
|
||||
ret_final += indent + "}\n\n";
|
||||
else:
|
||||
ret_final += ";\n"
|
||||
|
||||
ret_final += indent + "void " + class_prefix + "set_" + var_name + "(const " + var_type + " &val)"
|
||||
|
||||
if !header:
|
||||
ret_final += " {\n";
|
||||
ret_final += indent + var_name + " = val;\n"
|
||||
ret_final += indent + "}\n\n";
|
||||
else:
|
||||
ret_final += ";\n"
|
||||
|
||||
return ret_final
|
||||
|
||||
func transform_variable_assign(line : String) -> String:
|
||||
|
||||
if !line.ends_with(" as "):
|
||||
return line
|
||||
|
||||
#This should hadnle primitive types like int
|
||||
if !line.ends_with(".new()"):
|
||||
return line
|
||||
|
||||
return line
|
||||
|
||||
func transform_variable_to_cpp(line : String) -> String:
|
||||
line = line.replace("var ", "")
|
||||
|
||||
var var_final : String = ""
|
||||
|
||||
var param_type : String
|
||||
var var_name : String
|
||||
var assigned_value : String
|
||||
|
||||
var assigned_value_indx : int = line.find("=")
|
||||
|
||||
if assigned_value_indx != -1:
|
||||
assigned_value = line.substr(assigned_value_indx + 1).strip_edges()
|
||||
line = line.substr(0, assigned_value_indx).strip_edges()
|
||||
assigned_value = transform_variable_assign(assigned_value)
|
||||
|
||||
var type_indx : int = line.find(":")
|
||||
if type_indx != -1:
|
||||
param_type = line.substr(type_indx + 1).strip_edges()
|
||||
var_name = line.substr(0, type_indx).strip_edges()
|
||||
if param_type == "int" || param_type == "float" || param_type == "bool" || param_type == "RID":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "Vector2" || param_type == "Vector2i":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "Vector3" || param_type == "Vector3i":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "Rect2" || param_type == "Rect2i":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "Transform" || param_type == "Transform2D":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "String" || param_type == "StringName":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "Quat" || param_type == "Plane":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "NodePath" || param_type == "Dictionary":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "Color" || param_type == "Basis":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "Array" || param_type == "AABB":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "PoolByteArray" || param_type == "PoolColorArray":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "PoolIntArray" || param_type == "PoolRealArray":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "PoolVector2Array" || param_type == "PoolVector2iArray":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "PoolVector3Array" || param_type == "PoolVector3iArray":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "PoolStringArray":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type != "":
|
||||
if ClassDB.class_exists(param_type):
|
||||
#check if it's a reference
|
||||
var is_ref : bool = false
|
||||
var pcls : String = param_type
|
||||
while pcls != "Object":
|
||||
pcls = ClassDB.get_parent_class(pcls)
|
||||
|
||||
if pcls == "Reference":
|
||||
is_ref = true
|
||||
break
|
||||
|
||||
if is_ref:
|
||||
var_final += "Ref<" + param_type + "> " + var_name
|
||||
else:
|
||||
var_final += param_type + " *" + var_name
|
||||
|
||||
if assigned_value != "":
|
||||
var_final += " = " + assigned_value
|
||||
else:
|
||||
#Assume it needs a pointer
|
||||
var_final += param_type + " *" + var_name
|
||||
|
||||
if assigned_value != "":
|
||||
var_final += " = " + assigned_value
|
||||
else:
|
||||
var_final += "Variant " + var_name
|
||||
|
||||
if assigned_value != "":
|
||||
var_final += " = " + assigned_value
|
||||
|
||||
return var_final
|
||||
|
||||
func transform_method_to_cpp(name_prefix : String = "") -> String:
|
||||
if type != GDScopeType.GDSCOPE_TYPE_FUNC:
|
||||
return ""
|
||||
|
||||
var func_data : String = scope_data
|
||||
var func_ret_type : String = "void"
|
||||
|
||||
var indx : int = scope_data.find(" -> ")
|
||||
|
||||
if indx != -1:
|
||||
func_ret_type = scope_data.substr(indx + 4)
|
||||
func_data = scope_data.substr(0, indx)
|
||||
|
||||
var func_final : String = func_ret_type + " "
|
||||
indx = func_data.find("(")
|
||||
var func_name : String = func_data.substr(0, indx)
|
||||
func_final += name_prefix + func_name + "("
|
||||
|
||||
var func_params : String = func_data.substr(indx + 1, func_data.length() - indx - 2)
|
||||
|
||||
if func_params != "":
|
||||
var params : PoolStringArray = func_params.split(",", false)
|
||||
|
||||
for i in range(params.size()):
|
||||
var p : String = params[i]
|
||||
|
||||
var default_value_indx : int = p.find("=")
|
||||
var default_value : String
|
||||
|
||||
if default_value_indx != -1:
|
||||
default_value = p.substr(default_value_indx + 1).strip_edges()
|
||||
p = p.substr(0, default_value_indx).strip_edges()
|
||||
|
||||
var type_indx : int = p.find(":")
|
||||
|
||||
if type_indx != -1:
|
||||
var param_type : String = p.substr(type_indx + 1).strip_edges()
|
||||
p = p.substr(0, type_indx).strip_edges()
|
||||
|
||||
if param_type == "int" || param_type == "float" || param_type == "bool" || param_type == "RID":
|
||||
func_final += "const " + param_type + " "
|
||||
else:
|
||||
func_final += "const " + param_type + " &"
|
||||
else:
|
||||
func_final += "const Variant &"
|
||||
|
||||
func_final += p
|
||||
|
||||
if default_value_indx != -1:
|
||||
func_final += " = " + default_value
|
||||
|
||||
if i + 1 < params.size():
|
||||
func_final += ", "
|
||||
|
||||
func_final += ")"
|
||||
|
||||
return func_final
|
||||
|
||||
func camel_case_scope_data() -> void:
|
||||
scope_data = camel_case_name(scope_data)
|
||||
|
||||
func camel_case_name(cname : String) -> String:
|
||||
var ret : String = ""
|
||||
|
||||
var next_upper : bool = true
|
||||
for i in range(cname.length()):
|
||||
if cname[i] == "_":
|
||||
next_upper = true
|
||||
continue
|
||||
|
||||
if next_upper:
|
||||
ret += cname[i].to_upper()
|
||||
next_upper = false
|
||||
else:
|
||||
ret += cname[i]
|
||||
|
||||
return ret
|
||||
|
||||
func _to_string():
|
||||
return convert_to_string()
|
||||
|
||||
|
||||
|
||||
class GDSParser:
|
||||
var root : GDSScope.GDSScope
|
||||
|
||||
func parse(contents : String, file_name : String) -> void:
|
||||
root = GDSScope.new()
|
||||
root.raw_scope_data = file_name
|
||||
root.scope_data = file_name.get_file().trim_suffix(".gd")
|
||||
root.camel_case_scope_data()
|
||||
var c : PoolStringArray = split_preprocess_content(contents)
|
||||
root.parse(c)
|
||||
|
||||
|
||||
func split_preprocess_content(contents : String) -> PoolStringArray:
|
||||
var ret : PoolStringArray = PoolStringArray()
|
||||
|
||||
contents = contents.replace("\r\n", "\n")
|
||||
|
||||
var sp : PoolStringArray = contents.split("\n")
|
||||
|
||||
var pl : String = ""
|
||||
var accum : bool = false
|
||||
for i in range(sp.size()):
|
||||
var l : String = sp[i]
|
||||
l = l.strip_edges(false, true)
|
||||
|
||||
var lfstrip : String = l.strip_edges(true, false)
|
||||
if lfstrip == "":
|
||||
continue
|
||||
|
||||
if lfstrip.begins_with("#"):
|
||||
ret.append(lfstrip)
|
||||
continue
|
||||
|
||||
if lfstrip.begins_with("export"):
|
||||
var indx = lfstrip.find("var")
|
||||
var expstr : String = lfstrip.substr(0, indx)
|
||||
|
||||
ret.append("#" + expstr)
|
||||
l = l.replace(expstr, "")
|
||||
|
||||
var setget_indx = l.find(" setget ")
|
||||
if setget_indx != -1:
|
||||
var setget_str : String = l.substr(setget_indx)
|
||||
ret.append("#" + setget_str)
|
||||
l = l.substr(0, setget_indx).strip_edges(false, true)
|
||||
|
||||
var hash_symbol_index = l.find("#")
|
||||
if hash_symbol_index != -1:
|
||||
var comment_str : String = l.substr(hash_symbol_index)
|
||||
ret.append(comment_str)
|
||||
l = l.substr(0, hash_symbol_index).strip_edges(false, true)
|
||||
|
||||
if l.ends_with("\\"):
|
||||
if !accum:
|
||||
accum = true
|
||||
pl = l
|
||||
else:
|
||||
pl += l.substr(0, l.length() - 1).strip_edges()
|
||||
else:
|
||||
if accum:
|
||||
accum = false
|
||||
ret.append(pl)
|
||||
pl = ""
|
||||
else:
|
||||
ret.append(l)
|
||||
|
||||
return ret
|
||||
|
||||
func _to_string():
|
||||
return str(root)
|
||||
|
||||
func get_cpp_header_string(file_name : String) -> String:
|
||||
var include_guard_name : String = file_name.get_file()
|
||||
include_guard_name = include_guard_name.to_upper()
|
||||
include_guard_name = include_guard_name.trim_suffix(".GD")
|
||||
include_guard_name += "_H"
|
||||
|
||||
var s : String = "#ifndef " + include_guard_name + "\n"
|
||||
s += "#define " + include_guard_name + "\n"
|
||||
s += "\n\n"
|
||||
|
||||
s += root.get_cpp_header_string()
|
||||
|
||||
s += "\n\n"
|
||||
s += "#endif"
|
||||
s += "\n"
|
||||
|
||||
return s
|
||||
|
||||
func get_cpp_impl_string(file_name : String) -> String:
|
||||
var include_name : String = file_name.get_file()
|
||||
include_name = include_name.to_lower()
|
||||
include_name = include_name.trim_suffix(".gd")
|
||||
include_name += ".h"
|
||||
|
||||
var s : String = "\n"
|
||||
s += "#include \"" + include_name + "\"\n"
|
||||
s += "\n\n"
|
||||
|
||||
s += root.get_cpp_impl_string()
|
||||
|
||||
s += "\n\n"
|
||||
|
||||
return s
|
||||
|
||||
func process_file(file_name : String) -> void:
|
||||
var file : File = File.new()
|
||||
file.open(file_name, File.READ)
|
||||
var contents : String = file.get_as_text()
|
||||
file.close()
|
||||
|
||||
var parser : GDSParser = GDSParser.new()
|
||||
parser.parse(contents, file_name)
|
||||
#print(parser)
|
||||
#print(parser.get_cpp_header_string(file_name))
|
||||
#print(parser.get_cpp_impl_string(file_name))
|
||||
|
||||
var save_base_file_path : String = file_name.get_base_dir()
|
||||
var save_base_file_name : String = file_name.get_file().to_lower().trim_suffix(".gd")
|
||||
|
||||
var header_file : String = save_base_file_path + "/" + save_base_file_name + ".h"
|
||||
var impl_file : String = save_base_file_path + "/" + save_base_file_name + ".cpp"
|
||||
|
||||
var header_data : String = parser.get_cpp_header_string(file_name)
|
||||
var impl_data : String = parser.get_cpp_impl_string(file_name)
|
||||
|
||||
file.open(header_file, File.WRITE)
|
||||
file.store_string(header_data)
|
||||
file.close()
|
||||
|
||||
file.open(impl_file, File.WRITE)
|
||||
file.store_string(impl_data)
|
||||
file.close()
|
||||
|
@ -8,6 +8,9 @@ func _exit_tree():
|
||||
remove_tool_menu_item("Convert scripts")
|
||||
|
||||
func on_menu_clicked(val) -> void:
|
||||
var GDSParser = load("res://addons/gdc_converter/gdsparser.gd")
|
||||
var parser = GDSParser.new()
|
||||
|
||||
var dir = Directory.new()
|
||||
var dir_name = get_editor_interface().get_selected_path()
|
||||
if dir.open(dir_name) == OK:
|
||||
@ -17,752 +20,6 @@ func on_menu_clicked(val) -> void:
|
||||
|
||||
if !dir.current_is_dir():
|
||||
if file_name.get_extension() == "gd":
|
||||
process_file(dir_name + file_name)
|
||||
parser.process_file(dir_name + file_name)
|
||||
|
||||
file_name = dir.get_next()
|
||||
|
||||
|
||||
enum GDScopeType {
|
||||
GDSCOPE_TYPE_GENERIC = 0,
|
||||
GDSCOPE_TYPE_CLASS,
|
||||
GDSCOPE_TYPE_IF,
|
||||
GDSCOPE_TYPE_ELIF,
|
||||
GDSCOPE_TYPE_ELSE,
|
||||
GDSCOPE_TYPE_FUNC,
|
||||
GDSCOPE_TYPE_FOR,
|
||||
GDSCOPE_TYPE_WHILE,
|
||||
GDSCOPE_TYPE_ENUM,
|
||||
};
|
||||
|
||||
class GDSScope:
|
||||
var type : int = GDScopeType.GDSCOPE_TYPE_GENERIC
|
||||
var scope_data : String = ""
|
||||
var raw_scope_data : String = ""
|
||||
var scope_data_alt : String = ""
|
||||
var raw_scope_data_alt : String = ""
|
||||
var subscopes : Array = Array()
|
||||
var scope_lines : PoolStringArray = PoolStringArray()
|
||||
|
||||
func parse(contents : PoolStringArray, current_index : int = 0, current_indent : int = 0) -> int:
|
||||
while current_index < contents.size():
|
||||
var cl : String = contents[current_index]
|
||||
|
||||
if cl == "tool":
|
||||
scope_lines.append("#" + cl)
|
||||
current_index += 1
|
||||
continue
|
||||
|
||||
if cl.begins_with("class_name "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_CLASS
|
||||
raw_scope_data = cl
|
||||
scope_data = cl.trim_prefix("class_name ")
|
||||
current_index += 1
|
||||
continue
|
||||
|
||||
if cl.begins_with("extends "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_CLASS
|
||||
raw_scope_data_alt = cl
|
||||
scope_data_alt = cl.trim_prefix("extends ")
|
||||
current_index += 1
|
||||
continue
|
||||
|
||||
if cl.begins_with("#"):
|
||||
scope_lines.append(cl)
|
||||
current_index += 1
|
||||
continue
|
||||
|
||||
var curr_line_indent : int = get_indent_count(cl)
|
||||
var clstripped : String = cl.strip_edges(true, false)
|
||||
|
||||
if curr_line_indent < current_indent:
|
||||
return current_index
|
||||
|
||||
if cl.ends_with(":") || cl.begins_with("enum "):
|
||||
var scope : GDSScope = GDSScope.new()
|
||||
scope.parse_scope_data(clstripped)
|
||||
current_index += 1
|
||||
current_index = scope.parse(contents, current_index, curr_line_indent + 1)
|
||||
subscopes.append(scope)
|
||||
|
||||
#don't
|
||||
#current_index += 1
|
||||
continue
|
||||
|
||||
scope_lines.append(clstripped)
|
||||
current_index += 1
|
||||
|
||||
return current_index
|
||||
|
||||
func parse_scope_data(s : String) -> void:
|
||||
raw_scope_data = s
|
||||
|
||||
if raw_scope_data.begins_with("if "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_IF
|
||||
scope_data = raw_scope_data.trim_prefix("if ").trim_suffix(":")
|
||||
elif raw_scope_data.begins_with("elif "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_ELIF
|
||||
scope_data = raw_scope_data.trim_prefix("elif ").trim_suffix(":")
|
||||
elif raw_scope_data.begins_with("else"):
|
||||
type = GDScopeType.GDSCOPE_TYPE_ELSE
|
||||
elif raw_scope_data.begins_with("class "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_CLASS
|
||||
scope_data = raw_scope_data.trim_prefix("class ").trim_suffix(":")
|
||||
elif raw_scope_data.begins_with("enum "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_ENUM
|
||||
scope_data = raw_scope_data.trim_prefix("enum ").trim_suffix("{")
|
||||
elif raw_scope_data.begins_with("func "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_FUNC
|
||||
scope_data = raw_scope_data.trim_prefix("func ").trim_suffix(":")
|
||||
elif raw_scope_data.begins_with("for "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_FOR
|
||||
scope_data = raw_scope_data.trim_prefix("for ").trim_suffix(":")
|
||||
elif raw_scope_data.begins_with("while "):
|
||||
type = GDScopeType.GDSCOPE_TYPE_WHILE
|
||||
scope_data = raw_scope_data.trim_prefix("while ").trim_suffix(":")
|
||||
|
||||
func get_indent_count(s : String) -> int:
|
||||
var c : int = 0
|
||||
|
||||
for ch in s:
|
||||
if ch == "\t":
|
||||
c += 1
|
||||
else:
|
||||
break
|
||||
|
||||
return c
|
||||
|
||||
func convert_to_string(current_scope_level : int = 0) -> String:
|
||||
var indents : String = ""
|
||||
|
||||
for i in range(current_scope_level):
|
||||
indents += " "
|
||||
|
||||
var s : String = indents + "---GDSScope---\n"
|
||||
|
||||
s += indents + raw_scope_data + " -- " + type_to_print_string() + " "
|
||||
s += scope_data
|
||||
|
||||
if scope_data_alt != "":
|
||||
s += " " + scope_data_alt
|
||||
|
||||
s += "\n"
|
||||
|
||||
indents += " "
|
||||
|
||||
for l in scope_lines:
|
||||
s += indents + l + "\n"
|
||||
|
||||
for subs in subscopes:
|
||||
s += "\n"
|
||||
s += subs.convert_to_string(current_scope_level + 1)
|
||||
|
||||
s += "\n"
|
||||
|
||||
return s
|
||||
|
||||
func type_to_print_string() -> String:
|
||||
if type == GDScopeType.GDSCOPE_TYPE_CLASS:
|
||||
return "(CLASS)"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_IF:
|
||||
return "(IF)"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ELIF:
|
||||
return "(ELIF)"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ELSE:
|
||||
return "(ELSE)"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_FUNC:
|
||||
return "(FUNC)"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_FOR:
|
||||
return "(FOR)"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_WHILE:
|
||||
return "(WHILE)"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ENUM:
|
||||
return "(ENUM)"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_GENERIC:
|
||||
return "(GEN)"
|
||||
|
||||
return "(UNKN)"
|
||||
|
||||
func type_to_cpp_entity() -> String:
|
||||
if type == GDScopeType.GDSCOPE_TYPE_CLASS:
|
||||
return "class "
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_IF:
|
||||
return "if "
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ELIF:
|
||||
return "else if "
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ELSE:
|
||||
return "else "
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_FUNC:
|
||||
return ""
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_FOR:
|
||||
return "for "
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_WHILE:
|
||||
return "while "
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ENUM:
|
||||
return "enum "
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_GENERIC:
|
||||
return ""
|
||||
|
||||
return ""
|
||||
|
||||
func get_cpp_header_string(current_scope_level : int = 0) -> String:
|
||||
if type == GDScopeType.GDSCOPE_TYPE_IF:
|
||||
return ""
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ELIF:
|
||||
return ""
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ELSE:
|
||||
return ""
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_FOR:
|
||||
return ""
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_WHILE:
|
||||
return ""
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_GENERIC:
|
||||
return ""
|
||||
|
||||
var indents : String = ""
|
||||
|
||||
for i in range(current_scope_level):
|
||||
indents += " "
|
||||
|
||||
var s : String = ""
|
||||
|
||||
s += indents + type_to_cpp_entity()
|
||||
|
||||
if type == GDScopeType.GDSCOPE_TYPE_CLASS:
|
||||
s += scope_data
|
||||
|
||||
if scope_data_alt != "":
|
||||
s += " : public " + scope_data_alt
|
||||
|
||||
s += " {\n"
|
||||
|
||||
if scope_data_alt != "":
|
||||
s += indents + " GDCLASS(" + scope_data + ", " + scope_data_alt + ");\n\n"
|
||||
|
||||
s += indents + " public:\n"
|
||||
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_FUNC:
|
||||
s += transform_method_to_cpp() + ";"
|
||||
return s
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ENUM:
|
||||
s += scope_data + " {"
|
||||
|
||||
s += "\n"
|
||||
|
||||
indents += " "
|
||||
|
||||
if type == GDScopeType.GDSCOPE_TYPE_CLASS:
|
||||
for l in scope_lines:
|
||||
var gs : String = create_cpp_getter_setter(l, true, indents)
|
||||
|
||||
if gs != "":
|
||||
s += gs + "\n"
|
||||
|
||||
for subs in subscopes:
|
||||
var scstr : String = subs.get_cpp_header_string(current_scope_level + 1)
|
||||
|
||||
if scstr != "":
|
||||
s += scstr
|
||||
s += "\n"
|
||||
|
||||
if type == GDScopeType.GDSCOPE_TYPE_CLASS:
|
||||
s += "\n"
|
||||
s += indents + scope_data + "();\n"
|
||||
s += indents + "~" + scope_data + "();\n"
|
||||
s += "\n"
|
||||
s += indents + "protected:\n"
|
||||
s += indents + "static void _bind_methods();\n"
|
||||
|
||||
s += "\n"
|
||||
|
||||
if type != GDScopeType.GDSCOPE_TYPE_ENUM:
|
||||
for l in scope_lines:
|
||||
if l.begins_with("#"):
|
||||
l = l.replace("#", "//")
|
||||
s += indents + l + "\n"
|
||||
continue
|
||||
|
||||
if l.begins_with("var "):
|
||||
s += indents + transform_variable_to_cpp(l) + ";\n"
|
||||
else:
|
||||
s += indents + l + ";\n"
|
||||
else:
|
||||
for l in scope_lines:
|
||||
if l.begins_with("#"):
|
||||
l = l.replace("#", "//")
|
||||
s += indents + l + "\n"
|
||||
continue
|
||||
|
||||
s += indents + l + "\n"
|
||||
|
||||
if type == GDScopeType.GDSCOPE_TYPE_CLASS || type == GDScopeType.GDSCOPE_TYPE_ENUM:
|
||||
s += "};"
|
||||
else:
|
||||
s += "}"
|
||||
|
||||
s += "\n"
|
||||
|
||||
return s
|
||||
|
||||
func get_cpp_impl_string(current_scope_level : int = 0, owner_class_name : String = "") -> String:
|
||||
if type == GDScopeType.GDSCOPE_TYPE_ENUM:
|
||||
return ""
|
||||
|
||||
var indents : String = ""
|
||||
|
||||
for i in range(current_scope_level):
|
||||
indents += " "
|
||||
|
||||
var s : String = ""
|
||||
|
||||
s += indents
|
||||
|
||||
if type == GDScopeType.GDSCOPE_TYPE_IF:
|
||||
s += "if (" + scope_data + ") {"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ELIF:
|
||||
s += "if (" + scope_data + ") {"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_ELSE:
|
||||
s += "else {"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_FOR:
|
||||
s += "for (" + scope_data + ") {"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_WHILE:
|
||||
s += "while (" + scope_data + ") {"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_GENERIC:
|
||||
s += scope_data + " {"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_FUNC:
|
||||
s += transform_method_to_cpp(owner_class_name) + " {"
|
||||
elif type == GDScopeType.GDSCOPE_TYPE_CLASS:
|
||||
owner_class_name = scope_data + "::"
|
||||
|
||||
for l in scope_lines:
|
||||
var gs : String = create_cpp_getter_setter(l, false, indents, owner_class_name)
|
||||
|
||||
if gs != "":
|
||||
s += gs + "\n"
|
||||
|
||||
s += "\n"
|
||||
indents += " "
|
||||
|
||||
for subs in subscopes:
|
||||
var scstr : String = subs.get_cpp_impl_string(current_scope_level + 1, owner_class_name)
|
||||
|
||||
if scstr != "":
|
||||
s += scstr
|
||||
s += "\n"
|
||||
|
||||
if type == GDScopeType.GDSCOPE_TYPE_CLASS:
|
||||
s += "\n"
|
||||
s += indents + scope_data + "::" + scope_data + "() {\n"
|
||||
|
||||
for l in scope_lines:
|
||||
if l.find("preload") != -1:
|
||||
s += indents + "//" + l + ";\n"
|
||||
elif l.begins_with("var "):
|
||||
var vcpp : String = transform_variable_to_cpp(l)
|
||||
var index_fs : int = vcpp.find(" ")
|
||||
if index_fs != -1:
|
||||
vcpp = vcpp.substr(index_fs + 1)
|
||||
|
||||
s += indents + " " + vcpp + ";\n"
|
||||
|
||||
s += indents + "}\n\n"
|
||||
s += indents + scope_data + "::~" + scope_data + "() {\n"
|
||||
s += indents + "}\n\n"
|
||||
s += "\n"
|
||||
s += indents + "static void " + scope_data + "::_bind_methods() {\n"
|
||||
s += indents + "/*\n"
|
||||
|
||||
for l in scope_lines:
|
||||
var gs : String = create_cpp_getter_setter(l, true, indents + " ")
|
||||
|
||||
if gs != "":
|
||||
s += gs + "\n"
|
||||
|
||||
for subs in subscopes:
|
||||
var scstr : String = subs.get_cpp_header_string(indents.length() + 1)
|
||||
|
||||
if scstr != "":
|
||||
s += scstr + "\n"
|
||||
|
||||
s += indents + "*/\n"
|
||||
s += indents + "}\n\n"
|
||||
|
||||
s += "\n"
|
||||
|
||||
if type != GDScopeType.GDSCOPE_TYPE_CLASS:
|
||||
for l in scope_lines:
|
||||
if l.begins_with("#"):
|
||||
l = l.replace("#", "//")
|
||||
s += indents + l + ";\n"
|
||||
continue
|
||||
|
||||
s += indents + l + ";\n"
|
||||
s += "}\n"
|
||||
|
||||
return s
|
||||
|
||||
func create_cpp_getter_setter(line : String, header : bool, indent : String, class_prefix : String = "") -> String:
|
||||
if !line.begins_with("var "):
|
||||
return ""
|
||||
|
||||
var cpp_var : String = transform_variable_to_cpp(line)
|
||||
|
||||
var equals_index = cpp_var.find("=")
|
||||
if equals_index != -1:
|
||||
cpp_var = cpp_var.substr(0, equals_index)
|
||||
|
||||
cpp_var = cpp_var.strip_edges()
|
||||
|
||||
var name_start_index : int = cpp_var.find_last(" ")
|
||||
var var_type : String = cpp_var.substr(0, name_start_index).strip_edges()
|
||||
var var_name : String = cpp_var.substr(name_start_index + 1).strip_edges()
|
||||
|
||||
var ret_final : String = ""
|
||||
|
||||
if var_type == "int" || var_type == "float" || var_type == "bool" || var_type == "RID":
|
||||
ret_final += indent + var_type + " " + class_prefix + "get_" + var_name + "() const"
|
||||
|
||||
if !header:
|
||||
ret_final += " {\n";
|
||||
ret_final += indent + " return " + var_name + ";\n"
|
||||
ret_final += indent + "}\n\n";
|
||||
else:
|
||||
ret_final += ";\n"
|
||||
|
||||
ret_final += indent + "void " + class_prefix + "set_" + var_name + "(const " + var_type + " val)"
|
||||
|
||||
if !header:
|
||||
ret_final += " {\n";
|
||||
ret_final += indent + var_name + " = val;\n"
|
||||
ret_final += indent + "}\n\n";
|
||||
else:
|
||||
ret_final += ";\n"
|
||||
else:
|
||||
ret_final += indent + var_type + " " + class_prefix + "get_" + var_name + "()"
|
||||
|
||||
if !header:
|
||||
ret_final += " {\n";
|
||||
ret_final += indent + " return " + var_name + ";\n"
|
||||
ret_final += indent + "}\n\n";
|
||||
else:
|
||||
ret_final += ";\n"
|
||||
|
||||
ret_final += indent + "void " + class_prefix + "set_" + var_name + "(const " + var_type + " &val)"
|
||||
|
||||
if !header:
|
||||
ret_final += " {\n";
|
||||
ret_final += indent + var_name + " = val;\n"
|
||||
ret_final += indent + "}\n\n";
|
||||
else:
|
||||
ret_final += ";\n"
|
||||
|
||||
return ret_final
|
||||
|
||||
func transform_variable_assign(line : String) -> String:
|
||||
|
||||
if !line.ends_with(" as "):
|
||||
return line
|
||||
|
||||
#This should hadnle primitive types like int
|
||||
if !line.ends_with(".new()"):
|
||||
return line
|
||||
|
||||
return line
|
||||
|
||||
func transform_variable_to_cpp(line : String) -> String:
|
||||
line = line.replace("var ", "")
|
||||
|
||||
var var_final : String = ""
|
||||
|
||||
var param_type : String
|
||||
var var_name : String
|
||||
var assigned_value : String
|
||||
|
||||
var assigned_value_indx : int = line.find("=")
|
||||
|
||||
if assigned_value_indx != -1:
|
||||
assigned_value = line.substr(assigned_value_indx + 1).strip_edges()
|
||||
line = line.substr(0, assigned_value_indx).strip_edges()
|
||||
assigned_value = transform_variable_assign(assigned_value)
|
||||
|
||||
var type_indx : int = line.find(":")
|
||||
if type_indx != -1:
|
||||
param_type = line.substr(type_indx + 1).strip_edges()
|
||||
var_name = line.substr(0, type_indx).strip_edges()
|
||||
if param_type == "int" || param_type == "float" || param_type == "bool" || param_type == "RID":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "Vector2" || param_type == "Vector2i":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "Vector3" || param_type == "Vector3i":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "Rect2" || param_type == "Rect2i":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "Transform" || param_type == "Transform2D":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "String" || param_type == "StringName":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "Quat" || param_type == "Plane":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "NodePath" || param_type == "Dictionary":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "Color" || param_type == "Basis":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "Array" || param_type == "AABB":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "PoolByteArray" || param_type == "PoolColorArray":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "PoolIntArray" || param_type == "PoolRealArray":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "PoolVector2Array" || param_type == "PoolVector2iArray":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "PoolVector3Array" || param_type == "PoolVector3iArray":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type == "PoolStringArray":
|
||||
var_final += param_type + " " + var_name + " = " + assigned_value
|
||||
elif param_type != "":
|
||||
if ClassDB.class_exists(param_type):
|
||||
#check if it's a reference
|
||||
var is_ref : bool = false
|
||||
var pcls : String = param_type
|
||||
while pcls != "Object":
|
||||
pcls = ClassDB.get_parent_class(pcls)
|
||||
|
||||
if pcls == "Reference":
|
||||
is_ref = true
|
||||
break
|
||||
|
||||
if is_ref:
|
||||
var_final += "Ref<" + param_type + "> " + var_name
|
||||
else:
|
||||
var_final += param_type + " *" + var_name
|
||||
|
||||
if assigned_value != "":
|
||||
var_final += " = " + assigned_value
|
||||
else:
|
||||
#Assume it needs a pointer
|
||||
var_final += param_type + " *" + var_name
|
||||
|
||||
if assigned_value != "":
|
||||
var_final += " = " + assigned_value
|
||||
else:
|
||||
var_final += "Variant " + var_name
|
||||
|
||||
if assigned_value != "":
|
||||
var_final += " = " + assigned_value
|
||||
|
||||
return var_final
|
||||
|
||||
func transform_method_to_cpp(name_prefix : String = "") -> String:
|
||||
if type != GDScopeType.GDSCOPE_TYPE_FUNC:
|
||||
return ""
|
||||
|
||||
var func_data : String = scope_data
|
||||
var func_ret_type : String = "void"
|
||||
|
||||
var indx : int = scope_data.find(" -> ")
|
||||
|
||||
if indx != -1:
|
||||
func_ret_type = scope_data.substr(indx + 4)
|
||||
func_data = scope_data.substr(0, indx)
|
||||
|
||||
var func_final : String = func_ret_type + " "
|
||||
indx = func_data.find("(")
|
||||
var func_name : String = func_data.substr(0, indx)
|
||||
func_final += name_prefix + func_name + "("
|
||||
|
||||
var func_params : String = func_data.substr(indx + 1, func_data.length() - indx - 2)
|
||||
|
||||
if func_params != "":
|
||||
var params : PoolStringArray = func_params.split(",", false)
|
||||
|
||||
for i in range(params.size()):
|
||||
var p : String = params[i]
|
||||
|
||||
var default_value_indx : int = p.find("=")
|
||||
var default_value : String
|
||||
|
||||
if default_value_indx != -1:
|
||||
default_value = p.substr(default_value_indx + 1).strip_edges()
|
||||
p = p.substr(0, default_value_indx).strip_edges()
|
||||
|
||||
var type_indx : int = p.find(":")
|
||||
|
||||
if type_indx != -1:
|
||||
var param_type : String = p.substr(type_indx + 1).strip_edges()
|
||||
p = p.substr(0, type_indx).strip_edges()
|
||||
|
||||
if param_type == "int" || param_type == "float" || param_type == "bool" || param_type == "RID":
|
||||
func_final += "const " + param_type + " "
|
||||
else:
|
||||
func_final += "const " + param_type + " &"
|
||||
else:
|
||||
func_final += "const Variant &"
|
||||
|
||||
func_final += p
|
||||
|
||||
if default_value_indx != -1:
|
||||
func_final += " = " + default_value
|
||||
|
||||
if i + 1 < params.size():
|
||||
func_final += ", "
|
||||
|
||||
func_final += ")"
|
||||
|
||||
return func_final
|
||||
|
||||
func camel_case_scope_data() -> void:
|
||||
scope_data = camel_case_name(scope_data)
|
||||
|
||||
func camel_case_name(cname : String) -> String:
|
||||
var ret : String = ""
|
||||
|
||||
var next_upper : bool = true
|
||||
for i in range(cname.length()):
|
||||
if cname[i] == "_":
|
||||
next_upper = true
|
||||
continue
|
||||
|
||||
if next_upper:
|
||||
ret += cname[i].to_upper()
|
||||
next_upper = false
|
||||
else:
|
||||
ret += cname[i]
|
||||
|
||||
return ret
|
||||
|
||||
func _to_string():
|
||||
return convert_to_string()
|
||||
|
||||
class GDSParser:
|
||||
var root : GDSScope
|
||||
|
||||
func parse(contents : String, file_name : String) -> void:
|
||||
root = GDSScope.new()
|
||||
root.raw_scope_data = file_name
|
||||
root.scope_data = file_name.get_file().trim_suffix(".gd")
|
||||
root.camel_case_scope_data()
|
||||
var c : PoolStringArray = split_preprocess_content(contents)
|
||||
root.parse(c)
|
||||
|
||||
|
||||
func split_preprocess_content(contents : String) -> PoolStringArray:
|
||||
var ret : PoolStringArray = PoolStringArray()
|
||||
|
||||
contents = contents.replace("\r\n", "\n")
|
||||
|
||||
var sp : PoolStringArray = contents.split("\n")
|
||||
|
||||
var pl : String = ""
|
||||
var accum : bool = false
|
||||
for i in range(sp.size()):
|
||||
var l : String = sp[i]
|
||||
l = l.strip_edges(false, true)
|
||||
|
||||
var lfstrip : String = l.strip_edges(true, false)
|
||||
if lfstrip == "":
|
||||
continue
|
||||
|
||||
if lfstrip.begins_with("#"):
|
||||
ret.append(lfstrip)
|
||||
continue
|
||||
|
||||
if lfstrip.begins_with("export"):
|
||||
var indx = lfstrip.find("var")
|
||||
var expstr : String = lfstrip.substr(0, indx)
|
||||
|
||||
ret.append("#" + expstr)
|
||||
l = l.replace(expstr, "")
|
||||
|
||||
var setget_indx = l.find(" setget ")
|
||||
if setget_indx != -1:
|
||||
var setget_str : String = l.substr(setget_indx)
|
||||
ret.append("#" + setget_str)
|
||||
l = l.substr(0, setget_indx).strip_edges(false, true)
|
||||
|
||||
var hash_symbol_index = l.find("#")
|
||||
if hash_symbol_index != -1:
|
||||
var comment_str : String = l.substr(hash_symbol_index)
|
||||
ret.append(comment_str)
|
||||
l = l.substr(0, hash_symbol_index).strip_edges(false, true)
|
||||
|
||||
if l.ends_with("\\"):
|
||||
if !accum:
|
||||
accum = true
|
||||
pl = l
|
||||
else:
|
||||
pl += l.substr(0, l.length() - 1).strip_edges()
|
||||
else:
|
||||
if accum:
|
||||
accum = false
|
||||
ret.append(pl)
|
||||
pl = ""
|
||||
else:
|
||||
ret.append(l)
|
||||
|
||||
return ret
|
||||
|
||||
func _to_string():
|
||||
return str(root)
|
||||
|
||||
func get_cpp_header_string(file_name : String) -> String:
|
||||
var include_guard_name : String = file_name.get_file()
|
||||
include_guard_name = include_guard_name.to_upper()
|
||||
include_guard_name = include_guard_name.trim_suffix(".GD")
|
||||
include_guard_name += "_H"
|
||||
|
||||
var s : String = "#ifndef " + include_guard_name + "\n"
|
||||
s += "#define " + include_guard_name + "\n"
|
||||
s += "\n\n"
|
||||
|
||||
s += root.get_cpp_header_string()
|
||||
|
||||
s += "\n\n"
|
||||
s += "#endif"
|
||||
s += "\n"
|
||||
|
||||
return s
|
||||
|
||||
func get_cpp_impl_string(file_name : String) -> String:
|
||||
var include_name : String = file_name.get_file()
|
||||
include_name = include_name.to_lower()
|
||||
include_name = include_name.trim_suffix(".gd")
|
||||
include_name += ".h"
|
||||
|
||||
var s : String = "\n"
|
||||
s += "#include \"" + include_name + "\"\n"
|
||||
s += "\n\n"
|
||||
|
||||
s += root.get_cpp_impl_string()
|
||||
|
||||
s += "\n\n"
|
||||
|
||||
return s
|
||||
|
||||
func process_file(file_name : String) -> void:
|
||||
var file : File = File.new()
|
||||
file.open(file_name, File.READ)
|
||||
var contents : String = file.get_as_text()
|
||||
file.close()
|
||||
|
||||
var parser : GDSParser = GDSParser.new()
|
||||
parser.parse(contents, file_name)
|
||||
#print(parser)
|
||||
#print(parser.get_cpp_header_string(file_name))
|
||||
#print(parser.get_cpp_impl_string(file_name))
|
||||
|
||||
var save_base_file_path : String = file_name.get_base_dir()
|
||||
var save_base_file_name : String = file_name.get_file().to_lower().trim_suffix(".gd")
|
||||
|
||||
var header_file : String = save_base_file_path + "/" + save_base_file_name + ".h"
|
||||
var impl_file : String = save_base_file_path + "/" + save_base_file_name + ".cpp"
|
||||
|
||||
var header_data : String = parser.get_cpp_header_string(file_name)
|
||||
var impl_data : String = parser.get_cpp_impl_string(file_name)
|
||||
|
||||
file.open(header_file, File.WRITE)
|
||||
file.store_string(header_data)
|
||||
file.close()
|
||||
|
||||
file.open(impl_file, File.WRITE)
|
||||
file.store_string(impl_data)
|
||||
file.close()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user