REFACTOR: Stdlib now uses the out expression syntax or modules.

This commit is contained in:
Jeremy Wall 2019-02-24 08:16:07 -06:00
parent 1604981a5c
commit ec8c75f866
8 changed files with 48 additions and 48 deletions

View File

@ -7,7 +7,7 @@ let str_join = module{
sep=" ",
// The list is a required parameter.
list=NULL,
} => {
} => (result) {
// The function used by reduce to join the list into a string.
let joiner = func (acc, item) => select (acc.out == ""), NULL, {
true = acc{
@ -40,7 +40,7 @@ let enumerate = module{
step = 1,
// The list to enumerate.
list = NULL,
} => {
} => (result) {
let reducer = func (acc, item) => acc{
count = acc.count + acc.step,
list=acc.list + [[acc.count, item]],
@ -58,7 +58,7 @@ let enumerate = module{
let zip = module{
list1 = NULL,
list2 = NULL,
} => {
} => (result) {
let len = import "std/lists.ucg".len;
// Compute the length of each list.

View File

@ -19,8 +19,8 @@ let base_type_of = func (val) => reduce(func (acc, f) => select (acc.val is f),
// Turns any schema check module into a compile failure.
// The module must export the computed value as the result field.
let must = func (m, msg) => select m.result, fail msg, {
true = m.result,
let must = func (m, msg) => select m, fail msg, {
true = m,
};
// Any does a boolean match against a set of allowed shapes for a type.
@ -31,11 +31,11 @@ let any = module {
val=NULL,
// The set of allowed type shapes it can be.
types=[],
} => {
} => (result) {
let schema = import "std/schema.ucg";
let reducer = func (acc, t) => acc{
ok = acc.ok || (schema.shaped{val=acc.val, shape=t}.result),
ok = acc.ok || (schema.shaped{val=acc.val, shape=t}),
};
let any = func (val, types) => reduce(reducer, {ok=false, val=val}, types);
@ -65,19 +65,19 @@ let shaped = module {
// fields in tuples that are not present in the
// shape it is compared with.
partial = true,
} => {
} => (result) {
let schema = import "std/schema.ucg";
let simple_handler = func (val, shape) => val is schema.base_type_of(shape);
let tuple_handler = func (acc, name, value) => acc{
ok = select (name) in acc.shape, mod.partial, {
true = schema.shaped{val=value, shape=acc.shape.(name)}.result,
true = schema.shaped{val=value, shape=acc.shape.(name)},
},
};
let list_handler = func(acc, value) => acc{
ok = false || schema.any{val=value, types=acc.shape}.result,
ok = false || schema.any{val=value, types=acc.shape},
};
let result =select schema.base_type_of(mod.val), false, {

View File

@ -4,7 +4,7 @@ let ops = module {
let split_on = module{
on=" ",
str=mod.str,
} => {
} => (result) {
let splitter = func(acc, char) => acc{
out = select char == mod.on, acc.out, {
true = acc.out + [acc.buf],

View File

@ -6,7 +6,7 @@ let list_to_join = [1, 2, 3];
let asserts = t.asserts{};
assert asserts.equal{
left=list.str_join{sep=",", list=list_to_join}.result,
left=list.str_join{sep=",", list=list_to_join},
right="1,2,3"
};
@ -21,12 +21,12 @@ assert asserts.equal{
};
assert asserts.equal{
left=list.enumerate{list=["foo", "bar"]}.result,
left=list.enumerate{list=["foo", "bar"]},
right=[[0, "foo"], [1, "bar"]],
};
assert asserts.equal{
left=list.enumerate{start=1, list=["foo", "bar"]}.result,
left=list.enumerate{start=1, list=["foo", "bar"]},
right=[[1, "foo"], [2, "bar"]],
};
@ -35,11 +35,11 @@ assert asserts.equal{
start=1,
step=2,
list=["foo", "bar"]
}.result,
},
right=[[1, "foo"], [3, "bar"]],
};
assert asserts.equal{
left=list.zip{list1=[0, 1], list2=[3, 4]}.result,
left=list.zip{list1=[0, 1], list2=[3, 4]},
right=[[0, 3], [1, 4]],
};

View File

@ -7,7 +7,7 @@ assert t.ok{
};
assert t.not_ok{
test = schema.any{val=1, types=[1.0, ""]}.result,
test = schema.any{val=1, types=[1.0, ""]},
desc = "1 is not a float or string",
};
@ -62,61 +62,61 @@ assert t.equal{
};
assert t.equal{
left = schema.shaped{val="foo", shape=""}.result,
left = schema.shaped{val="foo", shape=""},
right = true,
};
assert t.ok{
test = schema.shaped{val="foo", shape=""}.result,
test = schema.shaped{val="foo", shape=""},
desc = "\"foo\" is same shape as \"\"",
};
assert t.not_ok{
test = schema.shaped{val="foo", shape=0}.result,
test = schema.shaped{val="foo", shape=0},
desc = "\"foo\" is not the same shape as 0",
};
assert t.ok{
test = schema.shaped{val={foo="bar"}, shape={foo=""}}.result,
test = schema.shaped{val={foo="bar"}, shape={foo=""}},
desc = "shaped for simple tuples works",
};
assert t.ok{
test = schema.shaped{val={foo="bar", count=1}, shape={foo=""}}.result,
test = schema.shaped{val={foo="bar", count=1}, shape={foo=""}},
desc = "shaped for partial tuples works",
};
assert t.not_ok{
test = schema.shaped{partial=false, val={foo="bar", count=1}, shape={foo=""}}.result,
test = schema.shaped{partial=false, val={foo="bar", count=1}, shape={foo=""}},
desc = "shaped for non partial tuples also works",
};
assert t.ok{
test = schema.shaped{val={foo="bar", inner={one=1}}, shape={foo="", inner={one=0}}}.result,
test = schema.shaped{val={foo="bar", inner={one=1}}, shape={foo="", inner={one=0}}},
desc = "shaped for nested tuples works",
};
assert t.ok{
test = schema.shaped{val={foo="bar", inner=[1, 2]}, shape={foo="", inner=[0]}}.result,
test = schema.shaped{val={foo="bar", inner=[1, 2]}, shape={foo="", inner=[0]}},
desc = "shaped for nested list in tuple works",
};
assert t.not_ok{
test = schema.shaped{val={inner={foo="bar"}}, shape={inner={foo=1}}}.result,
test = schema.shaped{val={inner={foo="bar"}}, shape={inner={foo=1}}},
desc = "shaped fails when the shape doesn't match",
};
assert t.ok{
test = schema.shaped{val={list=[1, "foo"]}, shape={list=[0, ""]}}.result,
test = schema.shaped{val={list=[1, "foo"]}, shape={list=[0, ""]}},
desc="inner list with valid types matches shape",
};
assert t.not_ok{
test = schema.shaped{val={list=[1, "foo", true]}, shape={list=[0, ""]}}.result,
test = schema.shaped{val={list=[1, "foo", true]}, shape={list=[0, ""]}},
desc="inner list with invalid types does not match shape",
};
assert t.ok{
test = schema.shaped{val={list=[1, "foo"]}, shape={list=[]}}.result,
test = schema.shaped{val={list=[1, "foo"]}, shape={list=[]}},
desc="inner list with valid types matches empty list shape",
};

View File

@ -4,17 +4,17 @@ let t = import "std/testing.ucg".asserts{};
let str_class = strings.ops{str="foo bar"};
assert t.equal{
left = str_class.split_on{}.result,
left = str_class.split_on{},
right = ["foo", "bar"],
};
assert t.equal{
left = strings.ops{str="foo"}.split_on{}.result,
left = strings.ops{str="foo"}.split_on{},
right = ["foo"],
};
assert t.equal{
left = strings.ops{str=""}.split_on{}.result,
left = strings.ops{str=""}.split_on{},
right = [""],
};

View File

@ -2,32 +2,32 @@ let tpl = import "std/tuples.ucg";
let t = (import "std/testing.ucg").asserts{};
assert t.equal{
left = tpl.fields{tpl={foo=1, bar=2}}.result,
left = tpl.fields{tpl={foo=1, bar=2}},
right = ["foo", "bar"],
};
assert t.equal{
left = tpl.values{tpl={foo=1, bar=2}}.result,
left = tpl.values{tpl={foo=1, bar=2}},
right = [1, 2],
};
assert t.equal{
left = tpl.iter{tpl={foo=1, bar=2}}.result,
left = tpl.iter{tpl={foo=1, bar=2}},
right = [["foo", 1], ["bar", 2]],
};
assert t.equal{
left = tpl.strip_nulls{tpl={foo="bar", bar=NULL}}.result,
left = tpl.strip_nulls{tpl={foo="bar", bar=NULL}},
right = {foo="bar"},
};
assert t.ok{
test = tpl.has_fields{tpl={foo=1, bar=2}, fields=["foo", "bar"]}.result,
test = tpl.has_fields{tpl={foo=1, bar=2}, fields=["foo", "bar"]},
desc = "tuple has fields has foo and bar fields",
};
assert t.not_ok{
test = tpl.has_fields{tpl={blah=1, bar=2}, fields=["foo", "bar"]}.result,
test = tpl.has_fields{tpl={blah=1, bar=2}, fields=["foo", "bar"]},
desc = "tuple does not have fields foo and bar",
};
@ -36,6 +36,6 @@ assert t.ok{
tpl={foo=1},
field="foo",
type="int",
}.result,
},
desc = "tuple has field of type int",
};

View File

@ -6,7 +6,7 @@ let assert_tuple = func (tpl) => select tpl is "tuple", NULL, {
// Return a list of the fields in a tuple.
let fields = module{
tpl = NULL,
} => {
} => (result) {
let assert_tuple = import "std/tuples.ucg".assert_tuple;
// First we check that mod.tpl is a tuple.
assert_tuple(mod.tpl);
@ -17,7 +17,7 @@ let fields = module{
// Return a list of the values in a tuple.
let values = module{
tpl = NULL,
} => {
} => (result) {
let assert_tuple = import "std/tuples.ucg".assert_tuple;
// First we check that mod.tpl is a tuple.
assert_tuple(mod.tpl);
@ -28,7 +28,7 @@ let values = module{
// Return a list of the key value pairs in the tuple.
let iter = module{
tpl = NULL,
} => {
} => (result) {
let assert_tuple = import "std/tuples.ucg".assert_tuple;
// First we check that mod.tpl is a tuple.
assert_tuple(mod.tpl);
@ -39,7 +39,7 @@ let iter = module{
// Strip all the null fields from a tuple.
let strip_nulls = module{
tpl = NULL,
} => {
} => (result) {
let assert_tuple = import "std/tuples.ucg".assert_tuple;
// First we check that mod.tpl is a tuple.
assert_tuple(mod.tpl);
@ -51,12 +51,12 @@ let strip_nulls = module{
let has_fields = module{
tpl = NULL,
fields = [],
} => {
} => (result) {
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;
let fs = lib.fields{tpl=mod.tpl};
let result = reduce(func (acc, f) => acc && (f in fs), true, mod.fields);
};
@ -66,7 +66,7 @@ let field_type = module{
tpl = NULL,
field = NULL,
type = NULL,
} => {
} => (result) {
let lib = import "std/tuples.ucg";
// First we check that mod.tpl is a tuple.
lib.assert_tuple(mod.tpl);
@ -82,7 +82,7 @@ let field_type = module{
};
// Get the list of field value pairs.
let it = lib.iter{tpl=mod.tpl}.result;
let it = lib.iter{tpl=mod.tpl};
// The reducer function used to check the field's types if it exists.
let reducer = func (acc, l) => acc && (select l.0 == mod.field, NULL, {
@ -91,5 +91,5 @@ let field_type = module{
});
// The computed answer true or false.
let result = lib.has_fields{tpl=mod.tpl, fields=[mod.field]}.result && reduce(reducer, true, it);
let result = lib.has_fields{tpl=mod.tpl, fields=[mod.field]} && reduce(reducer, true, it);
};