Beispiel #1
0
        TypedInteger ResolveAddressExpressionRecursively(SimpleTokenReader reader)
        {
            TypedInteger value = null;

            for (; ;)
            {
                if (value == null)
                {
                    value = ReadSingleAtom(reader);
                }

                if (reader.EOF || reader.Current.Value == ")")
                {
                    return(value);
                }

                if (reader.Current.Type != CppTokenizer.TokenType.Operator)
                {
                    throw new Exception("Expected an operator");
                }

                var op = reader.Current.Value;
                reader.ReadNext(true);
                var next = ReadSingleAtom(reader);

                if (value == null || next == null)
                {
                    return(null);
                }

                switch (op)
                {
                case "+":
                case "-":
                    if (next.IsAPointer)
                    {
                        throw new Exception("Cannot add pointers");
                    }

                    if (value.IsAPointer)
                    {
                        //We need to multiply this by the pointer size
                        throw new NotImplementedException();
                    }

                    if (op == "+")
                    {
                        value = new TypedInteger {
                            Value = value.Value + next.Value, Type = value.Type
                        }
                    }
                    ;
                    else
                    {
                        value = new TypedInteger {
                            Value = value.Value - next.Value, Type = value.Type
                        }
                    };

                    break;

                case "<<":
                    if (next.IsAPointer || value.IsAPointer)
                    {
                        throw new Exception("Cannot shift pointers");
                    }

                    value = new TypedInteger {
                        Value = value.Value << (int)next.Value, Type = value.Type
                    };
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
        }
Beispiel #2
0
        //On entry, reader should point to the first available token. On exit, it will point to the first token AFTER the read expression.
        TypedInteger ReadSingleAtom(SimpleTokenReader reader)
        {
            if (reader.Current.Type == CppTokenizer.TokenType.Bracket && reader.Current.Value == "(")
            {
                var token = reader.ReadNext(true);
                if (token.Type == CppTokenizer.TokenType.Identifier && !char.IsNumber(token.Value[0]))
                {
                    //This is a cast operator (e.g. "(void *)0x1234").
                    List <SimpleToken> typeTokens = new List <SimpleToken>();
                    typeTokens.Add(token);
                    int level = 0;
                    for (; ;)
                    {
                        token = reader.ReadNext(true);
                        if (token.Type == CppTokenizer.TokenType.Bracket)
                        {
                            if (token.Value == "(")
                            {
                                level++;
                            }
                            else if (token.Value == ")")
                            {
                                level--;
                            }
                        }

                        if (level < 0)  //Found a closing bracket for the cast
                        {
                            reader.ReadNext(true);
                            break;
                        }

                        typeTokens.Add(token);
                    }

                    TypedInteger value = ReadSingleAtom(reader);
                    if (value != null)
                    {
                        value.Type = typeTokens.ToArray();
                    }
                    return(value);
                }
                else
                {
                    //Other bracketed expression
                    var value = ResolveAddressExpressionRecursively(reader);
                    if (reader.Current.Value != ")")
                    {
                        throw new Exception("Expected ')'");
                    }
                    reader.ReadNext(true);
                    return(value);
                }
            }
            else if (reader.Current.Type == CppTokenizer.TokenType.Identifier)
            {
                var   token = reader.Current;
                ulong?value = HeaderFileParser.TryParseMaybeHex(token.Value);

                reader.ReadNext(true);

                if (!value.HasValue)
                {
                    if (_ThrowOnFailure)
                    {
                        throw new UnexpectedNonNumberException(token);
                    }
                    else
                    {
                        return(null);
                    }
                }

                return(new TypedInteger {
                    Value = value.Value
                });
            }
            else
            {
                if (_ThrowOnFailure)
                {
                    throw new Exception("Invalid atom: " + reader.Current.Value);
                }
                else
                {
                    return(null);
                }
            }
        }