From 9b57ca5aa7836cff0cb9289c53d6976f55110f10 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Sat, 2 Nov 2019 11:01:47 -0500 Subject: [PATCH] REFACTOR: Cleanup the syntax for the select expr This makes it both easier to correctly write a select expression as well as easier to parse and report syntax errors. --- docsite/site/content/reference/expressions.md | 18 +-- docsite/site/content/reference/grammar.md | 8 ++ integration_tests/comparisons_test.ucg | 4 +- .../functional_processing_test.ucg | 4 +- integration_tests/modules_test.ucg | 4 +- integration_tests/select_expressions_test.ucg | 16 +-- src/ast/printer/mod.rs | 5 +- src/ast/printer/test.rs | 4 +- src/build/compile_test.rs | 23 +--- src/parse/mod.rs | 111 ++++++++++++------ std/functional.ucg | 6 +- std/lists.ucg | 12 +- std/schema.ucg | 12 +- std/strings.ucg | 10 +- std/testing.ucg | 4 +- std/tests/lists_test.ucg | 32 ++--- std/tests/strings_test.ucg | 22 ++-- std/tests/testing_test.ucg | 32 ++--- std/tuples.ucg | 8 +- std/xml.ucg | 8 +- 20 files changed, 188 insertions(+), 155 deletions(-) diff --git a/docsite/site/content/reference/expressions.md b/docsite/site/content/reference/expressions.md index 7efd118..b8751fe 100644 --- a/docsite/site/content/reference/expressions.md +++ b/docsite/site/content/reference/expressions.md @@ -403,7 +403,7 @@ let test_tpl = { foo = "bar", quux = "baz", }; -let tpl_mapper = func (name, val) => select name, [name, val], { +let tpl_mapper = func (name, val) => select (name, [name, val]) => { "foo" = ["foo", "barbar"], quux = ["cute", "pygmy"], }; @@ -429,7 +429,7 @@ the item or field staying in the resulting list or tuple. ``` let list2 = ["foo", "bar", "foo", "bar"]; -let filtrator = func (item) => select item, NULL, { +let filtrator = func (item) => select (item, NULL) { foo = item, }; @@ -514,27 +514,27 @@ Conditionals UCG supports a limited conditional expression called a select. A select expression starts with the `select` keyword and is followed by a an expression resolving to a string or boolean naming the field to select, an optional -expression resolving to the default value, and finally a tuple literal to -select the field from. If the field selected is not in the tuple then the -default value will be used. If no default is specified then select will -throw a compile failure for the unhandled case. +expression resolving to the default value in parenthesis a `=>` and finally a +tuple literal to select the field from. If the field selected is not in the +tuple then the default value will be used. If no default is specified then +select will throw a compile failure for the unhandled case. ``` let want = "baz"; // field default -select want, "quux", { +select (want, "quux") => { baz = "foo", fuzz = "bang", }; // result will be "foo" // field default -select "quack", "quux", { +select ("quack", "quux") => { baz = "foo", fuzz = "bang", }; // result will be "quux" -let ifresult = select true, { +let ifresult = select (true) => { true = "true result", false = "false result", }; // result will be "true result" diff --git a/docsite/site/content/reference/grammar.md b/docsite/site/content/reference/grammar.md index 69d70bd..d9767e3 100644 --- a/docsite/site/content/reference/grammar.md +++ b/docsite/site/content/reference/grammar.md @@ -49,6 +49,7 @@ import_keyword: "import" ; include_keyword: "include" ; as_keyword: "as" ; func_keyword: "func" ; +select_keyword: "select" ; map_keyword: "map" ; reduce_keyword: "map" ; filter_keyword: "filter" ; @@ -111,6 +112,12 @@ literal: str | integer | float | list | tuple | null_keyword; grouped: lparen, expr, rparen ; ``` +#### Select expressions + +``` +select_expr: select_keyword, lparen, expr, [comma, expr], fatcomma, tuple ; +``` + #### Function Definition ``` @@ -189,6 +196,7 @@ trace_expr: trace_keyword, expr ; ``` non_operator_expr: literal | grouped + | select_def | import_expr | funcdef | module_def diff --git a/integration_tests/comparisons_test.ucg b/integration_tests/comparisons_test.ucg index f7456de..8e0c93d 100644 --- a/integration_tests/comparisons_test.ucg +++ b/integration_tests/comparisons_test.ucg @@ -121,8 +121,8 @@ assert { }; let want = "foo"; assert { - ok = select want, 1, { foo=2, } == 2, - desc = "select want, 1, { foo=2, } == 2", + ok = select (want, 1) => { foo=2, } == 2, + desc = "select (want, 1) => { foo=2, } == 2", }; // Contains comparison operators. diff --git a/integration_tests/functional_processing_test.ucg b/integration_tests/functional_processing_test.ucg index 424da95..44ff0bd 100644 --- a/integration_tests/functional_processing_test.ucg +++ b/integration_tests/functional_processing_test.ucg @@ -4,7 +4,7 @@ let list1 = [1, 2, 3, 4]; let list2 = ["foo", "bar", "foo", "bar"]; let mapper = func (item) => item + 1; -let filtrator = func (item) => select item, NULL, { +let filtrator = func (item) => select (item, NULL) => { foo = item, }; @@ -84,7 +84,7 @@ assert { desc = "map(identity_tpl_mapper, test_tpl) == test_tpl", }; -let tpl_mapper = func (name, val) => select name, [name, val], { +let tpl_mapper = func (name, val) => select (name, [name, val]) => { "foo" = ["foo", "barbar"], quux = ["cute", "pygmy"], }; diff --git a/integration_tests/modules_test.ucg b/integration_tests/modules_test.ucg index 1cb399d..589db4e 100644 --- a/integration_tests/modules_test.ucg +++ b/integration_tests/modules_test.ucg @@ -33,7 +33,7 @@ let embedded_mod = module { deep_value = "None", environ = "None", } => { - let env_name = select mod.environ, "qa", { + let env_name = select (mod.environ, "qa") => { None = "qa", prod = "prod", qa = "qa", @@ -113,7 +113,7 @@ assert t.equal{ let recursive_module = module {start=1, end=10} => (result) { let this = mod.this; - let result = select mod.start != mod.end, mod.start, { + let result = select (mod.start != mod.end, mod.start) => { true = this{start=mod.start + 1, end=mod.end}, }; }; diff --git a/integration_tests/select_expressions_test.ucg b/integration_tests/select_expressions_test.ucg index 292f6fe..dca182e 100644 --- a/integration_tests/select_expressions_test.ucg +++ b/integration_tests/select_expressions_test.ucg @@ -1,12 +1,12 @@ let goodwant = "door1"; let badwant = "door4"; -let got = select goodwant, "OOPS", { +let got = select (goodwant, "OOPS") => { door1 = "grand prize", door2 = "you lose", }; -let defaultgot = select badwant, "OOPS", { +let defaultgot = select (badwant, "OOPS") => { door1 = "grand prize", door2 = "you lose", }; @@ -23,7 +23,7 @@ assert { // select inside a function let condfunc = func (arg) => { - output = select arg, NULL, { + output = select (arg, NULL) => { opt1 = "yay", opt2 = "boo", }, @@ -44,7 +44,7 @@ assert { desc = "condfunc(\"invalid\") == {output = NULL}", }; -let iflike = select true, "default", { +let iflike = select (true, "default") => { true = "I was true", false = "I was false", }; @@ -54,7 +54,7 @@ assert { desc = "iflike == \"I was true\"", }; -let no_default_test = func(b) => select b, { +let no_default_test = func(b) => select (b) => { true = "I was true", false = "I was false", }; @@ -73,7 +73,7 @@ let tpl_fields = { test = "foo", }; -let no_default_select_result = select tpl_fields.test == "foo", { +let no_default_select_result = select (tpl_fields.test == "foo") => { true = true, false = false, }; @@ -83,9 +83,9 @@ assert { desc = "no default successfully select true", }; -let nested_select_result_no_defaults = select true, { +let nested_select_result_no_defaults = select (true) => { true = true, - false = select false, { + false = select (false) => { true = fail "whoops! this should never have triggered.", false = true, }, diff --git a/src/ast/printer/mod.rs b/src/ast/printer/mod.rs index 7cd400c..03aba29 100644 --- a/src/ast/printer/mod.rs +++ b/src/ast/printer/mod.rs @@ -516,12 +516,13 @@ where } } write!(self.w, "select ")?; + write!(self.w, "(")?; self.render_expr(&_def.val)?; - write!(self.w, ", ")?; if let Some(ref e) = _def.default { - self.render_expr(e)?; write!(self.w, ", ")?; + self.render_expr(e)?; } + write!(self.w, ") => ")?; self.render_tuple_def(&_def.tuple)?; } Expression::Simple(ref _def) => { diff --git a/src/ast/printer/test.rs b/src/ast/printer/test.rs index 67c4010..77574c1 100644 --- a/src/ast/printer/test.rs +++ b/src/ast/printer/test.rs @@ -149,13 +149,13 @@ fn test_out_expr_printing() { #[test] fn test_select_expr_no_default_printing() { - let input = "select true, {\n true = 1,\n false = 2,\n};"; + let input = "select (true) => {\n true = 1,\n false = 2,\n};"; assert_eq!(print_to_buffer(input), format!("{}\n", input)); } #[test] fn test_select_expr_with_default_printing() { - let input = "select true, 3, {\n true = 1,\n false = 2,\n};"; + let input = "select (true, 3) => {\n true = 1,\n false = 2,\n};"; assert_eq!(print_to_buffer(input), format!("{}\n", input)); } diff --git a/src/build/compile_test.rs b/src/build/compile_test.rs index 962e3ef..1f69646 100644 --- a/src/build/compile_test.rs +++ b/src/build/compile_test.rs @@ -542,10 +542,10 @@ fn test_func_call_wrong_argument_type_compile_failure() { #[test] fn test_select_missed_case_string_no_default_compile_failure() { assert_build_failure( - "select \"a\", { b = 1, };", + "select (\"a\") => { b = 1, };", vec![ - Regex::new(r"Unhandled select case .a. with no default").unwrap(), - Regex::new(r"at line: 1, column: 8").unwrap(), + Regex::new("Unhandled select case \"a\" with no default").unwrap(), + Regex::new(r"line: 1, column: 9").unwrap(), ], ) } @@ -553,21 +553,10 @@ fn test_select_missed_case_string_no_default_compile_failure() { #[test] fn test_select_missed_case_boolean_no_default_compile_failure() { assert_build_failure( - "select true, { false = 1, };", + "select (true) => { false = 1, };", vec![ Regex::new(r"Unhandled select case true with no default").unwrap(), - Regex::new(r"at line: 1, column: 8").unwrap(), + Regex::new(r"line: 1, column: 9").unwrap(), ], ) -} - -#[test] -fn test_bad_import_path_compile_failure() { - assert_build_failure( - "let bad = import \"no/such/path.ucg\";", - vec![ - Regex::new(r"OSError: Path not found").unwrap(), - Regex::new(r"at line: 1, column: 18").unwrap(), - ], - ) -} +} \ No newline at end of file diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 0df32e5..82ca4c7 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -461,47 +461,82 @@ fn tuple_to_select<'a>( } } -fn select_expression(input: SliceIter) -> Result, Expression> { - let parsed = do_each!(input, +make_fn!( + alt_select_expression, Expression>, + do_each!( + pos => pos, _ => word!("select"), - val => do_each!( - expr => trace_parse!(must!(expression)), - _ => must!(punct!(",")), - (expr) - ), - default_and_map => either!( + _ => must!(punct!("(")), + val => must!(expression), + default => optional!( do_each!( - default => do_each!( - expr => trace_parse!(expression), - _ => punct!(","), - (expr) - ), - map => trace_parse!(tuple), - (Some(default), map) - ), - do_each!( - map => trace_parse!(must!(tuple)), - (None, map) + _ => punct!(","), + def => must!(expression), + (def) ) ), - (val, default_and_map.0, default_and_map.1) - ); - match parsed { - Result::Abort(e) => Result::Abort(e), - Result::Fail(e) => Result::Fail(e), - Result::Incomplete(offset) => Result::Incomplete(offset), - Result::Complete(rest, (val, default, map)) => { - match tuple_to_select(input.clone(), val, default, map) { - Ok(expr) => Result::Complete(rest, expr), - Err(e) => Result::Fail(Error::caused_by( - "Invalid Select Expression", - Box::new(e), - Box::new(rest.clone()), - )), - } - } - } -} + _ => optional!(punct!(",")), + _ => must!(punct!(")")), + _ => must!(punct!("=>")), + _ => must!(punct!("{")), + tpl => must!(field_list), + _ => optional!(punct!(",")), + _ => must!(punct!("}")), + (Expression::Select(SelectDef { + val: Box::new(val), + default: default.map(|e| Box::new(e)), + tuple: tpl, + pos: pos, + })) + ) +); + +//fn select_expression(input: SliceIter) -> Result, Expression> { + //let parsed = do_each!(input, + //_ => word!("select"), + //val => do_each!( + //expr => wrap_err!( + //trace_parse!(must!(expression)), + //"Did you forget a comma after your selector value?"), + //_ => must!(punct!(",")), + //(expr) + //), + //default_and_map => either!( + //do_each!( + //default => do_each!( + //expr => trace_parse!(expression), + //_ => punct!(","), + //(expr) + //), + //map => trace_parse!(must!(tuple)), + //(Some(default), map) + //), + //do_each!( + //map => wrap_err!( + //trace_parse!(must!(tuple)), + //"Did you forget a comma after your default value?" + //), + //(None, map) + //) + //), + //(val, default_and_map.0, default_and_map.1) + //); + //match parsed { + //Result::Abort(e) => Result::Abort(e), + //Result::Fail(e) => Result::Fail(e), + //Result::Incomplete(offset) => Result::Incomplete(offset), + //Result::Complete(rest, (val, default, map)) => { + //match tuple_to_select(input.clone(), val, default, map) { + //Ok(expr) => Result::Complete(rest, expr), + //Err(e) => Result::Fail(Error::caused_by( + //"Invalid Select Expression", + //Box::new(e), + //Box::new(rest.clone()), + //)), + //} + //} + //} +//} make_fn!( simple_format_args, FormatArgs>, @@ -764,7 +799,7 @@ make_fn!( trace_parse!(not_expression), trace_parse!(fail_expression), trace_parse!(module_expression), - trace_parse!(select_expression), + trace_parse!(alt_select_expression), trace_parse!(grouped_expression), trace_parse!(include_expression), trace_parse!(unprefixed_expression) diff --git a/std/functional.ucg b/std/functional.ucg index ba86bb3..32831ae 100644 --- a/std/functional.ucg +++ b/std/functional.ucg @@ -18,11 +18,11 @@ let maybe = module{ } => ({do=do, is_null=is_null, or=or, unwrap=unwrap, expect=expect}) { let this = mod.this; - let do = func (op) => select (mod.val != NULL), this{val=NULL}, { + let do = func (op) => select ((mod.val != NULL), this{val=NULL}) => { true = this{val=op(mod.val)}, }; - let or = func (op) => select (mod.val == NULL), this{val=mod.val}, { + let or = func (op) => select ((mod.val == NULL), this{val=mod.val}) => { true = this{val=op()}, }; @@ -30,7 +30,7 @@ let maybe = module{ let unwrap = func() => mod.val; - let expect = func(msg) => select mod.val != NULL, fail msg, { + let expect = func(msg) => select (mod.val != NULL, fail msg) => { true = mod.val, }; }; diff --git a/std/lists.ucg b/std/lists.ucg index 93f7f85..8907db6 100644 --- a/std/lists.ucg +++ b/std/lists.ucg @@ -9,7 +9,7 @@ let str_join = module{ list=NULL, } => (result) { // The function used by reduce to join the list into a string. - let joiner = func (acc, item) => select (acc.out == ""), NULL, { + let joiner = func (acc, item) => select ((acc.out == ""), NULL) => { true = acc{ out="@@" % (acc.out,item), }, @@ -32,7 +32,7 @@ let reverse = func(list) => reduce(func (acc, item) => [item] + acc, [], list); // head returns the first item in a list as a list of one item. // This function is safe for empty list inputs but is not safe // for NULL inputs. -let head = func(list) => select len(list) > 0, [], { +let head = func(list) => select (len(list) > 0, []) => { true = [list.0], }; @@ -40,7 +40,7 @@ let head = func(list) => select len(list) > 0, [], { // This function is safe for empty lists but is not safe // for NULL inputs. let tail = func(list) => reduce( - func (acc, item) => select acc.count > 0, acc{count=1, tail=[]}, { + func (acc, item) => select (acc.count > 0, acc{count=1, tail=[]}) => { true = acc{count = acc.count + 1, tail = acc.tail + [item]}, }, {count=0}, @@ -81,7 +81,7 @@ let slice = module { let list_len = list.len(mod.list); - let end = select mod.end is "null", mod.end, { + let end = select (mod.end is "null", mod.end) => { true = list_len, }; @@ -92,7 +92,7 @@ let slice = module { let reducer = func(acc, item) => acc{ count = acc.count + 1, - list = select (acc.count >= mod.start) && (acc.count <= end), acc.list, { + list = select ((acc.count >= mod.start) && (acc.count <= end), acc.list) => { true = acc.list + [item], }, }; @@ -118,7 +118,7 @@ let zip = module{ let len2 = len(mod.list2); // Compute the min range of the two lists. - let rng = select (len1 >= len2), NULL, { + let rng = select ((len1 >= len2), NULL) => { true = 0:(len1 - 1), false = 0:(len2 - 1), }; diff --git a/std/schema.ucg b/std/schema.ucg index c000e39..5cfb701 100644 --- a/std/schema.ucg +++ b/std/schema.ucg @@ -12,14 +12,14 @@ let base_types = [ ]; // Computes the base type of a value. -let base_type_of = func (val) => reduce(func (acc, f) => select (acc.val is f), f, { +let base_type_of = func (val) => reduce(func (acc, f) => select ((acc.val is f), f) => { true = acc{typ = f}, false = acc, }, {val=val, typ="null"}, base_types).typ; // 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, fail msg, { +let must = func (m, msg) => select (m, fail msg) => { true = m, }; @@ -97,13 +97,13 @@ let shaped = module { 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, { + ok = select ((name) in acc.shape, mod.partial) => { true = this{val=value, shape=acc.shape.(name), partial=mod.partial}, }, }; let shape_tuple_handler = func (acc, field_name, value) => acc{ - ok = select (field_name) in acc.val, false, { + ok = select ((field_name) in acc.val, false) => { true = this{val=value, shape=acc.val.(field_name), partial=false}, }, }; @@ -118,7 +118,7 @@ let shaped = module { ok = acc.ok && schema.any{val=value, types=acc.shape}, }; - let result = select schema.base_type_of(mod.val), false, { + let result = select (schema.base_type_of(mod.val), false) => { str = simple_handler(mod.val, mod.shape), int = simple_handler(mod.val, mod.shape), float = simple_handler(mod.val, mod.shape), @@ -127,7 +127,7 @@ let shaped = module { tuple = (mod.shape is "tuple") && match_shape_fields(mod.val, mod.shape) && match_tuple_fields(mod.val, mod.shape), - list = (mod.shape is "list") && select mod.shape == [], true, { + list = (mod.shape is "list") && select (mod.shape == [], true) => { false = reduce(list_handler, {shape=mod.shape, ok=true}, mod.val).ok, }, func = simple_handler(mod.val, mod.shape), diff --git a/std/strings.ucg b/std/strings.ucg index 97e31f3..367ffeb 100644 --- a/std/strings.ucg +++ b/std/strings.ucg @@ -48,12 +48,12 @@ let ops = module { let maybe_prefix = check_str.substr{end=split_str.len - 1}; let maybe_suffix = check_str.substr{start=split_str.len}; - let result = select maybe_prefix.len == 0, { + let result = select (maybe_prefix.len == 0) => { // terminal condition true = mod.acc + [mod.buf], //true = mod, // recurse condition. - false = select maybe_prefix.str == mod.sep, { + false = select (maybe_prefix.str == mod.sep) => { true = this{ // this is a match to our separator str=maybe_suffix.str, sep=mod.sep, @@ -77,10 +77,10 @@ let ops = module { reduce( func(acc, char) => acc{ counter = acc.counter + 1, - left = select acc.counter < idx, acc.left, { + left = select (acc.counter < idx, acc.left) => { true = acc.left + char, }, - right = select acc.counter >= idx, acc.right, { + right = select (acc.counter >= idx, acc.right) => { true = acc.right + char, }, }, @@ -97,7 +97,7 @@ let ops = module { let pkg = mod.pkg(); let reducer = func(acc, char) => acc{ counter = acc.counter + 1, - str = select ((acc.counter >= mod.start) && (acc.counter <= mod.end)), acc.str, { + str = select ((acc.counter >= mod.start) && (acc.counter <= mod.end), acc.str) => { true = acc.str + char, }, }; diff --git a/std/testing.ucg b/std/testing.ucg index 526f334..d12dd11 100644 --- a/std/testing.ucg +++ b/std/testing.ucg @@ -38,7 +38,7 @@ let equal = module{ (mod.desc != NULL) || fail "description can't be null"; let ok = mod.left == mod.right; - let desc = select (mod.desc == ""), "@ == @" % (mod.left, mod.right), { + let desc = select ((mod.desc == ""), "@ == @" % (mod.left, mod.right)) => { false = mod.desc, }; }; @@ -54,7 +54,7 @@ let not_equal = module{ (mod.desc != NULL) || fail "description can't be null"; let ok = mod.left != mod.right; - let desc = select (mod.desc == ""), "@ != @" % (mod.left, mod.right), { + let desc = select ((mod.desc == ""), "@ != @" % (mod.left, mod.right)) => { false = mod.desc, }; }; \ No newline at end of file diff --git a/std/tests/lists_test.ucg b/std/tests/lists_test.ucg index 6b2217e..f00b350 100644 --- a/std/tests/lists_test.ucg +++ b/std/tests/lists_test.ucg @@ -1,34 +1,34 @@ let list = import "std/lists.ucg"; -let asserts = import "std/testing.ucg"; +let t = import "std/testing.ucg"; let list_to_join = [1, 2, 3]; -assert asserts.equal{ +assert t.equal{ left=list.ops{list=list_to_join}.str_join(","), right="1,2,3" }; -assert asserts.equal{ +assert t.equal{ left=list.ops{list=[0, 1, 2, 3]}.len, right=4, }; -assert asserts.equal{ +assert t.equal{ left = list.ops{list=[0, 1, 2, 3]}.reverse().list, right = [3, 2, 1, 0], }; -assert asserts.equal{ +assert t.equal{ left=list.ops{list=["foo", "bar"]}.enumerate().list, right=[[0, "foo"], [1, "bar"]], }; -assert asserts.equal{ +assert t.equal{ left=list.enumerate{start=1, list=["foo", "bar"]}, right=[[1, "foo"], [2, "bar"]], }; -assert asserts.equal{ +assert t.equal{ left=list.enumerate{ start=1, step=2, @@ -37,47 +37,47 @@ assert asserts.equal{ right=[[1, "foo"], [3, "bar"]], }; -assert asserts.equal{ +assert t.equal{ left=list.zip{list1=[0, 1], list2=[3, 4]}, right=[[0, 3], [1, 4]], }; -assert asserts.equal{ +assert t.equal{ left=list.tail([0,1,2,3,4]), right=[1,2,3,4], }; -assert asserts.equal{ +assert t.equal{ left=list.ops{list=[0,1,2,3,4]}.head(), right=[0], }; -assert asserts.equal{ +assert t.equal{ left=list.ops{list=[0,1,2,3,4]}.tail().list, right=[1,2,3,4], }; -assert asserts.equal{ +assert t.equal{ left=list.slice{end=2, list=[0,1,2,3]}, right=[0,1,2], }; -assert asserts.equal{ +assert t.equal{ left=list.slice{list=[0,1,2,3]}, right=[0,1,2,3], }; -assert asserts.equal{ +assert t.equal{ left=list.slice{end=0, list=[0,1,2,3]}, right=[0], }; -assert asserts.equal{ +assert t.equal{ left=list.slice{list=[]}, right=[], }; -assert asserts.equal{ +assert t.equal{ left=list.slice{list=[0]}, right=[0], }; \ No newline at end of file diff --git a/std/tests/strings_test.ucg b/std/tests/strings_test.ucg index e41d00c..a0cdfb6 100644 --- a/std/tests/strings_test.ucg +++ b/std/tests/strings_test.ucg @@ -1,54 +1,54 @@ let strings = import "std/strings.ucg"; -let asserts = import "std/testing.ucg"; +let t = import "std/testing.ucg"; let str_class = strings.ops{str="foo bar"}; -assert asserts.equal{ +assert t.equal{ left = str_class.split_on{}, right = ["foo", "bar"], }; -assert asserts.equal{ +assert t.equal{ left = strings.ops{str="foo"}.split_on{}, right = ["foo"], }; -assert asserts.equal{ +assert t.equal{ left = strings.ops{str=""}.split_on{}, right = [""], }; -assert asserts.equal{ +assert t.equal{ left = strings.ops{str="foo=>bar=>quux"}.split_on{on="=>"}, right = ["foo", "bar", "quux"], }; -assert asserts.equal{ +assert t.equal{ left = str_class.split_at(3), right = {left="foo", right=" bar"}, }; -assert asserts.equal{ +assert t.equal{ left = str_class.len, right = 7, }; -assert asserts.equal{ +assert t.equal{ left = str_class.chars, right = ["f", "o", "o", " ", "b", "a", "r"], }; -assert asserts.equal{ +assert t.equal{ left = str_class.substr{start=1}.str, right = "oo bar", }; -assert asserts.equal{ +assert t.equal{ left = str_class.substr{end=5}.str, right = "foo ba", }; -assert asserts.equal{ +assert t.equal{ left = str_class.substr{end=8}.str, right = "foo bar", }; \ No newline at end of file diff --git a/std/tests/testing_test.ucg b/std/tests/testing_test.ucg index 1a0d6f2..0d0c608 100644 --- a/std/tests/testing_test.ucg +++ b/std/tests/testing_test.ucg @@ -1,67 +1,67 @@ -let asserts = import "std/testing.ucg"; +let t = import "std/testing.ucg"; -let not_equal_result = asserts.not_equal{ +let not_equal_result = t.not_equal{ left=1, right=2, }; assert not_equal_result; -assert asserts.equal{ +assert t.equal{ left=not_equal_result.desc, right="1 != 2", }; -let bad_not_equal_result = asserts.not_equal{ +let bad_not_equal_result = t.not_equal{ left=1, right=1, }; -assert asserts.not_ok{test=bad_not_equal_result.ok}; -assert asserts.equal{ +assert t.not_ok{test=bad_not_equal_result.ok}; +assert t.equal{ left=bad_not_equal_result.desc, right="1 != 1", }; -let equal_result = asserts.equal{ +let equal_result = t.equal{ left=1, right=1, }; assert equal_result; -assert asserts.equal{ +assert t.equal{ left=equal_result.desc, right="1 == 1", }; -let bad_equal_result = asserts.equal{ +let bad_equal_result = t.equal{ left=1, right=2, }; -assert asserts.equal{ +assert t.equal{ left=bad_equal_result.desc, right="1 == 2", }; -let ok_result = asserts.ok{ +let ok_result = t.ok{ test=true, }; assert ok_result; -assert asserts.equal{ +assert t.equal{ left=ok_result.desc, right="TODO description", }; -let bad_ok_result = asserts.ok{ +let bad_ok_result = t.ok{ test=false, }; -assert asserts.equal{ +assert t.equal{ left=bad_ok_result.desc, right="TODO description", }; -let not_ok_result = asserts.not_ok{ +let not_ok_result = t.not_ok{ test=false, }; assert not_ok_result; -assert asserts.equal{ +assert t.equal{ left=not_ok_result.desc, right="TODO description", }; \ No newline at end of file diff --git a/std/tuples.ucg b/std/tuples.ucg index 2fd404a..8250fe0 100644 --- a/std/tuples.ucg +++ b/std/tuples.ucg @@ -1,5 +1,5 @@ // Assert that a value is a tuple. Generate a compile failure if it is not. -let assert_tuple = func (tpl) => select tpl is "tuple", NULL, { +let assert_tuple = func (tpl) => select (tpl is "tuple", NULL) => { false = fail "@ is not a tuple" % (tpl), }; @@ -91,12 +91,12 @@ let field_type = module{ pkg.assert_tuple(mod.tpl); // Next we assert that mod.field is a string. - select mod.field is "str", NULL, { + 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, { + select (mod.type is "str", NULL) => { false = fail "@ is not a string" % (mod.type), }; @@ -104,7 +104,7 @@ let field_type = module{ let it = pkg.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, { + let reducer = func (acc, l) => acc && (select (l.0 == mod.field, NULL) => { 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 }); diff --git a/std/xml.ucg b/std/xml.ucg index d150a1e..b69c77d 100644 --- a/std/xml.ucg +++ b/std/xml.ucg @@ -6,7 +6,7 @@ let validate_ns = func(ns) => schema.any{val=ns, types=["", {prefix="", uri=""}] // Constructs an xml namespace for use in an xml tag or document root. // Use NULL for the uri argument to use just the prefix. -let ns = func(prefix, uri) => select uri != NULL, { +let ns = func(prefix, uri) => select (uri != NULL) => { true = { prefix = prefix, uri = uri, @@ -30,9 +30,9 @@ let tag = module{ children = mod.children, }; - let result = select mod.ns == NULL, { + let result = select (mod.ns == NULL) => { true = base, - false = select pkg.validate_ns(mod.ns), { + false = select (pkg.validate_ns(mod.ns)) => { true = base{ns=mod.ns}, false = fail "XML Tag namespaces must be a string or tuple of {prefix=, uri=} but is @" % (mod.ns), }, @@ -49,7 +49,7 @@ let validate_node = func(node) => schema.any{val=node, types=["", {name = ""}], // // The root node must be a valid xml node. Either a text or an // xml node. -let doc = func(root) => select validate_node(root), { +let doc = func(root) => select (validate_node(root)) => { true = { root = root, },