diff --git a/src/bind.inc.php b/src/bind.inc.php index a3e1858..0bb8224 100644 --- a/src/bind.inc.php +++ b/src/bind.inc.php @@ -29,6 +29,7 @@ function supported_tokens() 'bhl_ecs_component', 'bhl_ecs_component_ref', 'bhl_coroutine', + 'bhl_static', 'bhl_async', 'bhl_native_class', 'bhl_native_class_params', @@ -42,6 +43,56 @@ function supported_tokens() ]; } +function bhl_prepare_meta(\mtgMetaInfo $orig) +{ + //NOTE: making a deep clone + $meta = unserialize(serialize($orig)); + + $arr_proxies = array(); + foreach($meta->getUnits() as $u) + { + if($u->object instanceof \mtgMetaStruct && !$u->object->hasToken('bhl_ecs_component')) + { + $need_to_replace = false; + $fields = $u->object->getFields(); + //NOTE: let's replace arrays with array proxies + foreach($fields as $name => $fld) + { + if($fld->getType() instanceof \mtgArrType) + { + $proxy_name = "List_{$fld->getType()->getValue()->getName()}"; + if(!isset($arr_proxies[$proxy_name])) + { + $proxy = new \mtgMetaStruct($proxy_name); + $proxy->setToken('bhl_native_arr_proxy', $fld->getType()->getValue()); + $proxy->setToken('bhl_no_itype', true); + $meta->addUnit(new \mtgMetaInfoUnit('', $proxy)); + $arr_proxies[$proxy_name] = $proxy; + } + else + $proxy = $arr_proxies[$proxy_name]; + + $new_fld = new \mtgMetaField($name, new \mtgTypeRef($proxy)); + //forcing no setter + $new_fld->setToken('bhl_set', 0); + $fields[$name] = $new_fld; + + $need_to_replace = true; + } + } + + if($need_to_replace) + { + foreach($u->object->getFields() as $fld) + $u->object->delField($fld); + $u->object->setFields($fields); + } + } + } + + return $meta; +} + function bhl_add_twig_support(\Twig\Environment $twig) { $twig->addTest(new \Twig\TwigTest('instanceof', @@ -198,7 +249,7 @@ function bhl_get_ns_prefix($name) function bhl_type_ref($type_str) { - if(preg_match('~((\w|\.)+)\[\]~', $type_str, $ms)) + if(preg_match('~\[\]((\w|\.)+)~', $type_str, $ms)) return "types.TArr(\"{$ms[1]}\")"; else if(preg_match('~async\s+func\s+((\w|\.)+)\s*\(\)~', $type_str, $ms)) return "types.TFunc(true, \"{$ms[1]}\")"; @@ -244,7 +295,7 @@ function bhl_gen_type(\mtgType $type = null) return rtrim($str, ","); } else if($type instanceof \mtgArrType) - return bhl_gen_type($type->getValue()) . "[]"; + return "[]" . bhl_gen_type($type->getValue()); return ''.$type; } diff --git a/tpl/codegen_register.twig b/tpl/codegen_autobind.twig similarity index 82% rename from tpl/codegen_register.twig rename to tpl/codegen_autobind.twig index e8ee6dc..faf61cf 100644 --- a/tpl/codegen_register.twig +++ b/tpl/codegen_autobind.twig @@ -16,7 +16,7 @@ namespace bhl { {% block declare %} #if !BHL_FRONT -{{ macro.decl_units(units) }} +{{ macro.decl_units(meta.units) }} #endif {% endblock %} @@ -26,9 +26,9 @@ public static void Register(Types types) { BHL_Types.Type_GenericArray = new GenericArrayTypeSymbol(new Proxy()); - {% block register %} - {{ macro.reg_units(units) }} - {% endblock %} +{% block register %} + {{ macro.reg_units(meta.units) }} +{% endblock %} } } diff --git a/tpl/codegen_types.twig b/tpl/codegen_types.twig index d5ea95f..eee4b88 100644 --- a/tpl/codegen_types.twig +++ b/tpl/codegen_types.twig @@ -4,12 +4,13 @@ static public class BHL_Types { static public IType Type_GenericArray; -{%- for u in units ~%} +{%- for u in meta.units ~%} {%- if u.object is instanceof('\\mtgMetaStruct') ~%} static public IType Type_{{u.object.name|norm_name}}; {%- endif ~%} -{%- endfor -%} +{%- endfor ~%} } + } //namespace bhl diff --git a/tpl/macro.twig b/tpl/macro.twig index 79f4fd2..87f4faa 100644 --- a/tpl/macro.twig +++ b/tpl/macro.twig @@ -1,4 +1,4 @@ -{%- macro func_native(o, scope = 'types.ns', this_prefix = '') ~%} +{%- macro reg_func_native(o, scope = 'types.ns', this_prefix = '') ~%} { var fn = new FuncSymbolNative("{{o.name|ns_last}}", @@ -44,7 +44,7 @@ } {%- endmacro -%} -{%- macro func_partial(o, scope = 'types.ns') ~%} +{%- macro reg_func_partial(o, scope = 'types.ns') ~%} { var fn = new FuncSymbolNative("{{o.name|ns_last}}", {%- if has_token(o, 'bhl_coroutine') -%} @@ -107,7 +107,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack {%- endif -%} {%- endmacro -%} -{%- macro func_partial_class(o, prefix, this_type = null) ~%} +{%- macro decl_func_partial_class(o, prefix, this_type = null) ~%} public partial class {{prefix}}{{o.name|norm_name}} {% if has_token(o, 'bhl_coroutine') %}: bhl.ICoroutine {% endif %} { @@ -139,6 +139,9 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack { var fn = new FuncSymbolNative("{{m.name|norm_name}}", + {% if has_token(m, 'bhl_static') ~%} + FuncAttrib.Static, + {% endif ~%} {{ m.returntype|bhl_type_ref }}, {{ count_default_args(m) }}, #if !BHL_FRONT @@ -158,9 +161,10 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack {{class_container}}.Define(fn); } - {%if has_token(m, 'bhl_bin_op') ~%} + {% if has_token(m, 'bhl_bin_op') ~%} { var fn = new FuncSymbolNative({{token(m, 'bhl_bin_op')}}, + FuncAttrib.Static, {{ m.returntype|bhl_type_ref }}, {{ count_default_args(m) }}, #if !BHL_FRONT @@ -179,7 +183,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack {{ _self.func_decl_args(m) }} ); - {{class_container}}.OverloadBinaryOperator(fn); + {{class_container}}.Define(fn); } {% endif ~%} @@ -213,7 +217,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack {%- macro Args(o, this_type) ~%} public struct Args { - {% if this_type ~%} + {% if this_type and not has_token(o, 'bhl_static') ~%} public {{this_type|native_type}} self; {% endif %} {% for arg in o.args ~%} @@ -315,7 +319,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack {%- endif ~%} {%- endfor ~%} - {%- if this_type ~%} + {%- if this_type and not has_token(o, 'bhl_static') ~%} { var dv = stack.Pop(); {{ _self.val2native(this_type, 'dv', arg_prefix ~ 'self') }}; @@ -491,7 +495,52 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack {%- endif -%} {%- endmacro -%} -{%- macro enum(o, scope = 'types.ns') ~%} +{%- macro reg_native_arr_proxy(o, scope = 'types.ns') ~%} + { + var cl = new ClassSymbolNative("{{o.name}}", + //constructor is not allowed + null + ); + { + var vs = new FieldSymbol("Count", Types.Int, + delegate(VM.Frame frm, Val ctx, ref Val v, FieldSymbol fld) + { +#if !BHL_FRONT + v.SetNum((ctx.obj as IList).Count); +#endif + }, + null); + cl.Define(vs); + } + { + var fn = new FuncSymbolNative("At", types.T("{{token(o, 'bhl_native_arr_proxy').name}}"), + delegate(VM.Frame frm, ValStack stack, FuncArgsInfo args_info, ref BHS status) + { +#if !BHL_FRONT + var val_idx = stack.Pop(); + var val_lst = stack.Pop(); + + var v = ((List<{{token(o, 'bhl_native_arr_proxy')|native_type}}>)val_lst.obj)[(int)val_idx._num]; + var dv = Val.New(frm.vm); + + {{ _self.native2val(token(o, 'bhl_native_arr_proxy'), 'v', 'dv') }}; + stack.Push(dv); + + val_idx.Release(); + val_lst.Release(); +#endif + return null; + }, + new FuncArgSymbol("idx", Types.Int) + ); + cl.Define(fn); + } + cl.Setup(); + {{scope}}.Define(cl); + } +{%- endmacro -%} + +{%- macro reg_enum(o, scope = 'types.ns') ~%} { var en = new EnumSymbol("{{o.name|ns_last}}"); @@ -508,7 +557,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack {%- endmacro -%} -{%- macro class(o, scope = 'types.ns') ~%} +{%- macro reg_class(o, scope = 'types.ns') ~%} {# ignore special case any #} {% if o.name == 'any' %} @@ -516,12 +565,9 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack { var cl = new ClassSymbolNative("{{o.name|ns_last}}", - {% if o.parent %} - (ClassSymbol)types.T("{{o.parent}}").Get(), - {% else ~%} - //no parent - null, - {% endif %} + {% if o.parent %} + types.T("{{o.parent}}"), + {% endif %} {% if has_token(o, 'bhl_no_new') ~%} //constructor is not allowed null @@ -542,6 +588,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack } {% endif ~%} ); + {{scope}}.{{o.name|ns_prefix}}Define(cl); {% if has_token(o, 'POD') and not has_token(o, 'bhl_custom_rw') %} {{Warn("bhl POD boxing '" ~ o.name ~ "'")}} @@ -553,14 +600,11 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack {% for m in o.getfuncs %} {% if has_token(m, 'bhl_native_prefix') %} - {{ _self.func_native(m, 'cl', '(('~token_or(o, 'bhl_native_class', o.name)~')stack.Pop()._obj).') }} + {{ _self.reg_func_native(m, 'cl', '(('~token_or(o, 'bhl_native_class', o.name)~')stack.Pop()._obj).') }} {% else %} {{ _self.method_partial(o, m, 'cl') }} {% endif %} {% endfor %} - - {{scope}}.{{o.name|ns_prefix}}Define(cl); - cl.Setup(); } {% endif %} @@ -631,7 +675,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack {%- endmacro -%} -{%- macro interface(o, scope = 'types.ns') ~%} +{%- macro reg_interface(o, scope = 'types.ns') ~%} { var ifs = new InterfaceSymbolNative("{{o.name|ns_last}}", null @@ -647,7 +691,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack {%- endmacro -%} -{%- macro ecs_component(o) ~%} +{%- macro reg_ecs_component(o) ~%} { var fn = new FuncSymbolNative("{{o.name}}_Ensure", Types.Void, #if !BHL_FRONT @@ -720,11 +764,11 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack {% if has_token(o, 'bhl_ecs_component_ref') %} { - var cl = new ClassSymbolNative("{{o.name}}__Ref", null, null); + var cl = new ClassSymbolNative("{{o.name}}__Ref"); + types.ns.Define(cl); {% for f in o.getfields %} {{ _self.ecs_component_field_ref(o, f) }} {% endfor %} - types.ns.Define(cl); cl.Setup(); { @@ -902,7 +946,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack {%- for u in units -%} {%- if u.object is instanceof('\\mtgMetaFunc') -%} {%- if not has_token(u.object, 'bhl_native_prefix') -%} - {{ _self.func_partial_class(u.object, 'Script_') }} + {{ _self.decl_func_partial_class(u.object, 'Script_') }} {%- endif -%} {%- endif -%} @@ -915,7 +959,7 @@ public partial class Script_{{u.object.name}} { {% for m in u.object.getfuncs %} {%- if not has_token(m, 'bhl_native_prefix') ~%} - {{ _self.func_partial_class(m, 'Method_', u.object) }} + {{ _self.decl_func_partial_class(m, 'Method_', u.object) }} {%- endif -%} {% endfor %} @@ -937,42 +981,47 @@ public partial class Script_{{u.object.name}} { {%- if u.object is instanceof('\\mtgMetaFunc') -%} {%- if has_token(u.object, 'bhl_native_prefix') -%} - {{ _self.func_native(u.object) }} + {{ _self.reg_func_native(u.object) }} {%- else -%} - {{ _self.func_partial(u.object) }} + {{ _self.reg_func_partial(u.object) }} {%- endif -%} {%- elseif u.object is instanceof('\\mtgMetaStruct') -%} {%- if has_token(u.object, 'bhl_ecs_component') -%} - {{ _self.ecs_component(u.object) }} + {{ _self.reg_ecs_component(u.object) }} + {%- elseif has_token(u.object, 'bhl_native_arr_proxy') -%} + {{ _self.reg_native_arr_proxy(u.object) }} {%- else -%} - {{ _self.class(u.object) }} + {{ _self.reg_class(u.object) }} {%- endif -%} {%- elseif u.object is instanceof('\\mtgMetaInterface') -%} - {{ _self.interface(u.object) }} + {{ _self.reg_interface(u.object) }} {%- elseif u.object is instanceof('\\mtgMetaEnum') -%} - {{ _self.enum(u.object) }} + {{ _self.reg_enum(u.object) }} {%- else -%} {{Error('Not supported type: ' ~ u.object)}} {%- endif -%} - {%- endfor -%} + {%- endfor ~%} + //assign global static types {%- for u in units -%} {%- if u.object is instanceof('\\mtgMetaStruct') ~%} {%- if not has_token(u.object, 'bhl_ecs_component') ~%} - { - var tmp = types.T("{{u.object.name}}").Get(); - if(tmp == null) - throw new System.Exception("Type '{{u.object.name}}' not resolved"); - BHL_Types.Type_{{u.object.name|norm_name}} = tmp; - } + { + var tmp = types.T("{{u.object.name}}").Get(); + if(tmp == null) + throw new System.Exception("Type '{{u.object.name}}' not resolved"); + if(tmp is ClassSymbol cs) + cs.Setup(); + BHL_Types.Type_{{u.object.name|norm_name}} = tmp; + } {%~ endif ~%} {%- endif -%}