deimos-lang/sketching/november_2025/rail.dm
2025-11-10 16:32:19 -06:00

128 lines
2.7 KiB
Plaintext

ns nr::train
use object::{assign, Props, props!}
pub int Train
name: String
primaryColor: Color
fld destination: String
fld volume: Int
fn blowHorn() -> IO
end
pub enum Color
White,
Blue,
Red
end
pub type Printer = fn (message: String) -> IO
pub fn create(props: obj Props<Train> + { printer: Printer }) -> Train =
SimpleTrain(props).with {
volume = 80
}
class SimpleTrain : Train
props!::<Train>()
printer: Printer
ctor(props: obj Props<Train> + { printer: Printer })
assign(self, props)
end
impl fn blowHorn() -> IO
printer("Train ${name} is blowing its horn at volume ${volume}!")
end
end
pub fn createViaObj(props: obj Props<Train>, printer: Printer) -> obj Train
obj {
...props,
printer,
blowHorn: fn () -> IO
printer("Dynamic object Train ${train} is blowing its horn at volume ${self.volume}!")
end
}
end
// props lib file
ns std::core::object
pub fn assign(target: obj, source: obj)
for [key, value] source.props() do
target[key] = value
end
end
pub type Props<T> = obj {
[K in keyof T]: T[K]
}
pub macro fn <T> props!(_: TokenStream) -> TokenStream
let result = TokenStream()
for [key, type] in std::intrinsics::propsAndTypes::<T>() do
result << quote! {
#key: #type
}
end
result
end
// io lib file
ns std::core
pub enum IO<S : Stream = Stream, E = Error> : fn () -> IO<S, E>
Success(stream: S)
impl ()
try
doCall(stream)
catch (e: E)
Failure(e)
end
end
end,
Failure(_)
impl ()
self
end
end;
int
fn <Z : Stream = S> doCall(stream: S) -> IO<Z, E>
end
end
// main example file
ns nr::example
use nr::train::{create, createViaObj, Train, Color}
fn main()
let train = create(obj {
name: 'Test Train',
primaryColor: Color::Blue,
destination: 'Nonavosa Central',
printer: println
})
train.blowHorn()
train.volume = 100
train.blowHorn()
let objTrain: obj Train = createViaObj(obj {
name: 'Obj Train',
primaryColor: Color::Red,
destination: 'Durandana',
printer: println
})
// Since it's an obj, we can dynamically add properties and override methods, similar to JS
objTrain.secondaryColor = Color::White
let originalBlowHorn = objTrain.blowHorn
objTrain.blowHorn = fn ()
originalBlowHorn()
println "Hello again! The train's colors are ${self.primaryColor} and ${self.secondaryColor}!"
end
objTrain.blowHorn()
end