9.0.0.1

8 — Modules🔗

Due Thursday, 30 October 2025, 11:59:59pm

Purpose to build a model of a language with a simple module system

Delivery Deliver your solutions in a directory called 8 within your assigned GitHub repository. The directory should contain the following items:

  • the executables xmodule as specified below;

  • the sub-directory 8/Tests/ with the required integration test; and

  • an optional sub-directory called 8/Other/ for all auxiliary files.

The directory 8/ may also contain a Makefile (see Make) in case you need us to build your executable. An executable should not be checked into a repository.

Programming Task Using your favorite programming language, you are to create a syntax model of the Module language, a revision of Class with a simple module system. This task requires (1) the extension of the parser, which maps ExampleEE expressions to ASTs; (2) a validity-checking checker; and (3) a linker, which eliminates modules and construct a conventional Class program.

ExampleEE is an Example whose Names also contain the following keywords: if0, while0, block, def, =, /, +, ==, class, method, isa, new, >, module, import.

See figure 12 for the grammar of the Module language. For Class, Declaration, Statement, and Expression, see figure 8. Each module contains and exports a single class. The potentially empty sequences of import make the exported classes available in the associated lexical regions:
  • A module is a lexical region in which the module’s imports are visible.

  • A system’s body consists of the potentially empty sequence of import specifications that follow the module sequence, the declarations, the statements, and the return expression.

    The body of a system is a lexical region in which the imported classes are visible.

The implementation of the parser should adapt your solution to 6 — Class: Syntax as much as possible.

The validity checker for Systems has the following tasks:
  • No two modules in a system may have the same ModuleName.

  • Every import specification must refer to a ModuleName that is defined in the preceding sequence of modules. This includes the import specifications in the body of the system.

Since each module contains a single class, it is no longer necessary to check whether any two classes share a name.

  • Each module must be closed with respect to collection of imported classes.

  • The system’s body must be closed with respect to collection of imported classes.

Recall that closed means all variable occurrences refer to a declaration or a parameter and all ClassNames refer to a defined or imported class.

The purpose of a linker is to translate a well-formed and valid Module system into the AST of a well-formed and valid Class program. To this end, it consumes an AST and performs the following two transformations. Java uses $ for similar purposes. Many other languages come with similar conventions.
  • First, it replaces all occurrences of any ClassName with its fully-qualified name.

    If module M defines class C, the fully qualified name is M.Cthat is, a name that is illegal in the surface syntax and guaranteed to be unique.

  • Second, it strips the module and import forms from the AST.

The first step requires a name-resolution convention for imports that are about to inject the same ClassName into a lexical region:

If more than one import in a sequence of import specification refers to the same ClassName, the linker uses the last one in the sequence to construct a fully-qualified name. If any imported ClassName coincides with the name of the module’s class definition, it is shadowed.

  System      ::= (Module^*

                   Import^*

                   Declaration^*

                   Statement^*

                   Expression)

  

  Module      ::= (module ModuleName Import^* Class)

  

  Import      ::= (import ModuleName)

  

  

  The set of ModuleNames is the same as the set of Variables.

Figure 12: The concrete syntax of the Module language

The xmodule program reads one ExampleEE from STDIN, constructs the AST, performs the validity checks, links the system into a complete program, runs the CESK machine, and writes one of the following strings to STDOUT: The outcomes are listed in the order in which they may occur for a given program.
  • "parser error" if the given ExampleEE is not an element of the Module grammar;

  • "duplicate module name" if in the well-formed Module system two of the module definitions come with the same name;

  • "duplicate method, field, or parameter name" if in the well-formed Module system at least one class definition comes with two fields or methods that have the same name;

  • "undeclared variable error" if in the well-formed Module system one of its variable occurrences comes without declaration or one occurrence of a ClassName in a statement or an expression comes without class definition;

  • "object" if the CESK machine produces an object for the well-formed and valid Module system;

  • a number n if the CESK machine produces a number n for the well-formed and valid Module system;

  • "run-time error" if the CESK machine produces an error outcome for the well-formed and valid Moduled system.

Testing Task Create 10 integration tests for xmodule.

A test always consists of inputs, expected output, and an automated procedure for comparing the actual output with the expected one. — For this course, an integration test consists of a pair of files: n-in.ss, the input file, and n-out.ss, the expected output file, where n is an integer between 0 and the requested number of tests (exclusive). The comparison procedure is (string or numeric) equality on the content of the output file and the actual output. — Constraint No test file may exceed the size limit of 5Kb.