Gradually adding support for all features

This commit is contained in:
Pavel Shevaev 2022-12-08 15:21:54 +03:00
parent 70c6c66f2d
commit f0f5ef4462
2 changed files with 125 additions and 2 deletions

View File

@ -96,6 +96,12 @@ function _add_twig_support(\Twig\Environment $twig)
return $opts;
}
));
$twig->addFunction(new \Twig\TwigFunction('buf2var',
function($name, $fname, $type, $buf, $tokens, $is_ptr)
{
return buf2var($name, $fname, $type, $buf, $tokens, $is_ptr);
}
));
$twig->addFilter(new \Twig\TwigFilter('go_type',
function($type, $tokens)
{
@ -122,7 +128,7 @@ function go_type(\mtgType $type, array $tokens = array())
if(array_key_exists("virtual", $tokens))
$str .= "I";
else
$str .= $vtype instanceof mtgMetaStruct ? "*" : "";
$str .= $vtype instanceof \mtgMetaStruct ? "*" : "";
$str .= $native;
@ -152,3 +158,96 @@ function go_type(\mtgType $type, array $tokens = array())
throw new Exception("Unknown type '$type'");
}
function builtin_type_prefix(\mtgBuiltinType $type)
{
switch($type->getName())
{
case "string":
return "String";
case "bool":
return "Bool";
case "blob":
return "Blob";
case "float":
return "Float";
case "double":
return "Double";
case "uint64":
return "U64";
case "int64":
return "I64";
case "uint":
case "uint32":
return "U32";
case "uint16":
return "U16";
case "uint8":
return "U8";
case "int":
case "int32":
return "I32";
case "int16":
return "I16";
case "int8":
return "I8";
default:
throw new Exception("Unknown type '{$type}'");
}
}
function buf2var($name, $fname, \mtgType $type, $buf, array $tokens = array(), $is_ptr = false)
{
$str = '';
if($type instanceof \mtgBuiltinType)
{
$str .= _read_op($tokens, $buf.'.Read'.builtin_type_prefix($type).'(&'.$fname.', "'.$name.'")');
}
else if($type instanceof \mtgMetaEnum)
{
$str .= _read_op($tokens, "{$buf}.ReadI32((*int32)(&{$fname}), \"$name\")");
$str .= "\n if !{$fname}.IsValid() { return errors.Errorf(\"Bad enum value %d for $name\", $fname) }";
}
else if($type instanceof \mtgMetaStruct)
{
if(array_key_exists('virtual', $tokens))
$str .= "if v, err := meta.ReadStructGeneric($buf, CreateById, \"{$name}\"); err != nil { return err } else { {$fname} = v.(I{$type}) }";
else
$str .= _read_op($tokens, "meta.ReadStruct($buf, ".($is_ptr?"":"&")."$fname, \"$name\")");
}
else if($type instanceof \mtgArrType)
{
$is_virtual = array_key_exists("virtual", $tokens);
$native_type = go_type($type->getValue(), $tokens);
$offset = "\n ";
$str .= "/*[]{$name}*/";
$str .= $offset . _read_op($tokens, "{$buf}.BeginContainer(\"$name\")");
//we don't want to propagate 'optionalness' below
unset($tokens['optional']);
$str .= $offset . "_{$name}_size, err := {$buf}.GetContainerSize()";
$str .= $offset . "if err != nil { return err }";
$need_new = !$is_virtual && $type->getValue() instanceof \mtgMetaStruct;
$str .= $offset . "for ; _{$name}_size > 0; _{$name}_size-- {";
$offset = "\n ";
$str .= $offset . "var tmp_{$name} {$native_type}";
$str .= $offset . buf2var("", "tmp_{$name}", $type->getValue(), $buf, $tokens, $is_virtual);
$str .= $offset . "{$fname} = append({$fname}, ".($need_new?"&":"")."tmp_{$name})";
$offset = "\n ";
$str .= $offset . "}";
$str .= $offset . _read_op($tokens, "{$buf}.EndContainer()");
$str .= "\n";
}
else
throw new Exception("Unknown type '{$type}'");
return $str;
}
function _read_op(array $tokens, $op)
{
return "if err := $op; err != nil { return " . (array_key_exists("optional", $tokens) ? "/*optional*/nil" : "err"). " }";
}

View File

@ -150,7 +150,31 @@ fieldsMask meta.FieldsMask //@bitfields support
{%- if o.parent ~%}
if err := self.{{o.parent.name}}.ReadFields(reader); err != nil { return err }
{%- endif -%}
{%- endif ~%}
{%- for f in o.fields ~%}
if _cont_size <= 0 {
return nil
}
{%if has_token(o, 'bitfields') ~%}
if !use_mask {
{%- endif ~%}
_cont_size--
{%if has_token(o, 'bitfields') ~%}
}
if !use_mask || (use_mask && self.HasValue({{loop.index0}})) {
{%- endif ~%}
{{buf2var(f.name, 'self.' ~ f.name|ucfirst, f.type, 'reader', f.tokens, false)}}
{%if has_token(o, 'bitfields') ~%}
}
{%- endif -%}
{%- endfor -%}
{% endmacro %}