AST.StructOrUnionSpec.GetExprType C# (CSharp) Метод

GetExprType() приватный Метод

private GetExprType ( Env env ) : ISemantReturn
env Env
Результат ISemantReturn
        public override ISemantReturn<ExprType> GetExprType(Env env) {

            StructOrUnionType type;

            // If no members provided, then we need to find the Type in the current environment.
            if (this.MemberDeclns.IsNone) {

                if (this.Name.IsNone) {
                    throw new InvalidProgramException("This should not pass the parser");
                }

                var name = this.Name.Value;
                var typeName = (this.StructOrUnion == StructOrUnion.STRUCT ? "struct" : "union") + $" {name}";

                // Try to find Type name in the current environment.
                var entryOpt = env.Find(typeName);

                // If name not found: create an incomplete Type and add it into the environment.
                if (entryOpt.IsNone) {
                    type = StructOrUnionType.CreateIncompleteType(this.StructOrUnion, name);
                    env = env.PushEntry(Env.EntryKind.TYPEDEF, typeName, type);
                    return SemantReturn.Create(env, type);
                }

                // If name found: fetch it.
                if (entryOpt.Value.Kind != Env.EntryKind.TYPEDEF) {
                    throw new InvalidProgramException("A struct or union in env that is not typedef? This should not appear.");
                }

                return SemantReturn.Create(env, entryOpt.Value.Type);

            }

            // If members are provided, the user is trying to define a new struct/union.

            if (this.Name.IsSome) {

                var name = this.Name.Value;
                var typeName = (this.StructOrUnion == StructOrUnion.STRUCT ? "struct" : "union") + $" {name}";

                // Try to find Type name in the current environment.
                // Notice we need to search the current **scope** only.
                var entryOpt = env.FindInCurrentScope(typeName);

                // If name not found: create an incomplete Type and add it into the environment.
                if (entryOpt.IsNone) {
                    type = StructOrUnionType.CreateIncompleteType(this.StructOrUnion, name);
                    env = env.PushEntry(Env.EntryKind.TYPEDEF, typeName, type);
                } else {
                    if (entryOpt.Value.Kind != Env.EntryKind.TYPEDEF) {
                        throw new InvalidProgramException(
                            "A struct or union in env that is not typedef? This should not appear.");
                    }

                    type = entryOpt.Value.Type as StructOrUnionType;
                    if (type == null) {
                        throw new InvalidProgramException(
                            $"{typeName} is not a struct or union? This should not appear.");
                    }
                }

                // Current Type mustn't be already complete.
                if (type.IsComplete) {
                    throw new InvalidOperationException($"Redifinition of {typeName}");
                }

            } else {
                var typeName = (this.StructOrUnion == StructOrUnion.STRUCT ? "struct" : "union") + " <unnamed>";
                type = StructOrUnionType.CreateIncompleteType(this.StructOrUnion, typeName);
            }

            var members = Semant(GetMembers, this.MemberDeclns.Value, ref env);
            type.Define(this.StructOrUnion, members);

            return SemantReturn.Create(env, type);
        }
    }