forked from tweag/nickel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstdlib.rs
87 lines (76 loc) · 2.77 KB
/
stdlib.rs
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
//! Load the Nickel standard library in strings at compile-time.
use crate::term::make as mk_term;
use crate::term::RichTerm;
/// This is an array containing all the Nickel standard library modules. Currently, this is one
/// monolithic `std` module, and the definitions of `internals` living at the toplevel.
///
/// Using a dedicated enum tpe, handling arrays, etc. for two modules can seem a bit overkill, but
/// we'll probably extend `StdlibModule` when we'll split the `std` module into several files.
pub fn modules() -> [StdlibModule; 2] {
[StdlibModule::Std, StdlibModule::Internals]
}
/// Represents a particular Nickel standard library module.
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub enum StdlibModule {
Std,
Internals,
}
impl StdlibModule {
pub fn file_name(&self) -> &'static str {
match self {
StdlibModule::Std => "<stdlib/std.ncl>",
StdlibModule::Internals => "<stdlib/internals.ncl>",
}
}
/// The name of the module. Used to determine its namespace in the initial environment (the
/// module named `std` will be put under the `std` identifier). `StdlibModule::Internals` is an
/// exception, because although it has a name, it's not put under any namespace but directly at
/// top-level in the environment.
pub fn name(&self) -> &'static str {
match self {
StdlibModule::Std => "std",
StdlibModule::Internals => "internals",
}
}
pub fn content(&self) -> &'static str {
match self {
StdlibModule::Std => include_str!("../stdlib/std.ncl"),
StdlibModule::Internals => include_str!("../stdlib/internals.ncl"),
}
}
}
pub struct UnknownStdlibModule;
macro_rules! generate_accessor {
($value:ident) => {
pub fn $value() -> RichTerm {
mk_term::var(format!("${}", stringify!($value)))
}
};
}
/// Accessors to the builtin contracts and other internals that aren't accessible from user code.
pub mod internals {
use super::*;
// `dyn` is a reserved keyword in rust
pub fn dynamic() -> RichTerm {
mk_term::var("$dyn")
}
generate_accessor!(num);
generate_accessor!(bool);
generate_accessor!(string);
generate_accessor!(array);
generate_accessor!(func);
generate_accessor!(forall_var);
generate_accessor!(forall);
generate_accessor!(fail);
generate_accessor!(enums);
generate_accessor!(enum_fail);
generate_accessor!(record);
generate_accessor!(dyn_record);
generate_accessor!(record_extend);
generate_accessor!(forall_tail);
generate_accessor!(dyn_tail);
generate_accessor!(empty_tail);
generate_accessor!(stdlib_contract_equal);
generate_accessor!(rec_default);
generate_accessor!(rec_force);
}