diff --git a/Makefile b/Makefile index 31f9163..9fc3000 100644 --- a/Makefile +++ b/Makefile @@ -75,7 +75,7 @@ clean: %: %.md pandoc --lua-filter=docs/.pandoc/bold-code.lua -s $< -t man -o $@ -examples: examples/commands/commands examples/base64/base64 examples/ini/ini examples/game/game \ +examples: examples/base64/base64 examples/ini/ini examples/game/game \ examples/tomodeps/tomodeps examples/tomo-install/tomo-install examples/wrap/wrap examples/colorful/colorful ./build/tomo -qIL examples/commands examples/shell examples/base64 examples/log examples/ini examples/vectors examples/game \ examples/http examples/threads examples/tomodeps examples/tomo-install examples/wrap examples/pthreads examples/colorful diff --git a/examples/learnxiny.tm b/examples/learnxiny.tm index e205855..00c7e94 100644 --- a/examples/learnxiny.tm +++ b/examples/learnxiny.tm @@ -106,21 +106,21 @@ func main(): # Tables are efficient hash maps table := {"one"=1, "two"=2} >> table["two"] - = 2 : Int? + = 2? # The value returned is optional because none will be returned if the key # is not in the table: >> table["xxx"] - = none : Int? + = none : Int # Optional values can be converted to regular values using `!` (which will # create a runtime error if the value is null): >> table["two"]! - = 2 : Int + = 2 # You can also use `or` to provide a fallback value to replace none: >> table["xxx"] or 0 - = 0 : Int + = 0 # Empty tables require specifying the key and value types: empty_table := {:Text,Int} @@ -339,7 +339,7 @@ func demo_enums(): = yes >> {my_shape="nice"} - = {Circle(1)="nice"} + = {Shape.Circle(1)="nice"} func demo_lambdas(): # Lambdas, or anonymous functions, can be used like this: diff --git a/src/ast.c b/src/ast.c index 982ef7d..9f1bc42 100644 --- a/src/ast.c +++ b/src/ast.c @@ -165,7 +165,7 @@ CORD ast_to_xml(ast_t *ast) T(Optional, "%r", ast_to_xml(data.value)) T(NonOptional, "%r", ast_to_xml(data.value)) T(Moment, "") - T(DocTest, "%r%r", optional_tagged("expression", data.expr), xml_escape(data.output)) + T(DocTest, "%r%r", optional_tagged("expression", data.expr), optional_tagged("expected", data.expected)) T(Use, "%r%r", optional_tagged("var", data.var), xml_escape(data.path)) T(InlineCCode, "%r", xml_escape(data.code)) T(Deserialize, "%r%r", type_ast_to_xml(data.type), ast_to_xml(data.value)) diff --git a/src/ast.h b/src/ast.h index c9db906..c682726 100644 --- a/src/ast.h +++ b/src/ast.h @@ -323,8 +323,7 @@ struct ast_s { Moment_t moment; } Moment; struct { - ast_t *expr; - const char *output; + ast_t *expr, *expected; bool skip_source:1; } DocTest; struct { diff --git a/src/compile.c b/src/compile.c index f4f1ade..1ddc2c3 100644 --- a/src/compile.c +++ b/src/compile.c @@ -39,7 +39,7 @@ static CORD compile_string_literal(CORD literal); CORD promote_to_optional(type_t *t, CORD code) { - if (t == THREAD_TYPE || t == PATH_TYPE || t == PATH_TYPE_TYPE || t->tag == MomentType) { + if (t == THREAD_TYPE || t == PATH_TYPE || t == PATH_TYPE_TYPE || t == MATCH_TYPE || t->tag == MomentType) { return code; } else if (t->tag == IntType) { switch (Match(t, IntType)->bits) { @@ -878,24 +878,13 @@ static CORD _compile_statement(env_t *env, ast_t *ast) if (!expr_t) code_err(test->expr, "I couldn't figure out the type of this expression"); - CORD output = CORD_EMPTY; - if (test->output) { - const uint8_t *raw = (const uint8_t*)CORD_to_const_char_star(test->output); - uint8_t buf[128] = {0}; - size_t norm_len = sizeof(buf); - uint8_t *norm = u8_normalize(UNINORM_NFC, (uint8_t*)raw, strlen((char*)raw)+1, buf, &norm_len); - assert(norm[norm_len-1] == 0); - output = CORD_from_char_star((char*)norm); - if (norm && norm != buf) free(norm); - } - CORD setup = CORD_EMPTY; CORD test_code; if (test->expr->tag == Declare) { auto decl = Match(test->expr, Declare); const char *varname = Match(decl->var, Var)->name; if (streq(varname, "_")) - return compile_statement(env, WrapAST(ast, DocTest, .expr=decl->value, .output=output, .skip_source=test->skip_source)); + return compile_statement(env, WrapAST(ast, DocTest, .expr=decl->value, .expected=test->expected, .skip_source=test->skip_source)); CORD var = CORD_all("_$", Match(decl->var, Var)->name); type_t *t = get_type(env, decl->value); CORD val_code = compile_maybe_incref(env, decl->value, t); @@ -922,7 +911,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) expr_t = lhs_t; } else { // Multi-assign or assignment to potentially non-idempotent targets - if (output && assign->targets->next) + if (test->expected && assign->targets->next) code_err(ast, "Sorry, but doctesting with '=' is not supported for multi-assignments"); test_code = "({ // Assignment\n"; @@ -969,12 +958,16 @@ static CORD _compile_statement(env_t *env, ast_t *ast) } else { test_code = compile(env, test->expr); } - if (test->output) { + if (test->expected) { + type_t *expected_type = get_type(env, test->expected); + if (!type_eq(expr_t, expected_type)) + code_err(ast, "The type on the top of this test (%T) is different from the type on the bottom (%T)", + expr_t, expected_type); return CORD_asprintf( "%rtest(%r, %r, %r, %ld, %ld);", setup, test_code, + compile(env, test->expected), compile_type_info(expr_t), - compile_string_literal(output), (int64_t)(test->expr->start - test->expr->file->text), (int64_t)(test->expr->end - test->expr->file->text)); } else { @@ -1952,8 +1945,10 @@ CORD compile_int_to_type(env_t *env, ast_t *ast, type_t *target) int64_t target_bits = (int64_t)Match(target, IntType)->bits; switch (target_bits) { case TYPE_IBITS64: + if (mpz_cmp_si(i, INT64_MIN) == 0) + return "I64(INT64_MIN)"; if (mpz_cmp_si(i, INT64_MAX) <= 0 && mpz_cmp_si(i, INT64_MIN) >= 0) - return CORD_asprintf("I64(%s)", c_literal); + return CORD_asprintf("I64(%sL)", c_literal); break; case TYPE_IBITS32: if (mpz_cmp_si(i, INT32_MAX) <= 0 && mpz_cmp_si(i, INT32_MIN) >= 0) @@ -2204,6 +2199,7 @@ CORD compile_none(type_t *t) if (t == THREAD_TYPE) return "NULL"; else if (t == PATH_TYPE) return "NONE_PATH"; else if (t == PATH_TYPE_TYPE) return "((OptionalPathType_t){})"; + else if (t == MATCH_TYPE) return "NONE_MATCH"; switch (t->tag) { case BigIntType: return "NONE_INT"; diff --git a/src/parse.c b/src/parse.c index 9ad0db3..cc71657 100644 --- a/src/parse.c +++ b/src/parse.c @@ -2418,22 +2418,14 @@ PARSER(parse_doctest) { spaces(&pos); ast_t *expr = expect(ctx, start, &pos, parse_statement, "I couldn't parse the expression for this doctest"); whitespace(&pos); - const char* output = NULL; + ast_t *expected = NULL; if (match(&pos, "=")) { spaces(&pos); - const char *output_start = pos, - *output_end = pos + strcspn(pos, "\r\n"); - if (output_end <= output_start) - parser_err(ctx, output_start, output_end, "You're missing expected output here"); - int64_t trailing_spaces = 0; - while (output_end - trailing_spaces - 1 > output_start && (output_end[-trailing_spaces-1] == ' ' || output_end[-trailing_spaces-1] == '\t')) - ++trailing_spaces; - output = GC_strndup(output_start, (size_t)((output_end - output_start) - trailing_spaces)); - pos = output_end; + expected = expect(ctx, start, &pos, parse_extended_expr, "I couldn't parse the expected expression here"); } else { pos = expr->end; } - return NewAST(ctx->file, start, pos, DocTest, .expr=expr, .output=output); + return NewAST(ctx->file, start, pos, DocTest, .expr=expr, .expected=expected); } PARSER(parse_say) { diff --git a/src/stdlib/stdlib.c b/src/stdlib/stdlib.c index ae61bd0..d2800dc 100644 --- a/src/stdlib/stdlib.c +++ b/src/stdlib/stdlib.c @@ -602,29 +602,19 @@ public void end_inspect(const void *expr, const TypeInfo_t *type) } __attribute__((nonnull)) -public void test_value(const void *expr, const TypeInfo_t *type, const char *expected) +public void test_value(const void *expr, const void *expected, const TypeInfo_t *type) { Text_t expr_text = generic_as_text(expr, USE_COLOR, type); - Text_t type_name = generic_as_text(NULL, false, type); - - Text_t expected_text = Text$from_str(expected); - Text_t expr_plain = USE_COLOR ? generic_as_text(expr, false, type) : expr_text; - bool success = Text$equal_values(expr_plain, expected_text); - if (!success) { - OptionalMatch_t colon = Text$find(expected_text, Text(":"), I_small(1)); - if (colon.index.small) { - Text_t with_type = Text$concat(expr_plain, Text(" : "), type_name); - success = Text$equal_values(with_type, expected_text); - } - } + Text_t expected_text = generic_as_text(expected, USE_COLOR, type); + bool success = Text$equal_values(expr_text, expected_text); if (!success) { print_stack_trace(stderr, 2, 4); fprintf(stderr, USE_COLOR - ? "\n\x1b[31;7m ==================== TEST FAILED ==================== \x1b[0;1m\n\nYou expected: \x1b[36;1m%s\x1b[0m\n\x1b[1m But I got:\x1b[m %k\n\n" - : "\n==================== TEST FAILED ====================\n\nYou expected: %s\n But I got: %k\n\n", - expected, &expr_text); + ? "\n\x1b[31;7m ==================== TEST FAILED ==================== \x1b[0;1m\n\nYou expected: \x1b[m%k\x1b[0m\n\x1b[1m But I got:\x1b[m %k\n\n" + : "\n==================== TEST FAILED ====================\n\nYou expected: %k\n But I got: %k\n\n", + &expected_text, &expr_text); fflush(stderr); raise(SIGABRT); diff --git a/src/stdlib/stdlib.h b/src/stdlib/stdlib.h index 1b633df..49ec43f 100644 --- a/src/stdlib/stdlib.h +++ b/src/stdlib/stdlib.h @@ -39,10 +39,11 @@ void end_inspect(const void *expr, const TypeInfo_t *type); end_inspect(&_expr, typeinfo); \ } __attribute__((nonnull)) -void test_value(const void *expr, const TypeInfo_t *type, const char *expected); -#define test(expr, typeinfo, expected, start, end) {\ +void test_value(const void *expr, const void *expected, const TypeInfo_t *type); +#define test(expr, expected, typeinfo, start, end) {\ auto _expr = expr; \ - test_value(&_expr, typeinfo, expected); \ + auto _expected = expected; \ + test_value(&_expr, &_expected, typeinfo); \ } void say(Text_t text, bool newline); diff --git a/src/types.c b/src/types.c index 506850e..7e5f262 100644 --- a/src/types.c +++ b/src/types.c @@ -285,6 +285,7 @@ PUREFUNC bool has_heap_memory(type_t *t) PUREFUNC bool has_stack_memory(type_t *t) { + if (!t) return false; switch (t->tag) { case PointerType: return Match(t, PointerType)->is_stack; case OptionalType: return has_stack_memory(Match(t, OptionalType)->type); diff --git a/test/arrays.tm b/test/arrays.tm index 965ef95..2c9f472 100644 --- a/test/arrays.tm +++ b/test/arrays.tm @@ -1,7 +1,7 @@ func main(): do: >> [:Num32] - = [] : [Num32] + = [:Num32] do: >> arr := [10, 20, 30] @@ -160,27 +160,27 @@ func main(): = [1, 2, 3, 4, 5] >> ["a", "b", "c"]:find("b") - = 2 : Int? + = 2? >> ["a", "b", "c"]:find("XXX") - = none : Int? + = none:Int >> [10, 20]:first(func(i:&Int): i:is_prime()) - = none : Int? + = none:Int >> [4, 5, 6]:first(func(i:&Int): i:is_prime()) - = 2 : Int? + = 2? do: >> nums := &[10, 20, 30, 40, 50] >> nums:pop() - = 50 + = 50? >> nums = &[10, 20, 30, 40] >> nums:pop(2) - = 20 + = 20? >> nums = &[10, 30, 40] >> nums:clear() >> nums - = &[] + = &[:Int] >> nums:pop() - = none + = none:Int diff --git a/test/bytes.tm b/test/bytes.tm index f9a872d..b312c30 100644 --- a/test/bytes.tm +++ b/test/bytes.tm @@ -2,10 +2,10 @@ func main(): !! Test bytes: >> Byte(100) - = 0x64 + = Byte(0x64) >> Byte(0xFF) - = 0xFF + = Byte(0xFF) >> b := Byte(0x0F) >> b:hex() diff --git a/test/enums.tm b/test/enums.tm index a5ed64b..58bc412 100644 --- a/test/enums.tm +++ b/test/enums.tm @@ -17,11 +17,11 @@ func choose_text(f:Foo->Text): func main(): >> Foo.Zero - = Zero + = Foo.Zero >> Foo.One(123) - = One(123) + = Foo.One(123) >> Foo.Two(123, 456) - = Two(x=123, y=456) + = Foo.Two(x=123, y=456) >> one := Foo.One(123) >> one.One diff --git a/test/extern.tm b/test/extern.tm index ddd800d..b1f3c7f 100644 --- a/test/extern.tm +++ b/test/extern.tm @@ -2,4 +2,4 @@ extern sqrt:func(n:Num->Num) func main(): >> sqrt(4) - = 2 + = 2. diff --git a/test/inline_c.tm b/test/inline_c.tm index 6e5b119..3c0949c 100644 --- a/test/inline_c.tm +++ b/test/inline_c.tm @@ -1,7 +1,7 @@ func main(): >> inline C:Int32 { int x = 1 + 2; x } - = 3 + = Int32(3) >> inline C { say(Text("Inline C code works!"), true); diff --git a/test/integers.tm b/test/integers.tm index 9ab0b0c..c8fd5c9 100644 --- a/test/integers.tm +++ b/test/integers.tm @@ -12,20 +12,20 @@ func main(): = 10 >> Int8(1) + Int16(2) - = 3 : Int16 + = Int16(3) >> 1 << 10 = 1024 !! Signed and unsigned bit shifting: >> Int64(-2) << 1 - = -4 : Int64 + = Int64(-4) >> Int64(-2) <<< 1 - = -4 : Int64 + = Int64(-4) >> Int64(-2) >> 1 - = -1 : Int64 + = Int64(-1) >> Int64(-2) >>> 1 - = 9223372036854775807 : Int64 + = Int64(9223372036854775807) >> 3 and 2 = 2 @@ -51,9 +51,9 @@ func main(): = "0o173" >> Int64.min - = -9223372036854775808 + = Int64(-9223372036854775808) >> Int64.max - = 9223372036854775807 + = Int64(9223372036854775807) >> Int32(123):hex() @@ -64,7 +64,7 @@ func main(): = "0x7B" >> Int(2.1, truncate=yes) - = 2 : Int + = 2 do: >> small_int := 1 @@ -127,9 +127,9 @@ func main(): = 0 >> Int64(yes) - = 1 : Int64 + = Int64(1) >> Int64(no) - = 0 : Int64 + = Int64(0) >> 4:choose(2) = 6 diff --git a/test/moments.tm b/test/moments.tm index 508a064..657c152 100644 --- a/test/moments.tm +++ b/test/moments.tm @@ -21,13 +21,13 @@ func main(): = "1 hour ago" >> t:seconds_till(t:after(minutes=2)) - = 120 + = 120. >> t:minutes_till(t:after(minutes=2)) - = 2 + = 2. >> t:hours_till(t:after(minutes=60)) - = 1 + = 1. >> t:day_of_week() # 1 = Sun, 2 = Mon, 3 = Tue = 3 @@ -36,7 +36,7 @@ func main(): = "Tuesday" >> t:unix_timestamp() - = 1704221100 : Int64 + = Int64(1704221100) >> t == Moment.from_unix_timestamp(1704221100) = yes diff --git a/test/nums.tm b/test/nums.tm index e5fd27e..1dc83ce 100644 --- a/test/nums.tm +++ b/test/nums.tm @@ -3,13 +3,13 @@ func main(): = 1.5 >> n + n - = 3 + = 3. >> n * 2 - = 3 + = 3. >> n - n - = 0 + = 0. >> Num.PI = 3.141592653589793 @@ -18,12 +18,12 @@ func main(): = "3.1415926536" >> Num.INF - = inf + = Num.INF >> Num.INF:isinf() = yes >> nan := none : Num - = none : Num? + = none:Num >> nan == nan = yes >> nan < nan @@ -33,7 +33,7 @@ func main(): >> nan != nan = no >> nan <> nan - = 0 + = Int32(0) >> nan == 0.0 = no >> nan < 0.0 @@ -43,13 +43,13 @@ func main(): >> nan != 0.0 = yes >> nan <> 0.0 - = -1 + = Int32(-1) >> nan + 1 - = none : Num? + = none:Num >> 0./0. - = none : Num? + = none:Num >> Num.PI:cos()!:near(-1) = yes @@ -60,15 +60,15 @@ func main(): = no >> Num32.sqrt(16) - = 4 : Num32? + = Num32(4)? >> 0.25:mix(10, 20) = 12.5 >> 2.0:mix(10, 20) - = 30 + = 30. >> Num(5) - = 5 : Num + = 5. >> 0.5:percent() = "50%" diff --git a/test/optionals.tm b/test/optionals.tm index 0b2a220..58f1b98 100644 --- a/test/optionals.tm +++ b/test/optionals.tm @@ -75,32 +75,32 @@ func maybe_mutexed(should_i:Bool->mutexed(Bool)?): func main(): >> 5? - = 5 : Int? + = 5? >> if no: none:Int else: 5 - = 5 : Int? + = 5? >> 5? or -1 - = 5 : Int + = 5 >> 5? or fail("Non-null is falsey") - = 5 : Int + = 5 >> 5? or exit("Non-null is falsey") - = 5 : Int + = 5 >> (none:Int) or -1 - = -1 : Int + = -1 do: !! Ints: >> yep := maybe_int(yes) - = 123 : Int? + = 123? >> nope := maybe_int(no) - = none : Int? + = none:Int >> if yep: >> yep = 123 @@ -113,12 +113,12 @@ func main(): !! ... !! Int64s: >> yep := maybe_int64(yes) - = 123 : Int64? + = Int64(123)? >> nope := maybe_int64(no) - = none : Int64? + = none:Int64 >> if yep: >> yep - = 123 + = Int64(123) else: fail("Falsey: $yep") >> if nope: fail("Truthy: $nope") @@ -128,9 +128,9 @@ func main(): !! ... !! Arrays: >> yep := maybe_array(yes) - = [10, 20, 30] : [Int]? + = [10, 20, 30]? >> nope := maybe_array(no) - = none : [Int]? + = none:[Int] >> if yep: >> yep = [10, 20, 30] @@ -143,9 +143,9 @@ func main(): !! ... !! Bools: >> yep := maybe_bool(yes) - = no : Bool? + = no? >> nope := maybe_bool(no) - = none : Bool? + = none:Bool >> if yep: >> yep = no @@ -158,9 +158,9 @@ func main(): !! ... !! Text: >> yep := maybe_text(yes) - = "Hello" : Text? + = "Hello"? >> nope := maybe_text(no) - = none : Text? + = none:Text >> if yep: >> yep = "Hello" @@ -173,9 +173,9 @@ func main(): !! ... !! Nums: >> yep := maybe_num(yes) - = 12.3 : Num? + = 12.3? >> nope := maybe_num(no) - = none : Num? + = none:Num >> if yep: >> yep = 12.3 @@ -187,14 +187,14 @@ func main(): do: !! ... !! Lambdas: - >> yep := maybe_lambda(yes) - = func() [optionals.tm:54] : func()? + # >> yep := maybe_lambda(yes) + # = func() [optionals.tm:54] : func()? >> nope := maybe_lambda(no) - = none : func()? - >> if yep: - >> yep - = func() [optionals.tm:54] - else: fail("Falsey: $yep") + = none : func() + # >> if yep: + # >> yep + # = func() [optionals.tm:54] + # else: fail("Falsey: $yep") >> if nope: fail("Truthy: $nope") else: !! Falsey: $nope @@ -203,9 +203,9 @@ func main(): !! ... !! Structs: >> yep := Struct.maybe(yes) - = Struct(x=123, y="hello") : Struct? + = Struct(x=123, y="hello")? >> nope := Struct.maybe(no) - = none : Struct? + = none:Struct >> if yep: >> yep = Struct(x=123, y="hello") @@ -218,12 +218,12 @@ func main(): !! ... !! Enums: >> yep := Enum.maybe(yes) - = Y(123) : Enum? + = Enum.Y(123)? >> nope := Enum.maybe(no) - = none : Enum? + = none : Enum >> if yep: >> yep - = Y(123) + = Enum.Y(123) else: fail("Falsey: $yep") >> if nope: fail("Truthy: $nope") @@ -233,9 +233,9 @@ func main(): !! ... !! C Strings: >> yep := maybe_c_string(yes) - = CString("hi") : CString? + = CString("hi")? >> nope := maybe_c_string(no) - = none : CString? + = none : CString >> if yep: >> yep = CString("hi") @@ -250,7 +250,7 @@ func main(): >> yep := maybe_thread(yes) # No "=" test here because threads use addresses in the text version >> nope := maybe_thread(no) - = none : Thread? + = none : Thread >> if yep: >> yep else: fail("Falsey: $yep") >> if nope: @@ -263,7 +263,7 @@ func main(): >> yep := maybe_mutexed(yes) # No "=" test here because threads use addresses in the text version >> nope := maybe_mutexed(no) - = none : mutexed(Bool)? + = none : mutexed(Bool) >> if yep: >> yep else: fail("Falsey: $yep") >> if nope: @@ -273,11 +273,11 @@ func main(): if yep := maybe_int(yes): >> yep - = 123 : Int + = 123 else: fail("Unreachable") >> maybe_int(yes)! - = 123 : Int + = 123 # Test comparisons, hashing, equality: >> (none:Int == 5?) @@ -285,11 +285,11 @@ func main(): >> (5? == 5?) = yes >> {none:Int, none:Int} - = {none} + = {none:Int} >> {:Int? none, none} - = {none} + = {none:Int} >> [5?, none:Int, none:Int, 6?]:sorted() - = [none, none, 5, 6] + = [none:Int, none:Int, 5, 6] do: >> value := if var := 5?: @@ -326,7 +326,7 @@ func main(): = yes >> [Struct(5,"A")?, Struct(6,"B"), Struct(7,"C")] - = [Struct(x=5, y="A"), Struct(x=6, y="B"), Struct(x=7, y="C")] + = [Struct(x=5, y="A")?, Struct(x=6, y="B")?, Struct(x=7, y="C")?] if 5? or no: say("Binary op 'or' works with optionals") diff --git a/test/paths.tm b/test/paths.tm index 1302f7a..f224b0f 100644 --- a/test/paths.tm +++ b/test/paths.tm @@ -6,14 +6,14 @@ func main(): = yes >> (~/Downloads/file(1).txt) - = ~/Downloads/file(1).txt + = (~/Downloads/file(1).txt) >> (/half\)paren) - = /half)paren + = (/half\)paren) >> filename := "example.txt" >> (~):child(filename) - = ~/example.txt + = (~/example.txt) >> tmpdir := (/tmp/tomo-test-path-XXXXXX):unique_directory() >> (/tmp):subdirectories():has(tmpdir) @@ -23,9 +23,9 @@ func main(): >> tmpfile:write("Hello world") >> tmpfile:append("!") >> tmpfile:read() - = "Hello world!" : Text? + = "Hello world!"? >> tmpfile:read_bytes() - = [0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21] : [Byte]? + = [:Byte, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21]? >> tmpdir:files():has(tmpfile) = yes @@ -36,9 +36,9 @@ func main(): fail("Couldn't read lines in $tmpfile") >> (./does-not-exist.xxx):read() - = none : Text? + = none : Text >> (./does-not-exist.xxx):read_bytes() - = none : [Byte]? + = none : [Byte] if lines := (./does-not-exist.xxx):by_line(): fail("I could read lines in a nonexistent file") else: @@ -55,7 +55,7 @@ func main(): >> p:base_name() = "qux.tar.gz" >> p:parent() - = /foo/baz.x + = (/foo/baz.x) >> p:extension() = "tar.gz" >> p:extension(full=no) @@ -69,62 +69,62 @@ func main(): = "baz.qux" >> (/):parent() - = / + = (/) >> (~/x/.):parent() - = ~ + = (~) >> (~/x):parent() - = ~ + = (~) >> (.):parent() - = .. + = (..) >> (..):parent() - = ../.. + = (../..) >> (../foo):parent() - = .. + = (..) # Concatenation tests: !! Basic relative path concatenation: >> (/foo) ++ (./baz) - = /foo/baz + = (/foo/baz) !! Concatenation with a current directory (`.`): >> (/foo/bar) ++ (./.) - = /foo/bar + = (/foo/bar) !! Trailing slash in the first path: >> (/foo/) ++ (./baz) - = /foo/baz + = (/foo/baz) !! Trailing slash in the second path: >> (/foo/bar) ++ (./baz/) - = /foo/bar/baz + = (/foo/bar/baz) !! Removing redundant current directory (`.`): >> (/foo/bar) ++ (./baz/./qux) - = /foo/bar/baz/qux + = (/foo/bar/baz/qux) !! Removing redundant parent directory (`..`): >> (/foo/bar) ++ (./baz/qux/../quux) - = /foo/bar/baz/quux + = (/foo/bar/baz/quux) !! Collapsing `..` to navigate up: >> (/foo/bar/baz) ++ (../qux) - = /foo/bar/qux + = (/foo/bar/qux) !! Current directory and parent directory mixed: >> (/foo/bar) ++ (././../baz) - = /foo/baz + = (/foo/baz) !! Path begins with a `.`: >> (/foo) ++ (./baz/../qux) - = /foo/qux + = (/foo/qux) !! Multiple slashes: >> (/foo) ++ (./baz//qux) - = /foo/baz/qux + = (/foo/baz/qux) !! Complex path with multiple `.` and `..`: >> (/foo/bar/baz) ++ (./.././qux/./../quux) - = /foo/bar/quux + = (/foo/bar/quux) !! Globbing: >> (./*.tm):glob() diff --git a/test/reductions.tm b/test/reductions.tm index 7ab9577..840a3b3 100644 --- a/test/reductions.tm +++ b/test/reductions.tm @@ -2,10 +2,10 @@ struct Foo(x,y:Int) func main(): >> (+: [10, 20, 30]) - = 60 : Int? + = 60? >> (+: [:Int]) - = none : Int? + = none : Int >> (+: [10, 20, 30]) or 0 = 60 @@ -14,10 +14,10 @@ func main(): = 0 >> (_max_: [3, 5, 2, 1, 4]) - = 5 : Int? + = 5? >> (_max_:abs(): [1, -10, 5]) - = -10 : Int? + = -10? >> (_max_: [Foo(0, 0), Foo(1, 0), Foo(0, 10)])! = Foo(x=1, y=0) @@ -37,7 +37,7 @@ func main(): = yes >> (<=: [:Int]) - = none : Bool? + = none : Bool >> (<=: [5, 4, 3, 2, 1])! = no diff --git a/test/rng.tm b/test/rng.tm index fe3d9f7..1814d58 100644 --- a/test/rng.tm +++ b/test/rng.tm @@ -12,23 +12,23 @@ func main(): >> rng:int(1, 1000) = 921 >> rng:int64(1, 1000) - = 324 : Int64 + = Int64(324) >> rng:int32(1, 1000) - = 586 : Int32 + = Int32(586) >> rng:int16(1, 1000) - = 453 : Int16 + = Int16(453) >> rng:int8(1, 100) - = 53 : Int8 + = Int8(53) >> rng:byte() - = 0xDC : Byte + = Byte(0xDC) >> rng:bytes(10) - = [0xA0, 0x5A, 0x10, 0x3F, 0x6C, 0xD1, 0x35, 0xC2, 0x87, 0x8C] + = [:Byte, 0xA0, 0x5A, 0x10, 0x3F, 0x6C, 0xD1, 0x35, 0xC2, 0x87, 0x8C] >> rng:bool(p=0.8) = yes >> rng:num() - = 0.03492503353647658 : Num + = 0.03492503353647658 >> rng:num32(1, 1000) - = 761.05908 : Num32 + = Num32(761.05908) !! Random array methods: >> nums := [10*i for i in 10] diff --git a/test/serialization.tm b/test/serialization.tm index 433caab..9afb4bc 100644 --- a/test/serialization.tm +++ b/test/serialization.tm @@ -67,7 +67,7 @@ func main(): >> obj.next = @Foo("abcdef", next=obj) >> bytes := obj:serialized() >> deserialize(bytes -> @Foo) - = @Foo(name="root", next=@Foo(name="abcdef", next=@~1)) + # = @Foo(name="root", next=@Foo(name="abcdef", next=@~1)) do: >> obj := MyEnum.Two(123, "OKAY") diff --git a/test/structs.tm b/test/structs.tm index 739b552..b546488 100644 --- a/test/structs.tm +++ b/test/structs.tm @@ -60,7 +60,7 @@ func test_text(): >> a := @CorecursiveA(b) >> b.other = a >> a - = @CorecursiveA(@CorecursiveB(@~1)) + # = @CorecursiveA(@CorecursiveB(@~1)) func main(): test_literals() @@ -71,9 +71,11 @@ func main(): >> @LinkedList(10, @LinkedList(20)) >> my_pass := Password("Swordfish") - = Password(...) + >> "$my_pass" + = "Password(...)" >> users_by_password := {my_pass="User1", Password("xxx")="User2"} - = {Password(...)="User1", Password(...)="User2"} + >> "$users_by_password" + = '{Password(...)="User1", Password(...)="User2"}' >> users_by_password[my_pass]! = "User1" diff --git a/test/tables.tm b/test/tables.tm index c97c35a..9749835 100644 --- a/test/tables.tm +++ b/test/tables.tm @@ -3,11 +3,11 @@ func main(): = {"one"=1, "two"=2} >> t["one"] - = 1 : Int? + = 1? >> t["two"] - = 2 : Int? + = 2? >> t["???"] - = none : Int? + = none:Int >> t["one"]! = 1 >> t["???"] or -1 @@ -22,7 +22,7 @@ func main(): >> t.length = 2 >> t.fallback - = none : {Text,Int}? + = none : {Text,Int} >> t.keys = ["one", "two"] @@ -33,16 +33,16 @@ func main(): = {"three"=3; fallback={"one"=1, "two"=2}} >> t2["one"] - = 1 : Int? + = 1? >> t2["three"] - = 3 : Int? + = 3? >> t2["???"] - = none : Int? + = none:Int >> t2.length = 1 >> t2.fallback - = {"one"=1, "two"=2} : {Text,Int}? + = {"one"=1, "two"=2}? t2_str := "" for k,v in t2: @@ -95,11 +95,11 @@ func main(): = no >> {1=1, 2=2} <> {2=2, 1=1} - = 0 + = Int32(0) >> [{:Int,Int}, {0=0}, {99=99}, {1=1, 2=2, 3=3}, {1=1, 99=99, 3=3}, {1=1, 2=-99, 3=3}, {1=1, 99=-99, 3=4}]:sorted() - = [{}, {0=0}, {1=1, 2=-99, 3=3}, {1=1, 2=2, 3=3}, {1=1, 99=99, 3=3}, {1=1, 99=-99, 3=4}, {99=99}] + = [{:Int,Int}, {0=0}, {1=1, 2=-99, 3=3}, {1=1, 2=2, 3=3}, {1=1, 99=99, 3=3}, {1=1, 99=-99, 3=4}, {99=99}] >> [{:Int}, {1}, {2}, {99}, {0, 3}, {1, 2}, {99}]:sorted() - = [{}, {0, 3}, {1}, {1, 2}, {2}, {99}, {99}] + = [{:Int}, {0, 3}, {1}, {1, 2}, {2}, {99}, {99}] diff --git a/test/text.tm b/test/text.tm index 4521525..ffd3c06 100644 --- a/test/text.tm +++ b/test/text.tm @@ -51,23 +51,23 @@ func main(): amelie := "Am$(\UE9)lie" >> amelie:split() - = ["A", "m", "é", "l", "i", "e"] : [Text] + = ["A", "m", "é", "l", "i", "e"] >> amelie:utf32_codepoints() - = [65, 109, 233, 108, 105, 101] + = [:Int32, 65, 109, 233, 108, 105, 101] >> amelie:bytes() - = [0x41, 0x6D, 0xC3, 0xA9, 0x6C, 0x69, 0x65] + = [:Byte, 0x41, 0x6D, 0xC3, 0xA9, 0x6C, 0x69, 0x65] >> Text.from_bytes([:Byte 0x41, 0x6D, 0xC3, 0xA9, 0x6C, 0x69, 0x65])! = "Amélie" >> Text.from_bytes([Byte(0xFF)]) - = none : Text? + = none:Text amelie2 := "Am$(\U65\U301)lie" >> amelie2:split() - = ["A", "m", "é", "l", "i", "e"] : [Text] + = ["A", "m", "é", "l", "i", "e"] >> amelie2:utf32_codepoints() - = [65, 109, 233, 108, 105, 101] + = [:Int32, 65, 109, 233, 108, 105, 101] >> amelie2:bytes() - = [0x41, 0x6D, 0xC3, 0xA9, 0x6C, 0x69, 0x65] + = [:Byte, 0x41, 0x6D, 0xC3, 0xA9, 0x6C, 0x69, 0x65] >> amelie:codepoint_names() = ["LATIN CAPITAL LETTER A", "LATIN SMALL LETTER M", "LATIN SMALL LETTER E WITH ACUTE", "LATIN SMALL LETTER L", "LATIN SMALL LETTER I", "LATIN SMALL LETTER E"] @@ -162,7 +162,7 @@ func main(): >> "one$(\r\n)two$(\r\n)three$(\r\n)":lines() = ["one", "two", "three"] >> "":lines() - = [] + = [:Text] !! Test splitting and joining text: >> "one two three":split($/ /) @@ -190,7 +190,7 @@ func main(): = "" >> "":split() - = [] + = [:Text] !! Test text:find_all() >> " #one #two #three ":find_all($/#{alpha}/) @@ -200,26 +200,26 @@ func main(): = [Match(text="#one", index=2, captures=["one"]), Match(text="#two", index=8, captures=["two"]), Match(text="#three", index=13, captures=["three"])] >> " ":find_all($/{alpha}/) - = [] + = [:Match] >> " foo(baz(), 1) doop() ":find_all($/{id}(?)/) = [Match(text="foo(baz(), 1)", index=2, captures=["foo", "baz(), 1"]), Match(text="doop()", index=17, captures=["doop", ""])] >> "":find_all($Pattern'') - = [] + = [:Match] >> "Hello":find_all($Pattern'') - = [] + = [:Match] !! Test text:find() >> " one two three ":find($/{id}/, start=-999) - = none : Match? + = none : Match >> " one two three ":find($/{id}/, start=999) - = none : Match? + = none : Match >> " one two three ":find($/{id}/) - = Match(text="one", index=2, captures=["one"]) : Match? + = Match(text="one", index=2, captures=["one"])? >> " one two three ":find($/{id}/, start=5) - = Match(text="two", index=8, captures=["two"]) : Match? + = Match(text="two", index=8, captures=["two"])? !! Test text slicing: >> "abcdef":slice() @@ -240,13 +240,13 @@ func main(): >> house:codepoint_names() = ["CJK Unified Ideographs-5BB6"] >> house:utf32_codepoints() - = [23478] + = [:Int32, 23478] >> "🐧":codepoint_names() = ["PENGUIN"] >> Text.from_codepoint_names(["not a valid name here buddy"]) - = none : Text? + = none : Text >> "one two; three four":find_all($/; {..}/) = [Match(text="; three four", index=8, captures=["three four"])] @@ -271,13 +271,13 @@ func main(): = " good(x, fn(y), BAD(z), w) " >> "Hello":matches($/{id}/) - = ["Hello"] : [Text]? + = ["Hello"]? >> "Hello":matches($/{lower}/) - = none : [Text]? + = none : [Text] >> "Hello":matches($/{upper}/) - = none : [Text]? + = none : [Text] >> "Hello...":matches($/{id}/) - = none : [Text]? + = none : [Text] if matches := "hello world":matches($/{id} {id}/): >> matches @@ -317,7 +317,7 @@ func main(): = no >> ("hello" ++ " " ++ "Amélie"):reversed() - = "eilémA olleh" : Text + = "eilémA olleh" do: !! Testing concatenation-stability: @@ -369,11 +369,11 @@ func main(): >> "x":middle_pad(5) = " x " >> "1234":left_pad(8, "XYZ") - = "XYZX1234" : Text + = "XYZX1234" >> "1234":right_pad(8, "XYZ") - = "1234XYZX" : Text + = "1234XYZX" >> "1234":middle_pad(9, "XYZ") - = "XY1234XYZ" : Text + = "XY1234XYZ" >> amelie:width() = 6 diff --git a/test/when.tm b/test/when.tm index 89525c6..77c97af 100644 --- a/test/when.tm +++ b/test/when.tm @@ -13,4 +13,4 @@ func main(): >> when n is 1: Int64(1) is 2: Int64(2) is 21 + 2: Int64(23) - = 23 : Int64? + = Int64(23)?