source: trunk/CrypPlugins/RPNExpression/RPNExpr.cs @ 2424

Last change on this file since 2424 was 841, checked in by Sören Rinne, 12 years ago
  • some changes in BM, BFP, LFSR, NLFSR
  • BFP now accepts x*.* instead of i_*.*
  • added 2 function parsers
File size: 30.5 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Reflection;
4using System.Globalization;
5
6namespace Cryptool.RPNExpression
7{
8    public enum RPNTokenType
9    {
10        Unknown,
11        Eof,
12        StartParentheses,
13        EndParentheses,
14        Ident,
15        String,
16        Number,
17        DateTime,
18        Boolean,
19        EndParam,
20        SquareBracket,
21
22        //operators
23        Mulitiply,
24        Divide,
25        Div,
26        Mod,
27        Plus,
28        Minus,
29        Less,
30        Greater,
31        LessOrEqual,
32        GreateOrEqual,
33        NotEqual,
34        Equal,
35        Or,
36        And,
37        Not,
38        JustPlus,
39        JustMinus
40    }
41
42    public enum RPNObjectType
43    {
44        Operand,
45        Operator, 
46        Function, 
47        DataField, 
48        Variable
49    }
50
51    public class ExprEnvironment
52    {
53        private SortedList<string, Type> functionList = new SortedList<string, Type>();
54
55        public SortedList<string, Type> FunctionList
56        {
57            get { return functionList; }
58        }
59
60        public void RegisterFunction(Type funcType)
61        {
62            FunctionAttribute funcAttrib = (FunctionAttribute)Attribute.GetCustomAttribute(funcType, typeof(FunctionAttribute));
63            functionList.Add(funcAttrib.FunctionName.ToUpper(), funcType);
64        }
65
66        public virtual void CalcDataField(string fieldName, ref object value)
67        {
68            throw new Exception("Can't find DataField " + fieldName + ".");
69        }
70
71        public RPNFunction FindFunction(RPNExpr expr, string func)
72        {
73            int index = functionList.IndexOfKey(func);
74
75            if (index > -1)
76            {
77                Assembly assembly = Assembly.GetAssembly(functionList.Values[index]);
78                RPNFunction rpnFunc = assembly.CreateInstance(functionList.Values[index].FullName) as RPNFunction;
79                rpnFunc.Owner = expr;
80                rpnFunc.ObjectType = RPNObjectType.Function;
81
82                return rpnFunc;
83            }
84            else
85            {
86                return null;
87            }
88        }
89    }
90
91    public abstract class RPNObject
92    {
93        public RPNExpr Owner;
94        public RPNObjectType ObjectType; 
95
96        public abstract object GetValue();
97
98        public RPNObject()
99        {
100        }
101
102        public RPNObject(RPNExpr owner, RPNObjectType objectType)
103        {
104            Owner = owner;
105            ObjectType = objectType;
106        }
107
108        public virtual bool IsAggregate()
109        {
110            return false;
111        }
112
113        protected bool IsNumeric(object value)
114        {
115            NumberFormatInfo provider = new NumberFormatInfo();
116            provider.NumberDecimalSeparator = ".";
117            string str = Convert.ToString(value, provider);
118            Double result;
119            return Double.TryParse(str, NumberStyles.Integer | NumberStyles.AllowThousands,
120                CultureInfo.CurrentCulture, out result);
121        }
122    }
123
124    public class RPNOperator: RPNObject
125    {
126        public RPNTokenType OperatorType;
127        public string OperatorStr; 
128
129        public RPNOperator(RPNExpr owner, RPNObjectType objectType) : base(owner, objectType)
130        {
131        }
132
133        public override string ToString()
134        {
135            return OperatorStr;
136        }
137
138        public override object GetValue()
139        {
140            Owner.Position--;
141
142            object value1 = Owner.RPNList[Owner.Position].GetValue();
143
144            switch (OperatorType)
145            {
146                case RPNTokenType.Not:
147                    if (!(value1 is bool))
148                        throw new Exception("Can't calculate " + RPNTokenType.Not.ToString() + " " + Convert.ToString(value1) + ".");
149                    return !Convert.ToBoolean(value1);
150                case RPNTokenType.JustPlus:
151                    return value1;
152                case RPNTokenType.JustMinus:
153                    if (!IsNumeric(value1))
154                        throw new Exception("Can't calculate " + RPNTokenType.JustMinus.ToString() + " " + Convert.ToString(value1) + ".");
155                    return -Convert.ToDouble(value1);
156                default:
157                    object value2 = null;
158                    if (Owner.Position >= 0)
159                        value2 = Owner.RPNList[Owner.Position].GetValue();
160                    switch (OperatorType)
161                    {
162                        case RPNTokenType.Plus:
163                            /*if (value1 is string)
164                            {
165                                return Convert.ToString(value2) + Convert.ToString(value1);
166                            }
167                            else if (IsNumeric(value1))
168                            {*/
169                                return Convert.ToInt32(value2) ^ Convert.ToInt32(value1);
170                            /*}
171                            else
172                                throw new Exception("Can't calculate " + RPNTokenType.Plus.ToString() + " " + Convert.ToString(value1) + ".");
173                             */
174                        /*case RPNTokenType.Minus:
175                            if (IsNumeric(value1))
176                            {
177                                return Convert.ToDouble(value2) - Convert.ToDouble(value1);
178                            }
179                            else
180                                throw new Exception("Can't calculate " + RPNTokenType.Minus.ToString() + " " + Convert.ToString(value1) + ".");
181                         */
182                        case RPNTokenType.Mulitiply:
183                            return Convert.ToInt32(value2) & Convert.ToInt32(value1);
184                        /*case RPNTokenType.Divide:
185                            return Convert.ToDouble(value2) / Convert.ToDouble(value1);
186                        case RPNTokenType.Less:
187                            return Convert.ToDouble(value2) < Convert.ToDouble(value1);
188                        case RPNTokenType.Greater:
189                            return Convert.ToDouble(value2) > Convert.ToDouble(value1);
190                        case RPNTokenType.LessOrEqual:
191                            return Convert.ToDouble(value2) <= Convert.ToDouble(value1);
192                        case RPNTokenType.GreateOrEqual:
193                            return Convert.ToDouble(value1) <= Convert.ToDouble(value2);
194                        case RPNTokenType.NotEqual:
195                            return Convert.ToDouble(value2) != Convert.ToDouble(value1);
196                        case RPNTokenType.Equal:
197                            return Convert.ToDouble(value2) == Convert.ToDouble(value1);
198                        case RPNTokenType.Or:
199                            return Convert.ToBoolean(value2) || Convert.ToBoolean(value1);
200                        case RPNTokenType.And:
201                            return Convert.ToBoolean(value2) && Convert.ToBoolean(value1);
202                         */
203                        default:
204                            throw new Exception("Can't calculate " + RPNTokenType.Not.ToString() + " " + Convert.ToString(value1) + ".");
205                    }
206            }
207        }
208    }
209
210    public class RPNOperand: RPNObject
211    {
212        public object Value;
213
214        public RPNOperand(RPNExpr owner, RPNObjectType objectType) : base(owner, objectType)
215        {
216        }
217
218        public override string ToString()
219        {
220            return Convert.ToString(Value);
221        }
222
223        public override object GetValue()
224        {
225            Owner.Position--;
226            return Value;
227        }
228    }
229
230    public class RPNDataField : RPNObject
231    {
232        public string Field;
233
234        public RPNDataField(RPNExpr owner, RPNObjectType objectType) : base(owner, objectType)
235        {
236        }
237
238        public override string ToString()
239        {
240            return Field;
241        }
242
243        public override object GetValue()
244        {
245            Owner.Position--;
246            object result = null;
247            Owner.Environment.CalcDataField(Field, ref result);
248            return result;
249        }
250    }
251
252    public class RPNVariable : RPNObject
253    {
254        public string Name;
255
256        public RPNVariable(RPNExpr owner, RPNObjectType objectType) : base(owner, objectType)
257        {
258        }
259
260        public override string ToString()
261        {
262            return Name;
263        }
264
265        public override object GetValue()
266        {
267            Owner.Position--;
268            return Owner.VariableByName(Name).value;
269        }
270    }
271
272    public class FunctionAttribute : Attribute
273    {
274        private string functionName;
275        private string paramTypes;
276        private string group;
277        private string paramNames;
278        private string description;
279
280        public string FunctionName
281        {
282            get { return functionName; }
283            set { functionName = value; }
284        }
285       
286        public string ParamTypes
287        {
288            get { return paramTypes; }
289            set { paramTypes = value; }
290        }
291       
292        public string Group
293        {
294            get { return group; }
295            set { group = value; }
296        }
297       
298        public string ParamNames
299        {
300            get { return paramNames; }
301            set { paramNames = value; }
302        }
303       
304        public string Description
305        {
306            get { return description; }
307            set { description = value; }
308        }
309
310        public FunctionAttribute(string functionName)
311        {
312            this.functionName = functionName;
313        }
314    }
315
316    public abstract class RPNFunction : RPNObject
317    {
318        protected List<object> Params = new List<object>();
319
320        public override string ToString()
321        {
322            FunctionAttribute funcAttrib = (FunctionAttribute)Attribute.GetCustomAttribute(this.GetType(), typeof(FunctionAttribute));
323            return funcAttrib.FunctionName;
324        }
325
326        public override object GetValue()
327        {
328            Owner.Position--;
329            FunctionAttribute funcAttrib = (FunctionAttribute)Attribute.GetCustomAttribute(this.GetType(), typeof(FunctionAttribute));
330
331            if (funcAttrib.ParamTypes != null)
332            {
333                for (int i = 0; i < funcAttrib.ParamTypes.Length; i++)
334                {
335                    Params.Insert(0, Owner.RPNList[Owner.Position].GetValue());
336                }
337            }
338            CheckParams();
339
340            return Calc();
341        }
342
343        private void DoRaise(string type, string value, int parameterIndex)
344        {
345            throw new Exception("Parameter " + Convert.ToString(parameterIndex + 1) +
346                                " should be of type " + type +
347                                ". Value of parameter is " + value + ".");
348        }
349
350        public abstract object Calc();
351
352        public virtual void Aggregate()
353        {
354        }
355
356        public virtual void Reset()
357        {
358        }
359
360        public virtual void CheckParams()
361        {
362            FunctionAttribute funcAttrib = (FunctionAttribute)Attribute.GetCustomAttribute(this.GetType(), typeof(FunctionAttribute));
363
364            if (funcAttrib.ParamTypes != null)
365            {
366                for (int i = 0; i < funcAttrib.ParamTypes.Length - 1; i++)
367                {
368                    switch (funcAttrib.ParamTypes[i])
369                    {
370                        case 'B':
371                            if (!(Params[i] is bool))
372                                DoRaise("Boolean", Convert.ToString(Params[i]), i);
373                            break;
374                        case 'D':
375                            if (!(Params[i] is DateTime))
376                                DoRaise("DateTime", Convert.ToString(Params[i]), i);
377                            break;
378                        case 'N':
379                            if (!(IsNumeric(Params[i])))
380                                DoRaise("Number", Convert.ToString(Params[i]), i);
381                            break;
382                        case 'S':
383                            if (!(Params[i] is string))
384                                DoRaise("String", Convert.ToString(Params[i]), i);
385                            break;
386                    }
387                }
388            }
389        }
390    }
391
392    public class RPNAggregateFunction : RPNFunction
393    {
394        public double Value;
395        public int Count;
396
397        public override object Calc()
398        {
399            return Value;
400        }
401
402        public override bool IsAggregate()
403        {
404            return true;
405        }
406
407        public override void Aggregate()
408        {
409            Owner.Position--;
410            Count++;
411        }
412
413        public override void Reset()
414        {
415            Value = 0;
416            Count = 0;
417        }
418    }
419
420    public class Variable
421    {
422        public string name; //private !!!
423        public object value; //private !!!
424
425        public Variable(string name, object value)
426        {
427            this.name = name;
428            this.value = value;
429        }
430    }
431
432    public class RPNParser
433    {
434        public RPNExpr Owner;
435
436        private char[] operators = { '+', '-', '*', '/', '<', '>', '=', '%' };
437        private string[] doubleOperators = { "<>", ">=", "<=", "%=", "/=" };
438
439        private string expr;
440        private int curPos;
441        private RPNTokenType tokenType;
442        private string token;
443       
444        private void SkipBlanks()
445        {
446            //while not at the end of the string and char at position is 32 or lower
447            while ((curPos < expr.Length) && (expr[curPos] <= 32))
448                 curPos++;
449        }
450
451        private void SetString(int from, int len)
452        {
453            token = expr.Substring(from, len);
454        }
455
456        private bool IsOperator(char c)
457        {
458            for (int i = 0; i < operators.Length; i++)
459                if (c == operators[i])
460                    return true;
461
462            return false;
463        }
464
465        private bool IsDoubleOperator(string s)
466        {
467            for (int i = 0; i < doubleOperators.Length; i++)
468                if (s == doubleOperators[i])
469                    return true;
470
471            return false;
472        }
473
474        public RPNParser(string expr)
475            {
476            this.expr = expr;
477            }
478
479        private void CheckToken(string s)
480        {
481            if (Token != s)
482                throw new Exception("Token >" + s + "< expected but >" + Token + "< found in expression >" + expr); // + "< at position " + Convert.ToString((int)oCurPos - (int)OrgText) + ".");
483        }
484
485        private void NotTerminated(string s)
486        {
487            throw new Exception(s + " not terminated in expression >" + expr + "<.");
488        }
489
490        public void NextToken()
491        {
492            int pos;
493
494            SkipBlanks();
495
496            if (curPos == expr.Length)
497            {
498                tokenType = RPNTokenType.Eof;
499                token = "";
500            }       
501            else if (char.IsLetter(expr[curPos])) //Function or boolean operator
502            {
503                pos = curPos;
504                curPos++;
505                while ((curPos < expr.Length) && char.IsLetterOrDigit(expr[curPos]))
506                    curPos++;
507               
508                tokenType = RPNTokenType.Ident;
509                SetString(pos, curPos - pos);
510
511                //check for AND, OR, NOT, TRUE, FALSE
512                switch (token.ToUpper())
513                {
514                    case "AND":
515                        tokenType = RPNTokenType.And;
516                        break;
517                    case "OR":
518                        tokenType = RPNTokenType.Or;
519                        break;
520                    case "NOT":
521                        tokenType = RPNTokenType.Not;
522                        break;
523                    case "TRUE":
524                        tokenType = RPNTokenType.Boolean;
525                        break;
526                    case "FALSE":
527                        tokenType = RPNTokenType.Boolean;
528                        break;
529                }   
530            }
531            else if (expr[curPos] == '\'') //String
532            {
533                bool terminated = false;
534                curPos++;
535                pos = curPos;
536
537                while (curPos < expr.Length)
538                {
539                    if (expr[curPos] == '\'')
540                    {
541                        terminated = true;
542                        tokenType = RPNTokenType.String;
543                        SetString(pos, curPos - pos);
544                        curPos++;
545                        break;
546                    }
547                    curPos++;
548                }
549
550                if (!terminated)
551                {
552                    NotTerminated("String");
553                }
554            }       
555            else if (IsOperator(expr[curPos])) //operator
556            {
557                char aOperator = expr[curPos];
558                pos = curPos;
559                curPos++;
560                while (curPos < expr.Length && IsDoubleOperator(aOperator + Convert.ToString(expr[curPos])))
561                    curPos++;
562                SetString(pos, curPos - pos);
563                switch (token)
564                {
565                    case "*":
566                        tokenType = RPNTokenType.Mulitiply;
567                        break;
568                    case "/":
569                        tokenType = RPNTokenType.Divide;
570                        break;
571                    case "/=":
572                        tokenType = RPNTokenType.Div;
573                        break;
574                    case "%=":
575                        tokenType = RPNTokenType.Mod;
576                        break;
577                    case "+":
578                        tokenType = RPNTokenType.Plus;
579                        break;
580                    case "-":
581                        tokenType = RPNTokenType.Minus;
582                        break;
583                    case "<":
584                        tokenType = RPNTokenType.Less;
585                        break;
586                    case ">":
587                        tokenType = RPNTokenType.Greater;
588                        break;
589                    case "<=":
590                        tokenType = RPNTokenType.LessOrEqual;
591                        break;
592                    case ">=":
593                        tokenType = RPNTokenType.GreateOrEqual;
594                        break;
595                    case "<>":
596                        tokenType = RPNTokenType.NotEqual;
597                        break;
598                    case "=":
599                        tokenType = RPNTokenType.Equal;
600                        break;
601                }
602            }
603            else if (char.IsDigit(expr[curPos])) //number
604            {
605                pos = curPos;
606                curPos++;
607                while (curPos < expr.Length && (char.IsDigit(expr[curPos]) || expr[curPos] == Convert.ToChar(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator)))
608                    curPos++;
609                tokenType = RPNTokenType.Number;
610                SetString(pos, curPos - pos);
611            }
612            else if (expr[curPos] == '"') //date
613            {
614                curPos++;
615                pos = curPos;
616                while (true)
617                {
618                    if ((curPos == expr.Length - 1) && (expr[curPos] != '"'))
619                        NotTerminated("Date");
620                    else if (expr[curPos] == '"')
621                    {
622                        tokenType = RPNTokenType.DateTime;
623                        SetString(pos, curPos - pos);
624                        curPos++;
625                        break;
626                    }
627                    curPos++;
628                }
629            }
630            else if (expr[curPos] == '(') //parentheses
631            {
632                curPos++;
633                tokenType = RPNTokenType.StartParentheses;
634                token = "(";
635            }
636            else if (expr[curPos] == ')')
637            {
638                curPos++;
639                tokenType = RPNTokenType.EndParentheses;
640                token = ")";
641            }
642            else if (expr[curPos] == '[') //square bracket
643            {
644                curPos++;
645                pos = curPos;
646                while (true)
647                {
648                    if ((curPos == expr.Length - 1) && (expr[curPos] != ']'))
649                        NotTerminated("Square Bracket");
650                    else if (expr[curPos] == ']')
651                    {
652                        tokenType = RPNTokenType.SquareBracket;
653                        SetString(pos, curPos - pos);
654                        curPos++;
655                        break;
656                    }
657                    curPos++;
658                }
659            }
660            else if (expr[curPos] == ';')
661            {
662                curPos++;
663                tokenType = RPNTokenType.EndParam;
664                token = ";";
665            }       
666            else //error
667            {
668                tokenType = RPNTokenType.Unknown;
669                token = "";
670            }
671        }
672
673        public string Token
674        {
675            get { return token; }
676        }
677
678        public RPNTokenType TokenType
679        {
680            get { return tokenType; }
681        }
682
683        private void UnexpectedToken()
684        {
685            throw new Exception("Unexpected token >" + Token + "< in expression >" + expr + "< at position " + curPos.ToString() + ".");
686        }
687
688        private void Factor()
689        {
690            RPNOperand operand;
691            RPNOperator aOperator;
692            switch (TokenType)
693            {
694                case RPNTokenType.Plus:
695                case RPNTokenType.Minus:
696                    aOperator = new RPNOperator(Owner, RPNObjectType.Operator);
697                    switch (TokenType)
698                    {
699                        case RPNTokenType.Plus:
700                            (aOperator as RPNOperator).OperatorType = RPNTokenType.JustPlus;
701                            break;
702                        case RPNTokenType.Minus:
703                            (aOperator as RPNOperator).OperatorType = RPNTokenType.JustMinus;
704                            break;
705                    }
706                    aOperator.OperatorStr = Token;
707                    NextToken();
708                    Term();
709                    Owner.RPNList.Add(aOperator);
710                    break;
711                case RPNTokenType.StartParentheses:
712                    NextToken();
713                    Evaluate();
714
715                    CheckToken(")");
716
717                    NextToken();
718                    break;
719                case RPNTokenType.SquareBracket:
720                    RPNDataField dataField = new RPNDataField(Owner, RPNObjectType.DataField);
721                    dataField.Field = Token;
722                    Owner.RPNList.Add(dataField);
723                    NextToken();
724                    break;
725                case RPNTokenType.Ident:
726                    RPNFunction func;
727                    if (Owner.Environment != null)
728                      func = Owner.Environment.FindFunction(Owner, Token.ToUpper());
729                    else
730                      func = null;
731                    if (func != null)
732                    {
733                        FunctionAttribute funcAttrib = (FunctionAttribute)Attribute.GetCustomAttribute(func.GetType(), typeof(FunctionAttribute));
734                        if (funcAttrib.ParamTypes != null && funcAttrib.ParamTypes.Length > 0)
735                        {
736                            NextToken();
737                            for (int i = 0; i < funcAttrib.ParamTypes.Length; i++)
738                            {
739                                if (i == 0)
740                                    CheckToken("(");
741                                else
742                                    CheckToken(";");
743                                NextToken();
744                                Evaluate();
745                            }
746                            CheckToken(")");
747                        }
748                        Owner.RPNList.Add(func);
749                    }
750                    else
751                    {
752                        RPNVariable var = Owner.FindVariable(Token.ToUpper());
753                        if (var != null)
754                            Owner.RPNList.Add(var);
755                        else
756                            throw new Exception("Unknown ident >" + Token + "< in expression >" + Owner.expression + "<.");
757                    }
758                    NextToken();
759                    break;
760                case RPNTokenType.Number:
761                    operand = new RPNOperand(Owner, RPNObjectType.Operand);
762                    float number = float.Parse(Token);
763                    operand.Value = (object)number;
764                    Owner.RPNList.Add(operand);
765                    NextToken();
766                    break;
767                case RPNTokenType.String:
768                    operand = new RPNOperand(Owner, RPNObjectType.Operand);
769                    operand.Value = Token;
770                    Owner.RPNList.Add(operand);
771                    NextToken();
772                    break;
773                case RPNTokenType.DateTime:
774                    operand = new RPNOperand(Owner, RPNObjectType.Operand);
775                    try
776                    {
777                        operand.Value = Convert.ToDateTime(Token);
778                    }
779                    catch
780                    {
781                        throw new Exception(Token + " is not a valid date.");
782                    }
783                    Owner.RPNList.Add(operand);
784                    NextToken();
785                    break;
786                case RPNTokenType.Boolean:
787                    operand = new RPNOperand(Owner, RPNObjectType.Operand);
788                    operand.Value = Convert.ToBoolean(Token);
789                    Owner.RPNList.Add(operand);
790                    NextToken();
791                    break;
792                case RPNTokenType.Not:
793                    aOperator = new RPNOperator(Owner, RPNObjectType.Operator);
794                    aOperator.OperatorType = TokenType;
795                    aOperator.OperatorStr = Token;
796                    NextToken();
797                    Factor();
798                    Owner.RPNList.Add(aOperator);
799                    break;
800                default:
801                    UnexpectedToken();
802                    break;
803
804            }
805        }
806
807        private void Term()
808        {
809            Factor();
810
811            switch (TokenType)
812            {
813                case RPNTokenType.Mulitiply:
814                case RPNTokenType.Divide:
815                case RPNTokenType.Div:
816                case RPNTokenType.Mod:
817                case RPNTokenType.And:
818                    RPNOperator aOperator = new RPNOperator(Owner, RPNObjectType.Operator);
819                    aOperator.OperatorType = TokenType;
820                    aOperator.OperatorStr = Token;
821
822                    NextToken();
823                    Term();
824
825                    Owner.RPNList.Add(aOperator);
826                    break;
827            }
828        }
829
830        private void Expression()
831        {
832            Term();
833
834            switch (TokenType)
835            {
836                case RPNTokenType.Plus:
837                case RPNTokenType.Minus:
838                case RPNTokenType.Or:
839                    RPNOperator aOperator = new RPNOperator(Owner, RPNObjectType.Operator);
840                    aOperator.OperatorType = TokenType;
841                    aOperator.OperatorStr = Token;
842
843                    NextToken();
844                    Expression();
845
846                    Owner.RPNList.Add(aOperator);
847                    break;
848            }
849        }
850
851        public void Evaluate()
852        {
853            Expression();
854
855            switch (TokenType)
856            {
857                case RPNTokenType.Less:
858                case RPNTokenType.Greater:
859                case RPNTokenType.LessOrEqual:
860                case RPNTokenType.GreateOrEqual:
861                case RPNTokenType.NotEqual:
862                case RPNTokenType.Equal:
863                    RPNOperator aOperator = new RPNOperator(Owner, RPNObjectType.Operator);
864                    aOperator.OperatorType = TokenType;
865                    aOperator.OperatorStr = Token;
866
867                    NextToken();
868                    Evaluate();
869
870                    Owner.RPNList.Add(aOperator);
871                    break;
872
873                case RPNTokenType.EndParentheses:
874                    break;
875                case RPNTokenType.EndParam:
876                    return;
877                case RPNTokenType.Eof:
878                    return;
879            }
880        }
881    }
882
883    public class RPNExpr
884    {
885        public string expression;
886
887        public ExprEnvironment Environment;
888        public SortedList<string, Variable> Variables = new SortedList<string, Variable>();
889        public int Position;
890        public List<RPNObject> RPNList = new List<RPNObject>();
891
892        public RPNExpr()
893        {
894        }
895
896        public RPNExpr(string expression)
897            {
898            this.expression = expression;
899            }
900
901        public void Prepare()
902        {
903            RPNList.Clear();
904
905            RPNParser parser = new RPNParser(expression);
906            parser.Owner = this;
907            parser.NextToken();
908            parser.Evaluate();
909        }
910
911        public object GetValue()
912        {
913            Position = RPNList.Count - 1;
914            return RPNList[Position].GetValue();
915        }
916
917        public void AddVariable(Variable variable)
918        {
919            Variables.Add(variable.name.ToUpper(), variable);
920        }
921
922        public Variable VariableByName(string name)
923        {
924            int index = Variables.IndexOfKey(name);
925
926            if (index > -1)
927                return Variables.Values[index];
928            else
929                return null;
930        }
931
932        public RPNVariable FindVariable(string pToken)
933        {
934            Variable var = VariableByName(pToken);
935
936            if (var != null)
937            {
938                RPNVariable result = new RPNVariable(this, RPNObjectType.Variable);
939                result.Name = pToken;
940                return result;
941            }
942            return null;
943        }
944    }
945}
Note: See TracBrowser for help on using the repository browser.