function serializeArgsType($namespace, $func, $indent) { global $cpp_keywords, $derived_types, $typeset, $current_server; $args = @$func->args; //there is not args anymore if (!$args) { return; } $args_set = parseArgs(@$func->args); $argsTyName = getArgsType($func->name); if (count($args_set) == 1) { return; } $tp_name = "{$current_server}::{$argsTyName}"; if (@$derived_types[$current_server][$argsTyName]) { return; } //there are args here //put echo "{$indent}\nCERL_IO_BEGIN_PUTTER({$namespace}::{$argsTyName})\n"; $indent2 = $indent . "\t"; foreach ($args as $arg) { $var_member = "val.{$arg->name}"; echo "{$indent2}NS_CERL_IO::put(os, {$var_member});\n"; } echo "{$indent}CERL_IO_END_PUTTER()\n"; //get echo "\n"; echo "{$indent}CERL_IO_BEGIN_GETTER({$namespace}::{$argsTyName})\n"; $indent2 = $indent . "\t"; $indent3 = $indent2 . "\t"; echo "{$indent2}return "; $i = 0; foreach ($args as $arg) { $var_member = "val.{$arg->name}"; if ($i++ == 0) { echo "NS_CERL_IO::get(is, {$var_member})"; } else { echo "\n{$indent3}&& NS_CERL_IO::get(is, {$var_member})"; } } echo ";\n"; echo "{$indent}CERL_IO_END_GETTER()\n"; //copy //printPODTYPE($args); $podTrue = true; echo "\n{$indent}template <class AllocT>\n"; echo "{$indent}inline void copy(AllocT& alloc, {$namespace}::{$argsTyName}& dest, const {$namespace}::{$argsTyName}& src)\n"; echo "{$indent}{\n"; echo "{$indent2}dest = src;\n"; foreach ($args as $arg) { if (!isPOD($arg->type)) { echo "{$indent2}NS_CERL_IO::copy(alloc, dest.{$arg->name}, src.{$arg->name});\n"; $podTrue = false; } } echo "{$indent}}\n"; if ($podTrue) { echo "{$indent}CERL_PODTYPE({$namespace}::{$argsTyName}, true);\n"; } else { echo "{$indent}CERL_PODTYPE({$namespace}::{$argsTyName}, false);\n"; } //dump echo "\ntemplate<class LogT>\n"; echo "inline void dump(LogT& log, const {$namespace}::{$argsTyName}& args)\n"; echo "{\n"; echo "\tNS_CERL_IO::dump(log, '{');\n"; $i = 0; foreach ($args as $var) { if ($i++ == 0) { echo "\tNS_CERL_IO::dump(log, args.{$var->name});\n"; } else { echo "\tNS_CERL_IO::dump(log, \", \");\n"; echo "\tNS_CERL_IO::dump(log, args.{$var->name});\n"; } } echo "\tNS_CERL_IO::dump(log, '}');\n"; echo "}\n"; }
function processRetType($func, $indent) { $async = @$func->async; $ret = @$func->type; $rettype = getRetType($func->name); $indent2 = $indent . "\t"; if ($async || !$ret) { return; } global $module, $current_server; global $typetraits, $derived_types; global $builtin_codes, $codeset; global $cpp_keywords; $coded_type = @$ret->coded_type; if (!$coded_type) { die("\n---Error: while define RetType of '{$func->name}', ret type must be coded!"); } checkCodedType($coded_type, $rettype); //ret type always coded. $exist_tp = typedefExistsType($ret, $rettype); if ($exist_tp) { echo "\n{$indent}typedef {$exist_tp} {$rettype};\n"; return; } echo "\n{$indent}typedef struct {$rettype}Tag {\n"; echo "{$indent2}cerl::Code _code;\n"; $items = $coded_type->items; $indent3 = $indent2; //将$items分为$constructArray和$nonConstructArray,分别表示包含构造函数和不包含构造函数的集合。 $constructArray = array(); $nonConstructArray = array(); foreach ($items as $item) { $vars = @$item->vars; $flag = false; //是否包含构造函数,true表示放在union外,false表示放在union内。 if ($vars) { foreach ($vars as $var) { $type = $var->type; $tp = @$type->named_type; if (!$tp) { die("\n---ERROR: Can not find the type definition of '{$var->name}' in '{$func->name}'!"); } $type_name = mapType($type, ""); if (!isPOD($type)) { $flag = true; break; } } if ($flag) { array_push($constructArray, $item); } else { array_push($nonConstructArray, $item); } } } if (count($nonConstructArray) > 0) { $count = getStructCount($nonConstructArray); if ($count > 1) { $indent3 = $indent2 . "\t"; echo "{$indent2}union {\n"; } foreach ($nonConstructArray as $item) { $vars = @$item->vars; if ($vars) { echo "{$indent3}struct {\n"; foreach ($vars as $var) { $type = $var->type; $tp = @$type->named_type; if (!$tp) { die("\n---ERROR: Can not find the type definition of '{$var->name}' in '{$func->name}'!"); } $type_name = mapType($type, ""); echo "{$indent3}\t{$type_name} {$var->name};\n"; } $item_name = $item->code == "ok" ? "" : $item->code; if ($item->code != "ok" && @$cpp_keywords[$item->code]) { $item_name = "_" . $item_name; } echo "{$indent3}}{$item_name};\n"; } } if ($count > 1) { echo "{$indent2}};\n"; } } if (count($constructArray) > 0) { foreach ($constructArray as $item) { $vars = @$item->vars; $indent3 = $indent2; if ($vars) { if ($item->code != "ok") { echo "{$indent2}struct {\n"; $indent3 = $indent2 . "\t"; } foreach ($vars as $var) { $type = $var->type; $tp = @$type->named_type; if (!$tp) { die("\n---ERROR: Can not find the type definition of '{$var->name}' in '{$func->name}'!"); } $type_name = mapType($type, ""); echo "{$indent3}{$type_name} {$var->name};\n"; } if ($item->code != "ok") { $item_name = $item->code; if (@$cpp_keywords[$item->code]) { $item_name = "_" . $item_name; } echo "{$indent2}}{$item_name};\n"; } } } } echo "\n{$indent2}{$rettype}Tag(cerl::Code code = cerl::code_error) {\n"; echo "{$indent2}\t_code = code;\n"; echo "{$indent2}}\n"; echo "\n{$indent2}operator cerl::Code() const {\n"; echo "{$indent2}\treturn _code;\n"; echo "{$indent2}}\n"; echo "\n{$indent2}void cerl_call operator=(cerl::Code code) {\n"; echo "{$indent2}\t_code = code;\n"; echo "{$indent2}}\n"; // generate dumpCode function echo "\n{$indent2}template <class LogT>\n"; echo "{$indent2}void cerl_call dumpCode(LogT& log) const {\n"; echo "{$indent2}\tNS_CERL_IO::dumpCode(log, _code);\n"; echo "{$indent2}}\n"; echo "{$indent}} {$rettype};\n"; /*end of struct*/ }