154 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			154 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # TODO/Plans
 | |
| 
 | |
| ## May 2025
 | |
| 
 | |
| - Refactor name-analysis to add custom errors for name-analysis only, which can then be tested.
 | |
| - Refactor `pub` fields of AST structs into private fields accessed by methods.
 | |
| 
 | |
| ## General Pipeline
 | |
| 
 | |
| - Transform a single file into a `CompilationUnit` AST node.
 | |
| - Gather all `CompilationUnit`s and determine which modules need to be built.
 | |
|   - A module corresponds to one syntactical namespace `ns`, but not its children!
 | |
|   - For a namespace to be used as a top-level grouping in a file, it must be declared like so:
 | |
|     ```
 | |
|     decl pub ns std {
 | |
|         decl pub ns core, http, json
 | |
|         decl ns internal
 | |
|     }
 | |
|     ```
 | |
|     Here, `decl` indicates that the namespace is declared for top-level usage in other files. `pub` indicates that the
 | |
|     namespace may be read from other namespaces. `std` here is the identifier for the namespace, and the contents
 | |
|     inside its brackets are child namespaces. The list of child namespaces are all nested insided `std`, so are
 | |
|     referenced like `std::core`, `std::http`, etc. The non-`pub` namespace `internal` is readable from within the
 | |
|     namespace `std`, but not from outside of it.
 | |
|   - A namespace inside a file but not `decl` (declared) can only have members *in that file*. It cannot be used as a
 | |
|     top-level namespace in another file. However, the accessibility rules are similar to top-level namespaces:
 | |
|     ```
 | |
|     ns std::core
 | |
| 
 | |
|     pub fn foo() = bar::baz()
 | |
| 
 | |
|     ns bar {
 | |
|         fn baz = hello()
 | |
|         prv fn hello = println("Hello, World!")
 | |
|     }
 | |
|     ```
 | |
|     In this example, the namespace `bar` is accesible from the rest of the file, but not outside of it. The function
 | |
|     `bar::baz` can be called by within `foo`, but `hello`, being private to `bar`, can only be called by `baz`.
 | |
| - Once the namespaces to be compiled have been computed, create a `DmModule` for each namespace.
 | |
| - For each `CompilationUnit`, associate it to the correct `DmModule`, and transform its declarations into the
 | |
|   appropriate objects, such as `DmInterface`, `DmImplementation`, `DmFunction`, or `DmConstant`.
 | |
| - Thus, a `DmModule` is a single-file containing all the code for one namespace, but not its child namespaces. Using
 | |
|   the above examples, the following DmModules would be created, with their appropriate contents:
 | |
|   - `pub ns std`: *no contents, only metadata.*
 | |
|   - `pub ns std::core`:
 | |
|     - `pub fn std::core::foo`
 | |
|   - `ns std::core::bar`
 | |
|     - `fn std::core::bar::baz`
 | |
|     - `prv fn std::core::bar::hello`: only accessible inside `std::core::bar`.
 | |
| 
 | |
| ## More Namespace Rules
 | |
| 
 | |
| Top-level namespace declaration:
 | |
| 
 | |
| ```
 | |
| decl pub ns std
 | |
| ```
 | |
| 
 | |
| Nested namespace declaration and members:
 | |
| 
 | |
| ```
 | |
| ns std::core // indicates that all members of this file are in the std::core namespace
 | |
| 
 | |
| // Indicates that array is a nested namespace in std::core, and is referencable by std::core::array
 | |
| pub ns array {
 | |
|     pub int SomeInterface
 | |
|     pub cls SomeClass : SomeInterace
 | |
|     pub fn associated_fn() {}
 | |
| }
 | |
| ```
 | |
| 
 | |
| ## Example of std lib would be coded
 | |
| 
 | |
| std/std.dm
 | |
| 
 | |
| ```
 | |
| decl pub ns std {
 | |
|     decl pub ns core, http, json
 | |
|     decl ns internal // only accessible to members of std
 | |
| }
 | |
| ```
 | |
| 
 | |
| std/core/core.dm
 | |
| 
 | |
| ```
 | |
| ns std
 | |
| 
 | |
| /* This declaration is merged with the one in std.dm */
 | |
| decl pub ns core {
 | |
|     decl pub ns hkt
 | |
| }
 | |
| ```
 | |
| 
 | |
| std/core/array.dm
 | |
| 
 | |
| ```
 | |
| ns std::core
 | |
| 
 | |
| use std::core::hkt::Monad
 | |
| 
 | |
| pub int Array<T> : Monad<List>[T] {}
 | |
| 
 | |
| impl ByteArray(fld raw_address: USize, fld count: USize) : Array<Byte> {
 | |
| 
 | |
|     impl fn map(fab) {
 | |
|         let mut rs = List(count) // dynamic list?
 | |
|         for (let i in 0..count) {
 | |
|             rs << fab(std::internal::mem::get_byte(raw_address + i))
 | |
|         }
 | |
|         rs
 | |
|     }
 | |
| 
 | |
|     impl fn flat_map(fab) {
 | |
|         let mut rs = []
 | |
|         for (let i in 0..count) {
 | |
|             rs << fab(std::internal::mem::get_byte(raw_address + i))
 | |
|         }
 | |
|         rs.flatten()
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 | |
| pub ns array {
 | |
| 
 | |
|     extern fn _of(ts: ...T): Array<T>
 | |
| 
 | |
|     pub fn <T> of(ts: ...T) = _of(ts)
 | |
| 
 | |
| }
 | |
| ```
 | |
| 
 | |
| std/core/hkt/monad.dm
 | |
| 
 | |
| ```
 | |
| ns std::core::hkt
 | |
| 
 | |
| pub hkt Monad<T = Self>[a] {
 | |
|     fn [b] map(fab: a -> b) -> T[b]
 | |
|     fn [b] flat_map(fab: a -> T[b]) -> T[b]
 | |
| 
 | |
|     def op fn pipe(fab: a -> b) -> T[b] = map(fab)
 | |
|     def op fn pipe(fab: a -> T[b]) -> T[b] = flat_map(fab)
 | |
| }
 | |
| ```
 | |
| 
 | |
| std/core/string.dm
 | |
| 
 | |
| ```
 | |
| ns std::core
 | |
| 
 | |
| pub int String : Monad<List>[Char]
 | |
| ```
 | |
| 
 | 
