Esempio n. 1
0
 private void AddToken(Token tok)
 {
     _tokenStack.Peek().AppendChild(tok);
 }
Esempio n. 2
0
        private Token CreateTokenTree(string cmd)
        {
            _tokenStack = new Stack<Token>();
            _tokenStack.Push(new Token(TokenType.Group, ""));

            _pos = 0;
            _cmd = cmd;
            _cmdLength = cmd.Length;

            char ch, nextCh1, nextCh2, lastCh = k_nullChar;

            while (_pos < _cmdLength)
            {
                ch = cmd[_pos];
                nextCh1 = (_pos + 1 < _cmdLength ? cmd[_pos + 1] : k_nullChar);
                nextCh2 = (_pos + 2 < _cmdLength ? cmd[_pos + 2] : k_nullChar);

                // Ignore whitespace
                if (Char.IsWhiteSpace(ch))
                {
                    _pos++;
                    continue;
                }

                // In this if/else block, ensure that g_pos is always advanced under all conditions,
                // unless an error is thrown.
                if (Char.IsLetter(ch))
                {
                    GrabAlnumToken();
                }
                else if (Char.IsDigit(ch) || ch == '.')
                {
                    GrabNumberToken();
                }
                else if (ch == '+')
                {
                    if (nextCh1 == '=')
                    {
                        AddToken(new Token(OperatorType.AddAssign, "+="));
                        _pos += 2;
                    }
                    else
                    {
                        AddToken(new Token(OperatorType.Add, "+"));
                        _pos++;
                    }
                }
                else if (ch == '-')
                {
                    if (Char.IsDigit(nextCh1) && (lastCh == k_nullChar || IsOperatorChar(lastCh)))
                    {
                        GrabNumberToken();
                    }
                    else if (nextCh1 == '=')
                    {
                        AddToken(new Token(OperatorType.SubAssign, "-="));
                        _pos += 2;
                    }
                    else
                    {
                        AddToken(new Token(OperatorType.Sub, "-"));
                        _pos++;
                    }
                }
                else if (ch == '*')
                {
                    if (nextCh1 == '=')
                    {
                        AddToken(new Token(OperatorType.MulAssign, "*="));
                        _pos += 2;
                    }
                    else
                    {
                        AddToken(new Token(OperatorType.Mul, "*"));
                        _pos++;
                    }
                }
                else if (ch == '/')
                {
                    if (nextCh1 == '=')
                    {
                        AddToken(new Token(OperatorType.DivAssign, "/="));
                        _pos += 2;
                    }
                    else
                    {
                        if (Settings.UseDivForFractions) AddToken(new Token(OperatorType.Fraction, "/"));
                        else AddToken(new Token(OperatorType.Div, "/"));
                        _pos++;
                    }
                }
                else if (ch == '%')
                {
                    if (nextCh1 == '=')
                    {
                        AddToken(new Token(OperatorType.ModAssign, "%="));
                        _pos += 2;
                    }
                    else
                    {
                        AddToken(new Token(OperatorType.Mod, "%"));
                        _pos++;
                    }
                }
                else if (ch == '<')
                {
                    if (nextCh1 == '<')
                    {
                        if (nextCh2 == '=')
                        {
                            AddToken(new Token(OperatorType.ShiftLeftAssign, "<<="));
                            _pos += 3;
                        }
                        else
                        {
                            AddToken(new Token(OperatorType.ShiftLeft, "<<"));
                            _pos += 2;
                        }
                    }
                    else if (nextCh1 == '=')
                    {
                        AddToken(new Token(OperatorType.LessOrEqual, "<="));
                        _pos += 2;
                    }
                    else
                    {
                        AddToken(new Token(OperatorType.LessThan, "<"));
                        _pos++;
                    }
                }
                else if (ch == '>')
                {
                    if (nextCh1 == '>')
                    {
                        if (nextCh2 == '=')
                        {
                            AddToken(new Token(OperatorType.ShiftRightAssign, ">>="));
                            _pos += 3;
                        }
                        else
                        {
                            AddToken(new Token(OperatorType.ShiftRight, ">>"));
                            _pos += 2;
                        }
                    }
                    else if (nextCh1 == '=')
                    {
                        AddToken(new Token(OperatorType.GreaterOrEqual, ">="));
                        _pos += 2;
                    }
                    else
                    {
                        AddToken(new Token(OperatorType.GreaterThan, ">"));
                        _pos++;
                    }
                }
                else if (ch == '|')
                {
                    if (nextCh1 == '=')
                    {
                        AddToken(new Token(OperatorType.BitwiseOrAssign, "|="));
                        _pos += 2;
                    }
                    else if (nextCh1 == '|')
                    {
                        AddToken(new Token(OperatorType.Or, "||"));
                        _pos += 2;
                    }
                    else
                    {
                        AddToken(new Token(OperatorType.BitwiseOr, "|"));
                        _pos++;
                    }
                }
                else if (ch == '^')
                {
                    if (nextCh1 == '=')
                    {
                        AddToken(new Token(Settings.EnableXor ? OperatorType.BitwiseXorAssign : OperatorType.PwrAssign, "^="));
                        _pos += 2;
                    }
                    else
                    {
                        AddToken(new Token(Settings.EnableXor ? OperatorType.BitwiseXor : OperatorType.Pwr, "^"));
                        _pos++;
                    }
                }
                else if (ch == '&')
                {
                    if (nextCh1 == '=')
                    {
                        AddToken(new Token(OperatorType.BitwiseAndAssign, "&="));
                        _pos += 2;
                    }
                    else if (nextCh1 == '&')
                    {
                        AddToken(new Token(OperatorType.And, "&&"));
                        _pos += 2;
                    }
                    else
                    {
                        AddToken(new Token(OperatorType.BitwiseAnd, "&"));
                        _pos++;
                    }
                }
                else if (ch == '=')
                {
                    if (nextCh1 == '=')
                    {
                        AddToken(new Token(OperatorType.Equal, "=="));
                        _pos += 2;
                    }
                    else
                    {
                        AddToken(new Token(OperatorType.Assign, "="));
                        _pos++;
                    }
                }
                else if (ch == '(')
                {
                    Token groupToken = new Token(TokenType.Group, "");
                    AddToken(groupToken);
                    _tokenStack.Push(groupToken);
                    _pos++;
                }
                else if (ch == ')')
                {
                    if (_tokenStack.Count <= 1) throw new Exception("Mismatched ')'.");
                    _tokenStack.Pop();
                    _pos++;
                }
                else if (ch == ',')
                {
                    AddToken(new Token(OperatorType.Comma, ","));
                    _pos++;
                }
                else if (ch == '\\')
                {
                    AddToken(new Token(OperatorType.Fraction, "\\"));
                    _pos++;
                }
                else if (ch == '\"')
                {
                    AddToken(new Token(OperatorType.Inches, "\""));
                    _pos++;
                }
                else if (ch == '\'')
                {
                    AddToken(new Token(OperatorType.Feet, "\'"));
                    _pos++;
                }
                else if (ch == '~')
                {
                    AddToken(new Token(OperatorType.BitwiseNot, "~"));
                    _pos++;
                }
                else if (ch == '[')
                {
                    GrabDateToken();
                }
                else if (ch == '{')
                {
                    GrabTimeSpanToken();
                }
                else if (ch == '!')
                {
                    if (nextCh1 == '=')
                    {
                        AddToken(new Token(OperatorType.NotEqual, "!="));
                        _pos += 2;
                    }
                    else
                    {
                        AddToken(new Token(OperatorType.Not, "!"));
                        _pos++;
                    }
                }
                else if (ch == '?')
                {
                    AddToken(new Token(OperatorType.Condition1, "?"));
                    _pos++;
                }
                else if (ch == ':')
                {
                    AddToken(new Token(OperatorType.Condition2, ":"));
                    _pos++;
                }
                else
                {
                    throw new Exception("Invalid char '" + ch + "'.");
                }

                lastCh = ch;
            }

            if (_tokenStack.Count != 1) throw new Exception("Mismatched '('.");
            return _tokenStack.Pop();
        }
