-module(bt_erl_parser). -include("bt_nodes.hrl"). -export([ parse/2, parse/3 ]). %% root. %% tree can either be TreeModule, or a 3 tuple {BBKeys, Params, GetTreeFn}. -spec parse(TreeModuleOr3Tuple :: atom() | {list(), list(), function()}, ArgsAsProplist :: list()) -> {Node :: bt_node(), NewBB :: blackboard()}. parse(TreeModule, ArgsAsProplist) when is_atom(TreeModule), is_list(ArgsAsProplist) -> parse({TreeModule:get_bb_keys(), TreeModule:get_params(), fun TreeModule:get_tree/2}, ArgsAsProplist); parse(Tree = {_BBKeys, _Params, _GetTreeFn}, ArgsAsProplist) -> parse({Tree, maps:from_list(ArgsAsProplist)}, bt_parser_utils:get_namespace(), bt_blackboard:get_empty()). %% TODO: should probably call above fn parse_root so as to not confuse with this one. since this one is anyway internal only %% sequence -spec parse(Node :: bt_node() | {TreeModule :: atom(), Args :: map()}, Namespace :: namespace(), BB :: blackboard()) -> {Node :: bt_node(), NewBB :: blackboard()}. parse(Sequence, Namespace, BB) when is_record(Sequence, sequence) -> erl_parse_sequence:parse(Sequence, Namespace, BB); %% selector (TODO) parse(Selector, Namespace, BB) when is_record(Selector, selector) -> erl_parse_selector:parse(Selector, Namespace, BB); %% decorator parse(Decorator = #decorator{child = Child}, Namespace, BB) when is_record(Decorator, decorator) -> {NewChild, NewBB} = parse(Child, Namespace, BB), {Decorator#decorator{child = NewChild}, NewBB}; %% task parse(Task, Namespace, BB) when is_record(Task, task) -> erl_parse_task:parse(Task, Namespace, BB); %% if none of the above, then its a subtree parse({{UnresolvedKeys, Params, GetTreeFn}, Args}, Namespace, BB) -> NewBB = bt_parser_utils:get_blackboard(UnresolvedKeys, Namespace, BB), bt_parser_utils:throw_error_if_args_and_params_dont_match("UnknownTree", Args, Params), BBKeyMap = bt_parser_utils:get_unresolved_key_bb_map(UnresolvedKeys, Namespace), parse(GetTreeFn(Args, BBKeyMap), Namespace, NewBB).