"Fossies" - the Fresh Open Source Software Archive

Member "ponyc-0.33.2/test/libponyc/sugar.cc" (3 Feb 2020, 37158 Bytes) of package /linux/misc/ponyc-0.33.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "sugar.cc": 0.33.1_vs_0.33.2.

    1 #include <gtest/gtest.h>
    2 #include <platform.h>
    3 
    4 #include "util.h"
    5 
    6 #define TEST_COMPILE(src) DO(test_compile(src, "sugar"))
    7 #define TEST_ERROR(src) DO(test_error(src, "sugar"))
    8 #define TEST_EQUIV(src, expect) DO(test_equiv(src, "sugar", expect, "parse"))
    9 
   10 
   11 class SugarTest: public PassTest
   12 {};
   13 
   14 
   15 TEST_F(SugarTest, DataType)
   16 {
   17   const char* short_form =
   18     "primitive Foo";
   19 
   20   const char* full_form =
   21     "use \"builtin\"\n"
   22     "primitive val Foo\n"
   23     "  new val create(): Foo val^ => true";
   24 
   25   TEST_EQUIV(short_form, full_form);
   26 }
   27 
   28 
   29 TEST_F(SugarTest, ClassWithoutCreate)
   30 {
   31   // Create constructor should be added if there isn't a create
   32   const char* short_form =
   33     "class iso Foo\n"
   34     "  let m:U32 = 3";
   35 
   36   const char* full_form =
   37     "use \"builtin\"\n"
   38     "class iso Foo\n"
   39     "  let m:U32\n"
   40     "  new iso create(): Foo iso^ =>\n"
   41     "    m = 3\n"
   42     "    true";
   43 
   44   TEST_EQUIV(short_form, full_form);
   45 }
   46 
   47 
   48 TEST_F(SugarTest, ClassWithCreateConstructor)
   49 {
   50   // Create constructor should not be added if it's already there
   51   const char* short_form =
   52     "class iso Foo\n"
   53     "  new create() => 3";
   54 
   55   const char* full_form =
   56     "use \"builtin\"\n"
   57     "class iso Foo\n"
   58     "  new ref create(): Foo ref^ => 3";
   59 
   60   TEST_EQUIV(short_form, full_form);
   61 }
   62 
   63 
   64 TEST_F(SugarTest, ClassWithConstructor)
   65 {
   66   // Create constructor should not be added if there's already a constructor
   67   const char* short_form =
   68     "class iso Foo\n"
   69     "  new make() => 3";
   70 
   71   const char* full_form =
   72     "use \"builtin\"\n"
   73     "class iso Foo\n"
   74     "  new ref make(): Foo ref^ => 3";
   75 
   76   TEST_EQUIV(short_form, full_form);
   77 }
   78 
   79 
   80 TEST_F(SugarTest, ClassWithCreateFunction)
   81 {
   82   // Create function doesn't clash with create constructor
   83   const char* short_form =
   84     "class Foo\n"
   85     "  fun ref create():U32 => 3";
   86 
   87   const char* full_form =
   88     "use \"builtin\"\n"
   89     "class ref Foo\n"
   90     "  fun ref create():U32 => 3";
   91 
   92   TEST_EQUIV(short_form, full_form);
   93 }
   94 
   95 
   96 TEST_F(SugarTest, ClassWithoutFieldOrCreate)
   97 {
   98   const char* short_form =
   99     "class iso Foo";
  100 
  101   const char* full_form =
  102     "use \"builtin\"\n"
  103     "class iso Foo\n"
  104     "  new iso create(): Foo iso^ => true";
  105 
  106   TEST_EQUIV(short_form, full_form);
  107 }
  108 
  109 
  110 TEST_F(SugarTest, ClassWithoutDefCap)
  111 {
  112   const char* short_form =
  113     "class Foo";
  114 
  115   const char* full_form =
  116     "use \"builtin\"\n"
  117     "class ref Foo\n"
  118     "  new iso create(): Foo iso^ => true";
  119 
  120   TEST_EQUIV(short_form, full_form);
  121 }
  122 
  123 
  124 TEST_F(SugarTest, ClassWithInitializedField)
  125 {
  126   const char* short_form =
  127     "class Foo\n"
  128     "  let x: U8 = 1\n";
  129 
  130   const char* full_form =
  131     "use \"builtin\"\n"
  132     "class ref Foo\n"
  133     "  let x: U8\n"
  134     "  new iso create(): Foo iso^ =>\n"
  135     "    x = 1\n"
  136     "    true\n";
  137   TEST_EQUIV(short_form, full_form);
  138 }
  139 
  140 TEST_F(SugarTest, ClassWithInitializedFieldAndManyConstructors)
  141 {
  142   const char* short_form =
  143     "class Foo\n"
  144     "  let x: U8 = 1\n"
  145     "  \n"
  146     "  new create1() => 1\n"
  147     "  new create2() => 2\n";
  148   const char* full_form =
  149     "use \"builtin\"\n"
  150     "class ref Foo\n"
  151     "  let x: U8\n"
  152     "  \n"
  153     "  new ref create1(): Foo ref^ =>\n"
  154     "    x = 1\n"
  155     "    1\n"
  156     "  \n"
  157     "  new ref create2(): Foo ref^ =>\n"
  158     "    x = 1\n"
  159     "    2\n";
  160 
  161   TEST_EQUIV(short_form, full_form);
  162 }
  163 
  164 TEST_F(SugarTest, ClassWithInitializedFieldsAndDocString)
  165 {
  166   const char* short_form =
  167     "class Foo\n"
  168     "  let x: U8 = 1\n"
  169     "  \n"
  170     "  new create() =>\n"
  171     "    \"\"\"\n"
  172     "    constructor docstring\n"
  173     "    \"\"\"\n"
  174     "    None\n";
  175 
  176   TEST_COMPILE(short_form);
  177   ast_t* foo = ast_childlast(module);
  178   ASSERT_NE(ast_id(foo), TK_NONE);
  179 
  180   AST_GET_CHILDREN(foo, id, typeparams, defcap, traits, members);
  181 
  182   ast_t* member = ast_child(members);
  183   while(member != NULL)
  184   {
  185     switch(ast_id(member))
  186     {
  187       case TK_NEW:
  188       {
  189         AST_GET_CHILDREN(member, cap, id, type_params, params, return_type,
  190           error, body, docstring);
  191 
  192         ASSERT_EQ(ast_id(docstring), TK_STRING) <<
  193           "docstring has not been extracted from the constructor body";
  194         ASSERT_STREQ(ast_name(docstring), "constructor docstring\n") <<
  195           "docstring has not been extracted correctly";
  196 
  197         ASSERT_EQ(ast_childcount(body), 2) <<
  198           "docstring has not been purged from the iconstructor body";
  199         return;
  200       }
  201       default:
  202       {}
  203     }
  204     member = ast_sibling(member);
  205   }
  206   FAIL() << "no constructor found";
  207 }
  208 
  209 
  210 TEST_F(SugarTest, ActorWithInitializedField)
  211 {
  212   // initializer should be added to every constructor
  213   const char* short_form =
  214     "actor Foo\n"
  215     "  let x: U8 = 1\n";
  216 
  217   const char* full_form =
  218     "use \"builtin\"\n"
  219     "actor tag Foo\n"
  220     "  let x: U8\n"
  221     "  new tag create(): Foo tag^ =>\n"
  222     "    x = 1\n"
  223     "    true\n";
  224 
  225   TEST_EQUIV(short_form, full_form);
  226 }
  227 
  228 
  229 TEST_F(SugarTest, ActorWithInitializedFieldAndManyConstructors)
  230 {
  231   const char* short_form =
  232     "actor Foo\n"
  233     "  let x: U8 = 1\n"
  234     "  \n"
  235     "  new create1() => 1\n"
  236     "  new create2() => 2\n";
  237   const char* full_form =
  238     "use \"builtin\"\n"
  239     "actor tag Foo\n"
  240     "  let x: U8\n"
  241     "  \n"
  242     "  new tag create1(): Foo tag^ =>\n"
  243     "    x = 1\n"
  244     "    1\n"
  245     "  \n"
  246     "  new tag create2(): Foo tag^ =>\n"
  247     "    x = 1\n"
  248     "    2\n";
  249 
  250   TEST_EQUIV(short_form, full_form);
  251 }
  252 
  253 
  254 TEST_F(SugarTest, ActorWithInitializedFieldsAndDocString)
  255 {
  256   const char* short_form =
  257     "actor Foo\n"
  258     "  let x: U8 = 1\n"
  259     "  \n"
  260     "  new create() =>\n"
  261     "    \"\"\"\n"
  262     "    constructor docstring\n"
  263     "    \"\"\"\n"
  264     "    None\n";
  265 
  266   TEST_COMPILE(short_form);
  267   ast_t* foo = ast_childlast(module);
  268   ASSERT_NE(ast_id(foo), TK_NONE);
  269 
  270   AST_GET_CHILDREN(foo, id, typeparams, defcap, traits, members);
  271 
  272   ast_t* member = ast_child(members);
  273   while(member != NULL)
  274   {
  275     switch(ast_id(member))
  276     {
  277       case TK_NEW:
  278       {
  279         AST_GET_CHILDREN(member, cap, id, type_params, params, return_type,
  280           error, body, docstring);
  281 
  282         ASSERT_EQ(ast_id(docstring), TK_STRING) <<
  283           "docstring has not been extracted from the constructor body";
  284         ASSERT_STREQ(ast_name(docstring), "constructor docstring\n") <<
  285           "docstring has not been extracted correctly";
  286 
  287         ASSERT_EQ(ast_childcount(body), 2) <<
  288           "docstring has not been purged from the iconstructor body";
  289         return;
  290       }
  291       default:
  292       {}
  293     }
  294     member = ast_sibling(member);
  295   }
  296   FAIL() << "no constructor found";
  297 }
  298 
  299 
  300 TEST_F(SugarTest, ActorWithCreateConstructor)
  301 {
  302   // Create constructor should not be added if it's already there
  303   const char* short_form =
  304     "actor Foo\n"
  305     " new create() => 3";
  306 
  307   const char* full_form =
  308     "use \"builtin\"\n"
  309     "actor tag Foo\n"
  310     "  new tag create(): Foo tag^ => 3";
  311 
  312   TEST_EQUIV(short_form, full_form);
  313 }
  314 
  315 
  316 TEST_F(SugarTest, ActorWithConstructor)
  317 {
  318   // Create constructor should not be added if there's already a constructor
  319   const char* short_form =
  320     "actor Foo\n"
  321     " new make() => 3";
  322 
  323   const char* full_form =
  324     "use \"builtin\"\n"
  325     "actor tag Foo\n"
  326     "  new tag make(): Foo tag^ => 3";
  327 
  328   TEST_EQUIV(short_form, full_form);
  329 }
  330 
  331 
  332 TEST_F(SugarTest, ActorWithCreateFunction)
  333 {
  334   // Create function doesn't clash with create constructor
  335   const char* short_form =
  336     "actor Foo\n"
  337     "  fun ref create():U32 => 3";
  338 
  339   const char* full_form =
  340     "use \"builtin\"\n"
  341     "actor tag Foo\n"
  342     "  fun ref create():U32 => 3";
  343 
  344   TEST_EQUIV(short_form, full_form);
  345 }
  346 
  347 
  348 TEST_F(SugarTest, ActorWithCreateBehaviour)
  349 {
  350   // Create behaviour doesn't clash with create constructor
  351   const char* short_form =
  352     "actor Foo\n"
  353     "  be create() => 3";
  354 
  355   const char* full_form =
  356     "use \"builtin\"\n"
  357     "actor tag Foo\n"
  358     "  be tag create():None => 3";
  359 
  360   TEST_EQUIV(short_form, full_form);
  361 }
  362 
  363 
  364 TEST_F(SugarTest, ActorWithoutFieldOrCreate)
  365 {
  366   const char* short_form =
  367     "actor Foo";
  368 
  369   const char* full_form =
  370     "use \"builtin\"\n"
  371     "actor tag Foo\n"
  372     "  new tag create(): Foo tag^ => true";
  373 
  374   TEST_EQUIV(short_form, full_form);
  375 }
  376 
  377 
  378 TEST_F(SugarTest, ActorWithoutDefCap)
  379 {
  380   const char* short_form =
  381     "actor Foo";
  382 
  383   const char* full_form =
  384     "use \"builtin\"\n"
  385     "actor tag Foo\n"
  386     "  new tag create(): Foo tag^ => true";
  387 
  388   TEST_EQUIV(short_form, full_form);
  389 }
  390 
  391 
  392 TEST_F(SugarTest, TraitWithCap)
  393 {
  394   const char* short_form = "trait box Foo";
  395 
  396   TEST_COMPILE(short_form);
  397 }
  398 
  399 
  400 TEST_F(SugarTest, TraitWithoutCap)
  401 {
  402   const char* short_form =
  403     "trait Foo";
  404 
  405   const char* full_form =
  406     "use \"builtin\"\n"
  407     "trait ref Foo";
  408 
  409   TEST_EQUIV(short_form, full_form);
  410 }
  411 
  412 
  413 TEST_F(SugarTest, TypeParamWithConstraint)
  414 {
  415   const char* short_form =
  416     "class ref Foo[A: U32]\n"
  417     "  var create: U32";
  418 
  419   TEST_COMPILE(short_form);
  420 }
  421 
  422 
  423 TEST_F(SugarTest, TypeParamWithoutConstraint)
  424 {
  425   const char* short_form =
  426     "class ref Foo[A]\n"
  427   "  var create: U32";
  428 
  429   const char* full_form =
  430     "use \"builtin\"\n"
  431     "class ref Foo[A: A]\n"
  432     "  var create: U32";
  433 
  434   TEST_EQUIV(short_form, full_form);
  435 }
  436 
  437 
  438 TEST_F(SugarTest, ConstructorNoReturnType)
  439 {
  440   const char* short_form =
  441     "class ref Foo\n"
  442     "  new create() => 3";
  443 
  444   const char* full_form =
  445     "use \"builtin\"\n"
  446     "class ref Foo\n"
  447     "  new ref create(): Foo ref^ => 3";
  448 
  449   TEST_EQUIV(short_form, full_form);
  450 }
  451 
  452 
  453 TEST_F(SugarTest, ConstructorInActor)
  454 {
  455   const char* short_form =
  456     "actor Foo\n"
  457     "  new create() => 3";
  458 
  459   const char* full_form =
  460     "use \"builtin\"\n"
  461     "actor tag Foo\n"
  462     "  new tag create(): Foo tag^ => 3";
  463 
  464   TEST_EQUIV(short_form, full_form);
  465 }
  466 
  467 
  468 TEST_F(SugarTest, ConstructorInDataType)
  469 {
  470   const char* short_form =
  471     "primitive Foo\n"
  472     "  new create() => 3";
  473 
  474   const char* full_form =
  475     "use \"builtin\"\n"
  476     "primitive val Foo\n"
  477     "  new val create(): Foo val^ => 3";
  478 
  479   TEST_EQUIV(short_form, full_form);
  480 }
  481 
  482 
  483 TEST_F(SugarTest, ConstructorInGenericClass)
  484 {
  485   const char* short_form =
  486     "class Foo[A: B, C]\n"
  487     "  new bar() => 3";
  488 
  489   const char* full_form =
  490     "use \"builtin\"\n"
  491     "class ref Foo[A: B, C: C]\n"
  492     "  new ref bar(): Foo[A, C] ref^ => 3";
  493 
  494   TEST_EQUIV(short_form, full_form);
  495 }
  496 
  497 
  498 TEST_F(SugarTest, BehaviourReturnType)
  499 {
  500   const char* short_form =
  501     "actor Foo\n"
  502     "  var create: U32\n"
  503     "  be foo() => 3";
  504 
  505   const char* full_form =
  506     "use \"builtin\"\n"
  507     "actor tag Foo\n"
  508     "  var create: U32\n"
  509     "  be tag foo():None => 3";
  510 
  511   TEST_EQUIV(short_form, full_form);
  512 }
  513 
  514 
  515 TEST_F(SugarTest, FunctionComplete)
  516 {
  517   const char* short_form =
  518     "class Foo\n"
  519     "  fun box foo(): U32 val => 3";
  520 
  521   TEST_COMPILE(short_form);
  522 }
  523 
  524 
  525 TEST_F(SugarTest, FunctionNoReturnNoBody)
  526 {
  527   const char* short_form =
  528     "trait Foo\n"
  529     "  fun foo()";
  530 
  531   const char* full_form =
  532     "use \"builtin\"\n"
  533     "trait ref Foo\n"
  534     "  fun box foo(): None";
  535 
  536   TEST_EQUIV(short_form, full_form);
  537 }
  538 
  539 
  540 TEST_F(SugarTest, FunctionNoReturnBody)
  541 {
  542   const char* short_form =
  543     "trait Foo\n"
  544     "  fun foo() => 3";
  545 
  546   const char* full_form =
  547     "use \"builtin\"\n"
  548     "trait ref Foo\n"
  549     "  fun box foo(): None => 3\n"
  550     "  None";
  551 
  552   TEST_EQUIV(short_form, full_form);
  553 }
  554 
  555 
  556 TEST_F(SugarTest, FunctionParamMustBeId)
  557 {
  558   const char* good1 =
  559     "trait Foo\n"
  560     "  fun foo(x: U64) => 3";
  561 
  562   TEST_COMPILE(good1);
  563 
  564   const char* good2 =
  565     "trait Foo\n"
  566     "  fun foo(_: U64) => 3";
  567 
  568   TEST_COMPILE(good2);
  569 
  570   const char* bad1 =
  571     "trait Foo\n"
  572     "  fun foo(x.y(): U64) => 3";
  573 
  574   TEST_ERROR(bad1);
  575 
  576   const char* bad2 =
  577     "trait Foo\n"
  578     "  fun foo($: U64) => 3";
  579 
  580   TEST_ERROR(bad2);
  581 }
  582 
  583 
  584 TEST_F(SugarTest, FunctionParamTypeRequired)
  585 {
  586   const char* good =
  587     "trait Foo\n"
  588     "  fun foo(x: U64) => 3";
  589 
  590   TEST_COMPILE(good);
  591 
  592   const char* bad =
  593     "trait Foo\n"
  594     "  fun foo(x) => 3";
  595 
  596   TEST_ERROR(bad);
  597 }
  598 
  599 
  600 TEST_F(SugarTest, FunctionGuardsNotAllowed)
  601 {
  602   const char* good =
  603     "trait Foo\n"
  604     "  fun foo(x: U64) => 3";
  605 
  606   TEST_COMPILE(good);
  607 
  608   const char* bad =
  609     "trait Foo\n"
  610     "  fun foo(x: U64 where x > 0) => 3";
  611 
  612   TEST_ERROR(bad);
  613 }
  614 
  615 
  616 TEST_F(SugarTest, IfWithoutElse)
  617 {
  618   const char* short_form =
  619     "class Foo\n"
  620     "  var create: U32\n"
  621     "  fun f(): U32 val =>\n"
  622     "    if 1 then 2 end";
  623 
  624   const char* full_form =
  625     "use \"builtin\"\n"
  626     "class ref Foo\n"
  627     "  var create: U32\n"
  628     "  fun box f(): U32 val =>\n"
  629     "    if 1 then 2 else None end";
  630 
  631   TEST_EQUIV(short_form, full_form);
  632 }
  633 
  634 
  635 TEST_F(SugarTest, IfWithElse)
  636 {
  637   const char* short_form =
  638     "class Foo\n"
  639     "  var create: U32\n"
  640     "  fun f(): U32 val =>\n"
  641     "    if 1 then 2 else 3 end";
  642 
  643   TEST_COMPILE(short_form);
  644 }
  645 
  646 
  647 TEST_F(SugarTest, NotIf)
  648 {
  649   const char* short_form =
  650     "class Foo\n"
  651     "  fun f() =>\n"
  652     "    let a = true\n"
  653     "    if not if a then not a else a end then a end";
  654 
  655   TEST_COMPILE(short_form);
  656 }
  657 
  658 
  659 TEST_F(SugarTest, WhileWithoutElse)
  660 {
  661   const char* short_form =
  662     "class Foo\n"
  663     "  var create: U32\n"
  664     "  fun f(): U32 val =>\n"
  665     "    while 1 do 2 end";
  666 
  667   const char* full_form =
  668     "use \"builtin\"\n"
  669     "class ref Foo\n"
  670     "  var create: U32\n"
  671     "  fun box f(): U32 val =>\n"
  672     "    while 1 do 2 else None end";
  673 
  674   TEST_EQUIV(short_form, full_form);
  675 }
  676 
  677 
  678 TEST_F(SugarTest, WhileWithElse)
  679 {
  680   const char* short_form =
  681     "class Foo\n"
  682     "  var create: U32\n"
  683     "  fun f(): U32 val =>\n"
  684     "    while 1 do 2 else 3 end";
  685 
  686   TEST_COMPILE(short_form);
  687 }
  688 
  689 
  690 TEST_F(SugarTest, NotWhileWithElse)
  691 {
  692   const char* short_form =
  693     "class Foo\n"
  694     "  fun f(): U32 val =>\n"
  695     "    let a = true\n"
  696     "    not while a do true else false end";
  697 
  698   TEST_COMPILE(short_form);
  699 }
  700 
  701 
  702 TEST_F(SugarTest, TryWithElseAndThen)
  703 {
  704   const char* short_form =
  705     "class Foo\n"
  706     "  var create: U32\n"
  707     "  fun f(): U32 val =>\n"
  708     "    try 1 else 2 then 3 end";
  709 
  710   TEST_COMPILE(short_form);
  711 }
  712 
  713 
  714 TEST_F(SugarTest, TryWithoutElseOrThen)
  715 {
  716   const char* short_form =
  717     "class Foo\n"
  718     "  var create: U32\n"
  719     "  fun f(): U32 val =>\n"
  720     "    try 1 end";
  721 
  722   const char* full_form =
  723     "use \"builtin\"\n"
  724     "class ref Foo\n"
  725     "  var create: U32\n"
  726     "  fun box f(): U32 val =>\n"
  727     "    try 1 else None then None end";
  728 
  729   TEST_EQUIV(short_form, full_form);
  730 }
  731 
  732 
  733 TEST_F(SugarTest, TryWithoutElse)
  734 {
  735   const char* short_form =
  736     "class Foo\n"
  737     "  var create: U32\n"
  738     "  fun f(): U32 val =>\n"
  739     "    try 1 then 2 end";
  740 
  741   const char* full_form =
  742     "use \"builtin\"\n"
  743     "class ref Foo\n"
  744     "  var create: U32\n"
  745     "  fun box f(): U32 val =>\n"
  746     "    $try_no_check 1 else None then 2 end";
  747 
  748   TEST_EQUIV(short_form, full_form);
  749 }
  750 
  751 
  752 TEST_F(SugarTest, TryWithoutThen)
  753 {
  754   const char* short_form =
  755     "class Foo\n"
  756     "  var create: U32\n"
  757     "  fun f(): U32 val =>\n"
  758     "    try 1 else 2 end";
  759 
  760   const char* full_form =
  761     "use \"builtin\"\n"
  762     "class ref Foo\n"
  763     "  var create: U32\n"
  764     "  fun box f(): U32 val =>\n"
  765     "    try 1 else 2 then None end";
  766 
  767   TEST_EQUIV(short_form, full_form);
  768 }
  769 
  770 
  771 TEST_F(SugarTest, ForWithoutElse)
  772 {
  773   const char* short_form =
  774     "class Foo\n"
  775     "  var create: U32\n"
  776     "  fun f(): U32 val =>\n"
  777     "    for i in 1 do 2 end";
  778 
  779   const char* full_form =
  780     "use \"builtin\"\n"
  781     "class ref Foo\n"
  782     "  var create: U32\n"
  783     "  fun box f(): U32 val =>\n"
  784     "  (\n"
  785     "    let $1 = (1)\n"
  786     "    while $1.has_next() do\n"
  787     "      let i = $try_no_check\n"
  788     "        $1.next()?\n"
  789     "      else\n"
  790     "        break\n"
  791     "      then\n"
  792     "        None\n"
  793     "      end\n"
  794     "      (2)\n"
  795     "    else None end\n"
  796     "  )";
  797 
  798   TEST_EQUIV(short_form, full_form);
  799 }
  800 
  801 
  802 TEST_F(SugarTest, ForWithElse)
  803 {
  804   const char* short_form =
  805     "class Foo\n"
  806     "  var create: U32\n"
  807     "  fun f(): U32 val =>\n"
  808     "    for i in 1 do 2 else 3 end";
  809 
  810   const char* full_form =
  811     "use \"builtin\"\n"
  812     "class ref Foo\n"
  813     "  var create: U32\n"
  814     "  fun box f(): U32 val =>\n"
  815     "  (\n"
  816     "    let $1 = (1)\n"
  817     "    while $1.has_next() do\n"
  818     "      let i = $try_no_check\n"
  819     "        $1.next()?\n"
  820     "      else\n"
  821     "        break\n"
  822     "      then\n"
  823     "        None\n"
  824     "      end\n"
  825     "      (2)\n"
  826     "    else 3 end\n"
  827     "  )";
  828 
  829   TEST_EQUIV(short_form, full_form);
  830 }
  831 
  832 
  833 TEST_F(SugarTest, NotForWithElse)
  834 {
  835   const char* short_form =
  836     "class Foo\n"
  837     "  fun f()=>\n"
  838     "    not for i in 1 do true else false end";
  839 
  840   TEST_COMPILE(short_form);
  841 }
  842 
  843 
  844 TEST_F(SugarTest, MultiIteratorFor)
  845 {
  846   const char* short_form =
  847     "class Foo\n"
  848     "  var create: U32\n"
  849     "  fun f(): U32 val =>\n"
  850     "    for (i, j) in 1 do 2 end";
  851 
  852   const char* full_form =
  853     "use \"builtin\"\n"
  854     "class ref Foo\n"
  855     "  var create: U32\n"
  856     "  fun box f(): U32 val =>\n"
  857     "  (\n"
  858     "    let $1 = (1)\n"
  859     "    while $1.has_next() do\n"
  860     "      (let i, let j) = $try_no_check\n"
  861     "        $1.next()?\n"
  862     "      else\n"
  863     "        break\n"
  864     "      then\n"
  865     "        None\n"
  866     "      end\n"
  867     "      (2)\n"
  868     "    else None end\n"
  869     "  )";
  870 
  871   TEST_EQUIV(short_form, full_form);
  872 }
  873 
  874 
  875 TEST_F(SugarTest, CaseWithBody)
  876 {
  877   const char* short_form =
  878     "class Foo\n"
  879     "  var create: U32\n"
  880     "  fun f(): U32 val =>\n"
  881     "    match(x)\n"
  882     "    |1 => 2\n"
  883     "    else\n"
  884     "      3\n"
  885     "    end";
  886 
  887   TEST_COMPILE(short_form);
  888 }
  889 
  890 
  891 TEST_F(SugarTest, CaseWithBodyAndFollowingCase)
  892 {
  893   const char* short_form =
  894     "class Foo\n"
  895     "  var create: U32\n"
  896     "  fun f(): U32 val =>\n"
  897     "    match(x)\n"
  898     "    |1 => 2\n"
  899     "    |3 => 4\n"
  900     "    else\n"
  901     "      5\n"
  902     "    end";
  903 
  904   TEST_COMPILE(short_form);
  905 }
  906 
  907 
  908 TEST_F(SugarTest, CaseWithNoBody)
  909 {
  910   const char* short_form =
  911     "class Foo\n"
  912     "  var create: U32\n"
  913     "  fun f(): U32 val =>\n"
  914     "    match(x)\n"
  915     "    |1\n"
  916     "    |2 => 3\n"
  917     "    else\n"
  918     "      4\n"
  919     "    end";
  920 
  921   const char* full_form =
  922     "use \"builtin\"\n"
  923     "class ref Foo\n"
  924     "  var create: U32\n"
  925     "  fun box f(): U32 val =>\n"
  926     "    match(x)\n"
  927     "    |1 => 3\n"
  928     "    |2 => 3\n"
  929     "    else\n"
  930     "      4\n"
  931     "    end";
  932 
  933   TEST_EQUIV(short_form, full_form);
  934 }
  935 
  936 
  937 TEST_F(SugarTest, CaseWithNoBodyMultiple)
  938 {
  939   const char* short_form =
  940     "class Foo\n"
  941     "  var create: U32\n"
  942     "  fun f(): U32 val =>\n"
  943     "    match(x)\n"
  944     "    |1\n"
  945     "    |2\n"
  946     "    |3\n"
  947     "    |4 => 5\n"
  948     "    else\n"
  949     "      6\n"
  950     "    end";
  951 
  952   const char* full_form =
  953     "use \"builtin\"\n"
  954     "class ref Foo\n"
  955     "  var create: U32\n"
  956     "  fun box f(): U32 val =>\n"
  957     "    match(x)\n"
  958     "    |1 => 5\n"
  959     "    |2 => 5\n"
  960     "    |3 => 5\n"
  961     "    |4 => 5\n"
  962     "    else\n"
  963     "      6\n"
  964     "    end";
  965 
  966   TEST_EQUIV(short_form, full_form);
  967 }
  968 
  969 
  970 TEST_F(SugarTest, CasePatternCapture)
  971 {
  972   const char* short_form =
  973     "class Foo\n"
  974     "  var create: U32\n"
  975     "  fun f(): U32 val =>\n"
  976     "    match(a)\n"
  977     "    | let x: U32 => 1\n"
  978     "    else\n"
  979     "      2\n"
  980     "    end";
  981 
  982   const char* full_form =
  983     "use \"builtin\"\n"
  984     "class ref Foo\n"
  985     "  var create: U32\n"
  986     "  fun box f(): U32 val =>\n"
  987     "    match(a)\n"
  988     "    | $let x: U32 => 1\n"
  989     "    else\n"
  990     "      2\n"
  991     "    end";
  992 
  993   TEST_EQUIV(short_form, full_form);
  994 }
  995 
  996 
  997 TEST_F(SugarTest, CasePatternCaptureVar)
  998 {
  999   const char* short_form =
 1000     "class Foo\n"
 1001     "  var create: U32\n"
 1002     "  fun f(): U32 val =>\n"
 1003     "    match(a)\n"
 1004     "    | var x: U32 => 1\n"
 1005     "    else\n"
 1006     "      2\n"
 1007     "    end";
 1008 
 1009   TEST_ERROR(short_form);
 1010 }
 1011 
 1012 
 1013 TEST_F(SugarTest, CasePatternCaptureInTuple)
 1014 {
 1015   const char* short_form =
 1016     "class Foo\n"
 1017     "  var create: U32\n"
 1018     "  fun f(): U32 val =>\n"
 1019     "    match(a)\n"
 1020     "    | (let x: U32, let y: U16) => 1\n"
 1021     "    else\n"
 1022     "      2\n"
 1023     "    end";
 1024 
 1025   const char* full_form =
 1026     "use \"builtin\"\n"
 1027     "class ref Foo\n"
 1028     "  var create: U32\n"
 1029     "  fun box f(): U32 val =>\n"
 1030     "    match(a)\n"
 1031     "    | ($let x: U32, $let y: U16) => 1\n"
 1032     "    else\n"
 1033     "      2\n"
 1034     "    end";
 1035 
 1036   TEST_EQUIV(short_form, full_form);
 1037 }
 1038 
 1039 
 1040 TEST_F(SugarTest, CasePatternCaptureInNestedTuple)
 1041 {
 1042   const char* short_form =
 1043     "class Foo\n"
 1044     "  var create: U32\n"
 1045     "  fun f(): U32 val =>\n"
 1046     "    match(a)\n"
 1047     "    | (4, (let y: U16, _)) => 1\n"
 1048     "    else\n"
 1049     "      2\n"
 1050     "    end";
 1051 
 1052   const char* full_form =
 1053     "use \"builtin\"\n"
 1054     "class ref Foo\n"
 1055     "  var create: U32\n"
 1056     "  fun box f(): U32 val =>\n"
 1057     "    match(a)\n"
 1058     "    | (4, ($let y: U16, _)) => 1\n"
 1059     "    else\n"
 1060     "      2\n"
 1061     "    end";
 1062 
 1063   TEST_EQUIV(short_form, full_form);
 1064 }
 1065 
 1066 
 1067 TEST_F(SugarTest, CasePatternCaptureNoType)
 1068 {
 1069   const char* short_form =
 1070     "class Foo\n"
 1071     "  var create: U32\n"
 1072     "  fun f(): U32 val =>\n"
 1073     "    match(a)\n"
 1074     "    | let x => 1\n"
 1075     "    else\n"
 1076     "      2\n"
 1077     "    end";
 1078 
 1079   TEST_ERROR(short_form);
 1080 }
 1081 
 1082 
 1083 TEST_F(SugarTest, CasePatternCaptureTupleType)
 1084 {
 1085   const char* short_form =
 1086     "class Foo\n"
 1087     "  var create: U32\n"
 1088     "  fun f(): U32 val =>\n"
 1089     "    match(a)\n"
 1090     "    | let x: (U32, U16) => 1\n"
 1091     "    else\n"
 1092     "      2\n"
 1093     "    end";
 1094 
 1095   TEST_ERROR(short_form);
 1096 }
 1097 
 1098 
 1099 TEST_F(SugarTest, CasePatternNotCaptureInSequence)
 1100 {
 1101   const char* short_form =
 1102     "class Foo\n"
 1103     "  var create: U32\n"
 1104     "  fun f(): U32 val =>\n"
 1105     "    match(a)\n"
 1106     "    | (4\n"
 1107     "       let x: U32) => 1\n"
 1108     "    else\n"
 1109     "      2\n"
 1110     "    end";
 1111 
 1112   const char* full_form =
 1113     "use \"builtin\"\n"
 1114     "class ref Foo\n"
 1115     "  var create: U32\n"
 1116     "  fun box f(): U32 val =>\n"
 1117     "    match(a)\n"
 1118     "    | (4\n"
 1119     "       let x: U32) => 1\n"
 1120     "    else\n"
 1121     "      2\n"
 1122     "    end";
 1123 
 1124   TEST_EQUIV(short_form, full_form);
 1125 }
 1126 
 1127 
 1128 TEST_F(SugarTest, MatchWithNoElse)
 1129 {
 1130   const char* short_form =
 1131     "class Foo\n"
 1132     "  var create: U32\n"
 1133     "  fun f(): U32 val =>\n"
 1134     "    match(x)\n"
 1135     "    |1 => 2\n"
 1136     "    end";
 1137 
 1138   const char* full_form =
 1139     "use \"builtin\"\n"
 1140     "class ref Foo\n"
 1141     "  var create: U32\n"
 1142     "  fun box f(): U32 val =>\n"
 1143     "    match(x)\n"
 1144     "    |1 => 2\n"
 1145     "    end";
 1146 
 1147   TEST_EQUIV(short_form, full_form);
 1148 }
 1149 
 1150 
 1151 TEST_F(SugarTest, UpdateLhsNotCall)
 1152 {
 1153   const char* short_form =
 1154     "class Foo\n"
 1155     "  var create: U32\n"
 1156     "  fun f(): U32 val =>\n"
 1157     "    foo = 1";
 1158 
 1159   TEST_COMPILE(short_form);
 1160 }
 1161 
 1162 
 1163 TEST_F(SugarTest, UpdateNoArgs)
 1164 {
 1165   const char* short_form =
 1166     "class Foo\n"
 1167     "  var create: U32\n"
 1168     "  fun f(): U32 val =>\n"
 1169     "    foo() = 1";
 1170 
 1171   const char* full_form =
 1172     "use \"builtin\"\n"
 1173     "class ref Foo\n"
 1174     "  var create: U32\n"
 1175     "  fun box f(): U32 val =>\n"
 1176     "    foo.update(where value $updatearg = 1)";
 1177 
 1178   TEST_EQUIV(short_form, full_form);
 1179 }
 1180 
 1181 
 1182 TEST_F(SugarTest, UpdateWithArgs)
 1183 {
 1184   const char* short_form =
 1185     "class Foo\n"
 1186     "  var create: U32\n"
 1187     "  fun f(): U32 val =>\n"
 1188     "    foo(2, 3 where bar = 4) = 1";
 1189 
 1190   const char* full_form =
 1191     "use \"builtin\"\n"
 1192     "class ref Foo\n"
 1193     "  var create: U32\n"
 1194     "  fun box f(): U32 val =>\n"
 1195     "    foo.update(2, 3 where bar = 4, value $updatearg = 1)";
 1196 
 1197   TEST_EQUIV(short_form, full_form);
 1198 }
 1199 
 1200 
 1201 // Operator subsituation
 1202 
 1203 TEST_F(SugarTest, Add)
 1204 {
 1205   const char* short_form =
 1206     "class Foo\n"
 1207     "  var create: U32\n"
 1208     "  fun f(): U32 val =>\n"
 1209     "    1 + 2";
 1210 
 1211   const char* full_form =
 1212     "use \"builtin\"\n"
 1213     "class ref Foo\n"
 1214     "  var create: U32\n"
 1215     "  fun box f(): U32 val =>\n"
 1216     "    1.add(2)";
 1217 
 1218   TEST_EQUIV(short_form, full_form);
 1219 }
 1220 
 1221 
 1222 TEST_F(SugarTest, Sub)
 1223 {
 1224   const char* short_form =
 1225     "class Foo\n"
 1226     "  var create: U32\n"
 1227     "  fun f(): U32 val =>\n"
 1228     "    1 - 2";
 1229 
 1230   const char* full_form =
 1231     "use \"builtin\"\n"
 1232     "class ref Foo\n"
 1233     "  var create: U32\n"
 1234     "  fun box f(): U32 val =>\n"
 1235     "    1.sub(2)";
 1236 
 1237   TEST_EQUIV(short_form, full_form);
 1238 }
 1239 
 1240 
 1241 TEST_F(SugarTest, Multiply)
 1242 {
 1243   const char* short_form =
 1244     "class Foo\n"
 1245     "  var create: U32\n"
 1246     "  fun f(): U32 val =>\n"
 1247     "    1 * 2";
 1248 
 1249   const char* full_form =
 1250     "use \"builtin\"\n"
 1251     "class ref Foo\n"
 1252     "  var create: U32\n"
 1253     "  fun box f(): U32 val =>\n"
 1254     "    1.mul(2)";
 1255 
 1256   TEST_EQUIV(short_form, full_form);
 1257 }
 1258 
 1259 
 1260 TEST_F(SugarTest, Divide)
 1261 {
 1262   const char* short_form =
 1263     "class Foo\n"
 1264     "  var create: U32\n"
 1265     "  fun f(): U32 val =>\n"
 1266     "    1 / 2";
 1267 
 1268   const char* full_form =
 1269     "use \"builtin\"\n"
 1270     "class ref Foo\n"
 1271     "  var create: U32\n"
 1272     "  fun box f(): U32 val =>\n"
 1273     "    1.div(2)";
 1274 
 1275   TEST_EQUIV(short_form, full_form);
 1276 }
 1277 
 1278 
 1279 TEST_F(SugarTest, Rem)
 1280 {
 1281   const char* short_form =
 1282     "class Foo\n"
 1283     "  var create: U32\n"
 1284     "  fun f(): U32 val =>\n"
 1285     "    1 % 2";
 1286 
 1287   const char* full_form =
 1288     "use \"builtin\"\n"
 1289     "class ref Foo\n"
 1290     "  var create: U32\n"
 1291     "  fun box f(): U32 val =>\n"
 1292     "    1.rem(2)";
 1293 
 1294   TEST_EQUIV(short_form, full_form);
 1295 }
 1296 
 1297 
 1298 TEST_F(SugarTest, UnaryMinus)
 1299 {
 1300   const char* short_form =
 1301     "class Foo\n"
 1302     "  var create: U32\n"
 1303     "  fun f(): U32 val =>\n"
 1304     "    -1";
 1305 
 1306   const char* full_form =
 1307     "use \"builtin\"\n"
 1308     "class ref Foo\n"
 1309     "  var create: U32\n"
 1310     "  fun box f(): U32 val =>\n"
 1311     "    1.neg()";
 1312 
 1313   TEST_EQUIV(short_form, full_form);
 1314 }
 1315 
 1316 
 1317 TEST_F(SugarTest, ShiftLeft)
 1318 {
 1319   const char* short_form =
 1320     "class Foo\n"
 1321     "  var create: U32\n"
 1322     "  fun f(): U32 val =>\n"
 1323     "    1 << 2";
 1324 
 1325   const char* full_form =
 1326     "use \"builtin\"\n"
 1327     "class ref Foo\n"
 1328     "  var create: U32\n"
 1329     "  fun box f(): U32 val =>\n"
 1330     "    1.shl(2)";
 1331 
 1332   TEST_EQUIV(short_form, full_form);
 1333 }
 1334 
 1335 
 1336 TEST_F(SugarTest, ShiftRight)
 1337 {
 1338   const char* short_form =
 1339     "class Foo\n"
 1340     "  var create: U32\n"
 1341     "  fun f(): U32 val =>\n"
 1342     "    1 >> 2";
 1343 
 1344   const char* full_form =
 1345     "use \"builtin\"\n"
 1346     "class ref Foo\n"
 1347     "  var create: U32\n"
 1348     "  fun box f(): U32 val =>\n"
 1349     "    1.shr(2)";
 1350 
 1351   TEST_EQUIV(short_form, full_form);
 1352 }
 1353 
 1354 
 1355 TEST_F(SugarTest, And)
 1356 {
 1357   const char* short_form =
 1358     "class Foo\n"
 1359     "  var create: U32\n"
 1360     "  fun f(): U32 val =>\n"
 1361     "    1 and 2";
 1362 
 1363   const char* full_form =
 1364     "use \"builtin\"\n"
 1365     "class ref Foo\n"
 1366     "  var create: U32\n"
 1367     "  fun box f(): U32 val =>\n"
 1368     "    1.op_and(2)";
 1369 
 1370   TEST_EQUIV(short_form, full_form);
 1371 }
 1372 
 1373 
 1374 TEST_F(SugarTest, Or)
 1375 {
 1376   const char* short_form =
 1377     "class Foo\n"
 1378     "  var create: U32\n"
 1379     "  fun f(): U32 val =>\n"
 1380     "    1 or 2";
 1381 
 1382   const char* full_form =
 1383     "use \"builtin\"\n"
 1384     "class ref Foo\n"
 1385     "  var create: U32\n"
 1386     "  fun box f(): U32 val =>\n"
 1387     "    1.op_or(2)";
 1388 
 1389   TEST_EQUIV(short_form, full_form);
 1390 }
 1391 
 1392 
 1393 TEST_F(SugarTest, Xor)
 1394 {
 1395   const char* short_form =
 1396     "class Foo\n"
 1397     "  var create: U32\n"
 1398     "  fun f(): U32 val =>\n"
 1399     "    1 xor 2";
 1400 
 1401   const char* full_form =
 1402     "use \"builtin\"\n"
 1403     "class ref Foo\n"
 1404     "  var create: U32\n"
 1405     "  fun box f(): U32 val =>\n"
 1406     "    1.op_xor(2)";
 1407 
 1408   TEST_EQUIV(short_form, full_form);
 1409 }
 1410 
 1411 
 1412 TEST_F(SugarTest, Not)
 1413 {
 1414   const char* short_form =
 1415     "class Foo\n"
 1416     "  var create: U32\n"
 1417     "  fun f(): U32 val =>\n"
 1418     "    not 1";
 1419 
 1420   const char* full_form =
 1421     "use \"builtin\"\n"
 1422     "class ref Foo\n"
 1423     "  var create: U32\n"
 1424     "  fun box f(): U32 val =>\n"
 1425     "    1.op_not()";
 1426 
 1427   TEST_EQUIV(short_form, full_form);
 1428 }
 1429 
 1430 
 1431 TEST_F(SugarTest, Eq)
 1432 {
 1433   const char* short_form =
 1434     "class Foo\n"
 1435     "  var create: U32\n"
 1436     "  fun f(): U32 val =>\n"
 1437     "    1 == 2";
 1438 
 1439   const char* full_form =
 1440     "use \"builtin\"\n"
 1441     "class ref Foo\n"
 1442     "  var create: U32\n"
 1443     "  fun box f(): U32 val =>\n"
 1444     "    1.eq(2)";
 1445 
 1446   TEST_EQUIV(short_form, full_form);
 1447 }
 1448 
 1449 
 1450 TEST_F(SugarTest, Ne)
 1451 {
 1452   const char* short_form =
 1453     "class Foo\n"
 1454     "  var create: U32\n"
 1455     "  fun f(): U32 val =>\n"
 1456     "    1 != 2";
 1457 
 1458   const char* full_form =
 1459     "use \"builtin\"\n"
 1460     "class ref Foo\n"
 1461     "  var create: U32\n"
 1462     "  fun box f(): U32 val =>\n"
 1463     "    1.ne(2)";
 1464 
 1465   TEST_EQUIV(short_form, full_form);
 1466 }
 1467 
 1468 
 1469 TEST_F(SugarTest, Lt)
 1470 {
 1471   const char* short_form =
 1472     "class Foo\n"
 1473     "  var create: U32\n"
 1474     "  fun f(): U32 val =>\n"
 1475     "    1 < 2";
 1476 
 1477   const char* full_form =
 1478     "use \"builtin\"\n"
 1479     "class ref Foo\n"
 1480     "  var create: U32\n"
 1481     "  fun box f(): U32 val =>\n"
 1482     "    1.lt(2)";
 1483 
 1484   TEST_EQUIV(short_form, full_form);
 1485 }
 1486 
 1487 
 1488 TEST_F(SugarTest, Le)
 1489 {
 1490   const char* short_form =
 1491     "class Foo\n"
 1492     "  var create: U32\n"
 1493     "  fun f(): U32 val =>\n"
 1494     "    1 <= 2";
 1495 
 1496   const char* full_form =
 1497     "use \"builtin\"\n"
 1498     "class ref Foo\n"
 1499     "  var create: U32\n"
 1500     "  fun box f(): U32 val =>\n"
 1501     "    1.le(2)";
 1502 
 1503   TEST_EQUIV(short_form, full_form);
 1504 }
 1505 
 1506 
 1507 TEST_F(SugarTest, Gt)
 1508 {
 1509   const char* short_form =
 1510     "class Foo\n"
 1511     "  var create: U32\n"
 1512     "  fun f(): U32 val =>\n"
 1513     "    1 > 2";
 1514 
 1515   const char* full_form =
 1516     "use \"builtin\"\n"
 1517     "class ref Foo\n"
 1518     "  var create: U32\n"
 1519     "  fun box f(): U32 val =>\n"
 1520     "    1.gt(2)";
 1521 
 1522   TEST_EQUIV(short_form, full_form);
 1523 }
 1524 
 1525 
 1526 TEST_F(SugarTest, Ge)
 1527 {
 1528   const char* short_form =
 1529     "class Foo\n"
 1530     "  var create: U32\n"
 1531     "  fun f(): U32 val =>\n"
 1532     "    1 >= 2";
 1533 
 1534   const char* full_form =
 1535     "use \"builtin\"\n"
 1536     "class ref Foo\n"
 1537     "  var create: U32\n"
 1538     "  fun box f(): U32 val =>\n"
 1539     "    1.ge(2)";
 1540 
 1541   TEST_EQUIV(short_form, full_form);
 1542 }
 1543 
 1544 
 1545 TEST_F(SugarTest, LambdaTypeSimple)
 1546 {
 1547   const char* short_form =
 1548     "trait Foo\n"
 1549     "  fun f(x: {()})";
 1550 
 1551   const char* full_form =
 1552     "use \"builtin\"\n"
 1553     "trait ref Foo\n"
 1554     "  fun box f(x: $T): None\n"
 1555 
 1556     "interface ref $T\n"
 1557     "  fun box apply(): None";
 1558 
 1559   TEST_EQUIV(short_form, full_form);
 1560 }
 1561 
 1562 
 1563 TEST_F(SugarTest, LambdaTypeNamed)
 1564 {
 1565   const char* short_form =
 1566     "trait Foo\n"
 1567     "  fun f(x: {bar ()})";
 1568 
 1569   const char* full_form =
 1570     "use \"builtin\"\n"
 1571     "trait ref Foo\n"
 1572     "  fun box f(x: $T): None\n"
 1573 
 1574     "interface ref $T\n"
 1575     "  fun box bar(): None";
 1576 
 1577   TEST_EQUIV(short_form, full_form);
 1578 }
 1579 
 1580 
 1581 TEST_F(SugarTest, LambdaTypeParamsAndReturn)
 1582 {
 1583   const char* short_form =
 1584     "trait Foo\n"
 1585     "  fun f(x: {(U32, U16): Bool})";
 1586 
 1587   const char* full_form =
 1588     "use \"builtin\"\n"
 1589     "trait ref Foo\n"
 1590     "  fun box f(x: $T): None\n"
 1591 
 1592     "interface ref $T\n"
 1593     "  fun box apply(p1: U32, p2: U16): Bool";
 1594 
 1595   TEST_EQUIV(short_form, full_form);
 1596 }
 1597 
 1598 
 1599 TEST_F(SugarTest, LambdaTypeFunTypeParams)
 1600 {
 1601   const char* short_form =
 1602     "trait Foo\n"
 1603     "  fun f(x: {[A: F64, B: F32](A, U16): B})";
 1604 
 1605   const char* full_form =
 1606     "use \"builtin\"\n"
 1607     "trait ref Foo\n"
 1608     "  fun box f(x: $T): None\n"
 1609 
 1610     "interface ref $T\n"
 1611     "  fun box apply[A: F64, B: F32](p1: A, p2: U16): B";
 1612 
 1613   TEST_EQUIV(short_form, full_form);
 1614 }
 1615 
 1616 
 1617 TEST_F(SugarTest, LambdaTypeCapAndError)
 1618 {
 1619   const char* short_form =
 1620     "trait Foo\n"
 1621     "  fun f(x: {ref (U32, U16): Bool ?})";
 1622 
 1623   const char* full_form =
 1624     "use \"builtin\"\n"
 1625     "trait ref Foo\n"
 1626     "  fun box f(x: $T): None\n"
 1627 
 1628     "interface ref $T\n"
 1629     "  fun ref apply(p1: U32, p2: U16): Bool ?";
 1630 
 1631   TEST_EQUIV(short_form, full_form);
 1632 }
 1633 
 1634 
 1635 TEST_F(SugarTest, LambdaTypeScopeTypeParams)
 1636 {
 1637   const char* short_form =
 1638     "trait Foo[A: F64, B: F32]\n"
 1639     "  fun f(x: {(A, U16): B})";
 1640 
 1641   const char* full_form =
 1642     "use \"builtin\"\n"
 1643     "trait ref Foo[A: F64, B: F32]\n"
 1644     "  fun box f(x: $T[A, B]): None\n"
 1645 
 1646     "interface ref $T[A: F64, B: F32]\n"
 1647     "  fun box apply(p1: A, p2: U16): B";
 1648 
 1649   TEST_EQUIV(short_form, full_form);
 1650 }
 1651 
 1652 
 1653 TEST_F(SugarTest, LambdaTypeScopeTypeParamsInFlet)
 1654 {
 1655   const char* short_form =
 1656     "class Foo[A: F64, B: F32]\n"
 1657     "  let f: {(A, U16): B}";
 1658 
 1659   const char* full_form =
 1660     "use \"builtin\"\n"
 1661     "class ref Foo[A: F64, B: F32]\n"
 1662     "  let f: $T[A, B]\n"
 1663     "  new iso create(): Foo[A, B] iso^ =>\n"
 1664     "    true\n"
 1665 
 1666     "interface ref $T[A: F64, B: F32]\n"
 1667     "  fun box apply(p1: A, p2: U16): B";
 1668 
 1669   TEST_EQUIV(short_form, full_form);
 1670 }
 1671 
 1672 
 1673 TEST_F(SugarTest, LambdaTypeSimpleAliased)
 1674 {
 1675   const char* short_form =
 1676     "type Foo is {()}";
 1677 
 1678   const char* full_form =
 1679     "use \"builtin\"\n"
 1680     "type Foo is $T\n"
 1681 
 1682     "interface ref $T\n"
 1683     "  fun box apply(): None";
 1684 
 1685   TEST_EQUIV(short_form, full_form);
 1686 }
 1687 
 1688 
 1689 TEST_F(SugarTest, UseGuardNormalises)
 1690 {
 1691   const char* short_form =
 1692     "use \"test:Foo\" if (windows or linux) and not debug";
 1693 
 1694   const char* full_form =
 1695     "use \"builtin\"\n"
 1696     "use \"test:Foo\" if\n"
 1697     "  $flag windows $ifdefor $flag linux\n"
 1698     "  $ifdefand $ifdefnot $flag debug";
 1699 
 1700   TEST_EQUIV(short_form, full_form);
 1701 }
 1702 
 1703 
 1704 TEST_F(SugarTest, UseGuardNeverTrue)
 1705 {
 1706   const char* short_form =
 1707     "use \"test:Foo\" if (debug and not debug)";
 1708 
 1709   TEST_ERROR(short_form);
 1710 }
 1711 
 1712 
 1713 TEST_F(SugarTest, UseGuardAlwaysTrue)
 1714 {
 1715   const char* short_form =
 1716     "use \"test:Foo\" if (debug or not debug)";
 1717 
 1718   TEST_COMPILE(short_form);
 1719 }
 1720 
 1721 
 1722 TEST_F(SugarTest, UseGuardUserFlagNormalises)
 1723 {
 1724   const char* short_form =
 1725     "use \"test:Foo\" if \"foo\"";
 1726 
 1727   const char* full_form =
 1728     "use \"builtin\"\n"
 1729     "use \"test:Foo\" if $flag foo";
 1730 
 1731   TEST_EQUIV(short_form, full_form);
 1732 }
 1733 
 1734 
 1735 TEST_F(SugarTest, IfdefElseCondition)
 1736 {
 1737   const char* short_form =
 1738     "class Foo\n"
 1739     "  var create: U32\n"
 1740     "  fun f() =>\n"
 1741     "    ifdef windows then\n"
 1742     "      3\n"
 1743     "    else\n"
 1744     "      4\n"
 1745     "    end";
 1746 
 1747   const char* full_form =
 1748     "use \"builtin\"\n"
 1749     "class ref Foo\n"
 1750     "  var create: U32\n"
 1751     "  fun box f(): None =>\n"
 1752     "    ifdef $flag windows $extra $ifdefnot $flag windows then\n"
 1753     "      3\n"
 1754     "    else\n"
 1755     "      4\n"
 1756     "    end\n"
 1757     "    None";
 1758 
 1759   TEST_EQUIV(short_form, full_form);
 1760 }
 1761 
 1762 
 1763 TEST_F(SugarTest, IfdefSugarElse)
 1764 {
 1765   const char* short_form =
 1766     "class Foo\n"
 1767     "  var create: U32\n"
 1768     "  fun f() =>\n"
 1769     "    ifdef windows then\n"
 1770     "      3\n"
 1771     "    end";
 1772 
 1773   const char* full_form =
 1774     "use \"builtin\"\n"
 1775     "class ref Foo\n"
 1776     "  var create: U32\n"
 1777     "  fun box f(): None =>\n"
 1778     "    ifdef $flag windows $extra $ifdefnot $flag windows then\n"
 1779     "      3\n"
 1780     "    else\n"
 1781     "      None\n"
 1782     "    end\n"
 1783     "    None";
 1784 
 1785   TEST_EQUIV(short_form, full_form);
 1786 }
 1787 
 1788 
 1789 TEST_F(SugarTest, NestedIfdefCondition)
 1790 {
 1791   const char* short_form =
 1792     "class Foo\n"
 1793     "  var create: U32\n"
 1794     "  fun f() =>\n"
 1795     "    ifdef windows then\n"
 1796     "      ifdef debug then\n"
 1797     "        1\n"
 1798     "      else\n"
 1799     "        2\n"
 1800     "      end\n"
 1801     "    else\n"
 1802     "      ifdef \"foo\" then\n"
 1803     "        3\n"
 1804     "      else\n"
 1805     "        4\n"
 1806     "      end\n"
 1807     "    end";
 1808 
 1809   const char* full_form =
 1810     "use \"builtin\"\n"
 1811     "class ref Foo\n"
 1812     "  var create: U32\n"
 1813     "  fun box f(): None =>\n"
 1814     "    ifdef $flag windows\n"
 1815     "    $extra $ifdefnot $flag windows then\n"
 1816     "      ifdef $flag windows $ifdefand $flag debug\n"
 1817     "      $extra $flag windows $ifdefand $ifdefnot $flag debug then\n"
 1818     "        1\n"
 1819     "      else\n"
 1820     "        2\n"
 1821     "      end\n"
 1822     "    else\n"
 1823     "      ifdef $ifdefnot $flag windows $ifdefand $flag foo\n"
 1824     "      $extra $ifdefnot $flag windows $ifdefand $ifdefnot $flag foo then\n"
 1825     "        3\n"
 1826     "      else\n"
 1827     "        4\n"
 1828     "      end\n"
 1829     "    end\n"
 1830     "    None";
 1831 
 1832   TEST_EQUIV(short_form, full_form);
 1833 }
 1834 
 1835 
 1836 TEST_F(SugarTest, IfdefElseConditionNeverTrue)
 1837 {
 1838   const char* short_form =
 1839     "class Foo\n"
 1840     "  var create: U32\n"
 1841     "  fun f() =>\n"
 1842     "    ifdef debug and not debug then\n"
 1843     "      3\n"
 1844     "    end";
 1845 
 1846   TEST_ERROR(short_form);
 1847 }
 1848 
 1849 
 1850 TEST_F(SugarTest, IfdefElseConditionAlwaysTrue)
 1851 {
 1852   const char* short_form =
 1853     "class Foo\n"
 1854     "  var create: U32\n"
 1855     "  fun f() =>\n"
 1856     "    ifdef debug or not debug then\n"
 1857     "      3\n"
 1858     "    end";
 1859 
 1860   TEST_ERROR(short_form);
 1861 }
 1862 
 1863 
 1864 TEST_F(SugarTest, NestedIfdefElseConditionNeverTrue)
 1865 {
 1866   const char* short_form =
 1867     "class Foo\n"
 1868     "  var create: U32\n"
 1869     "  fun f() =>\n"
 1870     "    ifdef windows then\n"
 1871     "      ifdef linux then\n"
 1872     "        3\n"
 1873     "      end\n"
 1874     "    end";
 1875 
 1876   TEST_ERROR(short_form);
 1877 }
 1878 
 1879 
 1880 TEST_F(SugarTest, NestedIfdefElseConditionAlwaysTrue)
 1881 {
 1882   const char* short_form =
 1883     "class Foo\n"
 1884     "  var create: U32\n"
 1885     "  fun f() =>\n"
 1886     "    ifdef windows then\n"
 1887     "      ifdef windows then\n"
 1888     "        3\n"
 1889     "      end\n"
 1890     "    end";
 1891 
 1892   TEST_ERROR(short_form);
 1893 }
 1894 
 1895 
 1896 TEST_F(SugarTest, IfdefPosix)
 1897 {
 1898   const char* short_form =
 1899     "class Foo\n"
 1900     "  var create: U32\n"
 1901     "  fun f() =>\n"
 1902     "    ifdef posix then\n"
 1903     "      3\n"
 1904     "    else\n"
 1905     "      4\n"
 1906     "    end";
 1907 
 1908   const char* full_form =
 1909     "use \"builtin\"\n"
 1910     "class ref Foo\n"
 1911     "  var create: U32\n"
 1912     "  fun box f(): None =>\n"
 1913     "    ifdef $flag linux $ifdefor $flag osx $ifdefor $flag bsd\n"
 1914     "    $extra $ifdefnot $noseq($flag linux $ifdefor $flag osx $ifdefor\n"
 1915     "      $flag bsd) then\n"
 1916     "      3\n"
 1917     "    else\n"
 1918     "      4\n"
 1919     "    end\n"
 1920     "    None";
 1921 
 1922   TEST_EQUIV(short_form, full_form);
 1923 }
 1924 
 1925 
 1926 TEST_F(SugarTest, AsOperatorWithLambdaType)
 1927 {
 1928   const char* short_form =
 1929     "class Foo\n"
 1930       "new create() =>\n"
 1931         "let x = {():U32 => 0 }\n"
 1932         "try x as {():U32} val end";
 1933 
 1934   TEST_COMPILE(short_form);
 1935 }