Starting to experiment with native array proxies

This commit is contained in:
Pavel Shevaev 2022-12-13 19:29:25 +03:00
parent 789bd45612
commit 4af69254e4
2 changed files with 97 additions and 27 deletions

View File

@ -45,6 +45,8 @@ function supported_tokens()
function bhl_add_twig_support(\Twig\Environment $twig)
{
$twig->addGlobal('native_array_types', array());
$twig->addTest(new \Twig\TwigTest('instanceof',
function($obj, $class)
{
@ -81,6 +83,22 @@ function bhl_add_twig_support(\Twig\Environment $twig)
return bhl_gen_native_type($type);
}
));
$twig->addFilter(new \Twig\TwigFilter('native_arr_type',
function($type) use($twig)
{
if($type instanceof \mtgArrType)
{
//let's remember all native array proxies
$types = $twig->getGlobals()['native_array_types'];
$proxy_name = "List_{$type->getValue()->getName()}";
$types[$proxy_name] = $type;
$twig->addGlobal('native_array_types', $types);
return $proxy_name;
}
else
return $type;
}
));
$twig->addFilter(new \Twig\TwigFilter('norm_name',
function($name)
{
@ -171,6 +189,12 @@ function bhl_add_twig_support(\Twig\Environment $twig)
return $arr;
}
));
$twig->addFunction(new \Twig\TwigFunction('get_native_arr_types',
function() use($twig)
{
return array_values($twig->getGlobals()['native_array_types']);
}
));
}
function bhl_get_last_name($name)
@ -199,7 +223,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]}\")";
@ -245,7 +269,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;
}

View File

@ -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 %} {
@ -495,7 +495,48 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%- endif -%}
{%- endmacro -%}
{%- macro enum(o, scope = 'types.ns') ~%}
{%- macro reg_native_arr_type(o, scope = 'types.ns') ~%}
{
var cl = new ClassSymbolNative("List_{{o.value.name}}",
//constructor is not allowed
null
);
{
var vs = new FieldSymbol("Count", Types.Int,
delegate(VM.Frame frame, 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("{{o.value.name}}"),
delegate(VM.Frame frame, ValStack stack, FuncArgsInfo args_info, ref BHS status)
{
#if !BHL_FRONT
var val_idx = stack.Pop();
var val_lst = stack.Pop();
stack.Push(Val.NewObj(frm.vm, ((List<{{o.value.name}}>)val_lst.obj)[(int)val_idx._num], BHL_Types.Type_{{o.value.name}}));
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}}");
@ -512,7 +553,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' %}
@ -555,7 +596,7 @@ 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 %}
@ -570,7 +611,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{% set class = token_or(o, 'bhl_native_class', o.name) %}
{
cl.Define(new FieldSymbol("{{f.name}}", {{f.type|bhl_type_ref}},
cl.Define(new FieldSymbol("{{f.name}}", {{f.type|native_arr_type|bhl_type_ref}},
{% if token_or(f, 'bhl_get', 1) != 0 ~%}
//getter
delegate(VM.Frame frm, Val ctx, ref Val v, FieldSymbol fld) {
@ -630,7 +671,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
@ -646,7 +687,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
@ -901,7 +942,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 -%}
@ -914,7 +955,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 %}
@ -936,26 +977,26 @@ 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) }}
{%- 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)}}
@ -963,17 +1004,22 @@ public partial class Script_{{u.object.name}} {
{%- endfor -%}
{%- for type in get_native_arr_types() -%}
{{ _self.reg_native_arr_type(type) }}
{%- 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");
if(tmp is ClassSymbol cs)
cs.Setup();
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 -%}