Esempio n. 3
0
        public Token Clone()
        {
            Token tok = new Token(_type, _text, _value != null ? _value.Clone() : null);
            tok._opType = _opType;
            tok._isFuncArgs = _isFuncArgs;

            if (_group != null)
            {
                foreach (Token t in _group) tok._group.Add(t.Clone());
            }

            if (_returnValues != null)
            {
                tok._returnValues = new List<Value>();
                foreach (Value v in _returnValues) tok._returnValues.Add(v.Clone());
            }

            return tok;
        }
Esempio n. 4
0
        private void Execute(Token parentToken, Token leftToken2, Token leftToken, Token rightToken)
        {
            switch (_type)
            {
                case TokenType.Operator:
                    Calc.Operator.Execute(this, parentToken, leftToken2, leftToken, rightToken);
                    break;

                case TokenType.Group:
                    if (leftToken != null && (leftToken._type == TokenType.Function || leftToken._type == TokenType.Macro)) _isFuncArgs = true;
                    ExecuteGroup();
                    _precedence = 0;
                    break;

                case TokenType.Function:
                    if (rightToken == null || rightToken._returnValues == null) throw new Exception("Missing argument list for function '" + _text + "'.");
                    _value = Function.Execute(_text, rightToken._returnValues.ToArray());
                    _precedence = 0;
                    rightToken.Enabled = false;
                    break;

                case TokenType.Macro:
                    {
                        if (rightToken == null || rightToken._returnValues == null) throw new Exception("Missing argument list for macro '" + _text + "'.");

                        // Pretend we're a group
                        this._type = TokenType.Group;

                        Data.GetMacro(Text).LoadTokenGroup(this, rightToken._returnValues.ToArray());
                        ExecuteGroup();
                        if (_returnValues.Count != 1) throw new Exception("Macro '" + _text + "' syntax error.");
                        _value = _returnValues[0];
                        _precedence = 0;
                        rightToken.Enabled = false;
                    }
                    break;

                default:
                    throw new Exception("Internal: Cannot execute token type '" + _type.ToString() + "'.");
            }
        }
