Make Inspect a builtin

This commit is contained in:
Richard Feldman 2023-08-10 21:23:52 -04:00
parent 75f6293e12
commit 700776fad7
No known key found for this signature in database
GPG key ID: F1F21AA5B1D9E43B
14 changed files with 63 additions and 29 deletions

View file

@ -0,0 +1,92 @@
interface Inspect
exposes [
Inspect,
Inspector,
InspectFormatter,
ElemWalker,
KeyValWalker,
inspect,
init,
list,
set,
dict,
tag,
tuple,
record,
bool,
str,
opaque,
u8,
i8,
u16,
i16,
u32,
i32,
u64,
i64,
u128,
i128,
f32,
f64,
dec,
custom,
apply,
toInspector,
]
imports [
Bool.{ Bool },
Num.{ U8, U16, U32, U64, U128, I8, I16, I32, I64, I128, F32, F64, Dec },
]
KeyValWalker state collection key val : collection, state, (state, key, val -> state) -> state
ElemWalker state collection elem : collection, state, (state, elem -> state) -> state
InspectFormatter has
init : {} -> f | f has InspectFormatter
tag : Str, List (Inspector f) -> Inspector f | f has InspectFormatter
tuple : List (Inspector f) -> Inspector f | f has InspectFormatter
record : List { key : Str, value : Inspector f } -> Inspector f | f has InspectFormatter
bool : Bool -> Inspector f | f has InspectFormatter
str : Str -> Inspector f | f has InspectFormatter
list : list, ElemWalker state list elem, (elem -> Inspector f) -> Inspector f | f has InspectFormatter
set : set, ElemWalker state set elem, (elem -> Inspector f) -> Inspector f | f has InspectFormatter
dict : dict, KeyValWalker state dict key value, (key -> Inspector f), (value -> Inspector f) -> Inspector f | f has InspectFormatter
# Note opaque is used for both opaque types and functions.
# The auto deriver for functions probably could put the function type.
# For regular opaque types, I think we can use the type name, though that may lead to some reflection related issues that still need to be discussed.
# As a simple baseline, it can just use the exact words `opaque` and `function` for now.
# In text, this would render as `<opaque>`, `<function>`, etc
opaque : Str -> Inspector f | f has InspectFormatter
u8 : U8 -> Inspector f | f has InspectFormatter
i8 : I8 -> Inspector f | f has InspectFormatter
u16 : U16 -> Inspector f | f has InspectFormatter
i16 : I16 -> Inspector f | f has InspectFormatter
u32 : U32 -> Inspector f | f has InspectFormatter
i32 : I32 -> Inspector f | f has InspectFormatter
u64 : U64 -> Inspector f | f has InspectFormatter
i64 : I64 -> Inspector f | f has InspectFormatter
u128 : U128 -> Inspector f | f has InspectFormatter
i128 : I128 -> Inspector f | f has InspectFormatter
f32 : F32 -> Inspector f | f has InspectFormatter
f64 : F64 -> Inspector f | f has InspectFormatter
dec : Dec -> Inspector f | f has InspectFormatter
Inspector f := f -> f | f has InspectFormatter
custom : (f -> f) -> Inspector f | f has InspectFormatter
custom = @Inspector
apply : Inspector f, f -> f | f has InspectFormatter
apply = \@Inspector fn, fmt -> fn fmt
Inspect has
toInspector : val -> Inspector f | val has Inspect, f has InspectFormatter
inspect : val -> f | val has Inspect, f has InspectFormatter
inspect = \val ->
(@Inspector valFn) = toInspector val
valFn (init {})

View file

