Add Lazy, a lazy-evaluating version of Groovy
[Funky.git] / lib / Funky / Private / extractFunctions__.h
blob0ec0f9a27e19cbeed82ec495a47106bf87734bc0
1 /* Funky: a light-weight embeddable programming language
2 * Copyright (c) 2007, Ronald Landheer-Cieslak
3 * All rights reserved
4 *
5 * This is free software. You may distribute it and/or modify it and
6 * distribute modified forms provided that the following terms are met:
8 * * Redistributions of the source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the distribution;
13 * * None of the names of the authors of this software may be used to endorse
14 * or promote this software, derived software or any distribution of this
15 * software or any distribution of which this software is part, without
16 * prior written permission from the authors involved;
17 * * Unless you have received a written statement from Ronald Landheer-Cieslak
18 * that says otherwise, the terms of the GNU General Public License, as
19 * published by the Free Software Foundation, version 2 or (at your option)
20 * any later version, also apply.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
34 namespace Funky
36 namespace Private
38 template < typename Arguments >
39 void extractFunctions__(
40 const boost::spirit::tree_parse_info<> & parse_result,
41 StoredFunctions< Arguments > & functions,
42 boost::spirit::tree_node< boost::spirit::node_val_data<> > & main)
44 // This is the type of an iterator with which we can traverse the parse tree
45 typedef boost::spirit::tree_match< const char * >::const_tree_iterator TreeIterator;
47 TreeIterator root_node(parse_result.trees.begin());
48 assert(root_node != parse_result.trees.end());
49 // we only have a script_id__ if there is at least one function before the first statement. Otherwise, the root node is a statement_id__
50 if (root_node->value.id() == script_id__)
52 // for each function definition,
53 for (TreeIterator current_function(root_node->children.begin()); current_function != root_node->children.end(); ++current_function)
55 if (current_function->value.id() == function_definition_id__)
57 TreeIterator function_definition_node(current_function->children.begin());
58 assert(
59 std::distance(function_definition_node, current_function->children.end()) == 4 ||
60 std::distance(function_definition_node, current_function->children.end()) == 5);
61 assert(function_definition_node->value.id() == function_definition_token_id__);
62 ++function_definition_node;
64 // extract the name
65 assert(function_definition_node->value.id() == function_name_id__);
66 std::string function_name(function_definition_node->value.begin(), function_definition_node->value.end());
67 ++function_definition_node;
68 // extract the number of expected arguments, if known
69 int expected_parameter_count(-1);
70 if (function_definition_node->value.id() == function_param_count_id__)
72 expected_parameter_count = boost::lexical_cast< int >(
73 std::string(function_definition_node->value.begin(), function_definition_node->value.end()));
74 ++function_definition_node;
76 else
77 { /* unknown parameter count */ }
79 ++function_definition_node; // (the colon)
80 // extract the statement
81 // store the statement in our function map, as a tree
82 boost::shared_ptr< ParsedFunction< Arguments > > function(new ParsedFunction< Arguments >(expected_parameter_count, *function_definition_node));
83 typename StoredFunctions< Arguments >::iterator where(functions.find(function_name));
84 if (where != functions.end())
85 functions.erase(where);
86 else
87 { /* not a duplicate definition */ }
88 functions.insert(typename StoredFunctions< Arguments >::value_type(function_name, function));
90 else
92 assert(current_function->value.id() == statement_id__);
93 main = *current_function;
97 else
99 assert(
100 root_node->value.id() == statement_id__ ||
101 root_node->value.id() == function_name_id__ /* call without arguments */);
102 main = *root_node;