Exemple #1
0
        public static (bool Valid, ulong Value, int NBits) Evaluate_Constant(string str, bool isCapitals = false)
        {
            // 1] test whether str has digits, if it has none it is not a constant
            if (!str.Any(char.IsDigit))
            {
                return(false, 0, -1);
            }

            // 2] test whether str is a constant
            var v = Parse_Constant(str, isCapitals);

            if (v.Valid)
            {
                return(v);
            }

            // 3] check if str contains operators
            if (str.Contains('+') || str.Contains('-') || str.Contains('*') || str.Contains('/') ||
                str.Contains("<<") || str.Contains(">>"))
            {
                // second: if str is not a constant, test whether evaluating it yields a ulong
                try
                {
                    var   t          = CSharpScript.EvaluateAsync <ulong>(str);
                    ulong value      = t.Result;
                    bool  isNegative = false;
                    return(true, value, AsmSourceTools.NBitsStorageNeeded(value, isNegative));
                }
                catch (Exception)
                {}
            }
            // 4] don't know what it is but it is not likely to be an constant.
            return(false, 0, -1);
        }
        public static (bool valid, ulong value, int nBits) Evaluate_Constant(string str, bool isCapitals = false)
        {
            Contract.Requires(str != null);

            // 1] test whether str has digits, if it has none it is not a constant
            if (!str.Any(char.IsDigit))
            {
                return(valid : false, value : 0, nBits : -1);
            }

            // 2] test whether str is a constant
            (bool valid, ulong value, int nBits)v = Parse_Constant(str, isCapitals);
            if (v.valid)
            {
                return(v);
            }

            // 3] check if str contains operators
            if (str.Contains('+') || str.Contains('-') || str.Contains('*') || str.Contains('/') ||
                str.Contains("<<") || str.Contains(">>"))
            {
                // second: if str is not a constant, test whether evaluating it yields a ulong
                try
                {
                    System.Threading.Tasks.Task <ulong> t = CSharpScript.EvaluateAsync <ulong>(str);
                    ulong value      = t.Result;
                    bool  isNegative = false;
                    return(valid : true, value : value, nBits : AsmSourceTools.NBitsStorageNeeded(value, isNegative));
                }
                catch (Exception)
                {
                    // Do nothing
                }
            }
            // 4] don't know what it is but it is not likely to be a constant.
            return(valid : false, value : 0, nBits : -1);
        }
