Exemplo n.º 1
0
        private IList <TSpec> ReadTSpecs()
        {
            var tspecs = new List <TSpec>();

            while (true)
            {
                SkipWhite();
                switch (PeekChar())
                {
                case '[':     // SZArray, Array, or GenericInst
                    ReadChar();
                    SkipWhite();
                    var peeked = PeekChar();
                    if (peeked == ']')
                    {
                        // SZ array
                        Verify(ReadChar() == ']', "Expected ']'");
                        tspecs.Add(SZArraySpec.Instance);
                    }
                    else if (peeked == '*' || peeked == ',' || peeked == '-' || char.IsDigit((char)peeked))
                    {
                        // Array

                        var arraySpec = new ArraySpec();
                        arraySpec.rank = 0;
                        while (true)
                        {
                            SkipWhite();
                            var c = PeekChar();
                            if (c == '*')
                            {
                                ReadChar();
                            }
                            else if (c == ',' || c == ']')
                            {
                            }
                            else if (c == '-' || char.IsDigit((char)c))
                            {
                                var  lower = ReadInt32();
                                uint?size;
                                SkipWhite();
                                Verify(ReadChar() == '.', "Expected '.'");
                                Verify(ReadChar() == '.', "Expected '.'");
                                if (PeekChar() == '.')
                                {
                                    ReadChar();
                                    size = null;
                                }
                                else
                                {
                                    SkipWhite();
                                    if (PeekChar() == '-')
                                    {
                                        var upper = ReadInt32();
                                        Verify(upper >= lower, "upper < lower");
                                        size = (uint)(upper - lower + 1);
                                        Verify(size.Value != 0 && size.Value <= 0x1FFFFFFF, "Invalid size");
                                    }
                                    else
                                    {
                                        var upper = ReadUInt32();
                                        var lsize = upper - lower + 1;
                                        Verify(lsize > 0 && lsize <= 0x1FFFFFFF, "Invalid size");
                                        size = (uint)lsize;
                                    }
                                }
                                if (arraySpec.lowerBounds.Count == arraySpec.rank)
                                {
                                    arraySpec.lowerBounds.Add(lower);
                                }
                                if (size.HasValue && arraySpec.sizes.Count == arraySpec.rank)
                                {
                                    arraySpec.sizes.Add(size.Value);
                                }
                            }
                            else
                            {
                                Verify(false, "Unknown char");
                            }

                            arraySpec.rank++;
                            SkipWhite();
                            if (PeekChar() != ',')
                            {
                                break;
                            }
                            ReadChar();
                        }

                        Verify(ReadChar() == ']', "Expected ']'");
                        tspecs.Add(arraySpec);
                    }
                    else
                    {
                        // Generic args

                        var ginstSpec = new GenericInstSpec();
                        while (true)
                        {
                            SkipWhite();
                            peeked = PeekChar();
                            var needSeperators = peeked == '[';
                            if (peeked == ']')
                            {
                                break;
                            }
                            Verify(!needSeperators || ReadChar() == '[', "Expected '['");
                            ginstSpec.args.Add(ReadType(needSeperators));
                            SkipWhite();
                            Verify(!needSeperators || ReadChar() == ']', "Expected ']'");
                            SkipWhite();
                            if (PeekChar() != ',')
                            {
                                break;
                            }
                            ReadChar();
                        }

                        Verify(ReadChar() == ']', "Expected ']'");
                        tspecs.Add(ginstSpec);
                    }
                    break;

                case '&':     // ByRef
                    ReadChar();
                    tspecs.Add(ByRefSpec.Instance);
                    break;

                case '*':     // Ptr
                    ReadChar();
                    tspecs.Add(PtrSpec.Instance);
                    break;

                default:
                    return(tspecs);
                }
            }
        }
		IList<TSpec> ReadTSpecs() {
			var tspecs = new List<TSpec>();
			while (true) {
				SkipWhite();
				switch (PeekChar()) {
				case '[':	// SZArray, Array, or GenericInst
					ReadChar();
					SkipWhite();
					var peeked = PeekChar();
					if (peeked == ']') {
						// SZ array
						Verify(ReadChar() == ']', "Expected ']'");
						tspecs.Add(SZArraySpec.Instance);
					}
					else if (peeked == '*' || peeked == ',' || peeked == '-' || char.IsDigit((char)peeked)) {
						// Array

						var arraySpec = new ArraySpec();
						arraySpec.rank = 0;
						while (true) {
							SkipWhite();
							int c = PeekChar();
							if (c == '*')
								ReadChar();
							else if (c == ',' || c == ']') {
							}
							else if (c == '-' || char.IsDigit((char)c)) {
								int lower = ReadInt32();
								uint? size;
								SkipWhite();
								Verify(ReadChar() == '.', "Expected '.'");
								Verify(ReadChar() == '.', "Expected '.'");
								if (PeekChar() == '.') {
									ReadChar();
									size = null;
								}
								else {
									SkipWhite();
									if (PeekChar() == '-') {
										int upper = ReadInt32();
										Verify(upper >= lower, "upper < lower");
										size = (uint)(upper - lower + 1);
										Verify(size.Value != 0 && size.Value <= 0x1FFFFFFF, "Invalid size");
									}
									else {
										uint upper = ReadUInt32();
										long lsize = (long)upper - (long)lower + 1;
										Verify(lsize > 0 && lsize <= 0x1FFFFFFF, "Invalid size");
										size = (uint)lsize;
									}
								}
								if (arraySpec.lowerBounds.Count == arraySpec.rank)
									arraySpec.lowerBounds.Add(lower);
								if (size.HasValue && arraySpec.sizes.Count == arraySpec.rank)
									arraySpec.sizes.Add(size.Value);
							}
							else
								Verify(false, "Unknown char");

							arraySpec.rank++;
							SkipWhite();
							if (PeekChar() != ',')
								break;
							ReadChar();
						}

						Verify(ReadChar() == ']', "Expected ']'");
						tspecs.Add(arraySpec);
					}
					else {
						// Generic args

						var ginstSpec = new GenericInstSpec();
						while (true) {
							SkipWhite();
							peeked = PeekChar();
							bool needSeperators = peeked == '[';
							if (peeked == ']')
								break;
							Verify(!needSeperators || ReadChar() == '[', "Expected '['");
							ginstSpec.args.Add(ReadType(needSeperators));
							SkipWhite();
							Verify(!needSeperators || ReadChar() == ']', "Expected ']'");
							SkipWhite();
							if (PeekChar() != ',')
								break;
							ReadChar();
						}

						Verify(ReadChar() == ']', "Expected ']'");
						tspecs.Add(ginstSpec);
					}
					break;

				case '&':	// ByRef
					ReadChar();
					tspecs.Add(ByRefSpec.Instance);
					break;

				case '*':	// Ptr
					ReadChar();
					tspecs.Add(PtrSpec.Instance);
					break;

				default:
					return tspecs;
				}
			}
		}