Esempio n. 5
0
 public void AppendChild(Token tok)
 {
     if (_type != TokenType.Group) throw new Exception("Internal: Child tokens cannot be appended to '" + _type.ToString() + "' tokens.");
     if (_group == null) _group = new List<Token>();
     _group.Add(tok);
 }
Esempio n. 6
0
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public static bool ProcessPossibleMacro(Token tokenGroup, string source)
        {
            // Macro definitions take the form:
            //	macroName(param1, param2, etc.)=<equation>

            List<Token> group = tokenGroup.Group;
            if (group.Count <= 3) return false;

            // First token must be the name
            if (group[0].Type != TokenType.Variable && group[0].Type != TokenType.Macro) return false;
            string macroName = group[0].Text;
            //if (Data.IsVariable(macroName)) return false;	// Cannot have a macro that is the same name as a variable.

            // Next token must be a set of brackets
            if (group[1].Type != TokenType.Group) return false;

            // Next token must be '='
            if (group[2].Type != TokenType.Operator || group[2].Operator != OperatorType.Assign) return false;

            // Check that arguments have correct form (arg, comma, arg, comma, ...)
            List<string> argNames = new List<string>();
            bool lookingForArg = true;
            bool gotAToken = false;

            foreach (Token argToken in group[1].Group)
            {
                if (lookingForArg)
                {
                    switch (argToken.Type)
                    {
                        case TokenType.Variable:
                        case TokenType.Function:
                        case TokenType.Macro:
                            break;

                        default:
                            throw new Exception("Expected macro argument name.");
                    }

                    // Check for duplicate argument name
                    foreach (string argName in argNames)
                    {
                        if (argName.ToLower() == argToken.Text.ToLower()) throw new Exception("Duplicate macro argument '" + argToken.Text + "'.");
                    }

                    argNames.Add(argToken.Text.ToLower());
                }
                else // looking for comma
                {
                    if (argToken.Type != TokenType.Operator || argToken.Operator != OperatorType.Comma) throw new Exception("Expected comma after argument.");
                }

                gotAToken = true;
                lookingForArg = !lookingForArg;
            }

            if (lookingForArg && gotAToken) return false;

            // Create a new group containing only the equation
            List<Token> eqGroup = new List<Token>();
            int eqGroupIndex = 0;
            foreach (Token tok in group)
            {
                if (eqGroupIndex++ >= 3) eqGroup.Add(tok.Clone());
            }

            PrepareMacroEquation(argNames, eqGroup);

            Macro macro = new Macro(macroName, argNames.ToArray(), eqGroup, source);

            if (Data.IsMacro(macroName))
            {
                Data.DeleteMacro(macroName);
                Data.AddMacro(macro);
                //_macros[macroName.ToLower()] = macro;
                if (!Globals.silentMode) Globals.form.WriteLine(HistoryType.Info, "Replaced macro '" + macroName + "'.");
            }
            else
            {
                Data.AddMacro(macro);
                //_macros.Add(macroName.ToLower(), macro);
                if (!Globals.silentMode) Globals.form.WriteLine(HistoryType.Info, "Created macro '" + macroName + "'.");
            }

            return true;
        }
