RiSE4fun samples for BekList of built-in samples for the Bek in RiSE4funen-USrise4fun &copy; 2017 Microsoft Corporationhttp://rise4fun.com//Images/Rise.gifRiSE4fun samples for Bekhttp://rise4fun.com/Bek/caesarciphercaesarcipher// Caesar used a simple cipher // where all the letters were shifted by 3 program caesarcipher(w) { return iter(c in w) { case(true): yield(c+3); }; } == display(caesarcipher); js(caesarcipher); http://rise4fun.com/Bek/helloworldhelloworld//Remove all the input letters and output "Hello World!" program helloworld(w){ return iter(c in w){case(true): yield();} end {case(true): yield("Hello World!");};} == //display the underlying transducer display(helloworld); //generate corresponding JavaScript js(helloworld); http://rise4fun.com/Bek/trivialtrivialprogram triv(w) { return iter(c in w) { case (true): yield(c); }; } program noop(w) { return iter(c in w) { case (c <= 0xFF): yield((((c >> 4) & 0xF) << 4)|(c & 0xF)); case (true): yield(c); }; } == //display the transducers triv and noop display(triv); display(noop); //check that triv and noop are equivalent eq(triv, noop); //generate JavaScript js(triv);http://rise4fun.com/Bek/escapequotesescapequotesprogram escape(t) { return iter(c in t)[b := false;]{ case (!(b) && ((c == '\'') || (c == '\"'))) : b := false; yield ('\\'); yield (c); case (c == '\\') : b := !(b); yield (c); case (true) : b := false; yield (c); }; } == //view the graph of explored escape display(ex(escape)); //check idempotence of escape eq(escape, join(escape,escape)); //generate JavaScript js(escape);http://rise4fun.com/Bek/escapequotes_buggyescapequotes_buggyprogram escape(t) { return iter(c in t)[b := false;]{ case (!(b) && ((c == '\'') || (c == '\"'))) : b := false; yield ('\\'); yield (c); case (c == '\\') : b := !(b); yield (c, c); //<--- bug, should be: yield (c); case (true) : b := false; yield (c); }; } == //check idempotence eq(escape, join(escape,escape)); //view the graph of the explored version of escape applied twice display(ex(join(escape,escape))); //generate JavaScript js(escape);http://rise4fun.com/Bek/swapcaseswapcase//swap lowercase and uppercase letters program swapcase(w) { return iter(c in w) { case (c in "[A-Z]"): yield (c + 0x20); case (c in "[a-z]"): yield (c - 0x20); case (true): yield(c); }; } //identity program id(w) { return iter(c in w) { case (true): yield(c); }; } == //show that swapcase is not idempotent: eq(swapcase, join(swapcase,swapcase)); //show that swapcase is the reverse of itself eq(id, join(swapcase,swapcase)); //show dot generated for swapcase dot(swapcase); //generate JavaScript js(swapcase); http://rise4fun.com/Bek/decodedigitpairsdecodedigitpairs//decode some consequtive digits between '5' and '9' as the corresponding ascii character program DecodeDigitPairs(input) { return iter(c in input) [d := 0;] { case (d == 0): //no previous digit was recorded if ((c>='5')&&(c<='9')) {d:=c;} //store the digit in register d else {yield(c);} case (true): // d != 0 so d is the previous digit if ((c>='5')&&(c<='9')) {yield(dec(d,c)); //computes the ascii repr. e.g. dec('7','7')='M' d:=0;} else {yield(c);} } end { case (d != 0): yield (d); //there was a final digit, just output it "as is" case (true): yield(); }; } == //show the graph display(DecodeDigitPairs); //show the explored graph (registers have been eliminated) display(ex(DecodeDigitPairs)); //generate JavaScript js(DecodeDigitPairs);http://rise4fun.com/Bek/base64encodebase64encode/* function base64 maps x to the following base64-digit 0..25 ==> 'A'..'Z' 26..51 ==> 'a'..'z' 52..61 ==> '0'..'9' 62 ==> '+' 63 ==> '/' */ function base64(x)=(ite(x<=25,x+65,ite(x<=51,x+71,ite(x<=61,x-4,ite(x==62,'+','/'))))); /* base64 encoder of an input of bytes, any value in the sequence > 0xFF raises an exception for example base64encode("Man") = "TWFu" */ program base64encode(input){ return iter(x in input)[q:=0;r:=0;]{ case (x>0xFF): raise InvalidCharacter; case (q==0): yield (base64(x>>2)); q:=1; r:=(x&3)<<4; case (q==1): yield (base64(r|(x>>4))); q:=2; r:=(x&0xF)<<2; case (q==2): yield (base64((r|(x>>6))), base64(x&0x3F)); q:=0; r:=0; end case (q==1): yield (base64(r),'=','='); end case (q==2): yield (base64(r),'='); }; } == eval(base64encode, "Man"); js(base64encode); http://rise4fun.com/Bek/commutecommute //replace all occurrences of "<" by "&lt;" and ">" by "&gt;" program escapeBrackets(input) { return iter(c in input) { case (c == '<') : yield ('&'); yield ('l'); yield ('t'); yield (';'); case (c == '>') : yield ('&'); yield ('g'); yield ('t'); yield (';'); case(true): yield(c); };} //escape unescaped quotes program escapeQuotes(t) { return iter(c in t)[b := false;]{ case (!(b) && ((c == '\'') || (c == '\"'))) : b := false; yield ('\\'); yield (c); case (c == '\\') : b := !(b); yield (c); case (true) : b := false; yield (c); }; } == //show that the above functions commute eq(join(escapeBrackets,escapeQuotes), join(escapeQuotes,escapeBrackets)); //generate JavaScript js(escapeQuotes);http://rise4fun.com/Bek/escapeStringescapeStringprogram escapeString(t){ s1 := iter(c in t) { case (c == '&') : yield ('&'); yield ('a'); yield ('m'); yield ('p'); yield (';'); case (c == '<') : yield ('&'); yield ('l'); yield ('t'); yield (';'); case (c == '>') : yield ('&'); yield ('g'); yield ('t'); yield (';'); case (c == '\"') : yield ('&'); yield ('q'); yield ('u'); yield ('o'); yield ('t'); yield (';'); case (c == '\'') : yield ('&'); yield ('#'); yield ('3'); yield ('9'); yield (';'); case (true) : yield (c); }; return s1; } == //check idempotence eq(escapeString, join(escapeString,escapeString)); //generate JavaScript js(escapeString);http://rise4fun.com/Bek/utf8encodeutf8encode//UTF8 encoding from UTF16 strings, hs is the lower two bits of the previous high surrogate //this encoder raises an exception when an invalid surrogate is detected program utf8encode(input){ return iter(c in input)[HS:=false; hs:=0;] { case (HS): //the previous character was a high surrogate if (!((c >= 0xdc00) && (c <= 0xdfff))) //not low surrogate { raise InvalidSurrogatePairException; } else { yield ((0x80|(hs << 4))|((c>>6)&0xF), 0x80|(c&0x3F)); HS:=false; hs:=0;} case (!HS): //the previous character was not a high surrogate if (c <= 0x7F) { yield(c); } //one byte: ASCII case else if (c <= 0x7FF) { //two bytes yield(0xC0 | ((c>>6) & 0x1F), 0x80 | (c & 0x3F)); } else if (!((c >= 0xd800) && (c <= 0xdbff))) { //not high surrogate if ((c >= 0xdc00) && (c <= 0xdfff)) { raise InvalidSurrogatePairException; } else { //three bytes yield(0xE0| ((c>>12) & 0xF), 0x80 | ((c>>6) & 0x3F), 0x80 | (c&0x3F)); } } else { yield (0xF0|(((1+((c>>6)&0xF))>>2)&7), (0x80|(((1+((c>>6)&0xF))&3)<<4))|((c>>2) & 0xF)); HS:=true; hs:=c&3; } } end { case (HS): raise InvalidSurrogatePairException; case (true): yield(); }; } == //display the graph display(utf8encode); //eliminate all registers utf = explore(utf8encode); display(utf); //check equivalence of the explored and unexplored versions eq(utf, utf8encode); //check idempotence of utf eq(utf, join(utf,utf)); //generate JavaScript js(utf8encode);http://rise4fun.com/Bek/htmldecodehtmldecode //restricted version of HTML decoding program htmldecode(w) { return iter(c in w) [ A := false; H := false; D1 := false; D2 := false; d1 := 0; d2 := 0;] { case (D2 && (c == ';')) : //e.g. &#38; yield(dec(d1,d2)); A := false; H := false; D1 := false; D2 := false; d1 := 0; d2 := 0; case (D2 && (c == '&')) : //e.g. &#38& yield('&','#', d1, d2); A := true; H := false; D1 := false; D2 := false; d1 := 0; d2 := 0; case (D2) : //e.g. &#38a yield('&','#',d1, d2, c); A := false; H := false; D1 := false; D2 := false; d1 := 0; d2 := 0; case (D1 && (c == ';')) : //e.g. &#3; yield(dec(d1)); A := false; H := false; D1 := false; D2 := false; d1 := 0; d2 := 0; case (D1 && (c == '&')) : //e.g. &#4& yield('&','#',d1); A := true; H := false; D1 := false; D2 := false; d1 := 0; d2 := 0; case (D1 && (('0' <= c) && (c <= '9'))) : //e.g. &#65 A := true; H := false; D1 := false; D2 := true; d2 := c; case (D1) : //e.g. &#6e yield('&','#',d1, c); A := false; H := false; D1 := false; D2 := false; d1 := 0; d2 := 0; case (H && (c == '&')) : // &#& yield('&','#'); A := true; H := false; D1 := false; D2 := false; d1 := 0; d2 := 0; case (H && (('0' <= c) && (c <= '9'))) : //e.g. &#6 A := false; H := false; D1 := true; D2 := false; d1 := c; d2 := 0; case (H) : //e.g. &#g yield('&','#', c); A := false; H := false; D1 := false; D2 := false; d1 := 0; d2 := 0; case (A && (c == '#')) : // &# A := false; H := true; D1 := false; D2 := false; d1 := 0; d2 := 0; case (A && (c == '&')) : // && yield('&'); case (A) : // e.g. &3 yield('&',c); A := false; H := false; D1 := false; D2 := false; d1 := 0; d2 := 0; case (c == '&'): // & A := true; case (true) : //any other case yield(c); A := false; H := false; D1 := false; D2 := false; d1 := 0; d2 := 0; } end { //characters to yield when input finished in the middle of a pattern case (D2) : yield('&','#',d1,d2); case (D1) : yield('&','#',d1); case (H) : yield('&','#'); case (A) : yield('&'); case (true): yield(); }; } == A = exB(htmldecode); R = re("^([^0-4])*$"); //restrict the input strings so that characters '0'..'4' are excluded B = restrict(A, R); //display the SFA for regex R display(R); //check partial equivalence up to input-length 8 eqB(8, A, join(A,A)); //now restrict to complement of "&#59;" R2 = complement(re(@"&#59;")); //view the corresponding automaton display(R2); A2 = restrict(A, R2); //check partial equivalence up to input-length 8 eqB(8, A2, join(A2,A2)); //view the transducer display(A2); //generate JavaScript js(htmldecode); http://rise4fun.com/Bek/cssencodecssencode//CssEncode, register hs only stores the last two bits of the high surrogate program CssEncode(input){ return iter(c in input)[HS:=false; hs:=0;] { case ((c == 0xFFFE) || (c == 0xFFFF)): raise InvalidUnicodeValueException; case (HS): //the previous character was a high surrogate if (!((c >= 0xdc00) && (c <= 0xdfff))) { raise InvalidSurrogatePairException; } else { yield (hex(((hs << 2)|((c >> 8) & 3))), hex(1,c), hex(c)); HS:=false; hs:=0; } case (true): //the previous character was a not a high surrogate if (((c >= 0xdc00) && (c <= 0xdfff))) { raise InvalidSurrogatePairException; } else if (((c >= 0xd800) && (c <= 0xdbff))) { yield ('\\', ite((((c >> 6) & 0xF)==0xF),'1','0'), hex(((c >> 6) + 1)), hex((c >> 2))); HS := true; hs := (c & 3); } else if (c > 0xFF) { yield ('\\','0','0',hex(3,c),hex(2,c),hex(1,c),hex(c));} else if (c in "[0-9A-Za-z\x80-\x90\x93-\x9A\xA0-\xA5]") { yield (c); } else { yield ('\\','0','0','0','0',hex(1,c),hex(c)); } } end { case (HS): raise InvalidSurrogatePairException; case (true): yield(); }; } //CssEncode, register hs only stores the last two bits of the high surrogate needed for //combining with a following low surrogate. Thus the generated SFT has minimal nr of states. program CssEncode2(input){ output := iter(c in input)[E1a:=false; E1b:=false; E2:=false; HS:=false; hs:=0;] { case (!(E1a || E1b || E2) && HS && !IsLowSurrogate(c)) : E1a := true; // InvalidSurrogatePairException case (!(E1a || E1b || E2) && !HS && IsLowSurrogate(c)) : E1b := true; // InvalidSurrogatePairException case (!(E1a || E1b || E2) && ((c == 0xFFFE) || (c == 0xFFFF))): E2 := true; // InvalidUnicodeValueException case (!(E1a || E1b || E2) && !HS && IsHighSurrogate(c)): //yield the beginning of the encoding, assuming a low surrogate follows yield ('\\'); yield (ite((((c >> 7) & 0xF)==0xF),'1','0')); //<-- BUG, should be c >> 6 (instead of c >> 7) yield (hex(((c >> 6) + 1))); yield (hex((c >> 2))); HS := true; // high surrogate bits are stored hs := (c & 3); // store the least two bits of the high surrogate needed for low surrogate combination case (!(E1a || E1b || E2) && HS && IsLowSurrogate(c)): // the value in hs is the lowest two bits of the prior high surrogate // and the current character is a low surrogate // yield the rest of the encoding of the combined codepoint yield (hex(((hs << 2)|((c >> 8) & 3)))); yield (hex(1,c)); yield (hex(c)); HS:=false; hs:=0; case (!(E1a || E1b || E2) && (c > 0xFF)): yield ('\\','0','0',hex(3,c),hex(2,c),hex(1,c),hex(c)); HS:=false; hs:=0; case (!(E1a || E1b || E2) && !(c in "[0-9A-Za-z\x80-\x90\x93-\x9A\xA0-\xA5]")): yield ('\\','0','0','0','0',hex(1,c),hex(c)); HS:=false; hs:=0; case (!(E1a || E1b || E2)): yield (c); // c is in CssSafeList: [0-9A-Za-z\x80-\x90\x93-\x9A\xA0-\xA5] HS:=false; hs:=0; case (true): raise InvalidInput; } end { case (!E1a && !E1b && !E2 && !HS): yield(); //succesful output case (true): raise InvalidInput; }; return output; } /* predefined library functions: ite(cond, tcase, fcase) = (cond ? tcase : fcase) IsLowSurrogate(c) = ((c >= 0xdc00) && (c <= 0xdfff)) IsHighSurrogate(c) = ((c >= 0xd800) && (c <= 0xdbff)) hex(c) = hex(0,c) = ite((c & 0xF) <= 9, 48 + (c & 0xF), 55 + (c & 0xF)) hex(k,c) = ite(((c >> (k*4)) & 0xF) <= 9, 48 + ((c >> (k*4)) & 0xF), 55 + ((c >> (k*4)) & 0xF)) e.g. hex(2,0xF567) = '5' */ == //check if the two versions of CSS encoders are equivalent for accepted inputs //note: a bug is planted into CssEncode2, marked by BUG eq(CssEncode, CssEncode2); //display CssEncode display(CssEncode); //generate JavaScript for CssEncode js(CssEncode);