Index: doc/proposals/modules-alvin/3_implementation_details/meta.md
===================================================================
--- doc/proposals/modules-alvin/3_implementation_details/meta.md	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
+++ doc/proposals/modules-alvin/3_implementation_details/meta.md	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
@@ -0,0 +1,5 @@
+At this point in development, there are enough ideas from my previous writeups that the questions "can it be done?" and "what are the tradeoffs?" are clear enough to start implementing.
+
+Now, the focus is on explaining the ideas succinctly and considering the order in which to implement features (some features require adding capabilities that are much harder to implement). As such, I'll be using this space to organize all these ideas into a suitable narrative, with accompanying code and examples.
+
+The prototype code described in today's meeting is in `prototype/`.
Index: doc/proposals/modules-alvin/3_implementation_details/prototype/Driver.py
===================================================================
--- doc/proposals/modules-alvin/3_implementation_details/prototype/Driver.py	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
+++ doc/proposals/modules-alvin/3_implementation_details/prototype/Driver.py	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
@@ -0,0 +1,266 @@
+import argparse
+import os
+from pprint import pprint
+from antlr4 import *
+from parser.CMODLexer import CMODLexer
+from parser.CMODParser import CMODParser
+
+def parse_args():
+    parser = argparse.ArgumentParser()
+    parser.add_argument("input_file", help="file to parse")
+    parser.add_argument("-r", "--project_root", help="the root folder of the project, used to find imported modules. All modules, including imports, should be within this folder")
+    args = parser.parse_args()
+    return args
+
+def main():
+    args = parse_args()
+    generate_code(args)
+
+def generate_code(args):
+    # args.input_file
+    # args.project_root
+
+    # This changes the OS directory to be project_root, and removes the suffix from input_file
+    # (output: input_module)
+    input_file = os.path.relpath(args.input_file, args.project_root)
+    os.chdir(args.project_root)
+    dot_index = input_file.rfind('.')
+    if dot_index < 0 or input_file[dot_index:] != '.cmod':
+        raise RuntimeError("input_file must use .cmod suffix")
+    input_module = input_file[:dot_index]
+
+    # Parses AST of a given module
+    # (output: get_module_info())
+    module_asts = {}  # dict[module_name: str, (text: str, tokens, tree)]
+    def get_module_info(module_name: str):
+        def insert_module_info(module_name):
+            input_stream = FileStream(module_name + ".cmod")
+            text = str(input_stream)
+            lexer = CMODLexer(input_stream)
+            tokens = lexer.getAllTokens()  # list[token: {text, start, stop, line, column}]
+                                           # stop is inclusive, just like getSourceInterval
+            lexer.reset()
+            stream = CommonTokenStream(lexer)
+            parser = CMODParser(stream)
+            tree = parser.compilationUnit()  # {getSourceInterval, getChildren, getChildCount, getChild, getText}
+            if parser.getNumberOfSyntaxErrors() > 0:
+                # Let it keep going with errors
+                print(f"// ERROR: syntax errors for file {module_name}")
+            module_asts[module_name] = text, tokens, tree
+
+        if module_name not in module_asts:
+            insert_module_info(module_name)
+        return module_asts[module_name]
+
+    # Gets imports of module
+    # (output: get_imports())
+    module_imports = {}  # dict[module_name: str, list[module_name: str]]
+    def get_imports(module_name: str):
+        def insert_imports(module_name):
+            _, _, tree = get_module_info(module_name)
+            import_names = []  # list[module_name: str]
+            for importDeclaration in tree.translationUnit().importDeclaration():
+                import_names.append(importDeclaration.Identifier().getText())
+            module_imports[module_name] = import_names
+
+        if module_name not in module_imports:
+            insert_imports(module_name)
+        return module_imports[module_name]
+
+    # Gets info for symbols of module
+    # (output: get_symbol_list())
+    module_symbols = {}  # dict[module_name: str, list[(symbol_name: str, idx: int, exported: bool)]]
+    def get_symbol_list(module_name: str):
+        def insert_symbol_list(module_name):
+            _, _, tree = get_module_info(module_name)
+            symbol_list = []  # list[(symbol_name: str, idx: int, exported: bool)]
+            for idx, externalDeclaration in enumerate(tree.translationUnit().externalDeclaration()):
+                exported = externalDeclaration.getChild(0).getText() == 'export'
+                structDefinition = externalDeclaration.structDefinition()
+                globalDefinition = externalDeclaration.globalDefinition()
+                functionDefinition = externalDeclaration.functionDefinition()
+                if structDefinition:
+                    symbol_name = structDefinition.Identifier().getText()
+                elif globalDefinition:
+                    symbol_name = globalDefinition.declarator().Identifier().getText()
+                elif functionDefinition:
+                    symbol_name = functionDefinition.declarator().Identifier().getText()
+                symbol_list.append((symbol_name, idx, exported))
+            module_symbols[module_name] = symbol_list
+
+        if module_name not in module_symbols:
+            insert_symbol_list(module_name)
+        return module_symbols[module_name]
+
+    # Gets info for symbols via lookup
+    # (output: lookup_symbol())
+    module_lookup = {}  # dict[parent_module_name: str, dict[symbol_name: str, (module_name: str, idx: int)]]
+    def lookup_symbol(parent_module_name: str, symbol_name: str) -> tuple[str, int] | None:
+        def generate_symbol_table(parent_module_name):
+            symbol_table = {}  # dict[symbol_name: str, (module_name: str, idx: int)]
+            def add_to_symbol_table(symbol_name, module_name, idx):
+                if symbol_name in symbol_table:
+                    # Let it keep going with errors
+                    print(f"// ERROR: symbol name clash for {symbol_name}")
+                else:
+                    symbol_table[symbol_name] = module_name, idx
+            for symbol_name, idx, _ in get_symbol_list(parent_module_name):
+                add_to_symbol_table(symbol_name, parent_module_name, idx)
+            for module_name in get_imports(parent_module_name):
+                for symbol_name, idx, exported in get_symbol_list(module_name):
+                    if exported:
+                        add_to_symbol_table(symbol_name, module_name, idx)
+            module_lookup[parent_module_name] = symbol_table
+
+        if parent_module_name not in module_lookup:
+            generate_symbol_table(parent_module_name)
+        if symbol_name in module_lookup[parent_module_name]:
+            return module_lookup[parent_module_name][symbol_name]
+        else:
+            # if symbol not found, hopefully it's fine
+            return None
+
+    # Generate the supporting code for a given symbol definition
+    # (output: codegen())
+    visited = {}  # dict[(module_name: str, idx: int), is_defn: bool]
+    visiting = set()  # set[(module_name: str, idx: int)]
+    def codegen(parent_module_name: str, idx: int, needs_defn: bool):
+        def codegen_type_info(typeSpecifier, uses_defn):
+            struct_identifier = typeSpecifier.Identifier()
+            if not struct_identifier:
+                return
+            res = lookup_symbol(parent_module_name, struct_identifier.getText())
+            if not res:
+                return
+            module_name, idx = res
+            codegen(module_name, idx, uses_defn)
+        def codegen_expression_info(expression):
+            for expr in expression.expression():
+                codegen_expression_info(expr)
+            typeSpecifier = expression.typeSpecifier()
+            if typeSpecifier:
+                codegen_type_info(typeSpecifier, expression.getChildCount() == 1)
+            identifier = expression.Identifier()
+            if identifier:
+                res = lookup_symbol(parent_module_name, identifier.getText())
+                if res:
+                    module_name, idx = res
+                    codegen(module_name, idx, False)
+
+        if (parent_module_name, idx) in visited:
+            # Unless we now need the definition, we can skip
+            if visited[(parent_module_name, idx)] == True or not needs_defn:
+                return
+        if (parent_module_name, idx) in visiting:
+            text, tokens, tree = get_module_info(parent_module_name)
+            structDefinition = tree.translationUnit().externalDeclaration(idx).structDefinition()
+            if not needs_defn and structDefinition:
+                # Special case: can revisit struct as a declaration
+                token_start = structDefinition.getSourceInterval()[0]
+                token_end = structDefinition.Identifier().getSourceInterval()[1]
+                text_start, text_end = tokens[token_start].start, tokens[token_end].stop
+                code = text[text_start:text_end+1]
+                code += ';'
+                print(code)
+                return
+            else:
+                # Let it keep going with errors
+                print(f"// ERROR: circular reference!")
+                return
+        visiting.add((parent_module_name, idx))
+
+        # get symbol definition
+        text, tokens, tree = get_module_info(parent_module_name)
+        externalDeclaration = tree.translationUnit().externalDeclaration(idx)
+        structDefinition = externalDeclaration.structDefinition()
+        globalDefinition = externalDeclaration.globalDefinition()
+        functionDefinition = externalDeclaration.functionDefinition()
+        if structDefinition:
+            # call codegen on children
+            if needs_defn:
+                for structField in structDefinition.structField():
+                    codegen_type_info(structField.typeSpecifier(),
+                                      structField.declarator().getChildCount() == 1)
+            # print out declaration / definition
+            token_start, token_end = structDefinition.getSourceInterval()
+            if not needs_defn:
+                token_end = structDefinition.Identifier().getSourceInterval()[1]
+            text_start, text_end = tokens[token_start].start, tokens[token_end].stop
+            code = text[text_start:text_end+1]
+            if not needs_defn:
+                code += ';'
+            print(code)
+        elif globalDefinition:
+            # call codegen on children
+            codegen_type_info(globalDefinition.typeSpecifier(),
+                              globalDefinition.declarator().getChildCount() == 1)
+            if needs_defn and globalDefinition.expression():
+                codegen_expression_info(globalDefinition.expression())
+            # print out declaration / definition
+            token_start, token_end = globalDefinition.getSourceInterval()
+            if not needs_defn:
+                token_end = globalDefinition.declarator().getSourceInterval()[1]
+            text_start, text_end = tokens[token_start].start, tokens[token_end].stop
+            code = text[text_start:text_end+1]
+            if not needs_defn:
+                code = 'extern ' + code + ';'
+            print(code)
+        elif functionDefinition:
+            # call codegen on children
+            codegen_type_info(functionDefinition.typeSpecifier(),
+                              functionDefinition.declarator().getChildCount() == 1)
+            parameterList = functionDefinition.parameterList()
+            if parameterList:
+                for typeSpecifier, declarator in zip(parameterList.typeSpecifier(),
+                                                     parameterList.declarator()):
+                    codegen_type_info(typeSpecifier, declarator.getChildCount() == 1)
+            if needs_defn:
+                for statement in functionDefinition.compoundStatement().statement():
+                    codegen_expression_info(statement.expression())
+            # print out declaration / definition
+            token_start, token_end = functionDefinition.getSourceInterval()
+            if not needs_defn:
+                token_end = functionDefinition.compoundStatement().getSourceInterval()[0] - 1
+            text_start, text_end = tokens[token_start].start, tokens[token_end].stop
+            code = text[text_start:text_end+1]
+            if not needs_defn:
+                code += ';'
+            print(code)
+
+        visiting.remove((parent_module_name, idx))
+        visited[(parent_module_name, idx)] = needs_defn
+    
+    # Now drive codegen through the input module
+    _, _, tree = get_module_info(input_module)
+    for _, idx, _ in get_symbol_list(input_module):
+        codegen(input_module, idx, True)
+
+def simple_parse(input_file):
+    # Used in debugging
+    input_stream = FileStream(input_file)
+    lexer = CMODLexer(input_stream)
+    stream = CommonTokenStream(lexer)
+    parser = CMODParser(stream)
+    tree = parser.compilationUnit()
+    print(tree.getText())
+
+def details(ast):
+    # Used in debugging
+    print(f"Details for {repr(ast)}")
+    num_auto_expand = 0
+    while ast.getChildCount() == 1:
+        ast = ast.getChild(0)
+        num_auto_expand += 1
+        print(repr(ast))
+    if num_auto_expand:
+        print(f"auto expanded {num_auto_expand} times")
+    n = ast.getChildCount()
+    print(n)
+    for i in range(n):
+        print()
+        print(i)
+        print(repr(ast.getChild(i)))
+        print(ast.getChild(i).getText())
+
+if __name__ == '__main__':
+    main()
Index: doc/proposals/modules-alvin/3_implementation_details/prototype/README.md
===================================================================
--- doc/proposals/modules-alvin/3_implementation_details/prototype/README.md	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
+++ doc/proposals/modules-alvin/3_implementation_details/prototype/README.md	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
@@ -0,0 +1,13 @@
+## Generating the parser code
+
+*The PLG environment is a shared system so you can't do `pip install antlr4-tools` . Instead, run `pipx install antlr4-tools` , then `pipx ensurepath` , exit and relogin to refresh PATH, then `antlr4 -v 4.13.2` (I had to run `~/.local/share/pipx/venvs/antlr4-tools/bin/antlr4 -v 4.13.2` because the path wasn't getting picked up initially). Once this is done, you can run `antlr4` and `antlr4-parse` normally.*
+
+Using ANTLR4 (v4.13.2) to parse grammars. See https://github.com/antlr/antlr4/blob/master/doc/getting-started.md for details. Run `pip install antlr4-tools` to get `antlr4` and `anltr4-parse` executables. Example command: `antlr4-parse -v 4.13.2 parser/CMOD.g4 compilationUnit -tree testing/basic.cmod`
+
+CMOD.g4 grammar inspired by https://github.com/antlr/grammars-v4/blob/master/c/C.g4 (though heavily edited afterwards). Ran `antlr4 -v 4.13.2 -Dlanguage=Python3 parser/CMOD.g4` to generate parser code (you can add `-visitor -listener` flags for extra capabilities).
+
+## Running the code
+
+*The PLG environment is a shared system so you can't do `pip install -r requirements.txt` . Instead, create a venv with `python3 -m venv ./.venv` , then install dependencies with `./.venv/bin/pip install -r requirements.txt` . After that, you can run on example code using `./.venv/bin/python3 Driver.py -r testing testing/basic.cmod`*
+
+Adapted the steps from https://github.com/antlr/antlr4/blob/master/doc/python-target.md to generate output. Run `pip install -r requirements.txt` to get needed libraries, then `python3 Driver.py -r testing testing/basic.cmod` to run on example code.
Index: doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMOD.g4
===================================================================
--- doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMOD.g4	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
+++ doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMOD.g4	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
@@ -0,0 +1,124 @@
+// C-like language with expressions removed, used to showcase module capabilities
+
+grammar CMOD;
+
+compilationUnit
+    : translationUnit EOF
+    ;
+
+translationUnit
+    : moduleDeclaration importDeclaration* externalDeclaration*
+    ;
+
+moduleDeclaration
+    : 'module' Identifier ';'
+    ;
+
+importDeclaration
+    : 'import' Identifier ';'
+    ;
+
+externalDeclaration
+    : 'export'? structDefinition
+    | 'export'? globalDefinition
+    | 'export'? functionDefinition
+    | ';' // stray ;
+    ;
+
+structDefinition
+    : 'struct' Identifier '{' structField* '}' ';'
+    ;
+
+structField
+    : typeSpecifier declarator ';'
+    ;
+
+globalDefinition
+    : typeSpecifier declarator ('=' expression)? ';'
+    ;
+
+functionDefinition
+    : typeSpecifier declarator '(' parameterList? ')' compoundStatement
+    ;
+
+parameterList
+    : typeSpecifier declarator (',' typeSpecifier declarator)*
+    ;
+
+compoundStatement
+    : '{' statement* '}'
+    ;
+
+statement
+    : expression ';'
+    ;
+
+expression
+    // Modules doesn't need to parse expressions correctly
+    // We just need to know which symbols are used
+    // Note this is a conservative overestimate
+    : expression expression
+    | ',' | '.' | '->' | '*' | '/' | '+' | '-' | '&' | '|' | '?' | ':' | '=' | '<' | '>'
+    | '(' expression ')'
+    | '[' expression ']'
+    | '{' expression '}'
+    | StringLiteral
+    | Number
+    | typeSpecifier '*'*
+    | Identifier
+    ;
+
+typeSpecifier
+    : 'void'
+    | 'char'
+    | 'short'
+    | 'int'
+    | 'long'
+    | 'float'
+    | 'double'
+    | 'struct' Identifier
+    ;
+
+declarator
+    : '*'? Identifier
+    ;
+
+Identifier
+    : Nondigit (Nondigit | Digit)*
+    ;
+
+Number
+    : Digit+ ('.' Digit*)?
+    ;
+
+fragment Nondigit
+    : [a-zA-Z_$]
+    ;
+
+fragment Digit
+    : [0-9]
+    ;
+
+StringLiteral
+    : '"' SChar* '"'
+    ;
+
+fragment SChar
+    : ~["\r\n]
+    ;
+
+Whitespace
+    : [ \t]+ -> channel(HIDDEN)
+    ;
+
+Newline
+    : ('\r' '\n'? | '\n') -> channel(HIDDEN)
+    ;
+
+BlockComment
+    : '/*' .*? '*/' -> channel(HIDDEN)
+    ;
+
+LineComment
+    : '//' ~[\r\n]* -> channel(HIDDEN)
+    ;
Index: doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMOD.interp
===================================================================
--- doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMOD.interp	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
+++ doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMOD.interp	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
@@ -0,0 +1,104 @@
+token literal names:
+null
+'module'
+';'
+'import'
+'export'
+'struct'
+'{'
+'}'
+'='
+'('
+')'
+','
+'.'
+'->'
+'*'
+'/'
+'+'
+'-'
+'&'
+'|'
+'?'
+':'
+'<'
+'>'
+'['
+']'
+'void'
+'char'
+'short'
+'int'
+'long'
+'float'
+'double'
+null
+null
+null
+null
+null
+null
+null
+
+token symbolic names:
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+Identifier
+Number
+StringLiteral
+Whitespace
+Newline
+BlockComment
+LineComment
+
+rule names:
+compilationUnit
+translationUnit
+moduleDeclaration
+importDeclaration
+externalDeclaration
+structDefinition
+structField
+globalDefinition
+functionDefinition
+parameterList
+compoundStatement
+statement
+expression
+typeSpecifier
+declarator
+
+
+atn:
+[4, 1, 39, 188, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 5, 1, 36, 8, 1, 10, 1, 12, 1, 39, 9, 1, 1, 1, 5, 1, 42, 8, 1, 10, 1, 12, 1, 45, 9, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 3, 4, 56, 8, 4, 1, 4, 1, 4, 3, 4, 60, 8, 4, 1, 4, 1, 4, 3, 4, 64, 8, 4, 1, 4, 1, 4, 3, 4, 68, 8, 4, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 74, 8, 5, 10, 5, 12, 5, 77, 9, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 90, 8, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 98, 8, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 5, 9, 109, 8, 9, 10, 9, 12, 9, 112, 9, 9, 1, 10, 1, 10, 5, 10, 116, 8, 10, 10, 10, 12, 10, 119, 9, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 5, 12, 157, 8, 12, 10, 12, 12, 12, 160, 9, 12, 1, 12, 3, 12, 163, 8, 12, 1, 12, 1, 12, 5, 12, 167, 8, 12, 10, 12, 12, 12, 170, 9, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 181, 8, 13, 1, 14, 3, 14, 184, 8, 14, 1, 14, 1, 14, 1, 14, 0, 1, 24, 15, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 0, 0, 215, 0, 30, 1, 0, 0, 0, 2, 33, 1, 0, 0, 0, 4, 46, 1, 0, 0, 0, 6, 50, 1, 0, 0, 0, 8, 67, 1, 0, 0, 0, 10, 69, 1, 0, 0, 0, 12, 81, 1, 0, 0, 0, 14, 85, 1, 0, 0, 0, 16, 93, 1, 0, 0, 0, 18, 102, 1, 0, 0, 0, 20, 113, 1, 0, 0, 0, 22, 122, 1, 0, 0, 0, 24, 162, 1, 0, 0, 0, 26, 180, 1, 0, 0, 0, 28, 183, 1, 0, 0, 0, 30, 31, 3, 2, 1, 0, 31, 32, 5, 0, 0, 1, 32, 1, 1, 0, 0, 0, 33, 37, 3, 4, 2, 0, 34, 36, 3, 6, 3, 0, 35, 34, 1, 0, 0, 0, 36, 39, 1, 0, 0, 0, 37, 35, 1, 0, 0, 0, 37, 38, 1, 0, 0, 0, 38, 43, 1, 0, 0, 0, 39, 37, 1, 0, 0, 0, 40, 42, 3, 8, 4, 0, 41, 40, 1, 0, 0, 0, 42, 45, 1, 0, 0, 0, 43, 41, 1, 0, 0, 0, 43, 44, 1, 0, 0, 0, 44, 3, 1, 0, 0, 0, 45, 43, 1, 0, 0, 0, 46, 47, 5, 1, 0, 0, 47, 48, 5, 33, 0, 0, 48, 49, 5, 2, 0, 0, 49, 5, 1, 0, 0, 0, 50, 51, 5, 3, 0, 0, 51, 52, 5, 33, 0, 0, 52, 53, 5, 2, 0, 0, 53, 7, 1, 0, 0, 0, 54, 56, 5, 4, 0, 0, 55, 54, 1, 0, 0, 0, 55, 56, 1, 0, 0, 0, 56, 57, 1, 0, 0, 0, 57, 68, 3, 10, 5, 0, 58, 60, 5, 4, 0, 0, 59, 58, 1, 0, 0, 0, 59, 60, 1, 0, 0, 0, 60, 61, 1, 0, 0, 0, 61, 68, 3, 14, 7, 0, 62, 64, 5, 4, 0, 0, 63, 62, 1, 0, 0, 0, 63, 64, 1, 0, 0, 0, 64, 65, 1, 0, 0, 0, 65, 68, 3, 16, 8, 0, 66, 68, 5, 2, 0, 0, 67, 55, 1, 0, 0, 0, 67, 59, 1, 0, 0, 0, 67, 63, 1, 0, 0, 0, 67, 66, 1, 0, 0, 0, 68, 9, 1, 0, 0, 0, 69, 70, 5, 5, 0, 0, 70, 71, 5, 33, 0, 0, 71, 75, 5, 6, 0, 0, 72, 74, 3, 12, 6, 0, 73, 72, 1, 0, 0, 0, 74, 77, 1, 0, 0, 0, 75, 73, 1, 0, 0, 0, 75, 76, 1, 0, 0, 0, 76, 78, 1, 0, 0, 0, 77, 75, 1, 0, 0, 0, 78, 79, 5, 7, 0, 0, 79, 80, 5, 2, 0, 0, 80, 11, 1, 0, 0, 0, 81, 82, 3, 26, 13, 0, 82, 83, 3, 28, 14, 0, 83, 84, 5, 2, 0, 0, 84, 13, 1, 0, 0, 0, 85, 86, 3, 26, 13, 0, 86, 89, 3, 28, 14, 0, 87, 88, 5, 8, 0, 0, 88, 90, 3, 24, 12, 0, 89, 87, 1, 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 91, 1, 0, 0, 0, 91, 92, 5, 2, 0, 0, 92, 15, 1, 0, 0, 0, 93, 94, 3, 26, 13, 0, 94, 95, 3, 28, 14, 0, 95, 97, 5, 9, 0, 0, 96, 98, 3, 18, 9, 0, 97, 96, 1, 0, 0, 0, 97, 98, 1, 0, 0, 0, 98, 99, 1, 0, 0, 0, 99, 100, 5, 10, 0, 0, 100, 101, 3, 20, 10, 0, 101, 17, 1, 0, 0, 0, 102, 103, 3, 26, 13, 0, 103, 110, 3, 28, 14, 0, 104, 105, 5, 11, 0, 0, 105, 106, 3, 26, 13, 0, 106, 107, 3, 28, 14, 0, 107, 109, 1, 0, 0, 0, 108, 104, 1, 0, 0, 0, 109, 112, 1, 0, 0, 0, 110, 108, 1, 0, 0, 0, 110, 111, 1, 0, 0, 0, 111, 19, 1, 0, 0, 0, 112, 110, 1, 0, 0, 0, 113, 117, 5, 6, 0, 0, 114, 116, 3, 22, 11, 0, 115, 114, 1, 0, 0, 0, 116, 119, 1, 0, 0, 0, 117, 115, 1, 0, 0, 0, 117, 118, 1, 0, 0, 0, 118, 120, 1, 0, 0, 0, 119, 117, 1, 0, 0, 0, 120, 121, 5, 7, 0, 0, 121, 21, 1, 0, 0, 0, 122, 123, 3, 24, 12, 0, 123, 124, 5, 2, 0, 0, 124, 23, 1, 0, 0, 0, 125, 126, 6, 12, -1, 0, 126, 163, 5, 11, 0, 0, 127, 163, 5, 12, 0, 0, 128, 163, 5, 13, 0, 0, 129, 163, 5, 14, 0, 0, 130, 163, 5, 15, 0, 0, 131, 163, 5, 16, 0, 0, 132, 163, 5, 17, 0, 0, 133, 163, 5, 18, 0, 0, 134, 163, 5, 19, 0, 0, 135, 163, 5, 20, 0, 0, 136, 163, 5, 21, 0, 0, 137, 163, 5, 8, 0, 0, 138, 163, 5, 22, 0, 0, 139, 163, 5, 23, 0, 0, 140, 141, 5, 9, 0, 0, 141, 142, 3, 24, 12, 0, 142, 143, 5, 10, 0, 0, 143, 163, 1, 0, 0, 0, 144, 145, 5, 24, 0, 0, 145, 146, 3, 24, 12, 0, 146, 147, 5, 25, 0, 0, 147, 163, 1, 0, 0, 0, 148, 149, 5, 6, 0, 0, 149, 150, 3, 24, 12, 0, 150, 151, 5, 7, 0, 0, 151, 163, 1, 0, 0, 0, 152, 163, 5, 35, 0, 0, 153, 163, 5, 34, 0, 0, 154, 158, 3, 26, 13, 0, 155, 157, 5, 14, 0, 0, 156, 155, 1, 0, 0, 0, 157, 160, 1, 0, 0, 0, 158, 156, 1, 0, 0, 0, 158, 159, 1, 0, 0, 0, 159, 163, 1, 0, 0, 0, 160, 158, 1, 0, 0, 0, 161, 163, 5, 33, 0, 0, 162, 125, 1, 0, 0, 0, 162, 127, 1, 0, 0, 0, 162, 128, 1, 0, 0, 0, 162, 129, 1, 0, 0, 0, 162, 130, 1, 0, 0, 0, 162, 131, 1, 0, 0, 0, 162, 132, 1, 0, 0, 0, 162, 133, 1, 0, 0, 0, 162, 134, 1, 0, 0, 0, 162, 135, 1, 0, 0, 0, 162, 136, 1, 0, 0, 0, 162, 137, 1, 0, 0, 0, 162, 138, 1, 0, 0, 0, 162, 139, 1, 0, 0, 0, 162, 140, 1, 0, 0, 0, 162, 144, 1, 0, 0, 0, 162, 148, 1, 0, 0, 0, 162, 152, 1, 0, 0, 0, 162, 153, 1, 0, 0, 0, 162, 154, 1, 0, 0, 0, 162, 161, 1, 0, 0, 0, 163, 168, 1, 0, 0, 0, 164, 165, 10, 22, 0, 0, 165, 167, 3, 24, 12, 23, 166, 164, 1, 0, 0, 0, 167, 170, 1, 0, 0, 0, 168, 166, 1, 0, 0, 0, 168, 169, 1, 0, 0, 0, 169, 25, 1, 0, 0, 0, 170, 168, 1, 0, 0, 0, 171, 181, 5, 26, 0, 0, 172, 181, 5, 27, 0, 0, 173, 181, 5, 28, 0, 0, 174, 181, 5, 29, 0, 0, 175, 181, 5, 30, 0, 0, 176, 181, 5, 31, 0, 0, 177, 181, 5, 32, 0, 0, 178, 179, 5, 5, 0, 0, 179, 181, 5, 33, 0, 0, 180, 171, 1, 0, 0, 0, 180, 172, 1, 0, 0, 0, 180, 173, 1, 0, 0, 0, 180, 174, 1, 0, 0, 0, 180, 175, 1, 0, 0, 0, 180, 176, 1, 0, 0, 0, 180, 177, 1, 0, 0, 0, 180, 178, 1, 0, 0, 0, 181, 27, 1, 0, 0, 0, 182, 184, 5, 14, 0, 0, 183, 182, 1, 0, 0, 0, 183, 184, 1, 0, 0, 0, 184, 185, 1, 0, 0, 0, 185, 186, 5, 33, 0, 0, 186, 29, 1, 0, 0, 0, 16, 37, 43, 55, 59, 63, 67, 75, 89, 97, 110, 117, 158, 162, 168, 180, 183]
Index: doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMOD.tokens
===================================================================
--- doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMOD.tokens	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
+++ doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMOD.tokens	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
@@ -0,0 +1,71 @@
+T__0=1
+T__1=2
+T__2=3
+T__3=4
+T__4=5
+T__5=6
+T__6=7
+T__7=8
+T__8=9
+T__9=10
+T__10=11
+T__11=12
+T__12=13
+T__13=14
+T__14=15
+T__15=16
+T__16=17
+T__17=18
+T__18=19
+T__19=20
+T__20=21
+T__21=22
+T__22=23
+T__23=24
+T__24=25
+T__25=26
+T__26=27
+T__27=28
+T__28=29
+T__29=30
+T__30=31
+T__31=32
+Identifier=33
+Number=34
+StringLiteral=35
+Whitespace=36
+Newline=37
+BlockComment=38
+LineComment=39
+'module'=1
+';'=2
+'import'=3
+'export'=4
+'struct'=5
+'{'=6
+'}'=7
+'='=8
+'('=9
+')'=10
+','=11
+'.'=12
+'->'=13
+'*'=14
+'/'=15
+'+'=16
+'-'=17
+'&'=18
+'|'=19
+'?'=20
+':'=21
+'<'=22
+'>'=23
+'['=24
+']'=25
+'void'=26
+'char'=27
+'short'=28
+'int'=29
+'long'=30
+'float'=31
+'double'=32
Index: doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMODLexer.interp
===================================================================
--- doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMODLexer.interp	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
+++ doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMODLexer.interp	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
@@ -0,0 +1,137 @@
+token literal names:
+null
+'module'
+';'
+'import'
+'export'
+'struct'
+'{'
+'}'
+'='
+'('
+')'
+','
+'.'
+'->'
+'*'
+'/'
+'+'
+'-'
+'&'
+'|'
+'?'
+':'
+'<'
+'>'
+'['
+']'
+'void'
+'char'
+'short'
+'int'
+'long'
+'float'
+'double'
+null
+null
+null
+null
+null
+null
+null
+
+token symbolic names:
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+Identifier
+Number
+StringLiteral
+Whitespace
+Newline
+BlockComment
+LineComment
+
+rule names:
+T__0
+T__1
+T__2
+T__3
+T__4
+T__5
+T__6
+T__7
+T__8
+T__9
+T__10
+T__11
+T__12
+T__13
+T__14
+T__15
+T__16
+T__17
+T__18
+T__19
+T__20
+T__21
+T__22
+T__23
+T__24
+T__25
+T__26
+T__27
+T__28
+T__29
+T__30
+T__31
+Identifier
+Number
+Nondigit
+Digit
+StringLiteral
+SChar
+Whitespace
+Newline
+BlockComment
+LineComment
+
+channel names:
+DEFAULT_TOKEN_CHANNEL
+HIDDEN
+
+mode names:
+DEFAULT_MODE
+
+atn:
+[4, 0, 39, 272, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 5, 32, 198, 8, 32, 10, 32, 12, 32, 201, 9, 32, 1, 33, 4, 33, 204, 8, 33, 11, 33, 12, 33, 205, 1, 33, 1, 33, 5, 33, 210, 8, 33, 10, 33, 12, 33, 213, 9, 33, 3, 33, 215, 8, 33, 1, 34, 1, 34, 1, 35, 1, 35, 1, 36, 1, 36, 5, 36, 223, 8, 36, 10, 36, 12, 36, 226, 9, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 38, 4, 38, 233, 8, 38, 11, 38, 12, 38, 234, 1, 38, 1, 38, 1, 39, 1, 39, 3, 39, 241, 8, 39, 1, 39, 3, 39, 244, 8, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 5, 40, 252, 8, 40, 10, 40, 12, 40, 255, 9, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 5, 41, 266, 8, 41, 10, 41, 12, 41, 269, 9, 41, 1, 41, 1, 41, 1, 253, 0, 42, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 0, 71, 0, 73, 35, 75, 0, 77, 36, 79, 37, 81, 38, 83, 39, 1, 0, 5, 4, 0, 36, 36, 65, 90, 95, 95, 97, 122, 1, 0, 48, 57, 3, 0, 10, 10, 13, 13, 34, 34, 2, 0, 9, 9, 32, 32, 2, 0, 10, 10, 13, 13, 279, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 1, 85, 1, 0, 0, 0, 3, 92, 1, 0, 0, 0, 5, 94, 1, 0, 0, 0, 7, 101, 1, 0, 0, 0, 9, 108, 1, 0, 0, 0, 11, 115, 1, 0, 0, 0, 13, 117, 1, 0, 0, 0, 15, 119, 1, 0, 0, 0, 17, 121, 1, 0, 0, 0, 19, 123, 1, 0, 0, 0, 21, 125, 1, 0, 0, 0, 23, 127, 1, 0, 0, 0, 25, 129, 1, 0, 0, 0, 27, 132, 1, 0, 0, 0, 29, 134, 1, 0, 0, 0, 31, 136, 1, 0, 0, 0, 33, 138, 1, 0, 0, 0, 35, 140, 1, 0, 0, 0, 37, 142, 1, 0, 0, 0, 39, 144, 1, 0, 0, 0, 41, 146, 1, 0, 0, 0, 43, 148, 1, 0, 0, 0, 45, 150, 1, 0, 0, 0, 47, 152, 1, 0, 0, 0, 49, 154, 1, 0, 0, 0, 51, 156, 1, 0, 0, 0, 53, 161, 1, 0, 0, 0, 55, 166, 1, 0, 0, 0, 57, 172, 1, 0, 0, 0, 59, 176, 1, 0, 0, 0, 61, 181, 1, 0, 0, 0, 63, 187, 1, 0, 0, 0, 65, 194, 1, 0, 0, 0, 67, 203, 1, 0, 0, 0, 69, 216, 1, 0, 0, 0, 71, 218, 1, 0, 0, 0, 73, 220, 1, 0, 0, 0, 75, 229, 1, 0, 0, 0, 77, 232, 1, 0, 0, 0, 79, 243, 1, 0, 0, 0, 81, 247, 1, 0, 0, 0, 83, 261, 1, 0, 0, 0, 85, 86, 5, 109, 0, 0, 86, 87, 5, 111, 0, 0, 87, 88, 5, 100, 0, 0, 88, 89, 5, 117, 0, 0, 89, 90, 5, 108, 0, 0, 90, 91, 5, 101, 0, 0, 91, 2, 1, 0, 0, 0, 92, 93, 5, 59, 0, 0, 93, 4, 1, 0, 0, 0, 94, 95, 5, 105, 0, 0, 95, 96, 5, 109, 0, 0, 96, 97, 5, 112, 0, 0, 97, 98, 5, 111, 0, 0, 98, 99, 5, 114, 0, 0, 99, 100, 5, 116, 0, 0, 100, 6, 1, 0, 0, 0, 101, 102, 5, 101, 0, 0, 102, 103, 5, 120, 0, 0, 103, 104, 5, 112, 0, 0, 104, 105, 5, 111, 0, 0, 105, 106, 5, 114, 0, 0, 106, 107, 5, 116, 0, 0, 107, 8, 1, 0, 0, 0, 108, 109, 5, 115, 0, 0, 109, 110, 5, 116, 0, 0, 110, 111, 5, 114, 0, 0, 111, 112, 5, 117, 0, 0, 112, 113, 5, 99, 0, 0, 113, 114, 5, 116, 0, 0, 114, 10, 1, 0, 0, 0, 115, 116, 5, 123, 0, 0, 116, 12, 1, 0, 0, 0, 117, 118, 5, 125, 0, 0, 118, 14, 1, 0, 0, 0, 119, 120, 5, 61, 0, 0, 120, 16, 1, 0, 0, 0, 121, 122, 5, 40, 0, 0, 122, 18, 1, 0, 0, 0, 123, 124, 5, 41, 0, 0, 124, 20, 1, 0, 0, 0, 125, 126, 5, 44, 0, 0, 126, 22, 1, 0, 0, 0, 127, 128, 5, 46, 0, 0, 128, 24, 1, 0, 0, 0, 129, 130, 5, 45, 0, 0, 130, 131, 5, 62, 0, 0, 131, 26, 1, 0, 0, 0, 132, 133, 5, 42, 0, 0, 133, 28, 1, 0, 0, 0, 134, 135, 5, 47, 0, 0, 135, 30, 1, 0, 0, 0, 136, 137, 5, 43, 0, 0, 137, 32, 1, 0, 0, 0, 138, 139, 5, 45, 0, 0, 139, 34, 1, 0, 0, 0, 140, 141, 5, 38, 0, 0, 141, 36, 1, 0, 0, 0, 142, 143, 5, 124, 0, 0, 143, 38, 1, 0, 0, 0, 144, 145, 5, 63, 0, 0, 145, 40, 1, 0, 0, 0, 146, 147, 5, 58, 0, 0, 147, 42, 1, 0, 0, 0, 148, 149, 5, 60, 0, 0, 149, 44, 1, 0, 0, 0, 150, 151, 5, 62, 0, 0, 151, 46, 1, 0, 0, 0, 152, 153, 5, 91, 0, 0, 153, 48, 1, 0, 0, 0, 154, 155, 5, 93, 0, 0, 155, 50, 1, 0, 0, 0, 156, 157, 5, 118, 0, 0, 157, 158, 5, 111, 0, 0, 158, 159, 5, 105, 0, 0, 159, 160, 5, 100, 0, 0, 160, 52, 1, 0, 0, 0, 161, 162, 5, 99, 0, 0, 162, 163, 5, 104, 0, 0, 163, 164, 5, 97, 0, 0, 164, 165, 5, 114, 0, 0, 165, 54, 1, 0, 0, 0, 166, 167, 5, 115, 0, 0, 167, 168, 5, 104, 0, 0, 168, 169, 5, 111, 0, 0, 169, 170, 5, 114, 0, 0, 170, 171, 5, 116, 0, 0, 171, 56, 1, 0, 0, 0, 172, 173, 5, 105, 0, 0, 173, 174, 5, 110, 0, 0, 174, 175, 5, 116, 0, 0, 175, 58, 1, 0, 0, 0, 176, 177, 5, 108, 0, 0, 177, 178, 5, 111, 0, 0, 178, 179, 5, 110, 0, 0, 179, 180, 5, 103, 0, 0, 180, 60, 1, 0, 0, 0, 181, 182, 5, 102, 0, 0, 182, 183, 5, 108, 0, 0, 183, 184, 5, 111, 0, 0, 184, 185, 5, 97, 0, 0, 185, 186, 5, 116, 0, 0, 186, 62, 1, 0, 0, 0, 187, 188, 5, 100, 0, 0, 188, 189, 5, 111, 0, 0, 189, 190, 5, 117, 0, 0, 190, 191, 5, 98, 0, 0, 191, 192, 5, 108, 0, 0, 192, 193, 5, 101, 0, 0, 193, 64, 1, 0, 0, 0, 194, 199, 3, 69, 34, 0, 195, 198, 3, 69, 34, 0, 196, 198, 3, 71, 35, 0, 197, 195, 1, 0, 0, 0, 197, 196, 1, 0, 0, 0, 198, 201, 1, 0, 0, 0, 199, 197, 1, 0, 0, 0, 199, 200, 1, 0, 0, 0, 200, 66, 1, 0, 0, 0, 201, 199, 1, 0, 0, 0, 202, 204, 3, 71, 35, 0, 203, 202, 1, 0, 0, 0, 204, 205, 1, 0, 0, 0, 205, 203, 1, 0, 0, 0, 205, 206, 1, 0, 0, 0, 206, 214, 1, 0, 0, 0, 207, 211, 5, 46, 0, 0, 208, 210, 3, 71, 35, 0, 209, 208, 1, 0, 0, 0, 210, 213, 1, 0, 0, 0, 211, 209, 1, 0, 0, 0, 211, 212, 1, 0, 0, 0, 212, 215, 1, 0, 0, 0, 213, 211, 1, 0, 0, 0, 214, 207, 1, 0, 0, 0, 214, 215, 1, 0, 0, 0, 215, 68, 1, 0, 0, 0, 216, 217, 7, 0, 0, 0, 217, 70, 1, 0, 0, 0, 218, 219, 7, 1, 0, 0, 219, 72, 1, 0, 0, 0, 220, 224, 5, 34, 0, 0, 221, 223, 3, 75, 37, 0, 222, 221, 1, 0, 0, 0, 223, 226, 1, 0, 0, 0, 224, 222, 1, 0, 0, 0, 224, 225, 1, 0, 0, 0, 225, 227, 1, 0, 0, 0, 226, 224, 1, 0, 0, 0, 227, 228, 5, 34, 0, 0, 228, 74, 1, 0, 0, 0, 229, 230, 8, 2, 0, 0, 230, 76, 1, 0, 0, 0, 231, 233, 7, 3, 0, 0, 232, 231, 1, 0, 0, 0, 233, 234, 1, 0, 0, 0, 234, 232, 1, 0, 0, 0, 234, 235, 1, 0, 0, 0, 235, 236, 1, 0, 0, 0, 236, 237, 6, 38, 0, 0, 237, 78, 1, 0, 0, 0, 238, 240, 5, 13, 0, 0, 239, 241, 5, 10, 0, 0, 240, 239, 1, 0, 0, 0, 240, 241, 1, 0, 0, 0, 241, 244, 1, 0, 0, 0, 242, 244, 5, 10, 0, 0, 243, 238, 1, 0, 0, 0, 243, 242, 1, 0, 0, 0, 244, 245, 1, 0, 0, 0, 245, 246, 6, 39, 0, 0, 246, 80, 1, 0, 0, 0, 247, 248, 5, 47, 0, 0, 248, 249, 5, 42, 0, 0, 249, 253, 1, 0, 0, 0, 250, 252, 9, 0, 0, 0, 251, 250, 1, 0, 0, 0, 252, 255, 1, 0, 0, 0, 253, 254, 1, 0, 0, 0, 253, 251, 1, 0, 0, 0, 254, 256, 1, 0, 0, 0, 255, 253, 1, 0, 0, 0, 256, 257, 5, 42, 0, 0, 257, 258, 5, 47, 0, 0, 258, 259, 1, 0, 0, 0, 259, 260, 6, 40, 0, 0, 260, 82, 1, 0, 0, 0, 261, 262, 5, 47, 0, 0, 262, 263, 5, 47, 0, 0, 263, 267, 1, 0, 0, 0, 264, 266, 8, 4, 0, 0, 265, 264, 1, 0, 0, 0, 266, 269, 1, 0, 0, 0, 267, 265, 1, 0, 0, 0, 267, 268, 1, 0, 0, 0, 268, 270, 1, 0, 0, 0, 269, 267, 1, 0, 0, 0, 270, 271, 6, 41, 0, 0, 271, 84, 1, 0, 0, 0, 12, 0, 197, 199, 205, 211, 214, 224, 234, 240, 243, 253, 267, 1, 0, 1, 0]
Index: doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMODLexer.py
===================================================================
--- doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMODLexer.py	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
+++ doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMODLexer.py	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
@@ -0,0 +1,189 @@
+# Generated from parser/CMOD.g4 by ANTLR 4.13.2
+from antlr4 import *
+from io import StringIO
+import sys
+if sys.version_info[1] > 5:
+    from typing import TextIO
+else:
+    from typing.io import TextIO
+
+
+def serializedATN():
+    return [
+        4,0,39,272,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,
+        2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,
+        13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,
+        19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,
+        26,7,26,2,27,7,27,2,28,7,28,2,29,7,29,2,30,7,30,2,31,7,31,2,32,7,
+        32,2,33,7,33,2,34,7,34,2,35,7,35,2,36,7,36,2,37,7,37,2,38,7,38,2,
+        39,7,39,2,40,7,40,2,41,7,41,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,
+        1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,4,1,4,
+        1,4,1,4,1,4,1,4,1,4,1,5,1,5,1,6,1,6,1,7,1,7,1,8,1,8,1,9,1,9,1,10,
+        1,10,1,11,1,11,1,12,1,12,1,12,1,13,1,13,1,14,1,14,1,15,1,15,1,16,
+        1,16,1,17,1,17,1,18,1,18,1,19,1,19,1,20,1,20,1,21,1,21,1,22,1,22,
+        1,23,1,23,1,24,1,24,1,25,1,25,1,25,1,25,1,25,1,26,1,26,1,26,1,26,
+        1,26,1,27,1,27,1,27,1,27,1,27,1,27,1,28,1,28,1,28,1,28,1,29,1,29,
+        1,29,1,29,1,29,1,30,1,30,1,30,1,30,1,30,1,30,1,31,1,31,1,31,1,31,
+        1,31,1,31,1,31,1,32,1,32,1,32,5,32,198,8,32,10,32,12,32,201,9,32,
+        1,33,4,33,204,8,33,11,33,12,33,205,1,33,1,33,5,33,210,8,33,10,33,
+        12,33,213,9,33,3,33,215,8,33,1,34,1,34,1,35,1,35,1,36,1,36,5,36,
+        223,8,36,10,36,12,36,226,9,36,1,36,1,36,1,37,1,37,1,38,4,38,233,
+        8,38,11,38,12,38,234,1,38,1,38,1,39,1,39,3,39,241,8,39,1,39,3,39,
+        244,8,39,1,39,1,39,1,40,1,40,1,40,1,40,5,40,252,8,40,10,40,12,40,
+        255,9,40,1,40,1,40,1,40,1,40,1,40,1,41,1,41,1,41,1,41,5,41,266,8,
+        41,10,41,12,41,269,9,41,1,41,1,41,1,253,0,42,1,1,3,2,5,3,7,4,9,5,
+        11,6,13,7,15,8,17,9,19,10,21,11,23,12,25,13,27,14,29,15,31,16,33,
+        17,35,18,37,19,39,20,41,21,43,22,45,23,47,24,49,25,51,26,53,27,55,
+        28,57,29,59,30,61,31,63,32,65,33,67,34,69,0,71,0,73,35,75,0,77,36,
+        79,37,81,38,83,39,1,0,5,4,0,36,36,65,90,95,95,97,122,1,0,48,57,3,
+        0,10,10,13,13,34,34,2,0,9,9,32,32,2,0,10,10,13,13,279,0,1,1,0,0,
+        0,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0,
+        13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0,
+        23,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,
+        33,1,0,0,0,0,35,1,0,0,0,0,37,1,0,0,0,0,39,1,0,0,0,0,41,1,0,0,0,0,
+        43,1,0,0,0,0,45,1,0,0,0,0,47,1,0,0,0,0,49,1,0,0,0,0,51,1,0,0,0,0,
+        53,1,0,0,0,0,55,1,0,0,0,0,57,1,0,0,0,0,59,1,0,0,0,0,61,1,0,0,0,0,
+        63,1,0,0,0,0,65,1,0,0,0,0,67,1,0,0,0,0,73,1,0,0,0,0,77,1,0,0,0,0,
+        79,1,0,0,0,0,81,1,0,0,0,0,83,1,0,0,0,1,85,1,0,0,0,3,92,1,0,0,0,5,
+        94,1,0,0,0,7,101,1,0,0,0,9,108,1,0,0,0,11,115,1,0,0,0,13,117,1,0,
+        0,0,15,119,1,0,0,0,17,121,1,0,0,0,19,123,1,0,0,0,21,125,1,0,0,0,
+        23,127,1,0,0,0,25,129,1,0,0,0,27,132,1,0,0,0,29,134,1,0,0,0,31,136,
+        1,0,0,0,33,138,1,0,0,0,35,140,1,0,0,0,37,142,1,0,0,0,39,144,1,0,
+        0,0,41,146,1,0,0,0,43,148,1,0,0,0,45,150,1,0,0,0,47,152,1,0,0,0,
+        49,154,1,0,0,0,51,156,1,0,0,0,53,161,1,0,0,0,55,166,1,0,0,0,57,172,
+        1,0,0,0,59,176,1,0,0,0,61,181,1,0,0,0,63,187,1,0,0,0,65,194,1,0,
+        0,0,67,203,1,0,0,0,69,216,1,0,0,0,71,218,1,0,0,0,73,220,1,0,0,0,
+        75,229,1,0,0,0,77,232,1,0,0,0,79,243,1,0,0,0,81,247,1,0,0,0,83,261,
+        1,0,0,0,85,86,5,109,0,0,86,87,5,111,0,0,87,88,5,100,0,0,88,89,5,
+        117,0,0,89,90,5,108,0,0,90,91,5,101,0,0,91,2,1,0,0,0,92,93,5,59,
+        0,0,93,4,1,0,0,0,94,95,5,105,0,0,95,96,5,109,0,0,96,97,5,112,0,0,
+        97,98,5,111,0,0,98,99,5,114,0,0,99,100,5,116,0,0,100,6,1,0,0,0,101,
+        102,5,101,0,0,102,103,5,120,0,0,103,104,5,112,0,0,104,105,5,111,
+        0,0,105,106,5,114,0,0,106,107,5,116,0,0,107,8,1,0,0,0,108,109,5,
+        115,0,0,109,110,5,116,0,0,110,111,5,114,0,0,111,112,5,117,0,0,112,
+        113,5,99,0,0,113,114,5,116,0,0,114,10,1,0,0,0,115,116,5,123,0,0,
+        116,12,1,0,0,0,117,118,5,125,0,0,118,14,1,0,0,0,119,120,5,61,0,0,
+        120,16,1,0,0,0,121,122,5,40,0,0,122,18,1,0,0,0,123,124,5,41,0,0,
+        124,20,1,0,0,0,125,126,5,44,0,0,126,22,1,0,0,0,127,128,5,46,0,0,
+        128,24,1,0,0,0,129,130,5,45,0,0,130,131,5,62,0,0,131,26,1,0,0,0,
+        132,133,5,42,0,0,133,28,1,0,0,0,134,135,5,47,0,0,135,30,1,0,0,0,
+        136,137,5,43,0,0,137,32,1,0,0,0,138,139,5,45,0,0,139,34,1,0,0,0,
+        140,141,5,38,0,0,141,36,1,0,0,0,142,143,5,124,0,0,143,38,1,0,0,0,
+        144,145,5,63,0,0,145,40,1,0,0,0,146,147,5,58,0,0,147,42,1,0,0,0,
+        148,149,5,60,0,0,149,44,1,0,0,0,150,151,5,62,0,0,151,46,1,0,0,0,
+        152,153,5,91,0,0,153,48,1,0,0,0,154,155,5,93,0,0,155,50,1,0,0,0,
+        156,157,5,118,0,0,157,158,5,111,0,0,158,159,5,105,0,0,159,160,5,
+        100,0,0,160,52,1,0,0,0,161,162,5,99,0,0,162,163,5,104,0,0,163,164,
+        5,97,0,0,164,165,5,114,0,0,165,54,1,0,0,0,166,167,5,115,0,0,167,
+        168,5,104,0,0,168,169,5,111,0,0,169,170,5,114,0,0,170,171,5,116,
+        0,0,171,56,1,0,0,0,172,173,5,105,0,0,173,174,5,110,0,0,174,175,5,
+        116,0,0,175,58,1,0,0,0,176,177,5,108,0,0,177,178,5,111,0,0,178,179,
+        5,110,0,0,179,180,5,103,0,0,180,60,1,0,0,0,181,182,5,102,0,0,182,
+        183,5,108,0,0,183,184,5,111,0,0,184,185,5,97,0,0,185,186,5,116,0,
+        0,186,62,1,0,0,0,187,188,5,100,0,0,188,189,5,111,0,0,189,190,5,117,
+        0,0,190,191,5,98,0,0,191,192,5,108,0,0,192,193,5,101,0,0,193,64,
+        1,0,0,0,194,199,3,69,34,0,195,198,3,69,34,0,196,198,3,71,35,0,197,
+        195,1,0,0,0,197,196,1,0,0,0,198,201,1,0,0,0,199,197,1,0,0,0,199,
+        200,1,0,0,0,200,66,1,0,0,0,201,199,1,0,0,0,202,204,3,71,35,0,203,
+        202,1,0,0,0,204,205,1,0,0,0,205,203,1,0,0,0,205,206,1,0,0,0,206,
+        214,1,0,0,0,207,211,5,46,0,0,208,210,3,71,35,0,209,208,1,0,0,0,210,
+        213,1,0,0,0,211,209,1,0,0,0,211,212,1,0,0,0,212,215,1,0,0,0,213,
+        211,1,0,0,0,214,207,1,0,0,0,214,215,1,0,0,0,215,68,1,0,0,0,216,217,
+        7,0,0,0,217,70,1,0,0,0,218,219,7,1,0,0,219,72,1,0,0,0,220,224,5,
+        34,0,0,221,223,3,75,37,0,222,221,1,0,0,0,223,226,1,0,0,0,224,222,
+        1,0,0,0,224,225,1,0,0,0,225,227,1,0,0,0,226,224,1,0,0,0,227,228,
+        5,34,0,0,228,74,1,0,0,0,229,230,8,2,0,0,230,76,1,0,0,0,231,233,7,
+        3,0,0,232,231,1,0,0,0,233,234,1,0,0,0,234,232,1,0,0,0,234,235,1,
+        0,0,0,235,236,1,0,0,0,236,237,6,38,0,0,237,78,1,0,0,0,238,240,5,
+        13,0,0,239,241,5,10,0,0,240,239,1,0,0,0,240,241,1,0,0,0,241,244,
+        1,0,0,0,242,244,5,10,0,0,243,238,1,0,0,0,243,242,1,0,0,0,244,245,
+        1,0,0,0,245,246,6,39,0,0,246,80,1,0,0,0,247,248,5,47,0,0,248,249,
+        5,42,0,0,249,253,1,0,0,0,250,252,9,0,0,0,251,250,1,0,0,0,252,255,
+        1,0,0,0,253,254,1,0,0,0,253,251,1,0,0,0,254,256,1,0,0,0,255,253,
+        1,0,0,0,256,257,5,42,0,0,257,258,5,47,0,0,258,259,1,0,0,0,259,260,
+        6,40,0,0,260,82,1,0,0,0,261,262,5,47,0,0,262,263,5,47,0,0,263,267,
+        1,0,0,0,264,266,8,4,0,0,265,264,1,0,0,0,266,269,1,0,0,0,267,265,
+        1,0,0,0,267,268,1,0,0,0,268,270,1,0,0,0,269,267,1,0,0,0,270,271,
+        6,41,0,0,271,84,1,0,0,0,12,0,197,199,205,211,214,224,234,240,243,
+        253,267,1,0,1,0
+    ]
+
+class CMODLexer(Lexer):
+
+    atn = ATNDeserializer().deserialize(serializedATN())
+
+    decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
+
+    T__0 = 1
+    T__1 = 2
+    T__2 = 3
+    T__3 = 4
+    T__4 = 5
+    T__5 = 6
+    T__6 = 7
+    T__7 = 8
+    T__8 = 9
+    T__9 = 10
+    T__10 = 11
+    T__11 = 12
+    T__12 = 13
+    T__13 = 14
+    T__14 = 15
+    T__15 = 16
+    T__16 = 17
+    T__17 = 18
+    T__18 = 19
+    T__19 = 20
+    T__20 = 21
+    T__21 = 22
+    T__22 = 23
+    T__23 = 24
+    T__24 = 25
+    T__25 = 26
+    T__26 = 27
+    T__27 = 28
+    T__28 = 29
+    T__29 = 30
+    T__30 = 31
+    T__31 = 32
+    Identifier = 33
+    Number = 34
+    StringLiteral = 35
+    Whitespace = 36
+    Newline = 37
+    BlockComment = 38
+    LineComment = 39
+
+    channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ]
+
+    modeNames = [ "DEFAULT_MODE" ]
+
+    literalNames = [ "<INVALID>",
+            "'module'", "';'", "'import'", "'export'", "'struct'", "'{'", 
+            "'}'", "'='", "'('", "')'", "','", "'.'", "'->'", "'*'", "'/'", 
+            "'+'", "'-'", "'&'", "'|'", "'?'", "':'", "'<'", "'>'", "'['", 
+            "']'", "'void'", "'char'", "'short'", "'int'", "'long'", "'float'", 
+            "'double'" ]
+
+    symbolicNames = [ "<INVALID>",
+            "Identifier", "Number", "StringLiteral", "Whitespace", "Newline", 
+            "BlockComment", "LineComment" ]
+
+    ruleNames = [ "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", 
+                  "T__7", "T__8", "T__9", "T__10", "T__11", "T__12", "T__13", 
+                  "T__14", "T__15", "T__16", "T__17", "T__18", "T__19", 
+                  "T__20", "T__21", "T__22", "T__23", "T__24", "T__25", 
+                  "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", 
+                  "Identifier", "Number", "Nondigit", "Digit", "StringLiteral", 
+                  "SChar", "Whitespace", "Newline", "BlockComment", "LineComment" ]
+
+    grammarFileName = "CMOD.g4"
+
+    def __init__(self, input=None, output:TextIO = sys.stdout):
+        super().__init__(input, output)
+        self.checkVersion("4.13.2")
+        self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache())
+        self._actions = None
+        self._predicates = None
+
+
Index: doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMODLexer.tokens
===================================================================
--- doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMODLexer.tokens	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
+++ doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMODLexer.tokens	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
@@ -0,0 +1,71 @@
+T__0=1
+T__1=2
+T__2=3
+T__3=4
+T__4=5
+T__5=6
+T__6=7
+T__7=8
+T__8=9
+T__9=10
+T__10=11
+T__11=12
+T__12=13
+T__13=14
+T__14=15
+T__15=16
+T__16=17
+T__17=18
+T__18=19
+T__19=20
+T__20=21
+T__21=22
+T__22=23
+T__23=24
+T__24=25
+T__25=26
+T__26=27
+T__27=28
+T__28=29
+T__29=30
+T__30=31
+T__31=32
+Identifier=33
+Number=34
+StringLiteral=35
+Whitespace=36
+Newline=37
+BlockComment=38
+LineComment=39
+'module'=1
+';'=2
+'import'=3
+'export'=4
+'struct'=5
+'{'=6
+'}'=7
+'='=8
+'('=9
+')'=10
+','=11
+'.'=12
+'->'=13
+'*'=14
+'/'=15
+'+'=16
+'-'=17
+'&'=18
+'|'=19
+'?'=20
+':'=21
+'<'=22
+'>'=23
+'['=24
+']'=25
+'void'=26
+'char'=27
+'short'=28
+'int'=29
+'long'=30
+'float'=31
+'double'=32
Index: doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMODListener.py
===================================================================
--- doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMODListener.py	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
+++ doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMODListener.py	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
@@ -0,0 +1,147 @@
+# Generated from parser/CMOD.g4 by ANTLR 4.13.2
+from antlr4 import *
+if "." in __name__:
+    from .CMODParser import CMODParser
+else:
+    from CMODParser import CMODParser
+
+# This class defines a complete listener for a parse tree produced by CMODParser.
+class CMODListener(ParseTreeListener):
+
+    # Enter a parse tree produced by CMODParser#compilationUnit.
+    def enterCompilationUnit(self, ctx:CMODParser.CompilationUnitContext):
+        pass
+
+    # Exit a parse tree produced by CMODParser#compilationUnit.
+    def exitCompilationUnit(self, ctx:CMODParser.CompilationUnitContext):
+        pass
+
+
+    # Enter a parse tree produced by CMODParser#translationUnit.
+    def enterTranslationUnit(self, ctx:CMODParser.TranslationUnitContext):
+        pass
+
+    # Exit a parse tree produced by CMODParser#translationUnit.
+    def exitTranslationUnit(self, ctx:CMODParser.TranslationUnitContext):
+        pass
+
+
+    # Enter a parse tree produced by CMODParser#moduleDeclaration.
+    def enterModuleDeclaration(self, ctx:CMODParser.ModuleDeclarationContext):
+        pass
+
+    # Exit a parse tree produced by CMODParser#moduleDeclaration.
+    def exitModuleDeclaration(self, ctx:CMODParser.ModuleDeclarationContext):
+        pass
+
+
+    # Enter a parse tree produced by CMODParser#importDeclaration.
+    def enterImportDeclaration(self, ctx:CMODParser.ImportDeclarationContext):
+        pass
+
+    # Exit a parse tree produced by CMODParser#importDeclaration.
+    def exitImportDeclaration(self, ctx:CMODParser.ImportDeclarationContext):
+        pass
+
+
+    # Enter a parse tree produced by CMODParser#externalDeclaration.
+    def enterExternalDeclaration(self, ctx:CMODParser.ExternalDeclarationContext):
+        pass
+
+    # Exit a parse tree produced by CMODParser#externalDeclaration.
+    def exitExternalDeclaration(self, ctx:CMODParser.ExternalDeclarationContext):
+        pass
+
+
+    # Enter a parse tree produced by CMODParser#structDefinition.
+    def enterStructDefinition(self, ctx:CMODParser.StructDefinitionContext):
+        pass
+
+    # Exit a parse tree produced by CMODParser#structDefinition.
+    def exitStructDefinition(self, ctx:CMODParser.StructDefinitionContext):
+        pass
+
+
+    # Enter a parse tree produced by CMODParser#structField.
+    def enterStructField(self, ctx:CMODParser.StructFieldContext):
+        pass
+
+    # Exit a parse tree produced by CMODParser#structField.
+    def exitStructField(self, ctx:CMODParser.StructFieldContext):
+        pass
+
+
+    # Enter a parse tree produced by CMODParser#globalDefinition.
+    def enterGlobalDefinition(self, ctx:CMODParser.GlobalDefinitionContext):
+        pass
+
+    # Exit a parse tree produced by CMODParser#globalDefinition.
+    def exitGlobalDefinition(self, ctx:CMODParser.GlobalDefinitionContext):
+        pass
+
+
+    # Enter a parse tree produced by CMODParser#functionDefinition.
+    def enterFunctionDefinition(self, ctx:CMODParser.FunctionDefinitionContext):
+        pass
+
+    # Exit a parse tree produced by CMODParser#functionDefinition.
+    def exitFunctionDefinition(self, ctx:CMODParser.FunctionDefinitionContext):
+        pass
+
+
+    # Enter a parse tree produced by CMODParser#parameterList.
+    def enterParameterList(self, ctx:CMODParser.ParameterListContext):
+        pass
+
+    # Exit a parse tree produced by CMODParser#parameterList.
+    def exitParameterList(self, ctx:CMODParser.ParameterListContext):
+        pass
+
+
+    # Enter a parse tree produced by CMODParser#compoundStatement.
+    def enterCompoundStatement(self, ctx:CMODParser.CompoundStatementContext):
+        pass
+
+    # Exit a parse tree produced by CMODParser#compoundStatement.
+    def exitCompoundStatement(self, ctx:CMODParser.CompoundStatementContext):
+        pass
+
+
+    # Enter a parse tree produced by CMODParser#statement.
+    def enterStatement(self, ctx:CMODParser.StatementContext):
+        pass
+
+    # Exit a parse tree produced by CMODParser#statement.
+    def exitStatement(self, ctx:CMODParser.StatementContext):
+        pass
+
+
+    # Enter a parse tree produced by CMODParser#expression.
+    def enterExpression(self, ctx:CMODParser.ExpressionContext):
+        pass
+
+    # Exit a parse tree produced by CMODParser#expression.
+    def exitExpression(self, ctx:CMODParser.ExpressionContext):
+        pass
+
+
+    # Enter a parse tree produced by CMODParser#typeSpecifier.
+    def enterTypeSpecifier(self, ctx:CMODParser.TypeSpecifierContext):
+        pass
+
+    # Exit a parse tree produced by CMODParser#typeSpecifier.
+    def exitTypeSpecifier(self, ctx:CMODParser.TypeSpecifierContext):
+        pass
+
+
+    # Enter a parse tree produced by CMODParser#declarator.
+    def enterDeclarator(self, ctx:CMODParser.DeclaratorContext):
+        pass
+
+    # Exit a parse tree produced by CMODParser#declarator.
+    def exitDeclarator(self, ctx:CMODParser.DeclaratorContext):
+        pass
+
+
+
+del CMODParser
Index: doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMODParser.py
===================================================================
--- doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMODParser.py	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
+++ doc/proposals/modules-alvin/3_implementation_details/prototype/parser/CMODParser.py	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
@@ -0,0 +1,1267 @@
+# Generated from parser/CMOD.g4 by ANTLR 4.13.2
+# encoding: utf-8
+from antlr4 import *
+from io import StringIO
+import sys
+if sys.version_info[1] > 5:
+	from typing import TextIO
+else:
+	from typing.io import TextIO
+
+def serializedATN():
+    return [
+        4,1,39,188,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7,
+        6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13,
+        2,14,7,14,1,0,1,0,1,0,1,1,1,1,5,1,36,8,1,10,1,12,1,39,9,1,1,1,5,
+        1,42,8,1,10,1,12,1,45,9,1,1,2,1,2,1,2,1,2,1,3,1,3,1,3,1,3,1,4,3,
+        4,56,8,4,1,4,1,4,3,4,60,8,4,1,4,1,4,3,4,64,8,4,1,4,1,4,3,4,68,8,
+        4,1,5,1,5,1,5,1,5,5,5,74,8,5,10,5,12,5,77,9,5,1,5,1,5,1,5,1,6,1,
+        6,1,6,1,6,1,7,1,7,1,7,1,7,3,7,90,8,7,1,7,1,7,1,8,1,8,1,8,1,8,3,8,
+        98,8,8,1,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9,1,9,5,9,109,8,9,10,9,12,9,
+        112,9,9,1,10,1,10,5,10,116,8,10,10,10,12,10,119,9,10,1,10,1,10,1,
+        11,1,11,1,11,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,
+        12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,
+        12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,5,12,157,8,12,10,12,12,12,
+        160,9,12,1,12,3,12,163,8,12,1,12,1,12,5,12,167,8,12,10,12,12,12,
+        170,9,12,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,3,13,181,8,
+        13,1,14,3,14,184,8,14,1,14,1,14,1,14,0,1,24,15,0,2,4,6,8,10,12,14,
+        16,18,20,22,24,26,28,0,0,215,0,30,1,0,0,0,2,33,1,0,0,0,4,46,1,0,
+        0,0,6,50,1,0,0,0,8,67,1,0,0,0,10,69,1,0,0,0,12,81,1,0,0,0,14,85,
+        1,0,0,0,16,93,1,0,0,0,18,102,1,0,0,0,20,113,1,0,0,0,22,122,1,0,0,
+        0,24,162,1,0,0,0,26,180,1,0,0,0,28,183,1,0,0,0,30,31,3,2,1,0,31,
+        32,5,0,0,1,32,1,1,0,0,0,33,37,3,4,2,0,34,36,3,6,3,0,35,34,1,0,0,
+        0,36,39,1,0,0,0,37,35,1,0,0,0,37,38,1,0,0,0,38,43,1,0,0,0,39,37,
+        1,0,0,0,40,42,3,8,4,0,41,40,1,0,0,0,42,45,1,0,0,0,43,41,1,0,0,0,
+        43,44,1,0,0,0,44,3,1,0,0,0,45,43,1,0,0,0,46,47,5,1,0,0,47,48,5,33,
+        0,0,48,49,5,2,0,0,49,5,1,0,0,0,50,51,5,3,0,0,51,52,5,33,0,0,52,53,
+        5,2,0,0,53,7,1,0,0,0,54,56,5,4,0,0,55,54,1,0,0,0,55,56,1,0,0,0,56,
+        57,1,0,0,0,57,68,3,10,5,0,58,60,5,4,0,0,59,58,1,0,0,0,59,60,1,0,
+        0,0,60,61,1,0,0,0,61,68,3,14,7,0,62,64,5,4,0,0,63,62,1,0,0,0,63,
+        64,1,0,0,0,64,65,1,0,0,0,65,68,3,16,8,0,66,68,5,2,0,0,67,55,1,0,
+        0,0,67,59,1,0,0,0,67,63,1,0,0,0,67,66,1,0,0,0,68,9,1,0,0,0,69,70,
+        5,5,0,0,70,71,5,33,0,0,71,75,5,6,0,0,72,74,3,12,6,0,73,72,1,0,0,
+        0,74,77,1,0,0,0,75,73,1,0,0,0,75,76,1,0,0,0,76,78,1,0,0,0,77,75,
+        1,0,0,0,78,79,5,7,0,0,79,80,5,2,0,0,80,11,1,0,0,0,81,82,3,26,13,
+        0,82,83,3,28,14,0,83,84,5,2,0,0,84,13,1,0,0,0,85,86,3,26,13,0,86,
+        89,3,28,14,0,87,88,5,8,0,0,88,90,3,24,12,0,89,87,1,0,0,0,89,90,1,
+        0,0,0,90,91,1,0,0,0,91,92,5,2,0,0,92,15,1,0,0,0,93,94,3,26,13,0,
+        94,95,3,28,14,0,95,97,5,9,0,0,96,98,3,18,9,0,97,96,1,0,0,0,97,98,
+        1,0,0,0,98,99,1,0,0,0,99,100,5,10,0,0,100,101,3,20,10,0,101,17,1,
+        0,0,0,102,103,3,26,13,0,103,110,3,28,14,0,104,105,5,11,0,0,105,106,
+        3,26,13,0,106,107,3,28,14,0,107,109,1,0,0,0,108,104,1,0,0,0,109,
+        112,1,0,0,0,110,108,1,0,0,0,110,111,1,0,0,0,111,19,1,0,0,0,112,110,
+        1,0,0,0,113,117,5,6,0,0,114,116,3,22,11,0,115,114,1,0,0,0,116,119,
+        1,0,0,0,117,115,1,0,0,0,117,118,1,0,0,0,118,120,1,0,0,0,119,117,
+        1,0,0,0,120,121,5,7,0,0,121,21,1,0,0,0,122,123,3,24,12,0,123,124,
+        5,2,0,0,124,23,1,0,0,0,125,126,6,12,-1,0,126,163,5,11,0,0,127,163,
+        5,12,0,0,128,163,5,13,0,0,129,163,5,14,0,0,130,163,5,15,0,0,131,
+        163,5,16,0,0,132,163,5,17,0,0,133,163,5,18,0,0,134,163,5,19,0,0,
+        135,163,5,20,0,0,136,163,5,21,0,0,137,163,5,8,0,0,138,163,5,22,0,
+        0,139,163,5,23,0,0,140,141,5,9,0,0,141,142,3,24,12,0,142,143,5,10,
+        0,0,143,163,1,0,0,0,144,145,5,24,0,0,145,146,3,24,12,0,146,147,5,
+        25,0,0,147,163,1,0,0,0,148,149,5,6,0,0,149,150,3,24,12,0,150,151,
+        5,7,0,0,151,163,1,0,0,0,152,163,5,35,0,0,153,163,5,34,0,0,154,158,
+        3,26,13,0,155,157,5,14,0,0,156,155,1,0,0,0,157,160,1,0,0,0,158,156,
+        1,0,0,0,158,159,1,0,0,0,159,163,1,0,0,0,160,158,1,0,0,0,161,163,
+        5,33,0,0,162,125,1,0,0,0,162,127,1,0,0,0,162,128,1,0,0,0,162,129,
+        1,0,0,0,162,130,1,0,0,0,162,131,1,0,0,0,162,132,1,0,0,0,162,133,
+        1,0,0,0,162,134,1,0,0,0,162,135,1,0,0,0,162,136,1,0,0,0,162,137,
+        1,0,0,0,162,138,1,0,0,0,162,139,1,0,0,0,162,140,1,0,0,0,162,144,
+        1,0,0,0,162,148,1,0,0,0,162,152,1,0,0,0,162,153,1,0,0,0,162,154,
+        1,0,0,0,162,161,1,0,0,0,163,168,1,0,0,0,164,165,10,22,0,0,165,167,
+        3,24,12,23,166,164,1,0,0,0,167,170,1,0,0,0,168,166,1,0,0,0,168,169,
+        1,0,0,0,169,25,1,0,0,0,170,168,1,0,0,0,171,181,5,26,0,0,172,181,
+        5,27,0,0,173,181,5,28,0,0,174,181,5,29,0,0,175,181,5,30,0,0,176,
+        181,5,31,0,0,177,181,5,32,0,0,178,179,5,5,0,0,179,181,5,33,0,0,180,
+        171,1,0,0,0,180,172,1,0,0,0,180,173,1,0,0,0,180,174,1,0,0,0,180,
+        175,1,0,0,0,180,176,1,0,0,0,180,177,1,0,0,0,180,178,1,0,0,0,181,
+        27,1,0,0,0,182,184,5,14,0,0,183,182,1,0,0,0,183,184,1,0,0,0,184,
+        185,1,0,0,0,185,186,5,33,0,0,186,29,1,0,0,0,16,37,43,55,59,63,67,
+        75,89,97,110,117,158,162,168,180,183
+    ]
+
+class CMODParser ( Parser ):
+
+    grammarFileName = "CMOD.g4"
+
+    atn = ATNDeserializer().deserialize(serializedATN())
+
+    decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
+
+    sharedContextCache = PredictionContextCache()
+
+    literalNames = [ "<INVALID>", "'module'", "';'", "'import'", "'export'", 
+                     "'struct'", "'{'", "'}'", "'='", "'('", "')'", "','", 
+                     "'.'", "'->'", "'*'", "'/'", "'+'", "'-'", "'&'", "'|'", 
+                     "'?'", "':'", "'<'", "'>'", "'['", "']'", "'void'", 
+                     "'char'", "'short'", "'int'", "'long'", "'float'", 
+                     "'double'" ]
+
+    symbolicNames = [ "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
+                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
+                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
+                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
+                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
+                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
+                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
+                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
+                      "<INVALID>", "Identifier", "Number", "StringLiteral", 
+                      "Whitespace", "Newline", "BlockComment", "LineComment" ]
+
+    RULE_compilationUnit = 0
+    RULE_translationUnit = 1
+    RULE_moduleDeclaration = 2
+    RULE_importDeclaration = 3
+    RULE_externalDeclaration = 4
+    RULE_structDefinition = 5
+    RULE_structField = 6
+    RULE_globalDefinition = 7
+    RULE_functionDefinition = 8
+    RULE_parameterList = 9
+    RULE_compoundStatement = 10
+    RULE_statement = 11
+    RULE_expression = 12
+    RULE_typeSpecifier = 13
+    RULE_declarator = 14
+
+    ruleNames =  [ "compilationUnit", "translationUnit", "moduleDeclaration", 
+                   "importDeclaration", "externalDeclaration", "structDefinition", 
+                   "structField", "globalDefinition", "functionDefinition", 
+                   "parameterList", "compoundStatement", "statement", "expression", 
+                   "typeSpecifier", "declarator" ]
+
+    EOF = Token.EOF
+    T__0=1
+    T__1=2
+    T__2=3
+    T__3=4
+    T__4=5
+    T__5=6
+    T__6=7
+    T__7=8
+    T__8=9
+    T__9=10
+    T__10=11
+    T__11=12
+    T__12=13
+    T__13=14
+    T__14=15
+    T__15=16
+    T__16=17
+    T__17=18
+    T__18=19
+    T__19=20
+    T__20=21
+    T__21=22
+    T__22=23
+    T__23=24
+    T__24=25
+    T__25=26
+    T__26=27
+    T__27=28
+    T__28=29
+    T__29=30
+    T__30=31
+    T__31=32
+    Identifier=33
+    Number=34
+    StringLiteral=35
+    Whitespace=36
+    Newline=37
+    BlockComment=38
+    LineComment=39
+
+    def __init__(self, input:TokenStream, output:TextIO = sys.stdout):
+        super().__init__(input, output)
+        self.checkVersion("4.13.2")
+        self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache)
+        self._predicates = None
+
+
+
+
+    class CompilationUnitContext(ParserRuleContext):
+        __slots__ = 'parser'
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def translationUnit(self):
+            return self.getTypedRuleContext(CMODParser.TranslationUnitContext,0)
+
+
+        def EOF(self):
+            return self.getToken(CMODParser.EOF, 0)
+
+        def getRuleIndex(self):
+            return CMODParser.RULE_compilationUnit
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterCompilationUnit" ):
+                listener.enterCompilationUnit(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitCompilationUnit" ):
+                listener.exitCompilationUnit(self)
+
+
+
+
+    def compilationUnit(self):
+
+        localctx = CMODParser.CompilationUnitContext(self, self._ctx, self.state)
+        self.enterRule(localctx, 0, self.RULE_compilationUnit)
+        try:
+            self.enterOuterAlt(localctx, 1)
+            self.state = 30
+            self.translationUnit()
+            self.state = 31
+            self.match(CMODParser.EOF)
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.exitRule()
+        return localctx
+
+
+    class TranslationUnitContext(ParserRuleContext):
+        __slots__ = 'parser'
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def moduleDeclaration(self):
+            return self.getTypedRuleContext(CMODParser.ModuleDeclarationContext,0)
+
+
+        def importDeclaration(self, i:int=None):
+            if i is None:
+                return self.getTypedRuleContexts(CMODParser.ImportDeclarationContext)
+            else:
+                return self.getTypedRuleContext(CMODParser.ImportDeclarationContext,i)
+
+
+        def externalDeclaration(self, i:int=None):
+            if i is None:
+                return self.getTypedRuleContexts(CMODParser.ExternalDeclarationContext)
+            else:
+                return self.getTypedRuleContext(CMODParser.ExternalDeclarationContext,i)
+
+
+        def getRuleIndex(self):
+            return CMODParser.RULE_translationUnit
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterTranslationUnit" ):
+                listener.enterTranslationUnit(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitTranslationUnit" ):
+                listener.exitTranslationUnit(self)
+
+
+
+
+    def translationUnit(self):
+
+        localctx = CMODParser.TranslationUnitContext(self, self._ctx, self.state)
+        self.enterRule(localctx, 2, self.RULE_translationUnit)
+        self._la = 0 # Token type
+        try:
+            self.enterOuterAlt(localctx, 1)
+            self.state = 33
+            self.moduleDeclaration()
+            self.state = 37
+            self._errHandler.sync(self)
+            _la = self._input.LA(1)
+            while _la==3:
+                self.state = 34
+                self.importDeclaration()
+                self.state = 39
+                self._errHandler.sync(self)
+                _la = self._input.LA(1)
+
+            self.state = 43
+            self._errHandler.sync(self)
+            _la = self._input.LA(1)
+            while (((_la) & ~0x3f) == 0 and ((1 << _la) & 8522825780) != 0):
+                self.state = 40
+                self.externalDeclaration()
+                self.state = 45
+                self._errHandler.sync(self)
+                _la = self._input.LA(1)
+
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.exitRule()
+        return localctx
+
+
+    class ModuleDeclarationContext(ParserRuleContext):
+        __slots__ = 'parser'
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def Identifier(self):
+            return self.getToken(CMODParser.Identifier, 0)
+
+        def getRuleIndex(self):
+            return CMODParser.RULE_moduleDeclaration
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterModuleDeclaration" ):
+                listener.enterModuleDeclaration(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitModuleDeclaration" ):
+                listener.exitModuleDeclaration(self)
+
+
+
+
+    def moduleDeclaration(self):
+
+        localctx = CMODParser.ModuleDeclarationContext(self, self._ctx, self.state)
+        self.enterRule(localctx, 4, self.RULE_moduleDeclaration)
+        try:
+            self.enterOuterAlt(localctx, 1)
+            self.state = 46
+            self.match(CMODParser.T__0)
+            self.state = 47
+            self.match(CMODParser.Identifier)
+            self.state = 48
+            self.match(CMODParser.T__1)
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.exitRule()
+        return localctx
+
+
+    class ImportDeclarationContext(ParserRuleContext):
+        __slots__ = 'parser'
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def Identifier(self):
+            return self.getToken(CMODParser.Identifier, 0)
+
+        def getRuleIndex(self):
+            return CMODParser.RULE_importDeclaration
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterImportDeclaration" ):
+                listener.enterImportDeclaration(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitImportDeclaration" ):
+                listener.exitImportDeclaration(self)
+
+
+
+
+    def importDeclaration(self):
+
+        localctx = CMODParser.ImportDeclarationContext(self, self._ctx, self.state)
+        self.enterRule(localctx, 6, self.RULE_importDeclaration)
+        try:
+            self.enterOuterAlt(localctx, 1)
+            self.state = 50
+            self.match(CMODParser.T__2)
+            self.state = 51
+            self.match(CMODParser.Identifier)
+            self.state = 52
+            self.match(CMODParser.T__1)
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.exitRule()
+        return localctx
+
+
+    class ExternalDeclarationContext(ParserRuleContext):
+        __slots__ = 'parser'
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def structDefinition(self):
+            return self.getTypedRuleContext(CMODParser.StructDefinitionContext,0)
+
+
+        def globalDefinition(self):
+            return self.getTypedRuleContext(CMODParser.GlobalDefinitionContext,0)
+
+
+        def functionDefinition(self):
+            return self.getTypedRuleContext(CMODParser.FunctionDefinitionContext,0)
+
+
+        def getRuleIndex(self):
+            return CMODParser.RULE_externalDeclaration
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterExternalDeclaration" ):
+                listener.enterExternalDeclaration(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitExternalDeclaration" ):
+                listener.exitExternalDeclaration(self)
+
+
+
+
+    def externalDeclaration(self):
+
+        localctx = CMODParser.ExternalDeclarationContext(self, self._ctx, self.state)
+        self.enterRule(localctx, 8, self.RULE_externalDeclaration)
+        self._la = 0 # Token type
+        try:
+            self.state = 67
+            self._errHandler.sync(self)
+            la_ = self._interp.adaptivePredict(self._input,5,self._ctx)
+            if la_ == 1:
+                self.enterOuterAlt(localctx, 1)
+                self.state = 55
+                self._errHandler.sync(self)
+                _la = self._input.LA(1)
+                if _la==4:
+                    self.state = 54
+                    self.match(CMODParser.T__3)
+
+
+                self.state = 57
+                self.structDefinition()
+                pass
+
+            elif la_ == 2:
+                self.enterOuterAlt(localctx, 2)
+                self.state = 59
+                self._errHandler.sync(self)
+                _la = self._input.LA(1)
+                if _la==4:
+                    self.state = 58
+                    self.match(CMODParser.T__3)
+
+
+                self.state = 61
+                self.globalDefinition()
+                pass
+
+            elif la_ == 3:
+                self.enterOuterAlt(localctx, 3)
+                self.state = 63
+                self._errHandler.sync(self)
+                _la = self._input.LA(1)
+                if _la==4:
+                    self.state = 62
+                    self.match(CMODParser.T__3)
+
+
+                self.state = 65
+                self.functionDefinition()
+                pass
+
+            elif la_ == 4:
+                self.enterOuterAlt(localctx, 4)
+                self.state = 66
+                self.match(CMODParser.T__1)
+                pass
+
+
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.exitRule()
+        return localctx
+
+
+    class StructDefinitionContext(ParserRuleContext):
+        __slots__ = 'parser'
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def Identifier(self):
+            return self.getToken(CMODParser.Identifier, 0)
+
+        def structField(self, i:int=None):
+            if i is None:
+                return self.getTypedRuleContexts(CMODParser.StructFieldContext)
+            else:
+                return self.getTypedRuleContext(CMODParser.StructFieldContext,i)
+
+
+        def getRuleIndex(self):
+            return CMODParser.RULE_structDefinition
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterStructDefinition" ):
+                listener.enterStructDefinition(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitStructDefinition" ):
+                listener.exitStructDefinition(self)
+
+
+
+
+    def structDefinition(self):
+
+        localctx = CMODParser.StructDefinitionContext(self, self._ctx, self.state)
+        self.enterRule(localctx, 10, self.RULE_structDefinition)
+        self._la = 0 # Token type
+        try:
+            self.enterOuterAlt(localctx, 1)
+            self.state = 69
+            self.match(CMODParser.T__4)
+            self.state = 70
+            self.match(CMODParser.Identifier)
+            self.state = 71
+            self.match(CMODParser.T__5)
+            self.state = 75
+            self._errHandler.sync(self)
+            _la = self._input.LA(1)
+            while (((_la) & ~0x3f) == 0 and ((1 << _la) & 8522825760) != 0):
+                self.state = 72
+                self.structField()
+                self.state = 77
+                self._errHandler.sync(self)
+                _la = self._input.LA(1)
+
+            self.state = 78
+            self.match(CMODParser.T__6)
+            self.state = 79
+            self.match(CMODParser.T__1)
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.exitRule()
+        return localctx
+
+
+    class StructFieldContext(ParserRuleContext):
+        __slots__ = 'parser'
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def typeSpecifier(self):
+            return self.getTypedRuleContext(CMODParser.TypeSpecifierContext,0)
+
+
+        def declarator(self):
+            return self.getTypedRuleContext(CMODParser.DeclaratorContext,0)
+
+
+        def getRuleIndex(self):
+            return CMODParser.RULE_structField
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterStructField" ):
+                listener.enterStructField(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitStructField" ):
+                listener.exitStructField(self)
+
+
+
+
+    def structField(self):
+
+        localctx = CMODParser.StructFieldContext(self, self._ctx, self.state)
+        self.enterRule(localctx, 12, self.RULE_structField)
+        try:
+            self.enterOuterAlt(localctx, 1)
+            self.state = 81
+            self.typeSpecifier()
+            self.state = 82
+            self.declarator()
+            self.state = 83
+            self.match(CMODParser.T__1)
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.exitRule()
+        return localctx
+
+
+    class GlobalDefinitionContext(ParserRuleContext):
+        __slots__ = 'parser'
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def typeSpecifier(self):
+            return self.getTypedRuleContext(CMODParser.TypeSpecifierContext,0)
+
+
+        def declarator(self):
+            return self.getTypedRuleContext(CMODParser.DeclaratorContext,0)
+
+
+        def expression(self):
+            return self.getTypedRuleContext(CMODParser.ExpressionContext,0)
+
+
+        def getRuleIndex(self):
+            return CMODParser.RULE_globalDefinition
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterGlobalDefinition" ):
+                listener.enterGlobalDefinition(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitGlobalDefinition" ):
+                listener.exitGlobalDefinition(self)
+
+
+
+
+    def globalDefinition(self):
+
+        localctx = CMODParser.GlobalDefinitionContext(self, self._ctx, self.state)
+        self.enterRule(localctx, 14, self.RULE_globalDefinition)
+        self._la = 0 # Token type
+        try:
+            self.enterOuterAlt(localctx, 1)
+            self.state = 85
+            self.typeSpecifier()
+            self.state = 86
+            self.declarator()
+            self.state = 89
+            self._errHandler.sync(self)
+            _la = self._input.LA(1)
+            if _la==8:
+                self.state = 87
+                self.match(CMODParser.T__7)
+                self.state = 88
+                self.expression(0)
+
+
+            self.state = 91
+            self.match(CMODParser.T__1)
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.exitRule()
+        return localctx
+
+
+    class FunctionDefinitionContext(ParserRuleContext):
+        __slots__ = 'parser'
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def typeSpecifier(self):
+            return self.getTypedRuleContext(CMODParser.TypeSpecifierContext,0)
+
+
+        def declarator(self):
+            return self.getTypedRuleContext(CMODParser.DeclaratorContext,0)
+
+
+        def compoundStatement(self):
+            return self.getTypedRuleContext(CMODParser.CompoundStatementContext,0)
+
+
+        def parameterList(self):
+            return self.getTypedRuleContext(CMODParser.ParameterListContext,0)
+
+
+        def getRuleIndex(self):
+            return CMODParser.RULE_functionDefinition
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterFunctionDefinition" ):
+                listener.enterFunctionDefinition(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitFunctionDefinition" ):
+                listener.exitFunctionDefinition(self)
+
+
+
+
+    def functionDefinition(self):
+
+        localctx = CMODParser.FunctionDefinitionContext(self, self._ctx, self.state)
+        self.enterRule(localctx, 16, self.RULE_functionDefinition)
+        self._la = 0 # Token type
+        try:
+            self.enterOuterAlt(localctx, 1)
+            self.state = 93
+            self.typeSpecifier()
+            self.state = 94
+            self.declarator()
+            self.state = 95
+            self.match(CMODParser.T__8)
+            self.state = 97
+            self._errHandler.sync(self)
+            _la = self._input.LA(1)
+            if (((_la) & ~0x3f) == 0 and ((1 << _la) & 8522825760) != 0):
+                self.state = 96
+                self.parameterList()
+
+
+            self.state = 99
+            self.match(CMODParser.T__9)
+            self.state = 100
+            self.compoundStatement()
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.exitRule()
+        return localctx
+
+
+    class ParameterListContext(ParserRuleContext):
+        __slots__ = 'parser'
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def typeSpecifier(self, i:int=None):
+            if i is None:
+                return self.getTypedRuleContexts(CMODParser.TypeSpecifierContext)
+            else:
+                return self.getTypedRuleContext(CMODParser.TypeSpecifierContext,i)
+
+
+        def declarator(self, i:int=None):
+            if i is None:
+                return self.getTypedRuleContexts(CMODParser.DeclaratorContext)
+            else:
+                return self.getTypedRuleContext(CMODParser.DeclaratorContext,i)
+
+
+        def getRuleIndex(self):
+            return CMODParser.RULE_parameterList
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterParameterList" ):
+                listener.enterParameterList(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitParameterList" ):
+                listener.exitParameterList(self)
+
+
+
+
+    def parameterList(self):
+
+        localctx = CMODParser.ParameterListContext(self, self._ctx, self.state)
+        self.enterRule(localctx, 18, self.RULE_parameterList)
+        self._la = 0 # Token type
+        try:
+            self.enterOuterAlt(localctx, 1)
+            self.state = 102
+            self.typeSpecifier()
+            self.state = 103
+            self.declarator()
+            self.state = 110
+            self._errHandler.sync(self)
+            _la = self._input.LA(1)
+            while _la==11:
+                self.state = 104
+                self.match(CMODParser.T__10)
+                self.state = 105
+                self.typeSpecifier()
+                self.state = 106
+                self.declarator()
+                self.state = 112
+                self._errHandler.sync(self)
+                _la = self._input.LA(1)
+
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.exitRule()
+        return localctx
+
+
+    class CompoundStatementContext(ParserRuleContext):
+        __slots__ = 'parser'
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def statement(self, i:int=None):
+            if i is None:
+                return self.getTypedRuleContexts(CMODParser.StatementContext)
+            else:
+                return self.getTypedRuleContext(CMODParser.StatementContext,i)
+
+
+        def getRuleIndex(self):
+            return CMODParser.RULE_compoundStatement
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterCompoundStatement" ):
+                listener.enterCompoundStatement(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitCompoundStatement" ):
+                listener.exitCompoundStatement(self)
+
+
+
+
+    def compoundStatement(self):
+
+        localctx = CMODParser.CompoundStatementContext(self, self._ctx, self.state)
+        self.enterRule(localctx, 20, self.RULE_compoundStatement)
+        self._la = 0 # Token type
+        try:
+            self.enterOuterAlt(localctx, 1)
+            self.state = 113
+            self.match(CMODParser.T__5)
+            self.state = 117
+            self._errHandler.sync(self)
+            _la = self._input.LA(1)
+            while (((_la) & ~0x3f) == 0 and ((1 << _la) & 68685921120) != 0):
+                self.state = 114
+                self.statement()
+                self.state = 119
+                self._errHandler.sync(self)
+                _la = self._input.LA(1)
+
+            self.state = 120
+            self.match(CMODParser.T__6)
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.exitRule()
+        return localctx
+
+
+    class StatementContext(ParserRuleContext):
+        __slots__ = 'parser'
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def expression(self):
+            return self.getTypedRuleContext(CMODParser.ExpressionContext,0)
+
+
+        def getRuleIndex(self):
+            return CMODParser.RULE_statement
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterStatement" ):
+                listener.enterStatement(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitStatement" ):
+                listener.exitStatement(self)
+
+
+
+
+    def statement(self):
+
+        localctx = CMODParser.StatementContext(self, self._ctx, self.state)
+        self.enterRule(localctx, 22, self.RULE_statement)
+        try:
+            self.enterOuterAlt(localctx, 1)
+            self.state = 122
+            self.expression(0)
+            self.state = 123
+            self.match(CMODParser.T__1)
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.exitRule()
+        return localctx
+
+
+    class ExpressionContext(ParserRuleContext):
+        __slots__ = 'parser'
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def expression(self, i:int=None):
+            if i is None:
+                return self.getTypedRuleContexts(CMODParser.ExpressionContext)
+            else:
+                return self.getTypedRuleContext(CMODParser.ExpressionContext,i)
+
+
+        def StringLiteral(self):
+            return self.getToken(CMODParser.StringLiteral, 0)
+
+        def Number(self):
+            return self.getToken(CMODParser.Number, 0)
+
+        def typeSpecifier(self):
+            return self.getTypedRuleContext(CMODParser.TypeSpecifierContext,0)
+
+
+        def Identifier(self):
+            return self.getToken(CMODParser.Identifier, 0)
+
+        def getRuleIndex(self):
+            return CMODParser.RULE_expression
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterExpression" ):
+                listener.enterExpression(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitExpression" ):
+                listener.exitExpression(self)
+
+
+
+    def expression(self, _p:int=0):
+        _parentctx = self._ctx
+        _parentState = self.state
+        localctx = CMODParser.ExpressionContext(self, self._ctx, _parentState)
+        _prevctx = localctx
+        _startState = 24
+        self.enterRecursionRule(localctx, 24, self.RULE_expression, _p)
+        try:
+            self.enterOuterAlt(localctx, 1)
+            self.state = 162
+            self._errHandler.sync(self)
+            token = self._input.LA(1)
+            if token in [11]:
+                self.state = 126
+                self.match(CMODParser.T__10)
+                pass
+            elif token in [12]:
+                self.state = 127
+                self.match(CMODParser.T__11)
+                pass
+            elif token in [13]:
+                self.state = 128
+                self.match(CMODParser.T__12)
+                pass
+            elif token in [14]:
+                self.state = 129
+                self.match(CMODParser.T__13)
+                pass
+            elif token in [15]:
+                self.state = 130
+                self.match(CMODParser.T__14)
+                pass
+            elif token in [16]:
+                self.state = 131
+                self.match(CMODParser.T__15)
+                pass
+            elif token in [17]:
+                self.state = 132
+                self.match(CMODParser.T__16)
+                pass
+            elif token in [18]:
+                self.state = 133
+                self.match(CMODParser.T__17)
+                pass
+            elif token in [19]:
+                self.state = 134
+                self.match(CMODParser.T__18)
+                pass
+            elif token in [20]:
+                self.state = 135
+                self.match(CMODParser.T__19)
+                pass
+            elif token in [21]:
+                self.state = 136
+                self.match(CMODParser.T__20)
+                pass
+            elif token in [8]:
+                self.state = 137
+                self.match(CMODParser.T__7)
+                pass
+            elif token in [22]:
+                self.state = 138
+                self.match(CMODParser.T__21)
+                pass
+            elif token in [23]:
+                self.state = 139
+                self.match(CMODParser.T__22)
+                pass
+            elif token in [9]:
+                self.state = 140
+                self.match(CMODParser.T__8)
+                self.state = 141
+                self.expression(0)
+                self.state = 142
+                self.match(CMODParser.T__9)
+                pass
+            elif token in [24]:
+                self.state = 144
+                self.match(CMODParser.T__23)
+                self.state = 145
+                self.expression(0)
+                self.state = 146
+                self.match(CMODParser.T__24)
+                pass
+            elif token in [6]:
+                self.state = 148
+                self.match(CMODParser.T__5)
+                self.state = 149
+                self.expression(0)
+                self.state = 150
+                self.match(CMODParser.T__6)
+                pass
+            elif token in [35]:
+                self.state = 152
+                self.match(CMODParser.StringLiteral)
+                pass
+            elif token in [34]:
+                self.state = 153
+                self.match(CMODParser.Number)
+                pass
+            elif token in [5, 26, 27, 28, 29, 30, 31, 32]:
+                self.state = 154
+                self.typeSpecifier()
+                self.state = 158
+                self._errHandler.sync(self)
+                _alt = self._interp.adaptivePredict(self._input,11,self._ctx)
+                while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
+                    if _alt==1:
+                        self.state = 155
+                        self.match(CMODParser.T__13) 
+                    self.state = 160
+                    self._errHandler.sync(self)
+                    _alt = self._interp.adaptivePredict(self._input,11,self._ctx)
+
+                pass
+            elif token in [33]:
+                self.state = 161
+                self.match(CMODParser.Identifier)
+                pass
+            else:
+                raise NoViableAltException(self)
+
+            self._ctx.stop = self._input.LT(-1)
+            self.state = 168
+            self._errHandler.sync(self)
+            _alt = self._interp.adaptivePredict(self._input,13,self._ctx)
+            while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
+                if _alt==1:
+                    if self._parseListeners is not None:
+                        self.triggerExitRuleEvent()
+                    _prevctx = localctx
+                    localctx = CMODParser.ExpressionContext(self, _parentctx, _parentState)
+                    self.pushNewRecursionContext(localctx, _startState, self.RULE_expression)
+                    self.state = 164
+                    if not self.precpred(self._ctx, 22):
+                        from antlr4.error.Errors import FailedPredicateException
+                        raise FailedPredicateException(self, "self.precpred(self._ctx, 22)")
+                    self.state = 165
+                    self.expression(23) 
+                self.state = 170
+                self._errHandler.sync(self)
+                _alt = self._interp.adaptivePredict(self._input,13,self._ctx)
+
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.unrollRecursionContexts(_parentctx)
+        return localctx
+
+
+    class TypeSpecifierContext(ParserRuleContext):
+        __slots__ = 'parser'
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def Identifier(self):
+            return self.getToken(CMODParser.Identifier, 0)
+
+        def getRuleIndex(self):
+            return CMODParser.RULE_typeSpecifier
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterTypeSpecifier" ):
+                listener.enterTypeSpecifier(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitTypeSpecifier" ):
+                listener.exitTypeSpecifier(self)
+
+
+
+
+    def typeSpecifier(self):
+
+        localctx = CMODParser.TypeSpecifierContext(self, self._ctx, self.state)
+        self.enterRule(localctx, 26, self.RULE_typeSpecifier)
+        try:
+            self.state = 180
+            self._errHandler.sync(self)
+            token = self._input.LA(1)
+            if token in [26]:
+                self.enterOuterAlt(localctx, 1)
+                self.state = 171
+                self.match(CMODParser.T__25)
+                pass
+            elif token in [27]:
+                self.enterOuterAlt(localctx, 2)
+                self.state = 172
+                self.match(CMODParser.T__26)
+                pass
+            elif token in [28]:
+                self.enterOuterAlt(localctx, 3)
+                self.state = 173
+                self.match(CMODParser.T__27)
+                pass
+            elif token in [29]:
+                self.enterOuterAlt(localctx, 4)
+                self.state = 174
+                self.match(CMODParser.T__28)
+                pass
+            elif token in [30]:
+                self.enterOuterAlt(localctx, 5)
+                self.state = 175
+                self.match(CMODParser.T__29)
+                pass
+            elif token in [31]:
+                self.enterOuterAlt(localctx, 6)
+                self.state = 176
+                self.match(CMODParser.T__30)
+                pass
+            elif token in [32]:
+                self.enterOuterAlt(localctx, 7)
+                self.state = 177
+                self.match(CMODParser.T__31)
+                pass
+            elif token in [5]:
+                self.enterOuterAlt(localctx, 8)
+                self.state = 178
+                self.match(CMODParser.T__4)
+                self.state = 179
+                self.match(CMODParser.Identifier)
+                pass
+            else:
+                raise NoViableAltException(self)
+
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.exitRule()
+        return localctx
+
+
+    class DeclaratorContext(ParserRuleContext):
+        __slots__ = 'parser'
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def Identifier(self):
+            return self.getToken(CMODParser.Identifier, 0)
+
+        def getRuleIndex(self):
+            return CMODParser.RULE_declarator
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterDeclarator" ):
+                listener.enterDeclarator(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitDeclarator" ):
+                listener.exitDeclarator(self)
+
+
+
+
+    def declarator(self):
+
+        localctx = CMODParser.DeclaratorContext(self, self._ctx, self.state)
+        self.enterRule(localctx, 28, self.RULE_declarator)
+        self._la = 0 # Token type
+        try:
+            self.enterOuterAlt(localctx, 1)
+            self.state = 183
+            self._errHandler.sync(self)
+            _la = self._input.LA(1)
+            if _la==14:
+                self.state = 182
+                self.match(CMODParser.T__13)
+
+
+            self.state = 185
+            self.match(CMODParser.Identifier)
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.exitRule()
+        return localctx
+
+
+
+    def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int):
+        if self._predicates == None:
+            self._predicates = dict()
+        self._predicates[12] = self.expression_sempred
+        pred = self._predicates.get(ruleIndex, None)
+        if pred is None:
+            raise Exception("No predicate with index:" + str(ruleIndex))
+        else:
+            return pred(localctx, predIndex)
+
+    def expression_sempred(self, localctx:ExpressionContext, predIndex:int):
+            if predIndex == 0:
+                return self.precpred(self._ctx, 22)
+         
+
+
+
+
Index: doc/proposals/modules-alvin/3_implementation_details/prototype/requirements.txt
===================================================================
--- doc/proposals/modules-alvin/3_implementation_details/prototype/requirements.txt	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
+++ doc/proposals/modules-alvin/3_implementation_details/prototype/requirements.txt	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
@@ -0,0 +1,1 @@
+antlr4-python3-runtime==4.13.2
Index: doc/proposals/modules-alvin/3_implementation_details/prototype/testing/a.cmod
===================================================================
--- doc/proposals/modules-alvin/3_implementation_details/prototype/testing/a.cmod	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
+++ doc/proposals/modules-alvin/3_implementation_details/prototype/testing/a.cmod	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
@@ -0,0 +1,11 @@
+module A;
+
+import Basic;
+
+export struct S foo(int i, int j, int k) {
+    struct S s;
+    s.i = i;
+    s.j = j;
+    s.k = f(k);
+    return s;
+}
Index: doc/proposals/modules-alvin/3_implementation_details/prototype/testing/basic.cmod
===================================================================
--- doc/proposals/modules-alvin/3_implementation_details/prototype/testing/basic.cmod	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
+++ doc/proposals/modules-alvin/3_implementation_details/prototype/testing/basic.cmod	(revision a9049dd64205261c925e9c9e1b7b6ef7b1da8073)
@@ -0,0 +1,24 @@
+module Basic;
+
+export struct S {
+    int i;
+    int j;
+    struct SS k;
+};
+
+struct SS {
+    struct S *a;
+    float b;
+};
+
+export struct SS f(int i) {
+    struct SS ss;
+    ss.b = ff(i);
+    return ss;
+}
+
+float ff(int i) {
+    return (float) i + j;
+}
+
+float j = 4.4;
