aboutsummaryrefslogtreecommitdiff
path: root/docs/notes/modules.txt
blob: 14df4a1c2c561233aeb3b48a2c4bdd9e3fbdc751 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131


Modules
-------

TODO:
  * update this text!
  * consider what will happen if "make" rewrites the filenames but not the -r
    option. Does "make" rewrite file names ever? When run with "make -f" ?
    

1. Importing a module
---------------------

Approach A: Implicit import

    int f() {
        return system:errno;
    }

    
    pros:
      * Least amount of typing/effort required.
    
    cons:
      * Error prone. What if system is misspelled? 
      * Makes the compilation process more complicated. All unidentified
        identifiers have to be searched for on the file system (in case
        they are modules).


Approach B: Explicit import in source files

    import system;
    
    int f() {
        return system:errno;
    }

    
    pros:
      * Only one line per module and submodule is needed.
    
    cons:
      * After parsing, the compiler has to check if more files have to
        be loaded.

Approach C: Explicit import in module files

    source file:
    
        int f() {
            return system:errno;
        }
    
    module file:
    
        [imports]
        system

    pros:
      * Easiest to implement?
    
    cons:
      * All symbols are imported in all files.
    

2. Nested modules in directories
--------------------------------

Approach A: Modules specified on the command-line

    pros:
      * Easiest to implement?
      * Most similar to C.
      * Can work with the other options, too.
    
    cons:
      * Needs a build system.


Approach B: Put a "project file" in the root
    
    pros:
      * Only one file needed per project
    
    cons:
      * Possible to accidentally include modules in the parent directories.
        This could possibly be abused by malicious users.
      * Does not scale for large codebases.


Approach C: Put a "module file" in each directory
    
    The module file can say whether is the root module or not.
    
    pros:
      * Module configuration is kept in directories.
      * Prevents accidental/malicious inclusion of modules in parent
        directories.
    
    cons:
      * More files needed.


3. Algorithm for compiling a module
-----------------------------------

When compiling a module (a source file):

    Parse the header file, with the namespace derived from its path.
    
    Parse the main source file, with the namespace derived from its path.
    
    Check that incomplete types in the header agree with those in the main
    source file.
    
    For each imported module:
        
        If the module hasn't been imported already:
            
            Parse its header file, into a namespace derived from its path.
    
    
    Process the file (bind identifiers, check types, generate
    IR or object code...)
    
    Clean up by removing the namespace of the main source file, and keep
    the namespaces of the header files in case they will be used by modules
    that will be compiled later.