TNB Library
TnbTmlCalculator.h
[詳解]
1#pragma once
14#include "TnbStrEx.h"
15#include "TnbTmlResult.h"
16#include "TnbTmlValue.h"
17#include "TnbTmlTextEscape.h"
18#include <math.h>
19
20
21
22//TNB Library
23namespace TNB
24{
25
26
27
41{
43 virtual ~ITmlExpander(void)
44 {
45 }
46
57 virtual CTmlResult ExpandVariable(CTmlValueCarrier& _val, LPCSTR lpszToken, const CTmlValuesVector& aValues, bool boIsTestMode) = 0;
58
65 virtual CTmlResult OnChangeValue(LPCSTR lpszName, const CTmlValue& val) = 0;
66};
67
68
69
91{
92public:
93
95 CTmlCalculator(void) : m_boIsTestMode(false), m_piExpander(NULL), m_dwTickCountBase(::GetTickCount())
96 {
97 }
98
103 void SetTestMode(bool boIsTestMode)
104 {
105 m_boIsTestMode = boIsTestMode;
106 }
107
113 bool IsTestMode(void) const
114 {
115 return m_boIsTestMode;
116 }
117
122 void SetExpander(ITmlExpander* piExpander = NULL)
123 {
124 m_piExpander = piExpander;
125 }
126
133 {
134 return m_aabWildResult;
135 }
136
147 CTmlResult TextToValue(CTmlValue& _answer, LPCSTR lpsz)
148 {
149 CTmlGrammar gram(lpsz, NULL);
150 CTmlResult r = TextToValue(_answer, gram);
151 if ( r.IsSuccess() )
152 {
153 if ( gram.PeekNextParts().GetKind() != CTmlGrammar::FINAL )
154 {
156 }
157 }
158 return r;
159 }
160
171 {
172 return m_TextToValue(_answer, _gram);
173 }
174
175private:
176 ITmlExpander* m_piExpander;
177 bool m_boIsTestMode;
178 CVectorT<CByteVector> m_aabWildResult;
179 DWORD m_dwTickCountBase;
180
188 CTmlResult m_CheckArithmeticType(int& _iAriType, CTmlGrammar& _gram)
189 {
190 LPCSTR P = _gram.GetPointer();
191 char s0 = *P;
192 char s1 = *(P + 1);
193 int l = 0;
194 _iAriType = 0;
195 if ( s0 == '+' && s1 == '+' )
196 {
197 _iAriType = '++';
198 l = 2;
199 }
200 else if ( s0 == '-' && s1 == '-' )
201 {
202 _iAriType = '--';
203 l = 2;
204 }
205 else if ( s0 == '+' || s0 == '-' || s0 == '*' || s0 == '/' || s0 == '<' || s0 == '>' || s0 == '=' )
206 {
207 if ( s1 == '=' )
208 {
209 _iAriType = s0 * 0x100 + s1;
210 l = 2;
211 }
212 else
213 {
214 _iAriType = s0;
215 l = 1;
216 }
217 }
218 else if ( s0 == '!' && s1 == '=' )
219 {
220 _iAriType = s0 * 0x100 + s1;
221 l = 2;
222 }
223 else if ( s0 == 'a' && s1 == 'n' && *(P + 2) == 'd' )
224 {
225 _iAriType = 'and';
226 l = 3;
227 }
228 else if ( s0 == 'o' && s1 == 'r' )
229 {
230 _iAriType = 'or';
231 l = 2;
232 }
233 if ( l > 0 )
234 {
235 CTmlGrammar gg = _gram;
236 if ( _gram.StepPointer(l) != l )
237 {
239 }
240 return Result_Success;
241 }
242 return Result_Nop;
243 }
244
250 int m_GetArithmeticTypeLevel(int iAriType)
251 {
252 switch ( iAriType )
253 {
254 case '=':
255 case '+=':
256 case '-=':
257 case '*=':
258 case '/=':
259 return 1;
260 case 'or':
261 return 2;
262 case 'and':
263 return 3;
264 case '==':
265 case '!=':
266 return 4;
267 case '<':
268 case '<=':
269 return 4;
270 case '>':
271 case '>=':
272 return 4;
273 case '+':
274 case '-':
275 return 7;
276 case '*':
277 case '/':
278 return 8;
279 case '++':
280 case '--':
281 return 9;
282 default:
283 ASSERTLIB(false);
284 break;
285 }
286 return 0;
287 }
288
296 CTmlResult m_FindValue(CTmlValueCarrier& _n, CTmlGrammar& _gram)
297 {
298 LPCSTR pp = _gram.GetPointer();
300 //
301 CTmlResult res;
303 CAscii s = _gram.PeekNextParts().GetString();
304 if ( s == "+" || s == "-" )
305 {
306 CTmlValue ii;
307 res = m_TextToValue(ii, _gram);
308 if ( res.IsError() )
309 {
310 return res;
311 }
312 val = ii;
313 }
314 else
315 {
316 if ( s == "(" )
317 {
318 _gram.GetNextParts();
319 CTmlValue ii;
320 res = m_TextToValue(ii, _gram);
321 if ( res.IsError() )
322 {
323 return res;
324 }
325 val = ii;
326 CTmlGrammar gg = _gram;
327 if ( _gram.GetNextParts().GetAt() != ')' )
328 {
329 // `)'がありません
331 }
332 }
333 else
334 {
335 res = m_TokenToOneValue(val, _gram);
336 if ( res.IsError() )
337 {
338 return res;
339 }
340 }
341 int a = 0;
342 CTmlGrammar gramBack = _gram;
343 m_CheckArithmeticType(a, gramBack);
344 if ( a == '++' || a == '--' )
345 {
346 CTmlValueCarrier dummy;
347 res = m_CalcValueAndValue(a, val, dummy);
348 if ( res.IsError() )
349 {
350 return res.SetLine(gramBack);
351 }
352 _gram = gramBack;
353 }
354 }
355 _n = val;
356 return Result_Success;
357 }
358
366 CTmlResult m_TokenToOneValue(CTmlValueCarrier& _n, CTmlGrammar& _gram)
367 {
368 LPCSTR pp = _gram.GetPointer();
370 CTmlResult res;
371 //そこはデータ?
372 res = m_SearchDataInToken(_n, _gram);
373 if ( ! res.IsNop() )
374 {
375 return res; //成功か失敗
376 }
377 //そこは数値?
378 res = m_SearchIntegerInToken(_n, _gram);
379 if ( ! res.IsNop() )
380 {
381 return res; //成功か失敗
382 }
383 //それは変数?
384 res = m_SearchVariableInToken(_n, _gram);
385 if ( ! res.IsNop() )
386 {
387 return res; //成功か失敗
388 }
389 //なにもなかった おかしい
390 _n = 0;
392 r.SetErrorString(_gram.GetNextParts().GetString());
393 return r.SetLine(_gram);
394 }
395
402 CTmlResult m_SearchDataInToken(CTmlValueCarrier& _n, CTmlGrammar& _gram)
403 {
404 LPCSTR pp = _gram.GetPointer();
406 CTmlGrammar gg = _gram;
407 const CTmlGrammar::CParts& parts = _gram.GetNextParts();
408 if ( parts.GetKind() == CTmlGrammar::STRING )
409 {
410 CTmlTextEscape txt;
411 CTmlResult r = txt.SetData(parts.GetString());
412 if ( r.IsError() )
413 {
414 r.SetLine(gg);
415 return r;
416 }
417 _n = txt.ToValue();
418 return Result_Success;
419 }
420 _n = 0;
421 _gram = gg;
422 return Result_Nop;
423 }
424
434 CTmlResult m_SearchIntegerInToken(CTmlValueCarrier& _n, CTmlGrammar& _gram)
435 {
436 LPCSTR pp = _gram.GetPointer();
438 CTmlGrammar gg = _gram;
439 //
440 int flag = 1;
441 int count = 0;
442 bool isFloat = false;
443 int value = 0;
444 double floatValue = 0.0;
445 CTmlGrammar::CParts parts = _gram.GetNextParts();
446 for ( ; parts.IsEqualString("-") || parts.IsEqualString("+"); parts = _gram.GetNextParts() )
447 {
448 if ( parts.IsEqualString("-") )
449 {
450 flag = -1;
451 }
452 }
453 LPCSTR P = parts.GetString();
454 if ( P[0]=='0' && (P[1] == 'x' || P[1] == 'X') )
455 {
456 P += 2;
457 while ( true )
458 {
459 int c = (*P) | 0x20;
460 if ( (c < '0' || c > '9') && (c < 'a' || c > 'f') )
461 {
462 break;
463 }
464 if ( c >= 'a' && c <= 'f' )
465 {
466 value = value * 16 + (c - 'a') + 10;
467 }
468 else
469 {
470 value = value * 16 + c - '0';
471 }
472 P++;
473 count++;
474 }
475 }
476 else if ( P[0]=='\'' )
477 {
478 P++;
479 count++;
480 while ( true )
481 {
482 if ( *P == 0 )
483 {
484 // `''がありません
486 }
487 if ( *P == '\'' )
488 {
489 break;
490 }
491 value = (value * 0x100) + *P;
492 P++;
493 count++;
494 }
495 }
496 else
497 {
498 while ( true )
499 {
500 if ( *P < '0' || *P > '9' )
501 {
502 break;
503 }
504 value = (value * 10) + *P - '0';
505 P++;
506 count++;
507 }
508 //-- 小数点をチェック
509 {
510 CTmlGrammar gg = _gram;
511 if ( _gram.GetNextParts().GetAt() == '.' )
512 {
513 CTmlGrammar gg = _gram;
514 parts = _gram.GetNextParts();
515 P = parts.GetString();
516 if ( *P >= '0' && *P <= '9' )
517 {
518 int i = 0;
519 double po = 1;
520 while ( true )
521 {
522 if ( *P < '0' || *P > '9' )
523 {
524 break;
525 }
526 i = (i * 10) + *P - '0';
527 P++;
528 po *= 10.0;
529 }
530 if ( ! isFloat )
531 {
532 isFloat = true;
533 floatValue = value;
534 }
535 double ii = i;
536 floatValue += ii / po;
537 }
538 else
539 {
540 _gram = gg;
541 }
542 }
543 else
544 {
545 _gram = gg;
546 }
547 }
548 //-- 指数部をチェック
549 if ( *P == 'e' || *P == 'E' )
550 {
551 parts = _gram.GetNextParts();
552 if ( parts.IsEqualString("+") || parts.IsEqualString("-") )
553 {
554 bool isPlus = parts.GetAt() == '+';
555 parts = _gram.GetNextParts();
556 P = parts.GetString();
557 if ( *P >= '0' && *P <= '9' )
558 {
559 int i = 0;
560 while ( true )
561 {
562 if ( *P < '0' || *P > '9' )
563 {
564 break;
565 }
566 i = (i * 10) + *P - '0';
567 P++;
568 }
569 if ( ! isFloat )
570 {
571 isFloat = true;
572 floatValue = value;
573 }
574 double ii = i;
575 floatValue *= pow(10.0, isPlus ? ii : -ii);
576 }
577 }
578 else
579 {
580 // `E(指数)の後にプラスマイナスがない
582 }
583 }
584 }
585 if ( count == 0 )
586 {
587 /*数値はなかった*/
588 _gram = gg;
589 _n = 0;
590 return Result_Nop;
591 }
592 if ( isFloat )
593 {
594 _n = floatValue * flag;
595 }
596 else
597 {
598 _n = value * flag;
599 }
600 return Result_Success;
601 }
602
609 CTmlResult m_SearchVariableInToken(CTmlValueCarrier& _n, CTmlGrammar& _gram)
610 {
611 LPCSTR pp = _gram.GetPointer();
613 CTmlGrammar gg = _gram;
614 _n = 0;
615 //関数名取得
616 CTmlGrammar::CParts parts = _gram.GetNextParts();
617 CAscii originalToken = parts.GetString();
618 CAscii token = LocalMapString(originalToken, LCMAP_LOWERCASE);
619 if ( parts.GetKind() != CTmlGrammar::TOKEN || token.IsEmpty() )
620 {
621 _gram = gg;
622 return Result_Nop;
623 }
624 //
625 CTmlValuesVector aValues;
626 CTmlGrammar backGram = _gram;
627 parts = _gram.GetNextParts();
628 if ( parts.GetKind() == CTmlGrammar::STRING )
629 {
630 //foo"〜" という形だ
631 CTmlTextEscape txt;
632 CTmlResult r = txt.SetData(parts.GetString());
633 if ( r.IsError() )
634 {
635 r.SetLine(backGram);
636 return r;
637 }
639 a = txt.ToValue();
640 aValues.Add(a());
641 }
642 else if ( parts.GetAt() == '(' )
643 {
644 //foo(〜〜)と言う形だ
645 CTmlGrammar bg = _gram;
646 if ( _gram.GetNextParts().GetAt() == ')' )
647 {
648 //すぐ閉じた
649 }
650 else
651 {
652 _gram = bg;
653 while ( true )
654 {
655 CTmlValue a;
656 CTmlResult res = m_TextToValue(a, _gram);
657 if ( res.IsError() )
658 {
659 return res;
660 }
661 aValues.Add(a);
662 if ( _gram.PeekNextParts().GetAt() != ',' )
663 {
664 break;
665 }
666 _gram.GetNextParts();
667 }
668 if ( _gram.GetNextParts().GetAt() != ')' )
669 {
670 //閉じてない!
671 _n = 0;
673 }
674 }
675 }
676 else
677 {
678 //括弧省略
679 _gram = backGram;
680 }
681 //
683 if ( m_piExpander != NULL )
684 {
685 //拡張IFが指定されているなら実行
686 res = m_piExpander->ExpandVariable(_n, token, aValues, IsTestMode());
687 }
688 if ( res.IsNop() )
689 {
690 //システム変数/関数
691 res = m_SearchSystemVariable(_n, token, aValues);
692 }
693 if( res.IsError() )
694 {
695 res.SetErrorString(parts.GetString());
696 res.SetLine(gg);
697 return res; //エラー
698 }
699 if ( res.IsSuccess() )
700 {
701 return Result_Success; //成功
702 }
703 _gram = gg;
704 return Result_Nop;
705 }
706
715 CTmlResult m_CalcValueAndValue(int iAriType, CTmlValueCarrier& a, CTmlValueCarrier& b)
716 {
717 if ( IsTestMode() )
718 {
719 return Result_Success;
720 }
721 //
722 #ifndef _TnbDOXYGEN //Document作成用シンボル
723 #if defined(_TnbDEBUG_ON) && defined(_DEBUG)
724 #define XXX( STR ){ ::OutputDebugStringA( \
725 CAscii::Fmt("calc ([%s]%s %s %s)\n", \
726 a.GetExName(), a().GetString(), STR, b().GetString() ) ); }
727 #else
728 #define XXX( STR )
729 #endif
730 #endif
731 CTmlResult res;
732 CTmlValue tvResult;
733 switch ( iAriType )
734 {
735 case '=':
736 case '+=':
737 case '-=':
738 case '*=':
739 case '/=':
740 case '--':
741 case '++':
742 {
743 const CAscii& strName = a.GetExName();
744 switch ( iAriType )
745 {
746 case '++':
747 case '--':
748 if ( strName.Compare("%BEFORE OPE") == 0 )
749 {
750 if ( ! b().HasData() )
751 {
752 b() = b() + (iAriType == '++' ? +1 : -1);
753 }
754 tvResult = b();
755 a = b();
756 }
757 else
758 {
759 tvResult = a();
760 if ( ! a().HasData() )
761 {
762 a() = a() + (iAriType == '++' ? +1 : -1);
763 }
764 }
765 break;
766 case '=':
767 XXX( "=" );
768 a() = b();
769 tvResult = a();
770 break;
771 case '+=':
772 XXX( "+=" );
773 a() = a() + b();
774 tvResult = a();
775 break;
776 case '-=':
777 XXX( "-=" );
778 a() = a() - b();
779 tvResult = a();
780 break;
781 case '*=':
782 XXX( "*=" );
783 a() = a() * b();
784 tvResult = a();
785 break;
786 default:// '/='
787 XXX( "/=" );
788 if ( b() == 0 )
789 {
790 TTRACE0(" →0で割ろうとしてます\n");
792 }
793 a() = a() / b();
794 tvResult = a();
795 break;
796 }
797 //
798 if ( ! strName.IsEmpty() )
799 {
800 res = m_OnChangeValue(strName, a());
801 }
802 }
803 break;
804 case 'or':
805 XXX( "or" );
806 tvResult = ( a().GetInteger() | b().GetInteger() );
807 break;
808 case 'and':
809 XXX( "and" );
810 tvResult = ( a().GetInteger() & b().GetInteger() );
811 break;
812 case '==':
813 XXX( "==" );
814 tvResult = ( a().Compare(m_aabWildResult, b()) == 0 );
815 break;
816 case '!=':
817 XXX( "!=" );
818 tvResult = ( a().Compare(m_aabWildResult, b()) != 0 );
819 break;
820 case '<':
821 XXX( "<" );
822 tvResult = ( a() < b() );
823 break;
824 case '<=':
825 XXX( "<=" );
826 tvResult = ( a() <= b() );
827 break;
828 case '>':
829 XXX( ">" );
830 tvResult = ( a() > b() );
831 break;
832 case '>=':
833 XXX( ">=" );
834 tvResult = ( a() >= b() );
835 break;
836 case '+':
837 XXX( "+" );
838 tvResult = ( a() + b() );
839 break;
840 case '-':
841 XXX( "-" );
842 tvResult = ( a() - b() );
843 break;
844 case '*':
845 XXX( "*" );
846 tvResult = ( a() * b() );
847 break;
848 case '/':
849 XXX( "/" );
850 if ( b()==0 )
851 {
852 TTRACE0(" →0で割ろうとしてます\n");
854 }
855 else
856 {
857 tvResult = ( a() / b() );
858 }
859 break;
860 default:
861 ASSERT(false);
862 break;
863 }
864 a = tvResult;
865 #undef XXX
866 return res;
867 }
868
869 #ifndef _TnbDOXYGEN //Document作成用シンボル
870
871 #define _CHECKPARAM_RETURN( PA, NU ) \
872 TTRACE1A("found System Var [%s]\n", lpszToken); \
873 if ( PA.GetSize() != NU ) { return CTmlResult::CheckParamNum(PA.GetSize(), NU); } \
874 if ( IsTestMode() ) { return Result_Success;}
875
876 #define IsTOKEN( XX ) ( STRLIB::Compare(lpszToken, XX)==0 )
877
878 #endif //_TnbDOXYGEN
879
890 CTmlResult m_SearchSystemVariable(CTmlValueCarrier& _n, LPCSTR lpszToken, const CTmlValuesVector& aValues)
891 {
892 if ( IsTOKEN("h") )
893 {
894 _CHECKPARAM_RETURN( aValues , 1 );
895 //
896 CTmlTextEscape txt;
897 CTmlResult r = txt.SetHexToData(aValues[0].GetString());
898 if ( r.IsError() )
899 {
900 return r;
901 }
902 _n = txt.ToValue();
903 return Result_Success;
904 }
905 else if ( IsTOKEN("tickcount") )
906 {
907 //ミリ秒カウンタ
908 _CHECKPARAM_RETURN( aValues , 0 );
909 //
910 _n = ToInt(::GetTickCount() - m_dwTickCountBase);
911 _n.Set("%tickcount"); //コールバック指示
912 return Result_Success;
913 }
914 else if ( IsTOKEN("wildres") )
915 {
916 //ワイルドカードの結果
917 _CHECKPARAM_RETURN( aValues , 1 );
918 //
919 int iIndex = aValues[0].GetInteger();
920 CTmlValue v;
921 if ( iIndex < ToInt(m_aabWildResult.GetSize()) )
922 {
923 v.SetData(m_aabWildResult[iIndex].GetSize(), m_aabWildResult[iIndex].ReferBuffer());
924 }
925 _n = v;
926 return Result_Success;
927 }
928 else if ( IsTOKEN("pausebox") )
929 {
930 //汎用グローバル関数「ダイアログ表示」
931 _CHECKPARAM_RETURN( aValues , 1 );
932 //
933 CStr str = aValues[0].GetString();
934 AfxMessageBox(str, MB_ICONINFORMATION);
935 _n = 0;
936 return Result_Success;
937 }
938 else if ( IsTOKEN("yesnobox") )
939 {
940 //汎用グローバル関数「ダイアログ表示」
941 _CHECKPARAM_RETURN( aValues , 1 );
942 //
943 CStr str = aValues[0].GetString();
944 int r = AfxMessageBox(CStr(aValues[0].GetString()), MB_YESNO | MB_ICONINFORMATION);
945 _n = (r == IDYES);
946 return Result_Success;
947 }
948 else if ( IsTOKEN("length") )
949 {
950 //汎用グローバル関数「データ長を得る」
951 _CHECKPARAM_RETURN( aValues , 1 );
952 //
953 _n = aValues[0].GetInteger();
954 return Result_Success;
955 }
956 else if ( IsTOKEN("compare") )
957 {
958 //汎用グローバル関数「比較」
959 _CHECKPARAM_RETURN( aValues , 2 );
960 //
961 _n = ( aValues[0] == aValues[1] );
962 return Result_Success;
963 }
964 else if ( IsTOKEN("mid") )
965 {
966 //汎用グローバル関数「データの一部を切りだし」ワイルドカードはなくなります。
967 if ( aValues.GetSize() == 2 )
968 {
969 if ( IsTestMode() ){ return Result_Success; }
970 CByteVector vb = aValues[0].GetData();
971 CTmlValue v;
972 v = vb.Mid(aValues[1].GetInteger());
973 _n = v;
974 return Result_Success;
975 }
976 else if ( aValues.GetSize() == 3 )
977 {
978 if ( IsTestMode() ){ return Result_Success; }
979 CByteVector vb = aValues[0].GetData();
980 CTmlValue v;
981 v = vb.Mid(aValues[1].GetInteger(), aValues[2].GetInteger());
982 _n = v;
983 return Result_Success;
984 }
985 return CTmlResult::CheckParamNum(aValues.GetSize(), 2);
986 }
987 else if ( IsTOKEN("todata") )
988 {
989 //汎用グローバル関数「データに変換(sprintf)」
990 size_t si = aValues.GetSize();
991 if ( si == 1 )
992 {
993 if ( IsTestMode() ){ return Result_Success; }
994 CTmlValue v;
995 v.SetString(CAscii::Fmt("%d", aValues[0].GetInteger()));
996 _n = v;
997 return Result_Success;
998 }
999 if ( si <= 6 ) //値5個まで対応
1000 {
1001 if ( IsTestMode() ){ return Result_Success; }
1002 //
1003 CAscii strRes;
1004 CAscii strForm = aValues[0].GetString();
1005 switch ( si )
1006 {
1007 case 2:
1008 strRes.Format(strForm, aValues[1].GetInteger());
1009 break;
1010 case 3:
1011 strRes.Format(strForm, aValues[1].GetInteger(), aValues[2].GetInteger());
1012 break;
1013 case 4:
1014 strRes.Format(strForm, aValues[1].GetInteger(), aValues[2].GetInteger(), aValues[3].GetInteger());
1015 break;
1016 case 5:
1017 strRes.Format(strForm, aValues[1].GetInteger(), aValues[2].GetInteger(), aValues[3].GetInteger(), aValues[4].GetInteger());
1018 break;
1019 case 6:
1020 strRes.Format(strForm, aValues[1].GetInteger(), aValues[2].GetInteger(), aValues[3].GetInteger(), aValues[4].GetInteger(), aValues[5].GetInteger());
1021 break;
1022 }
1023 CTmlValue v;
1024 v.SetString(strRes);
1025 _n = v;
1026 return Result_Success;
1027 }
1028 return CTmlResult::CheckParamNum(aValues.GetSize(), 7);
1029 }
1030 else if ( IsTOKEN("tovalue") )
1031 {
1032 //汎用グローバル関数「数値に変換(atoi)」
1033 _CHECKPARAM_RETURN( aValues , 1 );
1034 _n = STRLIB::ToInt(aValues[0].GetString());
1035 return Result_Success;
1036 }
1037 else if ( IsTOKEN("getat") )
1038 {
1039 //汎用グローバル関数「データの一箇所取り出し」
1040 _CHECKPARAM_RETURN( aValues , 2 );
1041 CByteVector vb = aValues[0].GetData();
1042 INDEX ind = aValues[1].GetInteger();
1043 if ( vb.IsInRange(ind) )
1044 {
1045 _n = static_cast<int>(vb[ind]);
1046 }
1047 else
1048 {
1049 _n = 0;
1050 }
1051 return Result_Success;
1052 }
1053#if 0
1054 else if ( IsTOKEN("getCurrentTimeString") )
1055 {
1056 //汎用グローバル関数「現在の時間(strftime)」
1057 TTRACE1("found System Func [%s]\n",lpszToken);
1058 if ( aValues.GetSize()==0 )
1059 {
1060 if ( IsTestMode() ){return Result_Success;}
1061 //
1062 CTime t = CTime::GetCurrentTime();
1063 CTmlValue v;
1064 v = t.Format( "%y%m%d%H%M%S" );
1065 tvxObject = v;
1066 return Result_Success;
1067 }
1068 else if ( aValues.GetSize()==1 )
1069 {
1070 if ( IsTestMode() ){return Result_Success;}
1071 //
1072 CTime t = CTime::GetCurrentTime();
1073 CTmlValue v;
1074 v = t.Format( aValues[0].GetString() );
1075 tvxObject = v;
1076 return Result_Success;
1077 }
1078 return CTmlResult::CheckParamNum(aValues.GetSize(), 1);
1079 }
1080#endif
1081 //
1082 _n = 0;
1083 return Result_Nop;
1084 }
1085
1086 #undef IsTOKEN
1087 #undef _CHECKPARAM_RETURN
1088
1097 CTmlResult m_OnChangeValue(LPCSTR lpszName, const CTmlValue& value)
1098 {
1099 if ( m_piExpander != NULL )
1100 {
1101 CTmlResult r = m_piExpander->OnChangeValue(lpszName, value);
1102 if ( ! r.IsNop() )
1103 {
1104 return r;
1105 }
1106 }
1107 //
1108 if ( STRLIB::Compare(lpszName, "%tickcount") == 0 )
1109 {
1110 m_dwTickCountBase = ::GetTickCount() - value.GetInteger();
1111 return Result_Success;
1112 }
1113 return Result_Success;
1114 }
1115
1126 CTmlResult m_TextToValue(CTmlValue& _answer, CTmlGrammar& _gram)
1127 {
1128 LPCSTR s = _gram.GetPointer();
1129 CTmlGrammar gg = _gram;
1130 CTmlValueCarrier leftSideValue;
1131 CTmlResult res;
1132 //頭記号チェック
1133 if ( s[0] == '-' || s[0] == '+' )
1134 {
1135 // いきなり - か + なら頭に0があるものとする
1136 leftSideValue = 0;
1137 if ( s[0] == s[1] )
1138 {
1139 // ++ ,--なら特殊状態にしておく
1140 leftSideValue.Set("%BEFORE OPE");
1141 }
1142 }
1143 else
1144 {
1145 res = m_FindValue(leftSideValue, _gram);
1146 if ( res.IsError() )
1147 {
1148 return res;
1149 }
1150 }
1151 //
1152 while ( true )
1153 {
1154 int iAriType = 0;
1155 res = m_CheckArithmeticType(iAriType, _gram);
1156 if ( ! res.IsSuccess() )
1157 {
1158 ASSERT( iAriType == 0 );
1159 LPCSTR P = _gram.GetPointer();
1160 if ( *P != 0 && *P != ')' )
1161 {
1162 CTmlGrammar backGram = _gram;
1163 CTmlValueCarrier dummy;
1164 res = m_FindValue(dummy, _gram);
1165 if ( res.GetResult() == Result_Success )
1166 {
1168 }
1169 _gram = backGram;
1170 }
1171 break;
1172 }
1173 int iLevel = m_GetArithmeticTypeLevel(iAriType);
1174 CTmlValueCarrier rightSideValue;
1175 res = m_FindValue(rightSideValue, _gram);
1176 if ( res.IsError() )
1177 {
1178 return res;
1179 }
1180 //
1181 while ( true )
1182 {
1183 int a = 0;
1184 CTmlGrammar backGram = _gram;
1185 res = m_CheckArithmeticType(a, _gram);
1186 if ( ! res.IsSuccess() )
1187 {
1188 ASSERT( a == 0 );
1189 break;
1190 }
1191 int l = m_GetArithmeticTypeLevel(a);
1192 if ( l == 1 )
1193 {
1194 // 代入関係は右優先
1195 if ( iLevel > l )
1196 {
1197 _gram = backGram;
1198 break;
1199 }
1200 }
1201 else
1202 {
1203 // 左優先
1204 if ( iLevel >= l )
1205 {
1206 _gram = backGram;
1207 break;
1208 }
1209 }
1210 //
1211 CTmlValueCarrier temp;
1212 res = m_FindValue(temp, _gram);
1213 if ( res.IsError() )
1214 {
1215 return res;
1216 }
1217 res = m_CalcValueAndValue(a, rightSideValue, temp);
1218 if ( res.IsError() )
1219 {
1220 return res.SetLine(_gram);
1221 }
1222 }
1223 res = m_CalcValueAndValue(iAriType, leftSideValue, rightSideValue);
1224 if ( res.IsError() )
1225 {
1226 return res.SetLine(_gram);
1227 }
1228 }
1229 _answer = leftSideValue();
1230 return Result_Success;
1231 }
1232
1233 friend class CTmlCalculatorTest;
1234};
1235
1236
1237
1238}; // TNB
1239
文字列処理関係のヘッダ
TinyMacroLang 結果関係のヘッダ
TinyMacroLang 計算関係のヘッダ
TinyMacroLang 値関係のヘッダ
[ETC] コピー不可能スーパークラス.
Definition: TnbDef.h:599
文法解析用パーツ管理クラス
bool IsEqualString(LPCSTR lpsz) const
[比較] 内容比較
TYP GetAt(INDEX index=0) const
[取得] 内容.
EPartsKind GetKind(void) const
[取得] 種類
const TYP * GetString(void) const
[取得] 内容
文法解析テンプレート
ITE GetPointer(void)
[取得] 現在のイテレータ
INT_PTR StepPointer(INT_PTR step)
[処理] ステップ.
CParts GetNextParts(bool boIsToken=true)
[取得] 次のパーツ取得
CParts PeekNextParts(bool boIsToken=true)
[確認] 次のパーツ確認
int Compare(const TYP *lpszSubject) const
[確認] 文字列比較
Definition: TnbStr.h:658
bool IsEmpty(void) const
[確認] 空チェック
Definition: TnbStr.h:528
static CStrT Fmt(const char *lpszFormat,...)
[作成] 書式付き文字列作成
Definition: TnbStr.h:1206
void Format(const TYP *lpszFormat,...)
[代入] 書式付き文字列代入.
Definition: TnbStr.h:359
TinyMacroLang 計算
CTmlResult TextToValue(CTmlValue &_answer, CTmlGrammar &_gram)
[処理] 計算.
CVectorT< CByteVector > & ReferElementWildResult(void)
[参照] ワイルドカードリザルト.
bool IsTestMode(void) const
[取得] テストモード状態取得
void SetExpander(ITmlExpander *piExpander=NULL)
[設定] 拡張処理指定
CTmlResult TextToValue(CTmlValue &_answer, LPCSTR lpsz)
[処理] 計算.
CTmlCalculator(void)
コンストラクタ
void SetTestMode(bool boIsTestMode)
[設定] テストモード設定.
TinyMacroLang 結果状態管理
Definition: TnbTmlResult.h:133
bool IsNop(void) const
[確認] NOP 確認.
Definition: TnbTmlResult.h:264
void SetErrorString(LPCSTR lpszString)
[設定] エラー内容設定
Definition: TnbTmlResult.h:300
static CTmlResult CheckParamNum(INT_PTR iParamNum, INT_PTR iExpectNum)
[確認] パラメータの数と、期待の数のチェック.
Definition: TnbTmlResult.h:453
EResult GetResult(void) const
[取得] リザルトコード取得.
Definition: TnbTmlResult.h:334
bool IsError(void) const
[確認] ERROR 確認.
Definition: TnbTmlResult.h:254
bool IsSuccess(void) const
[確認] SUCCESS 確認.
Definition: TnbTmlResult.h:244
CTmlResult & SetLine(LPCSTR lpszFileName, INT_PTR iFileLine)
[設定] エラーソースファイル名、行数設定
Definition: TnbTmlResult.h:311
TinyMacroLang 文字列解析
CTmlResult SetData(LPCSTR lpszData)
[代入] 文字列を代入.
CTmlResult SetHexToData(LPCSTR lpszData)
[代入] HEX表記文字列を代入.
CTmlValue ToValue(void) const
[取得] CTmlValue 型で取得.
TinyMacroLang 値参照管理
Definition: TnbTmlValue.h:654
void Set(LPCSTR lpsz)
[代入] 拡張ネーム指定.
Definition: TnbTmlValue.h:740
LPCSTR GetExName(void) const
[取得] 拡張ネーム取得
Definition: TnbTmlValue.h:760
TinyMacroLang 値管理
Definition: TnbTmlValue.h:43
CTmlValue & SetString(LPCSTR lpszData)
[代入] データ代入.
Definition: TnbTmlValue.h:103
CTmlValue & SetData(size_t len, LPCVOID P)
[代入] データ代入.
Definition: TnbTmlValue.h:128
int GetInteger(void) const
[取得] 数字取得.
Definition: TnbTmlValue.h:418
TinyMacroLang コード管理
Definition: TnbTmlResult.h:48
@ Operation_CheckFunc
関数チェック中
Definition: TnbTmlResult.h:79
@ Operation_Calc
計算処理中
Definition: TnbTmlResult.h:78
@ Result_Nop
処理なし
Definition: TnbTmlResult.h:89
@ Result_UnknownError
その他のエラー
Definition: TnbTmlResult.h:90
@ Result_Success
成功
Definition: TnbTmlResult.h:88
@ Result_UnfinishedExpression
計算式が途中で終わっている
Definition: TnbTmlResult.h:96
@ Result_ZeroDivide
0で割ろうとしてます
Definition: TnbTmlResult.h:97
@ Result_NotCloseParentheses
括弧が閉じていない
Definition: TnbTmlResult.h:94
@ Result_UnknownKeyword
知らないキーワード
Definition: TnbTmlResult.h:98
virtual size_t GetSize(void) const
[取得] サイズ取得
Definition: TnbVector.h:368
CVectorT< TYP > Mid(INDEX startIndex, size_t size=0) const
[作成] 切り出し
Definition: TnbVector.h:705
virtual INDEX Add(const TYP &t)
[追加] 要素一つ追加.
Definition: TnbVector.h:383
int Compare(LPCSTR P1, LPCSTR P2, INT_PTR len=-1, DWORD dwCmpFlags=0)
[比較] 文字列比較(ASCII/SJIS用)
Definition: TnbStrLib.h:135
TNB::CStrT< TCHAR > CStr
文字列クラス
Definition: TnbStr.h:1785
CAscii LocalMapString(LPCSTR lpsz, DWORD dwFlags)
[変換] 文字変換(ASCII/SJIS用)
Definition: TnbStrEx.h:161
int ToInt(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
Definition: TnbStrLib.h:367
void IgnoreUnusedValue(const T &value)
[宣言] 参照しない値宣言.
Definition: TnbDef.h:434
TNB Library
Definition: TnbDoxyTitle.txt:2
bool IsInRange(INDEX index) const
[確認] INDEXの有効確認.
TinyMacroLang 関数拡張インターフェース
virtual CTmlResult OnChangeValue(LPCSTR lpszName, const CTmlValue &val)=0
[処理] 変更(代入)コールバック
virtual CTmlResult ExpandVariable(CTmlValueCarrier &_val, LPCSTR lpszToken, const CTmlValuesVector &aValues, bool boIsTestMode)=0
[処理] 拡張変数、関数の処理
virtual ~ITmlExpander(void)
デストラクタ