Exemple #3
0
        /// <summary> Check if the provided string is a constant. Does not evaluate arithmetic in the string </summary>
        public static (bool Valid, ulong Value, int NBits) Parse_Constant(string str, bool isCapitals = false)
        {
            string token2;
            bool   isHex      = false;
            bool   isBinary   = false;
            bool   isDecimal  = false;
            bool   isOctal    = false;
            bool   isNegative = false;

            //Console.WriteLine("AsmSourceTools:ToConstant token=" + token);

            if (!isCapitals)
            {
                str = str.ToUpper();
            }
            str = str.Trim();

            if (str.StartsWith("-"))
            {
                token2     = str;
                isDecimal  = true;
                isNegative = true;
            }

            // note the special case of token 0h (zero hex) should not be confused with the prefix 0h;
            else if (str.EndsWith("H", StringComparison.Ordinal))
            {
                token2 = str.Substring(0, str.Length - 1);
                isHex  = true;
            }
            else if (str.StartsWith("0H", StringComparison.Ordinal) || str.StartsWith("0X", StringComparison.Ordinal) || str.StartsWith("$0", StringComparison.Ordinal))
            {
                token2 = str.Substring(2);
                isHex  = true;
            }
            else if (str.StartsWith("0O", StringComparison.Ordinal) || str.StartsWith("0Q", StringComparison.Ordinal))
            {
                token2  = str.Substring(2);
                isOctal = true;
            }
            else if (str.EndsWith("Q", StringComparison.Ordinal) || str.EndsWith("O", StringComparison.Ordinal))
            {
                token2  = str.Substring(0, str.Length - 1);
                isOctal = true;
            }
            else if (str.StartsWith("0D", StringComparison.Ordinal))
            {
                token2    = str.Substring(2);
                isDecimal = true;
            }
            else if (str.EndsWith("D", StringComparison.Ordinal))
            {
                token2    = str;
                isDecimal = true;
            }
            else if (str.StartsWith("0B", StringComparison.Ordinal) || str.StartsWith("0Y", StringComparison.Ordinal))
            {
                token2   = str.Substring(2);
                isBinary = true;
            }
            else if (str.EndsWith("Y", StringComparison.Ordinal))
            {
                token2   = str.Substring(0, str.Length - 1);
                isBinary = true;
            }
            else
            {
                // special case with trailing B: either this B is from a hex number of the Binary
                if (str.EndsWith("B", StringComparison.Ordinal))
                {
                    bool parsedSuccessfully_tmp = ulong.TryParse(str, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out var dummy);
                    if (parsedSuccessfully_tmp)
                    {
                        isHex  = true;
                        token2 = str;
                    }
                    else
                    {
                        token2   = str.Substring(0, str.Length - 1);
                        isBinary = true;
                    }
                }
                else
                {   // assume decimal
                    token2    = str;
                    isDecimal = true;
                }
            }
            ulong value = 0;
            bool  parsedSuccessfully;

            if (isHex)
            {
                parsedSuccessfully = ulong.TryParse(token2, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out value);
            }
            else if (isOctal)
            {
                try
                {
                    value = Convert.ToUInt64(token2, 8);
                    parsedSuccessfully = true;
                }
                catch
                {
                    parsedSuccessfully = false;
                }
            }
            else if (isBinary)
            {
                try
                {
                    value = Convert.ToUInt64(token2, 2);
                    parsedSuccessfully = true;
                }
                catch
                {
                    parsedSuccessfully = false;
                }
            }
            else if (isDecimal)
            {
                if (isNegative)
                {
                    parsedSuccessfully = long.TryParse(token2, NumberStyles.Integer, CultureInfo.CurrentCulture, out long signedValue);
                    value = (ulong)signedValue;
                    //Console.WriteLine("AsmSourceTools:ToConstant token2=" + token2 + "; signed value = " + Convert.ToString(signedValue, 16) + "; unsigned value = " + string.Format("{0:X}", value));
                }
                else
                {
                    parsedSuccessfully = ulong.TryParse(token2, NumberStyles.Integer, CultureInfo.CurrentCulture, out value);
                    if (!parsedSuccessfully)
                    {
                        parsedSuccessfully = ulong.TryParse(token2, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out value);
                    }
                }
            }
            else
            {
                // unreachable
                parsedSuccessfully = false;
            }

            int nBits = (parsedSuccessfully) ? AsmSourceTools.NBitsStorageNeeded(value, isNegative) : -1;

            return(Valid : parsedSuccessfully, Value : value, NBits : nBits);
        }
        public static (bool Valid, ulong Value, int NBits) Evaluate_Constant_OLD(string str, bool IsCapitals = false)
        {
            //Console.WriteLine("INFO: Evaluate_Constant: str=" + str + ": length=" + str.Length);

            if (!IsCapitals)
            {
                str = str.ToUpper();
            }

            Stack <ulong> vStack  = new Stack <ulong>();
            Stack <Op>    opStack = new Stack <Op>();

            opStack.Push(Op.OPENING); // Implicit opening parenthesis

            int pos        = 0;
            int exprLength = str.Length;

            while (pos <= exprLength)
            {
                if (pos == exprLength)
                {
                    Process_Closing_Parenthesis(vStack, opStack);
                    pos++;
                }
                else
                {
                    char c = str[pos];
                    if (Char.IsWhiteSpace(c))
                    {
                        pos++;
                    }
                    else
                    {
                        switch (c)
                        {
                        case ')':
                            Process_Closing_Parenthesis(vStack, opStack);
                            pos++;
                            break;

                        case '(':
                            Process_Opening_Parenthesis(vStack, opStack);
                            pos++;
                            break;

                        case '+':
                            if (!Process_Input_Operator(Op.PLUS, vStack, opStack))
                            {
                                return(false, 0, -1);
                            }
                            pos++;
                            break;

                        case '-':
                            if (!Process_Input_Operator(Op.MINUS, vStack, opStack))
                            {
                                return(false, 0, -1);
                            }
                            pos++;
                            break;

                        case '*':
                            if (!Process_Input_Operator(Op.TIMES, vStack, opStack))
                            {
                                return(false, 0, -1);
                            }
                            pos++;
                            break;

                        case '/':
                            if (!Process_Input_Operator(Op.DIV, vStack, opStack))
                            {
                                return(false, 0, -1);
                            }
                            pos++;
                            break;

                        case '|':
                            if (!Process_Input_Operator(Op.OR, vStack, opStack))
                            {
                                return(false, 0, -1);
                            }
                            pos++;
                            break;

                        case '&':
                            if (!Process_Input_Operator(Op.AND, vStack, opStack))
                            {
                                return(false, 0, -1);
                            }
                            pos++;
                            break;

                        case '<':
                            if ((pos + 1 < exprLength) && (str[pos + 1] == '<'))
                            {
                                pos++;
                                if (!Process_Input_Operator(Op.SHL, vStack, opStack))
                                {
                                    return(false, 0, -1);
                                }
                                pos++;
                            }
                            break;

                        case '>':
                            if ((pos + 1 < exprLength) && (str[pos + 1] == '>'))
                            {
                                pos++;
                                if (!Process_Input_Operator(Op.SHR, vStack, opStack))
                                {
                                    return(false, 0, -1);
                                }
                                pos++;
                            }
                            break;

                        default:
                            var v = Process_Input_Number(str, pos, vStack);
                            if (!v.Valid)
                            {
                                return(false, 0, -1);
                            }
                            pos = v.Pos;
                            break;
                        }
                    }
                }
            }

            if (vStack.Count == 1) // Result remains on values stacks
            {
                ulong v = vStack.Pop();
                return(true, v, AsmSourceTools.NBitsStorageNeeded(v, false));
            }
            else
            {
                return(false, 0, -1);
            }
        }