@ -15,6 +15,7 @@ pub fn module_source(module_id: ModuleId) -> &'static str {
ModuleId::ENCODE => ENCODE,
ModuleId::DECODE => DECODE,
ModuleId::HASH => HASH,
ModuleId::INSPECT => INSPECT,
ModuleId::JSON => JSON,
_ => internal_error!(
"ModuleId {:?} is not part of the standard library",
@ -34,4 +35,5 @@ const BOOL: &str = include_str!("../roc/Bool.roc");
const ENCODE: &str = include_str!("../roc/Encode.roc");
const DECODE: &str = include_str!("../roc/Decode.roc");
const HASH: &str = include_str!("../roc/Hash.roc");
const INSPECT: &str = include_str!("../roc/Inspect.roc");
const JSON: &str = include_str!("../roc/TotallyNotJson.roc");

View file

@ -25,6 +25,7 @@ const MODULES: &[(ModuleId, &str)] = &[
(ModuleId::ENCODE, "Encode.roc"),
(ModuleId::DECODE, "Decode.roc"),
(ModuleId::HASH, "Hash.roc"),
(ModuleId::INSPECT, "Inspect.roc"),
(ModuleId::JSON, "TotallyNotJson.roc"),
];

View file

@ -212,6 +212,7 @@ const BOX: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/Box.dat")) as &[_];
const ENCODE: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/Encode.dat")) as &[_];
const DECODE: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/Decode.dat")) as &[_];
const HASH: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/Hash.dat")) as &[_];
const INSPECT: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/Inspect.dat")) as &[_];
fn deserialize_help(bytes: &[u8]) -> TypeState {
let (state, _offset) = TypeState::deserialize(bytes);
@ -242,6 +243,7 @@ fn read_cached_types() -> MutMap<ModuleId, TypeState> {
output.insert(ModuleId::DECODE, deserialize_help(DECODE));
output.insert(ModuleId::HASH, deserialize_help(HASH));
output.insert(ModuleId::INSPECT, deserialize_help(INSPECT));
}
output

View file

@ -2290,6 +2290,7 @@ fn update<'a>(
extend_header_with_builtin(header, ModuleId::ENCODE);
extend_header_with_builtin(header, ModuleId::DECODE);
extend_header_with_builtin(header, ModuleId::HASH);
extend_header_with_builtin(header, ModuleId::INSPECT);
}
state
@ -3494,6 +3495,7 @@ fn load_module<'a>(
"Encode", ModuleId::ENCODE
"Decode", ModuleId::DECODE
"Hash", ModuleId::HASH
"Inspect", ModuleId::INSPECT
"TotallyNotJson", ModuleId::JSON
}
@ -5257,6 +5259,7 @@ fn canonicalize_and_constrain<'a>(
| ModuleId::DICT
| ModuleId::SET
| ModuleId::HASH
| ModuleId::INSPECT
);
if !name.is_builtin() || should_include_builtin {

View file

@ -25,5 +25,6 @@ pub const BUILTIN_MODULES: &[(ModuleId, &str)] = &[
(ModuleId::ENCODE, "Encode"),
(ModuleId::DECODE, "Decode"),
(ModuleId::HASH, "Hash"),
(ModuleId::INSPECT, "Inspect"),
(ModuleId::JSON, "TotallyNotJson"),
];

View file

@ -85,6 +85,7 @@ impl Default for ModuleCache<'_> {
ENCODE,
DECODE,
HASH,
INSPECT,
JSON,
}

View file

@ -113,6 +113,7 @@ impl ModuleName {
pub const ENCODE: &'static str = "Encode";
pub const DECODE: &'static str = "Decode";
pub const HASH: &'static str = "Hash";
pub const INSPECT: &'static str = "Inspect";
pub const JSON: &'static str = "TotallyNotJson";
pub fn as_str(&self) -> &str {

View file

@ -1588,9 +1588,43 @@ define_builtins! {
20 HASH_HASH_LIST: "hashList"
21 HASH_HASH_UNORDERED: "hashUnordered"
}
14 JSON: "TotallyNotJson" => {
14 INSPECT: "Inspect" => {
0 INSPECT_INSPECT_ABILITY: "Inspect" exposed_type=true
1 INSPECT_INSPECTOR: "Inspector" exposed_type=true
2 INSPECT_INSPECT_FORMATTER: "InspectFormatter" exposed_type=true
3 INSPECT_ELEM_WALKER: "ElemWalker" exposed_type=true
4 INSPECT_KEY_VAL_WALKER: "KeyValWalker" exposed_type=true
5 INSPECT_INSPECT: "inspect"
6 INSPECT_INIT: "init"
7 INSPECT_LIST: "list"
8 INSPECT_SET: "set"
9 INSPECT_DICT: "dict"
10 INSPECT_TAG: "tag"
11 INSPECT_TUPLE: "tuple"
12 INSPECT_RECORD: "record"
13 INSPECT_BOOL: "bool"
14 INSPECT_STR: "str"
15 INSPECT_OPAQUE: "opaque"
16 INSPECT_U8: "u8"
17 INSPECT_I8: "i8"
18 INSPECT_U16: "u16"
19 INSPECT_I16: "i16"
20 INSPECT_U32: "u32"
21 INSPECT_I32: "i32"
22 INSPECT_U64: "u64"
23 INSPECT_I64: "i64"
24 INSPECT_U128: "u128"
25 INSPECT_I128: "i128"
26 INSPECT_F32: "f32"
27 INSPECT_F64: "f64"
28 INSPECT_DEC: "dec"
29 INSPECT_CUSTOM: "custom"
30 INSPECT_APPLY: "apply"
31 INSPECT_TO_INSPECTOR: "toInspector"
}
15 JSON: "TotallyNotJson" => {
0 JSON_JSON: "TotallyNotJson"
}
num_modules: 15 // Keep this count up to date by hand! (TODO: see the mut_map! macro for how we could determine this count correctly in the macro)
num_modules: 16 // Keep this count up to date by hand! (TODO: see the mut_map! macro for how we could determine this count correctly in the macro)
}