4.0 KiB
4.0 KiB
TODO/Plans
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:
Here,decl pub ns std { decl pub ns core, http, json decl ns internal }
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 insidedstd
, so are referenced likestd::core
,std::http
, etc. The non-pub
namespaceinternal
is readable from within the namespacestd
, 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:
In this example, the namespacens std::core pub fn foo() = bar::baz() ns bar { fn baz = hello() prv fn hello = println("Hello, World!") }
bar
is accesible from the rest of the file, but not outside of it. The functionbar::baz
can be called by withinfoo
, buthello
, being private tobar
, can only be called bybaz
.
- A module corresponds to one syntactical namespace
- Once the namespaces to be compiled have been computed, create a
DmModule
for each namespace. - For each
CompilationUnit
, associate it to the correctDmModule
, and transform its declarations into the appropriate objects, such asDmInterface
,DmImplementation
,DmFunction
, orDmConstant
. - 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 insidestd::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]