2019-02-04 20:29:04 -06:00
|
|
|
// Assert that a value is a tuple. Generate a compile failure if it is not.
|
2019-01-24 20:04:40 -06:00
|
|
|
let assert_tuple = func (tpl) => select tpl is "tuple", NULL, {
|
2019-01-19 13:06:43 -06:00
|
|
|
false = fail "@ is not a tuple" % (tpl),
|
|
|
|
};
|
2019-01-09 22:25:11 -06:00
|
|
|
|
2019-02-04 20:29:04 -06:00
|
|
|
// Return a list of the fields in a tuple.
|
2019-01-09 22:25:11 -06:00
|
|
|
let fields = module{
|
|
|
|
tpl = NULL,
|
|
|
|
} => {
|
2019-01-19 13:06:43 -06:00
|
|
|
let assert_tuple = import "std/tuples.ucg".assert_tuple;
|
|
|
|
// First we check that mod.tpl is a tuple.
|
|
|
|
assert_tuple(mod.tpl);
|
|
|
|
|
2019-02-04 19:48:51 -06:00
|
|
|
let result = reduce(func (acc, field, value) => acc + [field], [], (mod.tpl));
|
2019-01-09 22:25:11 -06:00
|
|
|
};
|
|
|
|
|
2019-02-04 20:29:04 -06:00
|
|
|
// Return a list of the values in a tuple.
|
2019-01-09 22:25:11 -06:00
|
|
|
let values = module{
|
|
|
|
tpl = NULL,
|
|
|
|
} => {
|
2019-01-19 13:06:43 -06:00
|
|
|
let assert_tuple = import "std/tuples.ucg".assert_tuple;
|
|
|
|
// First we check that mod.tpl is a tuple.
|
|
|
|
assert_tuple(mod.tpl);
|
|
|
|
|
2019-02-04 19:48:51 -06:00
|
|
|
let result = reduce(func (acc, field, value) => acc + [value], [], (mod.tpl));
|
2019-01-09 22:33:03 -06:00
|
|
|
};
|
|
|
|
|
2019-02-04 20:29:04 -06:00
|
|
|
// Return a list of the key value pairs in the tuple.
|
2019-01-13 21:24:35 -06:00
|
|
|
let iter = module{
|
2019-01-09 22:33:03 -06:00
|
|
|
tpl = NULL,
|
|
|
|
} => {
|
2019-01-19 13:06:43 -06:00
|
|
|
let assert_tuple = import "std/tuples.ucg".assert_tuple;
|
|
|
|
// First we check that mod.tpl is a tuple.
|
|
|
|
assert_tuple(mod.tpl);
|
|
|
|
|
2019-02-04 19:48:51 -06:00
|
|
|
let result = reduce(func (acc, field, value) => acc + [[field, value]], [], (mod.tpl));
|
2019-01-15 19:31:55 -06:00
|
|
|
};
|
|
|
|
|
2019-02-04 20:29:04 -06:00
|
|
|
// Strip all the null fields from a tuple.
|
2019-01-15 19:31:55 -06:00
|
|
|
let strip_nulls = module{
|
|
|
|
tpl = NULL,
|
|
|
|
} => {
|
2019-01-19 13:06:43 -06:00
|
|
|
let assert_tuple = import "std/tuples.ucg".assert_tuple;
|
|
|
|
// First we check that mod.tpl is a tuple.
|
|
|
|
assert_tuple(mod.tpl);
|
|
|
|
|
2019-02-04 19:48:51 -06:00
|
|
|
let result = filter(func (name, value) => value != NULL, (mod.tpl));
|
2019-01-19 13:06:43 -06:00
|
|
|
};
|
|
|
|
|
2019-02-04 20:29:04 -06:00
|
|
|
// Check if a tuple has all the fields in a given list.
|
2019-01-19 13:06:43 -06:00
|
|
|
let has_fields = module{
|
|
|
|
tpl = NULL,
|
|
|
|
fields = [],
|
|
|
|
} => {
|
|
|
|
let lib = import "std/tuples.ucg";
|
|
|
|
// First we check that mod.tpl is a tuple.
|
|
|
|
lib.assert_tuple(mod.tpl);
|
|
|
|
|
|
|
|
let fs = lib.fields{tpl=mod.tpl}.result;
|
|
|
|
|
2019-02-04 19:48:51 -06:00
|
|
|
let result = reduce(reducer = func (acc, f) => acc && (f in fs), true, (mod.fields));
|
2019-01-19 13:06:43 -06:00
|
|
|
};
|
|
|
|
|
2019-02-04 20:29:04 -06:00
|
|
|
// Check if a field in a tuple is a given type.
|
2019-01-19 13:06:43 -06:00
|
|
|
let field_type = module{
|
|
|
|
tpl = NULL,
|
|
|
|
field = NULL,
|
|
|
|
type = NULL,
|
|
|
|
} => {
|
|
|
|
let lib = import "std/tuples.ucg";
|
|
|
|
// First we check that mod.tpl is a tuple.
|
|
|
|
lib.assert_tuple(mod.tpl);
|
|
|
|
|
|
|
|
// Next we assert that mod.field is a string.
|
|
|
|
select mod.field is "str", NULL, {
|
|
|
|
false = fail "@ is not a string" % (mod.field),
|
|
|
|
};
|
|
|
|
|
|
|
|
// and finally that mod.type is a string
|
|
|
|
select mod.type is "str", NULL, {
|
|
|
|
false = fail "@ is not a string" % (mod.type),
|
|
|
|
};
|
|
|
|
|
2019-02-04 20:29:04 -06:00
|
|
|
// Get the list of field value pairs.
|
2019-01-19 13:06:43 -06:00
|
|
|
let it = lib.iter{tpl=mod.tpl}.result;
|
2019-02-04 20:29:04 -06:00
|
|
|
|
|
|
|
// The reducer function used to check the field's types if it exists.
|
2019-01-24 20:04:40 -06:00
|
|
|
let reducer = func (acc, l) => acc && (select l.0 == mod.field, NULL, {
|
2019-01-19 13:06:43 -06:00
|
|
|
true = l.1 is mod.type, // if this is the field then we propagate if it's the right type.
|
|
|
|
false = true, // if this isn't the field then we propagate true
|
|
|
|
});
|
|
|
|
|
2019-02-04 20:29:04 -06:00
|
|
|
// The computed answer true or false.
|
2019-02-04 19:48:51 -06:00
|
|
|
let result = lib.has_fields{tpl=mod.tpl, fields=[mod.field]}.result && reduce(reducer, true, it);
|
2019-01-09 22:25:11 -06:00
|
|
|
};
|