Esempio n. 7
0
        public void LoadTokenGroup(Token token, Value[] args)
        {
            if (args.Length != _args.Length) throw new Exception("Macro '" + _name + "' requires " + _args.Length + " argument(s).");

            SortedList<string, Value> argList = new SortedList<string, Value>();
            int argIndex = 0;
            foreach (string argName in _args) argList.Add(argName, args[argIndex++]);

            foreach (Token eqToken in _eqGroup) token.AppendChild(eqToken.Clone());
            PrepareTokenGroupForMacroExe(token.Group, argList);
        }
Esempio n. 8
0
        public static void Execute(Token token, Token parent, Token left2, Token left, Token right)
        {
            _token = token;
            _parentToken = parent;
            _leftToken = left;
            _leftToken2 = left2;
            _rightToken = right;

            switch (token.Operator)
            {
                case OperatorType.Add:
                    BinaryOpTest();
                    BinaryOp(left.Value.Add(right.Value));
                    break;

                case OperatorType.Sub:
                    if (right == null || !right.HasValue) throw new Exception("Operator '-' expected value on right.");
                    if (left == null || !left.HasValue)
                    {
                        // Unary minus operator
                        UnaryOpTest();
                        UnaryOp((new Value(0, ValueFormat.Default)).Subtract(right.Value));
                    }
                    else
                    {
                        BinaryOpTest();
                        BinaryOp(left.Value.Subtract(right.Value));
                    }
                    break;

                case OperatorType.Mul:
                    BinaryOpTest();
                    BinaryOp(left.Value.Multiply(right.Value));
                    break;

                case OperatorType.Div:
                    BinaryOpTest();
                    BinaryOp(left.Value.Divide(right.Value));
                    break;

                case OperatorType.Mod:
                    BinaryOpTest();
                    BinaryOp(left.Value.Modulus(right.Value));
                    break;

                case OperatorType.Pwr:
                    BinaryOpTest();
                    BinaryOp(left.Value.Power(right.Value));
                    break;

                case OperatorType.ShiftLeft:
                    BinaryOpTest();
                    BinaryOp(left.Value.ShiftLeft(right.Value));
                    break;

                case OperatorType.ShiftRight:
                    BinaryOpTest();
                    BinaryOp(left.Value.ShiftRight(right.Value));
                    break;

                case OperatorType.BitwiseOr:
                    BinaryOpTest();
                    BinaryOp(left.Value.BitwiseOr(right.Value));
                    break;

                case OperatorType.BitwiseAnd:
                    BinaryOpTest();
                    BinaryOp(left.Value.BitwiseAnd(right.Value));
                    break;

                case OperatorType.BitwiseXor:
                    BinaryOpTest();
                    BinaryOp(left.Value.BitwiseXor(right.Value));
                    break;

                case OperatorType.Assign:
                    AssignOpTest();
                    AssignOp(right.Value);
                    break;

                case OperatorType.AddAssign:
                    AssignOpTest();
                    AssignOp(left.Value.Add(right.Value));
                    break;

                case OperatorType.SubAssign:
                    AssignOpTest();
                    AssignOp(left.Value.Subtract(right.Value));
                    break;

                case OperatorType.MulAssign:
                    AssignOpTest();
                    AssignOp(left.Value.Multiply(right.Value));
                    break;

                case OperatorType.DivAssign:
                    AssignOpTest();
                    AssignOp(left.Value.Divide(right.Value));
                    break;

                case OperatorType.ModAssign:
                    AssignOpTest();
                    AssignOp(left.Value.Modulus(right.Value));
                    break;

                case OperatorType.PwrAssign:
                    AssignOpTest();
                    AssignOp(left.Value.Power(right.Value));
                    break;

                case OperatorType.ShiftLeftAssign:
                    AssignOpTest();
                    AssignOp(left.Value.ShiftLeft(right.Value));
                    break;

                case OperatorType.ShiftRightAssign:
                    AssignOpTest();
                    AssignOp(left.Value.ShiftRight(right.Value));
                    break;

                case OperatorType.BitwiseOrAssign:
                    AssignOpTest();
                    AssignOp(left.Value.BitwiseOr(right.Value));
                    break;

                case OperatorType.BitwiseAndAssign:
                    AssignOpTest();
                    AssignOp(left.Value.BitwiseAnd(right.Value));
                    break;

                case OperatorType.BitwiseXorAssign:
                    AssignOpTest();
                    AssignOp(left.Value.BitwiseXor(right.Value));
                    break;

                case OperatorType.BitwiseNot:
                    UnaryOpTest();
                    UnaryOp(right.Value.BitwiseNot());
                    break;

                case OperatorType.Fraction:
                    {
                        BinaryOpTest();

                        decimal num = left.Value.DecValue;
                        decimal denom = right.Value.DecValue;

                        if (left2 != null && left2.HasValue)
                        {
                            decimal whole = left2.Value.DecValue;
                            if (whole < 0) num = whole * denom - num;
                            else num += whole * denom;

                            left2.Enabled = false;
                        }

                        BinaryOp(new Value(num, denom, ValueFormat.Fraction));
                    }
                    break;

                case OperatorType.Inches:
                    {
                        if (left == null || !left.HasValue) throw new Exception("Operator '\"' expected value on left.");

                        Value val;
                        if (left.Value.IsFractional)
                        {
                            val = left.Value.Clone();
                            val.Format = ValueFormat.Inches;
                        }
                        else if (left.Value.IsInteger)
                        {
                            val = Value.CreateFraction(left.Value, new Value(1, ValueFormat.Default));
                            val.Format = ValueFormat.Inches;
                        }
                        else throw new Exception("Operator '\"' expected an integer or fraction on left.");

                        SetValue(token, val);
                        left.Enabled = false;
                    }
                    break;

                case OperatorType.Feet:
                    {
                        if (left == null || !left.HasValue) throw new Exception("Operator ' expected value on left.");
                        if (!left.Value.IsFractional & !left.Value.IsInteger) throw new Exception("Operator ' expected an integer or fraction on left.");

                        Value val = Value.CreateFraction(left.Value, new Value(1, ValueFormat.Default)).Multiply(new Value(12, ValueFormat.Default));
                        val.Format = ValueFormat.Inches;
                        left.Enabled = false;

                        if (right != null && right.HasValue && (right.Value.Format == ValueFormat.Inches))
                        {
                            val = val.Add(right.Value);
                            right.Enabled = false;
                        }

                        SetValue(token, val);
                    }
                    break;

                case OperatorType.Comma:
                    // Hack for digit grouping. Only to be performed when not inside a function argument group.
                    if (Settings.DigitGrouping && !parent.IsFuncArgs)
                    {
                        if (left != null && left.HasValue && right != null && right.HasValue)
                        {
                            Value leftValue = left.Value;
                            Value rightValue = right.Value;

                            if (leftValue.IsInteger && (leftValue.Format == ValueFormat.Dec || leftValue.Format == ValueFormat.Default) &&
                                (rightValue.Format == ValueFormat.Dec || rightValue.Format == ValueFormat.Default))
                            {
                                SetValue(token, leftValue.Multiply(new Value(1000, ValueFormat.Default)).Add(rightValue));
                                left.Enabled = false;
                                right.Enabled = false;
                            }
                        }
                    }
                    token.Precedence = 0;
                    break;

                case OperatorType.Equal:
                    BinaryOpTest();
                    BinaryOp(new Value(left.Value.DecValue == right.Value.DecValue ? 1 : 0, ValueFormat.Default));
                    break;

                case OperatorType.NotEqual:
                    BinaryOpTest();
                    BinaryOp(new Value(left.Value.DecValue != right.Value.DecValue ? 1 : 0, ValueFormat.Default));
                    break;

                case OperatorType.LessThan:
                    BinaryOpTest();
                    BinaryOp(new Value(left.Value.DecValue < right.Value.DecValue ? 1 : 0, ValueFormat.Default));
                    break;

                case OperatorType.LessOrEqual:
                    BinaryOpTest();
                    BinaryOp(new Value(left.Value.DecValue <= right.Value.DecValue ? 1 : 0, ValueFormat.Default));
                    break;

                case OperatorType.GreaterThan:
                    BinaryOpTest();
                    BinaryOp(new Value(left.Value.DecValue > right.Value.DecValue ? 1 : 0, ValueFormat.Default));
                    break;

                case OperatorType.GreaterOrEqual:
                    BinaryOpTest();
                    BinaryOp(new Value(left.Value.DecValue >= right.Value.DecValue ? 1 : 0, ValueFormat.Default));
                    break;

                case OperatorType.Not:
                    UnaryOpTest();
                    UnaryOp(new Value(right.Value.DecValue == 0 ? 1 : 0, ValueFormat.Default));
                    break;

                case OperatorType.And:
                    BinaryOpTest();
                    BinaryOp(new Value(left.Value.DecValue != 0 && right.Value.DecValue != 0 ? 1 : 0, ValueFormat.Default));
                    break;

                case OperatorType.Or:
                    BinaryOpTest();
                    BinaryOp(new Value(left.Value.DecValue != 0 || right.Value.DecValue != 0 ? 1 : 0, ValueFormat.Default));
                    break;

                case OperatorType.Condition1:
                    BinaryOpTest();
                    if (left.Value.DecValue != 0) SetValue(token, new Value(1, ValueFormat.Default));
                    else SetValue(token, new Value(0, ValueFormat.Default));
                    left.Enabled = false;
                    break;

                case OperatorType.Condition2:
                    if (left == null || !left.HasValue) throw new Exception("Operator ':' expected value on left.");
                    if (right == null || !right.HasValue) throw new Exception("Operator ':' expected value on right.");
                    if (left2 == null || left2.Type != TokenType.Operator || left2.Operator != OperatorType.Condition1) throw new Exception("Operator ':' expected '?' to the left.");
                    SetValue(token, left2.Value.DecValue != 0 ? left.Value.Clone() : right.Value.Clone());
                    left.Enabled = left2.Enabled = right.Enabled = false;
                    break;
            }
        }
Esempio n. 9
0
 private static void SetValue(Token tok, Value val)
 {
     tok.Value = val;
     //tok.Type = TokenType.None;
     tok.Precedence = 0;
 }