More robust bhl_type_ref(..) implementation

This commit is contained in:
Pavel Shevaev 2023-03-29 18:16:32 +03:00
parent 4b3dbb2206
commit e443816b88
2 changed files with 58 additions and 25 deletions

View File

@ -121,7 +121,10 @@ function add_twig_support(\Twig\Environment $twig)
$twig->addFilter(new \Twig\TwigFilter('bhl_type_ref',
function($type)
{
return bhl_type_ref(is_string($type) ? $type : bhl_type($type));
if(is_string($type))
return "types.T(\"$type\")";
return bhl_type_ref($type);
}
));
$twig->addFilter(new \Twig\TwigFilter('native_type',
@ -158,11 +161,7 @@ function add_twig_support(\Twig\Environment $twig)
$twig->addFunction(new \Twig\TwigFunction('Warn',
function($e)
{
//NOTE: we can't just echo the value because it will
// be rendered into resulting code
register_shutdown_function(function() use($e) {
echo "WARN: $e\n";
});
Warn($e);
}
));
$twig->addFunction(new \Twig\TwigFunction('has_token',
@ -247,6 +246,15 @@ function add_twig_support(\Twig\Environment $twig)
));
}
function Warn($msg)
{
//NOTE: we can't just echo the value because it will
// be rendered into resulting code
register_shutdown_function(function() use($msg) {
echo "BHL BIND WARN: $msg\n";
});
}
function paginate($total, $step)
{
//pages are returned as an array where each element is in interval [N, Y)
@ -288,24 +296,48 @@ function norm_name($name)
return str_replace('.', '__', $name);
}
function bhl_type_ref($type_str)
function bhl_type_ref(\mtgType $type = null)
{
if(preg_match('~coro\s+func\s+((\w|\.)+)\s*\(\)~', $type_str, $ms))
return "types.TFunc(true, ".bhl_type_ref($ms[1]).")";
else if(preg_match('~coro\s+func\s+((\w|\.)+)\s*\(((\w|\.|\[|\])+)\)~', $type_str, $ms))
return "types.TFunc(true, ".bhl_type_ref($ms[1]).", ".bhl_type_ref($ms[3]).")";
else if(preg_match('~func\s+((\w|\.)+)\s*\(\)~', $type_str, $ms))
return "types.TFunc(false, ".bhl_type_ref($ms[1]).")";
else if(preg_match('~func\s+((\w|\.)+)\s*\(((\w|\.|\[|\])+)\)~', $type_str, $ms))
return "types.TFunc(false, ".bhl_type_ref($ms[1]).", ".bhl_type_ref($ms[3]).")";
else if(preg_match('~func\s+((\w|\.)+)\s*\(((\w|\.|\[|\])+)\s*,((\w|\.|\[|\])+)\)~', $type_str, $ms))
return "types.TFunc(false, ".bhl_type_ref($ms[1]).", ".bhl_type_ref($ms[3]).", ".bhl_type_ref($ms[5]).")";
else if(preg_match('~\[\]((\w|\.)+)~', $type_str, $ms))
return "types.TArr(".bhl_type_ref($ms[1]).")";
else if(preg_match('~((\w|\.)+)\,((\w|\.)+)~', $type_str, $ms))
return "types.T(".bhl_type_ref($ms[1]).", ".bhl_type_ref($ms[3]).")";
else
return "types.T(\"$type_str\")";
if($type === null)
return 'types.T("void")';
if($type instanceof \mtgBuiltinType)
{
if($type->isFloat() || $type->isDouble())
return 'types.T("float")';
else if($type->isInt() || $type->isUint())
return 'types.T("int")';
}
else if($type instanceof \mtgMetaFunc)
{
$is_coro = $type->hasToken("bhl_coroutine");
$str = '';
$str .= "types.TFunc(".($is_coro?"true":"false").", ";
$str .= $type->getReturnType() ? bhl_type_ref($type->getReturnType()) : bhl_type_ref(null);
foreach($type->getArgs() as $arg)
$str .= bhl_type_ref($arg->getType()) . ",";
$str = rtrim($str, ',');
$str .= ")";
return $str;
}
else if($type instanceof \mtgMultiType)
{
$str = 'types.T(';
foreach($type->getValues() as $sub_type)
$str .= bhl_type_ref($sub_type) . ",";
$str = rtrim($str, ",");
$str .= ")";
return $str;
}
else if($type instanceof \mtgArrType)
{
return 'types.TArr(' . bhl_type_ref($type->getValue()) . ')';
}
//fallback
return 'types.T("' . $type. '")';
}
function bhl_type(\mtgType $type = null)
@ -342,6 +374,7 @@ function bhl_type(\mtgType $type = null)
else if($type instanceof \mtgArrType)
return "[]" . bhl_type($type->getValue());
//fallback
return ''.$type;
}

View File

@ -350,7 +350,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
new FuncArgSymbol("{{arg.name}}",
{%-if has_token(arg, 'bhl_coroutine') -%}
{{('coro ' ~ (arg.type|bhl_type))|bhl_type_ref}},
{{arg.type|bhl_type_ref|replace({'false,':'true,'})}},
{%-else-%}
{{arg.type|bhl_type_ref}},
{%-endif-%}
@ -594,7 +594,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{{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 ~ "'")}}
{{Warn("POD boxing '" ~ o.name ~ "'")}}
{% endif %}
{% for f in o.getfields %}