src/AstTypeEnvironmentAnalysis.cpp
void TypeEnvironmentAnalysis::updateTypeEnvironment(const AstProgram& program) {
    // build up new type system based on defined types

    // create all type symbols in a first step
    for (const auto& cur : program.getTypes()) {
        // support faulty codes with multiple definitions
        if (env.isType(cur->getName())) {
            continue;
        }

        // create type within type environment
        if (auto* t = dynamic_cast<const AstPrimitiveType*>(cur)) {
            if (t->isNumeric()) {
                env.createNumericType(cur->getName());
            } else {
                env.createSymbolType(cur->getName());
            }
        } else if (dynamic_cast<const AstUnionType*>(cur)) {
            // initialize the union
            env.createUnionType(cur->getName());
        } else if (dynamic_cast<const AstRecordType*>(cur)) {
            // initialize the record
            env.createRecordType(cur->getName());
        } else {
            std::cout << "Unsupported type construct: " << typeid(cur).name() << "\n";
            assert(false && "Unsupported Type Construct!");
        }
    }

    // link symbols in a second step
    for (const auto& cur : program.getTypes()) {
        Type* type = env.getModifiableType(cur->getName());
        assert(type && "It should be there!");

        if (dynamic_cast<const AstPrimitiveType*>(cur)) {
            // nothing to do here
        } else if (auto* t = dynamic_cast<const AstUnionType*>(cur)) {
            // get type as union type
            auto* ut = dynamic_cast<UnionType*>(type);
            if (!ut) {
                continue;  // support faulty input
            }

            // add element types
            for (const auto& cur : t->getTypes()) {
                if (env.isType(cur)) {
                    ut->add(env.getType(cur));
                }
            }
        } else if (auto* t = dynamic_cast<const AstRecordType*>(cur)) {
            // get type as record type
            auto* rt = dynamic_cast<RecordType*>(type);
            if (!rt) {
                continue;  // support faulty input
            }

            // add fields
            for (const auto& f : t->getFields()) {
                if (env.isType(f.type)) {
                    rt->add(f.name, env.getType(f.type));
                }
            }
        } else {
            std::cout << "Unsupported type construct: " << typeid(cur).name() << "\n";
            assert(false && "Unsupported Type Construct!");
        }
    }
}
/**
 * A utility function utilized by the finishParsing member function to update a type environment
 * out of a given list of types in the AST
 *
 * @param types the types specified in the input file, contained in the AST
 * @param env the type environment to be updated
 */
A utility function utilized by the finishParsing member function to update a type environment
out of a given list of types in the AST

@param types the types specified in the input file, contained in the AST
@param env the type environment to be updated
A utility function utilized by the finishParsing member function to update a type environment out of a given list of types in the AST @param types the types specified in the input file contained in the AST @param env the type environment to be updated
void TypeEnvironmentAnalysis::updateTypeEnvironment(const AstProgram& program) {
    for (const auto& cur : program.getTypes()) {
        if (env.isType(cur->getName())) {
            continue;
        }
        if (auto* t = dynamic_cast<const AstPrimitiveType*>(cur)) {
            if (t->isNumeric()) {
                env.createNumericType(cur->getName());
            } else {
                env.createSymbolType(cur->getName());
            }
        } else if (dynamic_cast<const AstUnionType*>(cur)) {
            env.createUnionType(cur->getName());
        } else if (dynamic_cast<const AstRecordType*>(cur)) {
            env.createRecordType(cur->getName());
        } else {
            std::cout << "Unsupported type construct: " << typeid(cur).name() << "\n";
            assert(false && "Unsupported Type Construct!");
        }
    }
    for (const auto& cur : program.getTypes()) {
        Type* type = env.getModifiableType(cur->getName());
        assert(type && "It should be there!");
        if (dynamic_cast<const AstPrimitiveType*>(cur)) {
        } else if (auto* t = dynamic_cast<const AstUnionType*>(cur)) {
            auto* ut = dynamic_cast<UnionType*>(type);
            if (!ut) {
                continue;  
            }
            for (const auto& cur : t->getTypes()) {
                if (env.isType(cur)) {
                    ut->add(env.getType(cur));
                }
            }
        } else if (auto* t = dynamic_cast<const AstRecordType*>(cur)) {
            auto* rt = dynamic_cast<RecordType*>(type);
            if (!rt) {
                continue;  
            }
            for (const auto& f : t->getFields()) {
                if (env.isType(f.type)) {
                    rt->add(f.name, env.getType(f.type));
                }
            }
        } else {
            std::cout << "Unsupported type construct: " << typeid(cur).name() << "\n";
            assert(false && "Unsupported Type Construct!");
        }
    }
}
void TypeEnvironmentAnalysis :: updateTypeEnvironment ( const AstProgram & program ) { for ( const auto & cur : program . getTypes ( ) ) { if ( env . isType ( cur -> getName ( ) ) ) { continue ; } if ( auto * t = dynamic_cast < const AstPrimitiveType * > ( cur ) ) { if ( t -> isNumeric ( ) ) { env . createNumericType ( cur -> getName ( ) ) ; } else { env . createSymbolType ( cur -> getName ( ) ) ; } } else if ( dynamic_cast < const AstUnionType * > ( cur ) ) { env . createUnionType ( cur -> getName ( ) ) ; } else if ( dynamic_cast < const AstRecordType * > ( cur ) ) { env . createRecordType ( cur -> getName ( ) ) ; } else { std :: cout << " " << typeid ( cur ) . name ( ) << " \n " ; assert ( false && " " ) ; } } for ( const auto & cur : program . getTypes ( ) ) { Type * type = env . getModifiableType ( cur -> getName ( ) ) ; assert ( type && " " ) ; if ( dynamic_cast < const AstPrimitiveType * > ( cur ) ) { } else if ( auto * t = dynamic_cast < const AstUnionType * > ( cur ) ) { auto * ut = dynamic_cast < UnionType * > ( type ) ; if ( ! ut ) { continue ; } for ( const auto & cur : t -> getTypes ( ) ) { if ( env . isType ( cur ) ) { ut -> add ( env . getType ( cur ) ) ; } } } else if ( auto * t = dynamic_cast < const AstRecordType * > ( cur ) ) { auto * rt = dynamic_cast < RecordType * > ( type ) ; if ( ! rt ) { continue ; } for ( const auto & f : t -> getFields ( ) ) { if ( env . isType ( f . type ) ) { rt -> add ( f . name , env . getType ( f . type ) ) ; } } } else { std :: cout << " " << typeid ( cur ) . name ( ) << " \n " ; assert ( false && " " ) ; } } }
A utility function utilized by the finishParsing member function to update a type environment
 out of a given list of types in the AST
A utility function utilized by the finishParsing member function to update a type environment out of a given list of types in the AST
// build up new type system based on defined types // create all type symbols in a first step // support faulty codes with multiple definitions // create type within type environment // initialize the union // initialize the record // link symbols in a second step // nothing to do here // get type as union type // support faulty input // add element types // get type as record type // support faulty input // add fields