implemented "while", "if" and "include"
@@ -0,0 +1,91 @@ | ||
1 | +// search.cpp: search the target file | |
2 | + | |
3 | +// Copyright Takeshi Mouri 2007, 2008. | |
4 | +// Distributed under the Boost Software License, Version 1.0. | |
5 | +// (See accompanying file LICENSE_1_0.txt or copy at | |
6 | +// http://www.boost.org/LICENSE_1_0.txt) | |
7 | + | |
8 | +// See http://hamigaki.sourceforge.jp/libs/bjam for library home page. | |
9 | + | |
10 | +#define HAMIGAKI_BJAM2_SOURCE | |
11 | +#include <hamigaki/bjam2/util/search.hpp> | |
12 | +#include <hamigaki/bjam2/util/path.hpp> | |
13 | +#include <hamigaki/bjam2/bjam_context.hpp> | |
14 | +#include <boost/assign/list_of.hpp> | |
15 | +#include <boost/filesystem/operations.hpp> | |
16 | +#include <boost/filesystem/path.hpp> | |
17 | + | |
18 | +namespace fs = boost::filesystem; | |
19 | + | |
20 | +namespace hamigaki { namespace bjam2 { | |
21 | + | |
22 | +HAMIGAKI_BJAM2_DECL | |
23 | +void call_bind_rule( | |
24 | + context& ctx, const std::string& name, const std::string& filename) | |
25 | +{ | |
26 | + frame& f = ctx.current_frame(); | |
27 | + module& m = f.current_module(); | |
28 | + | |
29 | + const string_list& bindrule = m.variables.get_values("BINDRULE"); | |
30 | + if (!bindrule.empty()) | |
31 | + { | |
32 | + const std::string& rule_name = bindrule[0]; | |
33 | + list_of_list args; | |
34 | + args.push_back(boost::assign::list_of(name)); | |
35 | + args.push_back(boost::assign::list_of(filename)); | |
36 | + ctx.invoke_rule(rule_name, args); | |
37 | + } | |
38 | +} | |
39 | + | |
40 | +HAMIGAKI_BJAM2_DECL | |
41 | +std::string search_target(context& ctx, const std::string& name) | |
42 | +{ | |
43 | + frame& f = ctx.current_frame(); | |
44 | + module& m = f.current_module(); | |
45 | + | |
46 | + path_components compo; | |
47 | + split_path(compo, name); | |
48 | + compo.grist.clear(); | |
49 | + compo.member.clear(); | |
50 | + | |
51 | + const string_list& locate = m.variables.get_values("LOCATE"); | |
52 | + const string_list& search_list = m.variables.get_values("SEARCH"); | |
53 | + | |
54 | + bool found = false; | |
55 | + std::string filename; | |
56 | + | |
57 | + if (!locate.empty()) | |
58 | + { | |
59 | + compo.root = locate[0]; | |
60 | + filename = make_path(compo); | |
61 | + found = true; | |
62 | + } | |
63 | + else if (!search_list.empty()) | |
64 | + { | |
65 | + for (std::size_t i = 0, size = search_list.size(); i < size; ++i) | |
66 | + { | |
67 | + compo.root = search_list[i]; | |
68 | + filename = make_path(compo); | |
69 | + | |
70 | + if (fs::exists(fs::path(filename))) | |
71 | + { | |
72 | + found = true; | |
73 | + break; | |
74 | + } | |
75 | + } | |
76 | + } | |
77 | + | |
78 | + if (!found) | |
79 | + { | |
80 | + compo.root.clear(); | |
81 | + fs::path ph(make_path(compo)); | |
82 | + fs::path work(ctx.working_directory()); | |
83 | + filename = fs::complete(ph, work).file_string(); | |
84 | + } | |
85 | + | |
86 | + call_bind_rule(ctx, name, filename); | |
87 | + | |
88 | + return filename; | |
89 | +} | |
90 | + | |
91 | +} } // End namespaces bjam2, hamigaki. |
@@ -9,17 +9,22 @@ | ||
9 | 9 | |
10 | 10 | #include <hamigaki/bjam2/grammars/bjam_grammar_gen.hpp> |
11 | 11 | #include <hamigaki/bjam2/grammars/bjam_grammar_id.hpp> |
12 | +#include <hamigaki/bjam2/util/argument_parser.hpp> | |
12 | 13 | #include <hamigaki/bjam2/util/class.hpp> |
13 | 14 | #include <hamigaki/bjam2/util/list_of_list.hpp> |
14 | 15 | #include <hamigaki/bjam2/util/pattern.hpp> |
16 | +#include <hamigaki/bjam2/util/search.hpp> | |
15 | 17 | #include <hamigaki/bjam2/util/variable_expansion.hpp> |
16 | 18 | #include <hamigaki/bjam2/bjam_context.hpp> |
19 | +#include <hamigaki/bjam2/bjam_exceptions.hpp> | |
17 | 20 | #include <boost/bind.hpp> |
18 | 21 | #include <boost/next_prior.hpp> |
19 | 22 | #include <boost/ref.hpp> |
20 | 23 | #include <cassert> |
21 | 24 | #include <exception> |
25 | +#include <fstream> | |
22 | 26 | #include <iostream> |
27 | +#include <list> | |
23 | 28 | |
24 | 29 | namespace bj = hamigaki::bjam2; |
25 | 30 | namespace bs = boost::spirit; |
@@ -28,11 +33,29 @@ | ||
28 | 33 | typedef parse_tree_match_t::node_t node_t; |
29 | 34 | typedef parse_tree_match_t::const_tree_iterator iter_t; |
30 | 35 | |
36 | +std::list<node_t> trees; // FIXME | |
37 | + | |
38 | +bs::tree_parse_info<> parse_bjam(const char* s, std::size_t n) | |
39 | +{ | |
40 | + return bj::bjam_grammar_gen<const char*>::parse_bjam_grammar(s, s+n); | |
41 | +} | |
42 | + | |
31 | 43 | std::string node_value(const node_t& node) |
32 | 44 | { |
33 | 45 | return std::string(node.value.begin(), node.value.end()); |
34 | 46 | } |
35 | 47 | |
48 | +std::string eval_arg_p(const node_t& node) | |
49 | +{ | |
50 | + typedef node_t::parse_node_t::const_iterator_t const_iterator_t; | |
51 | + | |
52 | + const_iterator_t beg = node.value.begin(); | |
53 | + const_iterator_t end = node.value.end(); | |
54 | + | |
55 | + bs::scanner<const_iterator_t> scan(beg, end); | |
56 | + return bj::arg_p.parse(scan).value(); | |
57 | +} | |
58 | + | |
36 | 59 | void set_true(bj::string_list& lhs, const bj::string_list& rhs) |
37 | 60 | { |
38 | 61 | if (lhs) |
@@ -82,6 +105,7 @@ | ||
82 | 105 | bj::string_list eval_expr(bj::context& ctx, const node_t& tree); |
83 | 106 | bj::string_list eval_rule(bj::context& ctx, const node_t& tree); |
84 | 107 | bj::string_list eval_block(bj::context& ctx, const node_t& tree); |
108 | +bj::string_list eval_run(bj::context& ctx, const node_t& tree); | |
85 | 109 | |
86 | 110 | bj::string_list eval_func_impl(bj::context& ctx, iter_t beg, iter_t end) |
87 | 111 | { |
@@ -135,7 +159,7 @@ | ||
135 | 159 | const bj::variable_table& table = f.current_module().variables; |
136 | 160 | const bj::list_of_list& args = f.arguments(); |
137 | 161 | |
138 | - const std::string& name = ::node_value(tree.children.front()); | |
162 | + const std::string& name = ::eval_arg_p(tree.children.front()); | |
139 | 163 | return bj::expand_variable(name, table, args); |
140 | 164 | } |
141 | 165 | else |
@@ -194,7 +218,7 @@ | ||
194 | 218 | return bj::string_list("1"); |
195 | 219 | else if (beg == end) |
196 | 220 | return bj::string_list(); |
197 | - | |
221 | + | |
198 | 222 | const bj::string_list& rhs = ::eval_list(ctx, *(beg++)); |
199 | 223 | if (::includes(values, rhs)) |
200 | 224 | ::set_true(values, rhs); |
@@ -332,6 +356,61 @@ | ||
332 | 356 | return values; |
333 | 357 | } |
334 | 358 | |
359 | +bj::string_list eval_block_stmt(bj::context& ctx, const node_t& tree) | |
360 | +{ | |
361 | + assert(tree.value.id() == bj::block_stmt_id); | |
362 | + | |
363 | + iter_t beg = tree.children.begin(); | |
364 | + iter_t end = tree.children.end(); | |
365 | + assert(beg != end); | |
366 | + | |
367 | + ++beg; | |
368 | + if (beg->value.id() == bj::block_id) | |
369 | + return ::eval_block(ctx, *beg); | |
370 | + else | |
371 | + return bj::string_list(); | |
372 | +} | |
373 | + | |
374 | +bj::string_list eval_include_stmt(bj::context& ctx, const node_t& tree) | |
375 | +{ | |
376 | + assert(tree.value.id() == bj::include_stmt_id); | |
377 | + | |
378 | + iter_t beg = tree.children.begin(); | |
379 | + iter_t end = tree.children.end(); | |
380 | + assert(beg != end); | |
381 | + | |
382 | + ++beg; | |
383 | + if (beg->value.id() != bj::list_id) | |
384 | + return bj::string_list(); | |
385 | + | |
386 | + const bj::string_list& names = ::eval_list(ctx, *beg); | |
387 | + if (names.empty()) | |
388 | + return bj::string_list(); | |
389 | + | |
390 | + const std::string& target_name = names[0]; | |
391 | + bj::scoped_on_target gurad(ctx, target_name); | |
392 | + const std::string& filename = bj::search_target(ctx, target_name); | |
393 | + | |
394 | + std::ifstream is(filename.c_str(), std::ios_base::binary); | |
395 | + if (!is) | |
396 | + throw bj::cannot_open_file(filename); | |
397 | + | |
398 | + std::string str( | |
399 | + std::istreambuf_iterator<char>(is), | |
400 | + (std::istreambuf_iterator<char>()) | |
401 | + ); | |
402 | + is.close(); | |
403 | + | |
404 | + bj::scoped_change_filename guard(ctx.current_frame(), filename); | |
405 | + bs::tree_parse_info<> info = ::parse_bjam(str.c_str(), str.size()); | |
406 | + | |
407 | + trees.push_back(node_t()); | |
408 | + trees.back().swap(info.trees[0]); | |
409 | + ::eval_run(ctx, trees.back()); | |
410 | + | |
411 | + return bj::string_list(); | |
412 | +} | |
413 | + | |
335 | 414 | bj::string_list eval_invoke_stmt(bj::context& ctx, const node_t& tree) |
336 | 415 | { |
337 | 416 | assert(tree.value.id() == bj::invoke_stmt_id); |
@@ -340,7 +419,7 @@ | ||
340 | 419 | iter_t end = tree.children.end(); |
341 | 420 | assert(beg != end); |
342 | 421 | |
343 | - const std::string& name = ::node_value(*(beg++)); | |
422 | + const std::string& name = ::eval_arg_p(*(beg++)); | |
344 | 423 | bj::list_of_list args; |
345 | 424 | if (beg->value.id() == bj::lol_id) |
346 | 425 | args = ::eval_lol(ctx, *beg); |
@@ -357,7 +436,7 @@ | ||
357 | 436 | default: |
358 | 437 | assert(0); |
359 | 438 | case '=': |
360 | - return bj::assign_mode::set_default; | |
439 | + return bj::assign_mode::set; | |
361 | 440 | case '+': |
362 | 441 | return bj::assign_mode::append; |
363 | 442 | case '?': |
@@ -417,8 +496,23 @@ | ||
417 | 496 | return values; |
418 | 497 | } |
419 | 498 | |
420 | -void eval_for_stmt(bj::context& ctx, const node_t& tree) | |
499 | +bj::string_list eval_return_stmt(bj::context& ctx, const node_t& tree) | |
421 | 500 | { |
501 | + assert(tree.value.id() == bj::return_stmt_id); | |
502 | + | |
503 | + iter_t beg = tree.children.begin(); | |
504 | + iter_t end = tree.children.end(); | |
505 | + assert(beg != end); | |
506 | + | |
507 | + ++beg; | |
508 | + if (beg->value.id() == bj::list_id) | |
509 | + return ::eval_list(ctx, *beg); | |
510 | + else | |
511 | + return bj::string_list(); | |
512 | +} | |
513 | + | |
514 | +bj::string_list eval_for_stmt(bj::context& ctx, const node_t& tree) | |
515 | +{ | |
422 | 516 | assert(tree.value.id() == bj::for_stmt_id); |
423 | 517 | |
424 | 518 | iter_t beg = tree.children.begin(); |
@@ -425,14 +519,16 @@ | ||
425 | 519 | iter_t end = tree.children.end(); |
426 | 520 | assert(beg != end); |
427 | 521 | |
522 | + ++beg; | |
523 | + | |
428 | 524 | bool local = false; |
429 | - if (::node_value(*++beg) == "local") | |
525 | + if (::node_value(*beg) == "local") | |
430 | 526 | { |
431 | 527 | local = true; |
432 | 528 | ++beg; |
433 | 529 | } |
434 | 530 | |
435 | - const std::string& var = ::node_value(*(beg++)); | |
531 | + const std::string& var = ::eval_arg_p(*(beg++)); | |
436 | 532 | ++beg; |
437 | 533 | bj::string_list values; |
438 | 534 | if (beg->value.id() == bj::list_id) |
@@ -448,6 +544,8 @@ | ||
448 | 544 | if (beg->value.id() == bj::block_id) |
449 | 545 | ::eval_block(ctx, *beg); |
450 | 546 | } |
547 | + | |
548 | + return bj::string_list(); | |
451 | 549 | } |
452 | 550 | |
453 | 551 | bj::string_list |
@@ -461,7 +559,7 @@ | ||
461 | 559 | while (beg != end) |
462 | 560 | { |
463 | 561 | ++beg; |
464 | - const std::string& pattern = ::node_value(*(beg++)); | |
562 | + const std::string& pattern = ::eval_arg_p(*(beg++)); | |
465 | 563 | |
466 | 564 | if (++beg == end) |
467 | 565 | break; |
@@ -522,7 +620,7 @@ | ||
522 | 620 | return bj::string_list(); |
523 | 621 | } |
524 | 622 | |
525 | -void eval_class_stmt(bj::context& ctx, const node_t& tree) | |
623 | +bj::string_list eval_class_stmt(bj::context& ctx, const node_t& tree) | |
526 | 624 | { |
527 | 625 | assert(tree.value.id() == bj::class_stmt_id); |
528 | 626 |
@@ -544,6 +642,8 @@ | ||
544 | 642 | ++beg; |
545 | 643 | if (beg->value.id() == bj::block_id) |
546 | 644 | ::eval_block(ctx, *beg); |
645 | + | |
646 | + return bj::string_list(); | |
547 | 647 | } |
548 | 648 | |
549 | 649 | bj::string_list eval_while_stmt(bj::context& ctx, const node_t& tree) |
@@ -567,6 +667,38 @@ | ||
567 | 667 | return values; |
568 | 668 | } |
569 | 669 | |
670 | +bj::string_list eval_if_stmt(bj::context& ctx, const node_t& tree) | |
671 | +{ | |
672 | + assert(tree.value.id() == bj::if_stmt_id); | |
673 | + | |
674 | + iter_t beg = tree.children.begin(); | |
675 | + iter_t end = tree.children.end(); | |
676 | + | |
677 | + ++beg; | |
678 | + const bj::string_list& cond = ::eval_expr(ctx, *(beg++)); | |
679 | + ++beg; | |
680 | + | |
681 | + bj::string_list values; | |
682 | + if (cond) | |
683 | + { | |
684 | + if (beg->value.id() == bj::block_id) | |
685 | + values = ::eval_block(ctx, *beg); | |
686 | + } | |
687 | + else | |
688 | + { | |
689 | + if (beg->value.id() == bj::block_id) | |
690 | + ++beg; | |
691 | + ++beg; | |
692 | + | |
693 | + if (beg != end) | |
694 | + { | |
695 | + ++beg; | |
696 | + values = ::eval_rule(ctx, *beg); | |
697 | + } | |
698 | + } | |
699 | + return values; | |
700 | +} | |
701 | + | |
570 | 702 | bj::list_of_list eval_arglist(bj::context& ctx, const node_t& tree) |
571 | 703 | { |
572 | 704 | assert(tree.value.id() == bj::arglist_id); |
@@ -582,7 +714,7 @@ | ||
582 | 714 | return bj::list_of_list(); |
583 | 715 | } |
584 | 716 | |
585 | -void eval_rule_stmt(bj::context& ctx, const node_t& tree) | |
717 | +bj::string_list eval_rule_stmt(bj::context& ctx, const node_t& tree) | |
586 | 718 | { |
587 | 719 | assert(tree.value.id() == bj::rule_stmt_id); |
588 | 720 |
@@ -591,13 +723,14 @@ | ||
591 | 723 | assert(beg != end); |
592 | 724 | |
593 | 725 | bj::rule_definition def; |
594 | - if (::node_value(*++beg) == "local") | |
726 | + if (::node_value(*beg) == "local") | |
595 | 727 | { |
596 | 728 | def.exported = false; |
597 | 729 | ++beg; |
598 | 730 | } |
731 | + ++beg; | |
599 | 732 | |
600 | - const std::string& name = ::node_value(*(beg++)); | |
733 | + const std::string& name = ::eval_arg_p(*(beg++)); | |
601 | 734 | if (beg->value.id() == bj::arglist_id) |
602 | 735 | def.parameters = ::eval_arglist(ctx, *(beg++)); |
603 | 736 | def.body = boost::bind(&eval_rule, _1, boost::cref(*beg)); |
@@ -605,8 +738,119 @@ | ||
605 | 738 | bj::frame& f = ctx.current_frame(); |
606 | 739 | bj::rule_table& table = f.current_module().rules; |
607 | 740 | table.set_rule_definition(name, def); |
741 | + | |
742 | + return bj::string_list(); | |
608 | 743 | } |
609 | 744 | |
745 | +bj::string_list eval_on_stmt(bj::context& ctx, const node_t& tree) | |
746 | +{ | |
747 | + assert(tree.value.id() == bj::on_stmt_id); | |
748 | + | |
749 | + iter_t beg = tree.children.begin(); | |
750 | + iter_t end = tree.children.end(); | |
751 | + assert(beg != end); | |
752 | + | |
753 | + ++beg; | |
754 | + const bj::string_list& targets = ::eval_arg(ctx, *(beg++)); | |
755 | + if (targets.empty()) | |
756 | + return bj::string_list(); | |
757 | + | |
758 | + bj::scoped_on_target guard(ctx, targets[0]); | |
759 | + return ::eval_rule(ctx, *beg); | |
760 | +} | |
761 | + | |
762 | +bj::action_modifier::values eval_eflags(const node_t& tree) | |
763 | +{ | |
764 | + assert(tree.value.id() == bj::eflags_id); | |
765 | + | |
766 | + iter_t beg = tree.children.begin(); | |
767 | + iter_t end = tree.children.end(); | |
768 | + | |
769 | + bj::action_modifier::values eflags = bj::action_modifier::values(); | |
770 | + while (beg != end) | |
771 | + { | |
772 | + switch (*beg->value.begin()) | |
773 | + { | |
774 | + case 'u': | |
775 | + eflags = eflags | bj::action_modifier::updated; | |
776 | + break; | |
777 | + case 't': | |
778 | + eflags = eflags | bj::action_modifier::together; | |
779 | + break; | |
780 | + case 'i': | |
781 | + eflags = eflags | bj::action_modifier::ignore; | |
782 | + break; | |
783 | + case 'q': | |
784 | + eflags = eflags | bj::action_modifier::quietly; | |
785 | + break; | |
786 | + case 'p': | |
787 | + eflags = eflags | bj::action_modifier::piecemeal; | |
788 | + break; | |
789 | + case 'e': | |
790 | + eflags = eflags | bj::action_modifier::existing; | |
791 | + break; | |
792 | + } | |
793 | + } | |
794 | + return eflags; | |
795 | +} | |
796 | + | |
797 | +bj::string_list eval_bindlist(bj::context& ctx, const node_t& tree) | |
798 | +{ | |
799 | + assert(tree.value.id() == bj::bindlist_id); | |
800 | + | |
801 | + iter_t beg = tree.children.begin(); | |
802 | + iter_t end = tree.children.end(); | |
803 | + assert(beg != end); | |
804 | + | |
805 | + ++beg; | |
806 | + | |
807 | + if (beg == end) | |
808 | + return ::eval_list(ctx, *beg); | |
809 | + else | |
810 | + return bj::string_list(); | |
811 | +} | |
812 | + | |
813 | +bj::string_list eval_actions_stmt(bj::context& ctx, const node_t& tree) | |
814 | +{ | |
815 | + assert(tree.value.id() == bj::actions_stmt_id); | |
816 | + | |
817 | + iter_t beg = tree.children.begin(); | |
818 | + iter_t end = tree.children.end(); | |
819 | + assert(beg != end); | |
820 | + | |
821 | + ++beg; | |
822 | + | |
823 | + bj::rule_definition def; | |
824 | + if (beg->value.id() == bj::eflags_id) | |
825 | + def.modifiers = ::eval_eflags(*(beg++)); | |
826 | + | |
827 | + const std::string& name = ::eval_arg_p(*(beg++)); | |
828 | + | |
829 | + if (beg->value.id() == bj::bindlist_id) | |
830 | + def.binds = ::eval_bindlist(ctx, *(beg++)); | |
831 | + | |
832 | + ++beg; | |
833 | + def.commands = ::node_value(*beg); | |
834 | + | |
835 | + bj::frame& f = ctx.current_frame(); | |
836 | + bj::rule_table& table = f.current_module().rules; | |
837 | + | |
838 | + table.set_rule_actions(name, def); | |
839 | + | |
840 | + const boost::optional<std::string> module_name = f.module_name(); | |
841 | + if (module_name) | |
842 | + { | |
843 | + std::string full_name = *module_name; | |
844 | + full_name += '.'; | |
845 | + full_name += name; | |
846 | + | |
847 | + bj::module& root = ctx.get_module(boost::optional<std::string>()); | |
848 | + root.rules.set_rule_actions(full_name, def); | |
849 | + } | |
850 | + | |
851 | + return bj::string_list(); | |
852 | +} | |
853 | + | |
610 | 854 | bj::string_list eval_rule(bj::context& ctx, const node_t& tree) |
611 | 855 | { |
612 | 856 | assert(tree.value.id() == bj::rule_id); |
@@ -615,51 +859,38 @@ | ||
615 | 859 | iter_t end = tree.children.end(); |
616 | 860 | assert(beg != end); |
617 | 861 | |
618 | - if (beg->value.id() == bj::invoke_stmt_id) | |
862 | + if (beg->value.id() == bj::block_stmt_id) | |
863 | + return ::eval_block_stmt(ctx, *beg); | |
864 | + else if (beg->value.id() == bj::include_stmt_id) | |
865 | + return ::eval_include_stmt(ctx, *beg); | |
866 | + else if (beg->value.id() == bj::invoke_stmt_id) | |
619 | 867 | return ::eval_invoke_stmt(ctx, *beg); |
620 | 868 | else if (beg->value.id() == bj::set_stmt_id) |
621 | 869 | return ::eval_set_stmt(ctx, *beg); |
622 | 870 | else if (beg->value.id() == bj::set_on_stmt_id) |
623 | 871 | return ::eval_set_on_stmt(ctx, *beg); |
872 | + else if (beg->value.id() == bj::return_stmt_id) | |
873 | + return ::eval_return_stmt(ctx, *beg); | |
624 | 874 | else if (beg->value.id() == bj::for_stmt_id) |
625 | - { | |
626 | - ::eval_for_stmt(ctx, *beg); | |
627 | - return bj::string_list(); | |
628 | - } | |
875 | + return ::eval_for_stmt(ctx, *beg); | |
629 | 876 | else if (beg->value.id() == bj::switch_stmt_id) |
630 | 877 | return ::eval_switch_stmt(ctx, *beg); |
631 | 878 | else if (beg->value.id() == bj::module_stmt_id) |
632 | 879 | return ::eval_module_stmt(ctx, *beg); |
633 | 880 | else if (beg->value.id() == bj::class_stmt_id) |
634 | - { | |
635 | - ::eval_class_stmt(ctx, *beg); | |
636 | - return bj::string_list(); | |
637 | - } | |
881 | + return ::eval_class_stmt(ctx, *beg); | |
638 | 882 | else if (beg->value.id() == bj::while_stmt_id) |
639 | 883 | return ::eval_while_stmt(ctx, *beg); |
884 | + else if (beg->value.id() == bj::if_stmt_id) | |
885 | + return ::eval_if_stmt(ctx, *beg); | |
640 | 886 | else if (beg->value.id() == bj::rule_stmt_id) |
641 | - { | |
642 | - eval_rule_stmt(ctx, *beg); | |
643 | - return bj::string_list(); | |
644 | - } | |
887 | + return ::eval_rule_stmt(ctx, *beg); | |
888 | + else if (beg->value.id() == bj::on_stmt_id) | |
889 | + return ::eval_on_stmt(ctx, *beg); | |
890 | + else if (beg->value.id() == bj::actions_stmt_id) | |
891 | + return ::eval_actions_stmt(ctx, *beg); | |
645 | 892 | else |
646 | 893 | { |
647 | - const std::string& x = ::node_value(*(beg++)); | |
648 | - if (x == "return") | |
649 | - { | |
650 | - if (beg->value.id() == bj::list_id) | |
651 | - return ::eval_list(ctx, *beg); | |
652 | - else | |
653 | - return bj::string_list(); | |
654 | - } | |
655 | - else if (x == "{") | |
656 | - { | |
657 | - if (beg->value.id() == bj::block_id) | |
658 | - return ::eval_block(ctx, *beg); | |
659 | - else | |
660 | - return bj::string_list(); | |
661 | - } | |
662 | - | |
663 | 894 | // TODO |
664 | 895 | return bj::string_list(); |
665 | 896 | } |
@@ -682,7 +913,7 @@ | ||
682 | 913 | |
683 | 914 | bj::string_list eval_local_set_stmt(bj::context& ctx, const node_t& tree) |
684 | 915 | { |
685 | - assert(tree.value.id() == bj::set_stmt_id); | |
916 | + assert(tree.value.id() == bj::local_set_stmt_id); | |
686 | 917 | |
687 | 918 | iter_t beg = tree.children.begin(); |
688 | 919 | iter_t end = tree.children.end(); |
@@ -727,10 +958,7 @@ | ||
727 | 958 | return values; |
728 | 959 | } |
729 | 960 | else |
730 | - { | |
731 | - // TODO | |
732 | - return bj::string_list(); | |
733 | - } | |
961 | + return ::eval_local_set_stmt(ctx, *beg); | |
734 | 962 | } |
735 | 963 | |
736 | 964 | bj::string_list eval_block(bj::context& ctx, const node_t& tree) |
@@ -762,9 +990,6 @@ | ||
762 | 990 | } |
763 | 991 | |
764 | 992 | |
765 | -#include <fstream> | |
766 | -#include <sstream> | |
767 | - | |
768 | 993 | bj::string_list echo(bj::context& ctx) |
769 | 994 | { |
770 | 995 | const bj::list_of_list& args = ctx.current_frame().arguments(); |
@@ -773,17 +998,6 @@ | ||
773 | 998 | return bj::string_list(); |
774 | 999 | } |
775 | 1000 | |
776 | -bs::tree_parse_info<> parse_bjam(const char* s) | |
777 | -{ | |
778 | - return bj::bjam_grammar_gen<const char*>:: | |
779 | - parse_bjam_grammar(s, s+std::strlen(s)); | |
780 | -} | |
781 | - | |
782 | -bs::tree_parse_info<> parse_bjam(const char* s, std::size_t n) | |
783 | -{ | |
784 | - return bj::bjam_grammar_gen<const char*>::parse_bjam_grammar(s, s+n); | |
785 | -} | |
786 | - | |
787 | 1001 | int main() |
788 | 1002 | { |
789 | 1003 | try |
@@ -27,11 +27,13 @@ | ||
27 | 27 | assign_list_id, |
28 | 28 | arglist_id, |
29 | 29 | rule_id, |
30 | + block_stmt_id, | |
30 | 31 | include_stmt_id, |
31 | 32 | invoke_stmt_id, |
32 | 33 | set_stmt_id, |
33 | 34 | set_on_stmt_id, |
34 | 35 | assign_id, |
36 | + return_stmt_id, | |
35 | 37 | for_stmt_id, |
36 | 38 | switch_stmt_id, |
37 | 39 | cases_id, |
@@ -42,11 +42,13 @@ | ||
42 | 42 | rule_t arglist; |
43 | 43 | rule_t rule; |
44 | 44 | rule_t local_set_stmt; |
45 | + rule_t block_stmt; | |
45 | 46 | rule_t include_stmt; |
46 | 47 | rule_t invoke_stmt; |
47 | 48 | rule_t set_stmt; |
48 | 49 | rule_t set_on_stmt; |
49 | 50 | rule_t assign; |
51 | + rule_t return_stmt; | |
50 | 52 | rule_t for_stmt; |
51 | 53 | rule_t switch_stmt; |
52 | 54 | rule_t cases; |
@@ -106,16 +108,12 @@ | ||
106 | 108 | ; |
107 | 109 | |
108 | 110 | rule |
109 | - = keyword_p("{") | |
110 | - >> block | |
111 | - >> keyword_p("}") | |
111 | + = block_stmt | |
112 | 112 | | include_stmt |
113 | 113 | | invoke_stmt |
114 | 114 | | set_stmt |
115 | 115 | | set_on_stmt |
116 | - | keyword_p("return") | |
117 | - >> list | |
118 | - >> keyword_p(";") | |
116 | + | return_stmt | |
119 | 117 | | for_stmt |
120 | 118 | | switch_stmt |
121 | 119 | | module_stmt |
@@ -127,6 +125,12 @@ | ||
127 | 125 | | actions_stmt |
128 | 126 | ; |
129 | 127 | |
128 | + block_stmt | |
129 | + = keyword_p("{") | |
130 | + >> block | |
131 | + >> keyword_p("}") | |
132 | + ; | |
133 | + | |
130 | 134 | include_stmt |
131 | 135 | = keyword_p("include") |
132 | 136 | >> list |
@@ -163,6 +167,12 @@ | ||
163 | 167 | >> keyword_p("=") |
164 | 168 | ; |
165 | 169 | |
170 | + return_stmt | |
171 | + = keyword_p("return") | |
172 | + >> list | |
173 | + >> keyword_p(";") | |
174 | + ; | |
175 | + | |
166 | 176 | for_stmt |
167 | 177 | = keyword_p("for") |
168 | 178 | >> !keyword_p("local") |
@@ -336,11 +346,13 @@ | ||
336 | 346 | assign_list.set_id(assign_list_id); |
337 | 347 | arglist.set_id(arglist_id); |
338 | 348 | rule.set_id(rule_id); |
349 | + block_stmt.set_id(block_stmt_id); | |
339 | 350 | include_stmt.set_id(include_stmt_id); |
340 | 351 | invoke_stmt.set_id(invoke_stmt_id); |
341 | 352 | set_stmt.set_id(set_stmt_id); |
342 | 353 | set_on_stmt.set_id(set_on_stmt_id); |
343 | 354 | assign.set_id(assign_id); |
355 | + return_stmt.set_id(return_stmt_id); | |
344 | 356 | for_stmt.set_id(for_stmt_id); |
345 | 357 | switch_stmt.set_id(switch_stmt_id); |
346 | 358 | cases.set_id(cases_id); |
@@ -372,10 +384,13 @@ | ||
372 | 384 | BOOST_SPIRIT_DEBUG_RULE(assign_list); |
373 | 385 | BOOST_SPIRIT_DEBUG_RULE(arglist); |
374 | 386 | BOOST_SPIRIT_DEBUG_RULE(rule); |
387 | + BOOST_SPIRIT_DEBUG_RULE(block_stmt); | |
388 | + BOOST_SPIRIT_DEBUG_RULE(include_stmt); | |
375 | 389 | BOOST_SPIRIT_DEBUG_RULE(invoke_stmt); |
376 | 390 | BOOST_SPIRIT_DEBUG_RULE(set_stmt); |
377 | 391 | BOOST_SPIRIT_DEBUG_RULE(set_on_stmt); |
378 | 392 | BOOST_SPIRIT_DEBUG_RULE(assign); |
393 | + BOOST_SPIRIT_DEBUG_RULE(return_stmt); | |
379 | 394 | BOOST_SPIRIT_DEBUG_RULE(for_stmt); |
380 | 395 | BOOST_SPIRIT_DEBUG_RULE(switch_stmt); |
381 | 396 | BOOST_SPIRIT_DEBUG_RULE(cases); |
@@ -0,0 +1,37 @@ | ||
1 | +// search.hpp: search the target file | |
2 | + | |
3 | +// Copyright Takeshi Mouri 2007, 2008. | |
4 | +// Distributed under the Boost Software License, Version 1.0. | |
5 | +// (See accompanying file LICENSE_1_0.txt or copy at | |
6 | +// http://www.boost.org/LICENSE_1_0.txt) | |
7 | + | |
8 | +// See http://hamigaki.sourceforge.jp/libs/bjam for library home page. | |
9 | + | |
10 | +#ifndef HAMIGAKI_BJAM2_UTIL_SEARCH_HPP | |
11 | +#define HAMIGAKI_BJAM2_UTIL_SEARCH_HPP | |
12 | + | |
13 | +#include <hamigaki/bjam2/bjam_config.hpp> | |
14 | +#include <string> | |
15 | + | |
16 | +#ifdef BOOST_HAS_ABI_HEADERS | |
17 | + #include BOOST_ABI_PREFIX | |
18 | +#endif | |
19 | + | |
20 | +namespace hamigaki { namespace bjam2 { | |
21 | + | |
22 | +class context; | |
23 | + | |
24 | +HAMIGAKI_BJAM2_DECL | |
25 | +void call_bind_rule( | |
26 | + context& ctx, const std::string& name, const std::string& filename); | |
27 | + | |
28 | +HAMIGAKI_BJAM2_DECL | |
29 | +std::string search_target(context& ctx, const std::string& name); | |
30 | + | |
31 | +} } // End namespaces bjam2, hamigaki. | |
32 | + | |
33 | +#ifdef BOOST_HAS_ABI_HEADERS | |
34 | + #include BOOST_ABI_SUFFIX | |
35 | +#endif | |
36 | + | |
37 | +#endif // HAMIGAKI_BJAM2_UTIL_SEARCH_HPP |
@@ -20,12 +20,12 @@ | ||
20 | 20 | { |
21 | 21 | enum values |
22 | 22 | { |
23 | - updated, | |
24 | - together, | |
25 | - ignore, | |
26 | - quietly, | |
27 | - piecemeal, | |
28 | - existing | |
23 | + updated = 1u << 0, | |
24 | + together = 1u << 1, | |
25 | + ignore = 1u << 2, | |
26 | + quietly = 1u << 3, | |
27 | + piecemeal = 1u << 4, | |
28 | + existing = 1u << 5, | |
29 | 29 | }; |
30 | 30 | }; |
31 | 31 |
@@ -37,21 +37,49 @@ | ||
37 | 37 | ); |
38 | 38 | } |
39 | 39 | |
40 | +inline action_modifier::values | |
41 | +operator&(action_modifier::values lhs, action_modifier::values rhs) | |
42 | +{ | |
43 | + return static_cast<action_modifier::values>( | |
44 | + static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs) | |
45 | + ); | |
46 | +} | |
47 | + | |
40 | 48 | #if defined(BOOST_SPIRIT_DEBUG) |
41 | 49 | inline std::ostream& operator<<(std::ostream& os, action_modifier::values x) |
42 | 50 | { |
43 | - if (x == action_modifier::updated) | |
44 | - return os << "updated"; | |
45 | - else if (x == action_modifier::together) | |
46 | - return os << "together"; | |
47 | - else if (x == action_modifier::ignore) | |
48 | - return os << "ignore"; | |
49 | - else if (x == action_modifier::quietly) | |
50 | - return os << "quietly"; | |
51 | - else if (x == action_modifier::piecemeal) | |
52 | - return os << "piecemeal"; | |
53 | - else | |
54 | - return os << "existing"; | |
51 | + const char* delim = ""; | |
52 | + if (x & action_modifier::updated) | |
53 | + { | |
54 | + os << delim << "updated"; | |
55 | + delim = " "; | |
56 | + } | |
57 | + if (x & action_modifier::together) | |
58 | + { | |
59 | + os << delim << "together"; | |
60 | + delim = " "; | |
61 | + } | |
62 | + if (x & action_modifier::ignore) | |
63 | + { | |
64 | + os << delim << "ignore"; | |
65 | + delim = " "; | |
66 | + } | |
67 | + if (x & action_modifier::quietly) | |
68 | + { | |
69 | + os << delim << "quietly"; | |
70 | + delim = " "; | |
71 | + } | |
72 | + if (x & action_modifier::piecemeal) | |
73 | + { | |
74 | + os << delim << "piecemeal"; | |
75 | + delim = " "; | |
76 | + } | |
77 | + if (x & action_modifier::existing) | |
78 | + { | |
79 | + os << delim << "existing"; | |
80 | + delim = " "; | |
81 | + } | |
82 | + return os; | |
55 | 83 | } |
56 | 84 | #endif |
57 | 85 |