!failを入れてみた
@@ -125,6 +125,8 @@ | ||
125 | 125 | ExecContext_Factory newExecContext_Times( newExecContext_Times_Function); |
126 | 126 | ExecContextRoot *newExecContext_Cut_Function(ExecContext *p_, void *f_, const PPredicate *pred_, VLocal *l) { return new ExecContext_Cut( p_, f_, pred_, l); } |
127 | 127 | ExecContext_Factory newExecContext_Cut( newExecContext_Cut_Function); |
128 | +ExecContextRoot *newExecContext_CutFail_Function(ExecContext *p_, void *f_, const PPredicate *pred_, VLocal *l) { return new ExecContext_CutFail( p_, f_, pred_, l); } | |
129 | +ExecContext_Factory newExecContext_CutFail( newExecContext_CutFail_Function); | |
128 | 130 | |
129 | 131 | ExecContextRoot *newExecContext_Fail_Function(ExecContext *p_, void *f_, const PPredicate *pred_, VLocal *l) { return new ExecContext_Fail( p_, f_, pred_, l); } |
130 | 132 | ExecContext_Factory newExecContext_Fail( newExecContext_Fail_Function); |
@@ -493,6 +495,7 @@ | ||
493 | 495 | factory_map.insert(ExecContext_Factory_Pair( string("counter"), &newExecContext_Counter)); |
494 | 496 | factory_map.insert(ExecContext_Factory_Pair( string("times"), &newExecContext_Times)); |
495 | 497 | factory_map.insert(ExecContext_Factory_Pair( string("!"), &newExecContext_Cut)); |
498 | + factory_map.insert(ExecContext_Factory_Pair( string("!fail"), &newExecContext_CutFail)); | |
496 | 499 | factory_map.insert(ExecContext_Factory_Pair( string("fail"), &newExecContext_Fail)); |
497 | 500 | factory_map.insert(ExecContext_Factory_Pair( string("raise"), &newExecContext_Raise)); |
498 | 501 | factory_map.insert(ExecContext_Factory_Pair( string("next"), &newExecContext_Next)); |
@@ -470,7 +470,6 @@ | ||
470 | 470 | // マルチスレッド動作時の整合性を保つため、gl = ExecContext.hlocalとする |
471 | 471 | } |
472 | 472 | ExecContextBase(ExecContext *p_, void *f_, const PPredicate *pred_, VLocal *l) : ExecContextRoot(p_, f_, pred_, l), backup(), objs() { |
473 | - pobjs = &objs; | |
474 | 473 | init(); |
475 | 474 | } |
476 | 475 | // recreate メモリマネージャレベルでのオブジェクトのリサイクル |
@@ -568,7 +567,7 @@ | ||
568 | 567 | horn = 0; |
569 | 568 | goal = 0; |
570 | 569 | hl = &hlocal; // ローカル変数エリア |
571 | - // ecs,afterunifyのreserveはfirst,backtrackで行う | |
570 | + afterunify.reserve(pred->size()); | |
572 | 571 | horns = 0; |
573 | 572 | skipnamechk = false; |
574 | 573 | hornidx = 0; |
@@ -577,7 +576,6 @@ | ||
577 | 576 | nextidx = (size_t)-1; |
578 | 577 | pipe = 0; |
579 | 578 | trueflg = false; |
580 | - afterunify.reserve(pred->size()); | |
581 | 579 | nobacktrack = false; |
582 | 580 | last_result = false; |
583 | 581 | }; |
@@ -592,6 +590,7 @@ | ||
592 | 590 | ExecContextBase::backup = *gl; // ややこしいがCut述語使用時の整合性を取る為ここでバッグアップを取得しておく |
593 | 591 | ecs.assign(goal->size(), 0); |
594 | 592 | afterunify.reserve(vcnt); |
593 | + afterunify.clear(); | |
595 | 594 | horns = 0; |
596 | 595 | skipnamechk = false; |
597 | 596 | hornidx = 0; |
@@ -622,7 +621,7 @@ | ||
622 | 621 | bool execute(PException &excp, bool forward); |
623 | 622 | |
624 | 623 | virtual void cleanup() { |
625 | - for_each( ecs.begin(), ecs.end(), MyDeleteObject()); | |
624 | + for_each( ecs.begin(), ecs.end(), MyDeleteEC()); | |
626 | 625 | ecs.clear(); |
627 | 626 | ExecContextBase::cleanup(); |
628 | 627 | } |
@@ -704,6 +703,11 @@ | ||
704 | 703 | |
705 | 704 | struct ExecContext_Cut : public ExecContextRoot { |
706 | 705 | ExecContext_Cut(ExecContext *p_, void *f_, const PPredicate *pred_, VLocal *l) : ExecContextRoot(p_, f_, pred_, l) { delflg = false; } |
706 | + virtual void recreate(const PPredicate *pred_, VLocal *l) { ExecContextRoot::init(pred_, l); delflg = false; } | |
707 | + virtual void recreate(ExecContext *p_, void *f_, const PPredicate *pred_, VLocal *l) { ExecContextRoot::init(p_,f,pred_, l); delflg = false; } | |
708 | + virtual void reinit(const PPredicate *pred_, VLocal *l) { ExecContextRoot::init(pred_, l); delflg = false; } | |
709 | + virtual void reinit(ExecContext *p_, void *f_, const PPredicate *pred_, VLocal *l) { ExecContextRoot::init(p_,f,pred_, l); delflg = false; } | |
710 | + | |
707 | 711 | virtual bool first(PException &excp) { |
708 | 712 | // 使用予定の親のローカル変数の値をcloneする、 |
709 | 713 | Array<bool> maker; |
@@ -739,6 +743,7 @@ | ||
739 | 743 | } |
740 | 744 | } |
741 | 745 | |
746 | + // 親の評価コンテクストを削除する | |
742 | 747 | for ( size_t i = 0; i < p->goalidx; i++ ) { |
743 | 748 | ExecContextRoot *e = p->ecs[i]; |
744 | 749 | if ( e ) { |
@@ -746,7 +751,7 @@ | ||
746 | 751 | p->ecs[i] = 0; |
747 | 752 | } |
748 | 753 | } |
749 | - if ( p->goalidx >= p->goal->size() ) { | |
754 | + if ( p->goalidx >= p->goal->size() - 1 ) { | |
750 | 755 | p->delflg = true; |
751 | 756 | } |
752 | 757 | return true; |
@@ -758,6 +763,15 @@ | ||
758 | 763 | } |
759 | 764 | }; |
760 | 765 | |
766 | +struct ExecContext_CutFail : public ExecContext_Cut { | |
767 | + ExecContext_CutFail(ExecContext *p_, void *f_, const PPredicate *pred_, VLocal *l) : ExecContext_Cut(p_, f_, pred_, l) {} | |
768 | + virtual bool first(PException &excp) { | |
769 | + ExecContext_Cut::first(excp); | |
770 | + p->nobacktrack = true; | |
771 | + return false; | |
772 | + } | |
773 | +}; | |
774 | + | |
761 | 775 | struct ExecContext_Fail : public ExecContextRoot { |
762 | 776 | ExecContext_Fail(ExecContext *p_, void *f_, const PPredicate *pred_, VLocal *l) : ExecContextRoot(p_, f_, pred_, l) {} |
763 | 777 | virtual bool first(PException &excp) { |
@@ -23,12 +23,12 @@ | ||
23 | 23 | |
24 | 24 | // 定数 |
25 | 25 | #ifdef ___X64____ |
26 | -#define VERSION_TEXT "ADP Ver 0.82.0301 X64 (http://www.adp.la/)\nCopyright (C) 2010-2012 Katsuhisa Ohfuji. This progman is distributed under GPL.\n" | |
26 | +#define VERSION_TEXT "ADP Ver 0.82.0304 X64 (http://www.adp.la/)\nCopyright (C) 2010-2012 Katsuhisa Ohfuji. This progman is distributed under GPL.\n" | |
27 | 27 | #else |
28 | 28 | #if _WIN32 |
29 | -#define VERSION_TEXT "ADP Ver 0.82.0301 x86 (http://www.adp.la/)\nCopyright (C) 2010-2012 Katsuhisa Ohfuji. This progman is distributed under GPL.\n" | |
29 | +#define VERSION_TEXT "ADP Ver 0.82.0304 x86 (http://www.adp.la/)\nCopyright (C) 2010-2012 Katsuhisa Ohfuji. This progman is distributed under GPL.\n" | |
30 | 30 | #else |
31 | -#define VERSION_TEXT "ADP Ver 0.82.0301 (http://www.adp.la/)\nCopyright (C) 2010-2012 Katsuhisa Ohfuji. This progman is distributed under GPL.\n" | |
31 | +#define VERSION_TEXT "ADP Ver 0.82.0304 (http://www.adp.la/)\nCopyright (C) 2010-2012 Katsuhisa Ohfuji. This progman is distributed under GPL.\n" | |
32 | 32 | #endif |
33 | 33 | #endif |
34 | 34 |
@@ -939,30 +939,49 @@ | ||
939 | 939 | if ( *c == ';' ) c.next(); // skip ; |
940 | 940 | // バックトラックの最適化 |
941 | 941 | if ( !body.empty() ) { |
942 | - const PPredicate *p = dynamic_cast<const PPredicate *>(body.back()); | |
942 | + PPredicate *p = dynamic_cast<PPredicate *>(const_cast<PObject*>(body.back())); | |
943 | 943 | // 最後のカットは取り除く(first/backtrackメソッドで頑張る) |
944 | 944 | if ( p != 0 ) { |
945 | 945 | if ( p->ncmp("!") ) { |
946 | 946 | body.pop_back(); |
947 | 947 | nobacktrack = true; |
948 | - if ( c.cut.size() == 1 ) { | |
949 | - c.cut.clear(); | |
948 | + Array<PPredicate *>::iterator f = find( c.cut.begin(), c.cut.end(), p); | |
949 | + if ( f != c.cut.end() ) { | |
950 | + c.cut.erase(f); | |
950 | 951 | } |
951 | 952 | } |
953 | + | |
954 | + // 最後がfalseでその前が!なら !fail に置き換える | |
955 | + if ( body.size() >= 2 && p->ncmp("fail") ) { | |
956 | + PPredicate *pp = dynamic_cast<PPredicate *>(const_cast<PObject*>(body[body.size()-2])); | |
957 | + if ( pp != 0 && pp->ncmp("!") ) { | |
958 | + PString *n = dynamic_cast<PString*>(const_cast<PObject*>(pp->name)); | |
959 | + if ( n ) { | |
960 | + n->value = "!fail"; | |
961 | + body.pop_back(); | |
962 | + Array<PPredicate *>::iterator f = find( c.cut.begin(), c.cut.end(), pp); | |
963 | + if ( f != c.cut.end() ) { | |
964 | + c.cut.erase(f); | |
965 | + } | |
966 | + } | |
967 | + } | |
968 | + } | |
952 | 969 | } |
970 | + | |
953 | 971 | // 途中のカットに関しては引数に保存する変数を入れる |
954 | - for ( size_t i = 0; i < c.vstat.size(); i++ ) { | |
955 | - if ( c.vstat[i] == 3 ) { | |
956 | - PVeriable *v = get_gc()->factory.createObject<PVeriable>(); | |
957 | - v->makeVeriable(c, c.vary[i], false ); | |
958 | - // カットが複数ある場合、本来ならそのカットの位置に対して保存する変数を決定すべきだが | |
959 | - // そんなにカットを使う機会も考えられないのでカット1つを想定して最適化している | |
960 | - for ( size_t j = 0; j < c.cut.size(); j++ ) { | |
961 | - c.cut[j]->addMethodArg(c,0,v); | |
972 | + if ( !c.cut.empty() ) { | |
973 | + for ( size_t i = 0; i < c.vstat.size(); i++ ) { | |
974 | + if ( c.vstat[i] == 3 ) { | |
975 | + PVeriable *v = get_gc()->factory.createObject<PVeriable>(); | |
976 | + v->makeVeriable(c, c.vary[i], false ); | |
977 | + // カットが複数ある場合、本来ならそのカットの位置に対して保存する変数を決定すべきだが | |
978 | + // そんなにカットを使う機会も考えられないのでカット1つを想定して最適化している | |
979 | + for ( size_t j = 0; j < c.cut.size(); j++ ) { | |
980 | + c.cut[j]->addMethodArg(c,0,v); | |
981 | + } | |
962 | 982 | } |
963 | 983 | } |
964 | 984 | } |
965 | - | |
966 | 985 | } |
967 | 986 | return this; |
968 | 987 | } |