all tasks

This commit is contained in:
Ingy döt Net 2013-04-11 01:07:29 -07:00
parent b83f433714
commit 68f8f3e56b
14735 changed files with 178959 additions and 0 deletions

View file

@ -0,0 +1,13 @@
As the world gets smaller each day, internationalization becomes more and more important. For handling multiple languages, [[Unicode]] is your best friend. It is a very capable tool, but also quite complex compared to older single- and double-byte character encodings. How well prepared is your programming language for Unicode? Discuss and demonstrate its unicode awareness and capabilities. Some suggested topics:
* How easy is it to present Unicode strings in source code? Can Unicode literals be written directly, or be part of identifiers/keywords/etc?
* How well can the language communicate with the rest of the world? Is it good at input/output with Unicode?
* Is it convenient to manipulate Unicode strings in the language?
* How broad/deep does the language support Unicode? What encodings (e.g. UTF-8, UTF-16, etc) can be used? Normalization?
'''Note''' This task is a bit unusual in that it encourages general discussion rather than clever coding.
See also:
* [[Unicode variable names]]
* [[Terminal control/Display an extended character]]

View file

@ -0,0 +1,301 @@
#!/usr/local/bin/a68g --script #
# -*- coding: utf-8 -*- #
# UNICHAR/UNICODE must be printed using REPR to convert to UTF8 #
MODE UNICHAR = STRUCT(BITS #31# bits); # assuming bits width >=31 #
MODE UNICODE = FLEX[0]UNICHAR;
OP INITUNICHAR = (BITS bits)UNICHAR: (UNICHAR out; bits OF out := #ABS# bits; out);
OP INITUNICHAR = (CHAR char)UNICHAR: (UNICHAR out; bits OF out := BIN ABS char; out);
OP INITBITS = (UNICHAR unichar)BITS: #BIN# bits OF unichar;
PROC raise value error = ([]UNION(FORMAT,BITS,STRING)argv )VOID: (
putf(stand error, argv); stop
);
MODE YIELDCHAR = PROC(CHAR)VOID; MODE GENCHAR = PROC(YIELDCHAR)VOID;
MODE YIELDUNICHAR = PROC(UNICHAR)VOID; MODE GENUNICHAR = PROC(YIELDUNICHAR)VOID;
PRIO DOCONV = 1;
# Convert a stream of UNICHAR into a stream of UTFCHAR #
OP DOCONV = (GENUNICHAR gen unichar, YIELDCHAR yield)VOID:(
BITS non ascii = NOT 2r1111111;
# FOR UNICHAR unichar IN # gen unichar( # ) DO ( #
## (UNICHAR unichar)VOID: (
BITS bits := INITBITS unichar;
IF (bits AND non ascii) = 2r0 THEN # ascii #
yield(REPR ABS bits)
ELSE
FLEX[6]CHAR buf := "?"*6; # initialise work around #
INT bytes := 0;
BITS byte lead bits = 2r10000000;
FOR ofs FROM UPB buf BY -1 WHILE
bytes +:= 1;
buf[ofs]:= REPR ABS (byte lead bits OR bits AND 2r111111);
bits := bits SHR 6;
# WHILE # bits NE 2r0 DO
SKIP
OD;
BITS first byte lead bits = BIN (ABS(2r1 SHL bytes)-2) SHL (UPB buf - bytes + 1);
buf := buf[UPB buf-bytes+1:];
buf[1] := REPR ABS(BIN ABS buf[1] OR first byte lead bits);
FOR i TO UPB buf DO yield(buf[i]) OD
FI
# OD # ))
);
# Convert a STRING into a stream of UNICHAR #
OP DOCONV = (STRING string, YIELDUNICHAR yield)VOID: (
PROC gen char = (YIELDCHAR yield)VOID:
FOR i FROM LWB string TO UPB string DO yield(string[i]) OD;
gen char DOCONV yield
);
CO Prosser/Thompson UTF8 encoding scheme
Bits Last code point Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6
7 U+007F 0xxxxxxx
11 U+07FF 110xxxxx 10xxxxxx
16 U+FFFF 1110xxxx 10xxxxxx 10xxxxxx
21 U+1FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
26 U+3FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
31 U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
END CO
# Quickly calculate the length of the UTF8 encoded string #
PROC upb utf8 = (STRING utf8 string)INT:(
INT bytes to go := 0;
INT upb := 0;
FOR i FROM LWB utf8 string TO UPB utf8 string DO
CHAR byte := utf8 string[i];
IF bytes to go = 0 THEN # start new utf char #
bytes to go :=
IF ABS byte <= ABS 2r01111111 THEN 1 # 7 bits #
ELIF ABS byte <= ABS 2r11011111 THEN 2 # 11 bits #
ELIF ABS byte <= ABS 2r11101111 THEN 3 # 16 bits #
ELIF ABS byte <= ABS 2r11110111 THEN 4 # 21 bits #
ELIF ABS byte <= ABS 2r11111011 THEN 5 # 26 bits #
ELIF ABS byte <= ABS 2r11111101 THEN 6 # 31 bits #
ELSE raise value error(("Invalid UTF-8 bytes", BIN ABS byte)); ~ FI
FI;
bytes to go -:= 1; # skip over trailing bytes #
IF bytes to go = 0 THEN upb +:= 1 FI
OD;
upb
);
# Convert a stream of CHAR into a stream of UNICHAR #
OP DOCONV = (GENCHAR gen char, YIELDUNICHAR yield)VOID: (
INT bytes to go := 0;
INT lshift;
BITS mask, out;
# FOR CHAR byte IN # gen char( # ) DO ( #
## (CHAR byte)VOID: (
INT bits := ABS byte;
IF bytes to go = 0 THEN # start new unichar #
bytes to go :=
IF bits <= ABS 2r01111111 THEN 1 # 7 bits #
ELIF bits <= ABS 2r11011111 THEN 2 # 11 bits #
ELIF bits <= ABS 2r11101111 THEN 3 # 16 bits #
ELIF bits <= ABS 2r11110111 THEN 4 # 21 bits #
ELIF bits <= ABS 2r11111011 THEN 5 # 26 bits #
ELIF bits <= ABS 2r11111101 THEN 6 # 31 bits #
ELSE raise value error(("Invalid UTF-8 bytes", BIN bits)); ~ FI;
IF bytes to go = 1 THEN
lshift := 7; mask := 2r1111111
ELSE
lshift := 7 - bytes to go; mask := BIN(ABS(2r1 SHL lshift)-1)
FI;
out := mask AND BIN bits;
lshift := 6; mask := 2r111111 # subsequently pic 6 bits at a time #
ELSE
out := (out SHL lshift) OR ( mask AND BIN bits)
FI;
bytes to go -:= 1;
IF bytes to go = 0 THEN yield(INITUNICHAR out) FI
# OD # ))
);
# Convert a string of UNICHAR into a stream of UTFCHAR #
OP DOCONV = (UNICODE unicode, YIELDCHAR yield)VOID:(
PROC gen unichar = (YIELDUNICHAR yield)VOID:
FOR i FROM LWB unicode TO UPB unicode DO yield(unicode[i]) OD;
gen unichar DOCONV yield
);
# Some convenience/shorthand U operators #
# Convert a BITS into a UNICODE char #
OP U = (BITS bits)UNICHAR:
INITUNICHAR bits;
# Convert a []BITS into a UNICODE char #
OP U = ([]BITS array bits)[]UNICHAR:(
[LWB array bits:UPB array bits]UNICHAR out;
FOR i FROM LWB array bits TO UPB array bits DO bits OF out[i]:=array bits[i] OD;
out
);
# Convert a CHAR into a UNICODE char #
OP U = (CHAR char)UNICHAR:
INITUNICHAR char;
# Convert a STRING into a UNICODE string #
OP U = (STRING utf8 string)UNICODE: (
FLEX[upb utf8(utf8 string)]UNICHAR out;
INT i := 0;
# FOR UNICHAR char IN # utf8 string DOCONV (
## (UNICHAR char)VOID:
out[i+:=1] := char
# OD #);
out
);
# Convert a UNICODE string into a UTF8 STRING #
OP REPR = (UNICODE string)STRING: (
STRING out;
# FOR CHAR char IN # string DOCONV (
## (CHAR char)VOID: (
out +:= char
# OD #));
out
);
# define the most useful OPerators on UNICODE CHARacter arrays #
# Note: LWB, UPB and slicing works as per normal #
OP + = (UNICODE a,b)UNICODE: (
[UPB a + UPB b]UNICHAR out;
out[:UPB a]:= a; out[UPB a+1:]:= b;
out
);
OP + = (UNICODE a, UNICHAR b)UNICODE: a+UNICODE(b);
OP + = (UNICHAR a, UNICODE b)UNICODE: UNICODE(a)+b;
OP + = (UNICHAR a,b)UNICODE: UNICODE(a)+b;
# Suffix a character to the end of a UNICODE string #
OP +:= = (REF UNICODE a, UNICODE b)VOID: a := a + b;
OP +:= = (REF UNICODE a, UNICHAR b)VOID: a := a + b;
# Prefix a character to the beginning of a UNICODE string #
OP +=: = (UNICODE b, REF UNICODE a)VOID: a := b + a;
OP +=: = (UNICHAR b, REF UNICODE a)VOID: a := b + a;
OP * = (UNICODE a, INT n)UNICODE: (
UNICODE out := a;
FOR i FROM 2 TO n DO out +:= a OD;
out
);
OP * = (INT n, UNICODE a)UNICODE: a * n;
OP * = (UNICHAR a, INT n)UNICODE: UNICODE(a)*n;
OP * = (INT n, UNICHAR a)UNICODE: n*UNICODE(a);
OP *:= = (REF UNICODE a, INT b)VOID: a := a * b;
# Wirthy Operators #
OP LT = (UNICHAR a,b)BOOL: ABS bits OF a LT ABS bits OF b,
LE = (UNICHAR a,b)BOOL: ABS bits OF a LE ABS bits OF b,
EQ = (UNICHAR a,b)BOOL: ABS bits OF a EQ ABS bits OF b,
NE = (UNICHAR a,b)BOOL: ABS bits OF a NE ABS bits OF b,
GE = (UNICHAR a,b)BOOL: ABS bits OF a GE ABS bits OF b,
GT = (UNICHAR a,b)BOOL: ABS bits OF a GT ABS bits OF b;
# ASCII OPerators #
OP < = (UNICHAR a,b)BOOL: a LT b,
<= = (UNICHAR a,b)BOOL: a LE b,
= = (UNICHAR a,b)BOOL: a EQ b,
/= = (UNICHAR a,b)BOOL: a NE b,
>= = (UNICHAR a,b)BOOL: a GE b,
> = (UNICHAR a,b)BOOL: a GT b;
# Non ASCII OPerators
OP ≤ = (UNICHAR a,b)BOOL: a LE b,
≠ = (UNICHAR a,b)BOOL: a NE b,
≥ = (UNICHAR a,b)BOOL: a GE b;
#
# Compare two UNICODE strings for equality #
PROC unicode cmp = (UNICODE str a,str b)INT: (
IF LWB str a > LWB str b THEN exit lt ELIF LWB str a < LWB str b THEN exit gt FI;
INT min upb = UPB(UPB str a < UPB str b | str a | str b );
FOR i FROM LWB str a TO min upb DO
UNICHAR a := str a[i], UNICHAR b := str b[i];
IF a < b THEN exit lt ELIF a > b THEN exit gt FI
OD;
IF UPB str a > UPB str b THEN exit gt ELIF UPB str a < UPB str b THEN exit lt FI;
exit eq: 0 EXIT
exit lt: -1 EXIT
exit gt: 1
);
OP LT = (UNICODE a,b)BOOL: unicode cmp(a,b)< 0,
LE = (UNICODE a,b)BOOL: unicode cmp(a,b)<=0,
EQ = (UNICODE a,b)BOOL: unicode cmp(a,b) =0,
NE = (UNICODE a,b)BOOL: unicode cmp(a,b)/=0,
GE = (UNICODE a,b)BOOL: unicode cmp(a,b)>=0,
GT = (UNICODE a,b)BOOL: unicode cmp(a,b)> 0;
# ASCII OPerators #
OP < = (UNICODE a,b)BOOL: a LT b,
<= = (UNICODE a,b)BOOL: a LE b,
= = (UNICODE a,b)BOOL: a EQ b,
/= = (UNICODE a,b)BOOL: a NE b,
>= = (UNICODE a,b)BOOL: a GE b,
> = (UNICODE a,b)BOOL: a GT b;
# Non ASCII OPerators
OP ≤ = (UNICODE a,b)BOOL: a LE b,
≠ = (UNICODE a,b)BOOL: a NE b,
≥ = (UNICODE a,b)BOOL: a GE b;
#
COMMENT - Todo: for all UNICODE and UNICHAR
Add NonASCII OPerators: ×, ×:=,
Add ASCII Operators: &, &:=, &=:
Add Wirthy OPerators: PLUSTO, PLUSAB, TIMESAB for UNICODE/UNICHAR,
Add UNICODE against UNICHAR comparison OPerators,
Add char_in_string and string_in_string PROCedures,
Add standard Unicode functions:
to_upper_case, to_lower_case, unicode_block, char_count,
get_directionality, get_numeric_value, get_type, is_defined,
is_digit, is_identifier_ignorable, is_iso_control,
is_letter, is_letter_or_digit, is_lower_case, is_mirrored,
is_space_char, is_supplementary_code_point, is_title_case,
is_unicode_identifier_part, is_unicode_identifier_start,
is_upper_case, is_valid_code_point, is_whitespace
END COMMENT
test:(
UNICHAR aircraft := U16r 2708;
printf(($"aircraft: "$, $"16r"16rdddd$, UNICODE(aircraft), $g$, " => ", REPR UNICODE(aircraft), $l$));
UNICODE chinese forty two = U16r 56db + U16r 5341 + U16r 4e8c;
printf(($"chinese forty two: "$, $g$, REPR chinese forty two, ", length string = ", UPB chinese forty two, $l$));
UNICODE poker = U "A123456789♥♦♣♠JQK";
printf(($"poker: "$, $g$, REPR poker, ", length string = ", UPB poker, $l$));
UNICODE selectric := U"×÷≤≥≠¬∨∧⏨→↓↑□⌊⌈⎩⎧○⊥¢";
printf(($"selectric: "$, $g$, REPR selectric, $l$));
printf(($"selectric*4: "$, $g$, REPR(selectric*4), $l$));
print((
"1 < 2 is ", U"1" < U"2", ", ",
"111 < 11 is ",U"111" < U"11", ", ",
"111 < 12 is ",U"111" < U"12", ", ",
"♥ < ♦ is ", U"♥" < U"♦", ", ",
"♥Q < ♥K is ",U"♥Q" < U"♥K", " & ",
"♥J < ♥K is ",U"♥J" < U"♥K", new line
))
)

View file

@ -0,0 +1,58 @@
VDU 23,22,640;512;8,16,16,128+8 : REM Select UTF-8 mode
*FONT Times New Roman, 20
PRINT "Arabic:"
arabic1$ = "هنا مثال يمكنك من الكتابة من اليمين"
arabic2$ = "الى اليسار باللغة العربية"
VDU 23,16,2;0;0;0;13 : REM Select right-to-left printing
PRINT FNarabic(arabic1$) ' FNarabic(arabic2$)
VDU 23,16,0;0;0;0;13 : REM Select left-to-right printing
PRINT '"Hebrew:"
hebrew$ = "זוהי הדגמה של כתיבת טקסט בעברית מימין לשמאל"
VDU 23,16,2;0;0;0;13 : REM Select right-to-left printing
PRINT hebrew$
VDU 23,16,0;0;0;0;13 : REM Select left-to-right printing
END
REM!Eject
DEF FNarabic(A$)
LOCAL A%, B%, L%, O%, P%, U%, B$
A$ += CHR$0
FOR A% = !^A$ TO !^A$+LENA$-1
IF ?A%<&80 OR ?A%>=&C0 THEN
L% = O% : O% = P% : P% = U%
U% = ((?A% AND &3F) << 6) + (A%?1 AND &3F)
IF ?A%<&80 U% = 0
CASE TRUE OF
WHEN U%=&60C OR U%=&61F: U% = 0
WHEN U%<&622:
WHEN U%<&626: U% = &01+2*(U%-&622)
WHEN U%<&628: U% = &09+4*(U%-&626)
WHEN U%<&62A: U% = &0F+4*(U%-&628)
WHEN U%<&62F: U% = &15+4*(U%-&62A)
WHEN U%<&633: U% = &29+2*(U%-&62F)
WHEN U%<&63B: U% = &31+4*(U%-&633)
WHEN U%<&641:
WHEN U%<&648: U% = &51+4*(U%-&641)
WHEN U%<&64B: U% = &6D+2*(U%-&648)
ENDCASE
IF P% IF P%<&80 THEN
B% = P%
IF O%=&5D IF P%<&5 B% += &74
IF O%=&5D IF P%=&7 B% += &72
IF O%=&5D IF P%=&D B% += &6E
IF B%>P% B$=LEFT$(B$,LENB$-3) : O% = L%
IF U% IF P%>7 IF P%<>&D IF P%<>&13 IF P%<>&29 IF P%<>&2B IF P%<>&2D IF P%<>&2F IF P%<>&6D IF P%<>&6F B% += 2
IF O% IF O%>7 IF O%<>&D IF O%<>&13 IF O%<>&29 IF O%<>&2B IF O%<>&2D IF O%<>&2F IF O%<>&6D IF O%<>&6F B% += 1
B$ = LEFT$(LEFT$(B$))+CHR$&EF+CHR$(&BA+(B%>>6))+CHR$(&80+(B%AND&3F))
ENDIF
ENDIF
B$ += CHR$?A%
NEXT
= LEFT$(B$)

View file

@ -0,0 +1,30 @@
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
/* wchar_t is the standard type for wide chars; what it is internally
* depends on the compiler.
*/
wchar_t poker[] = L"♥♦♣♠";
wchar_t four_two[] = L"\x56db\x5341\x4e8c";
int main() {
/* Set the locale to alert C's multibyte output routines */
if (!setlocale(LC_CTYPE, "")) {
fprintf(stderr, "Locale failure, check your env vars\n");
return 1;
}
#ifdef __STDC_ISO_10646__
/* C99 compilers should understand these */
printf("%lc\n", 0x2708); /* ✈ */
printf("%ls\n", poker); /* ♥♦♣♠ */
printf("%ls\n", four_two); /* 四十二 */
#else
/* oh well */
printf("airplane\n");
printf("club diamond club spade\n");
printf("for ty two\n");
#endif
return 0;
}

View file

@ -0,0 +1,5 @@
var i int
var u rune
for i, u = range "voilà" {
fmt.Println(i, u)
}

View file

@ -0,0 +1,4 @@
w := "voilà"
for i := 0; i < len(w); i++ {
fmt.Println(i, w[i])
}

View file

@ -0,0 +1,2 @@
'♥♦♣♠'
♥♦♣♠

View file

@ -0,0 +1,2 @@
#'♥♦♣♠'
12

View file

@ -0,0 +1,4 @@
7 u:'♥♦♣♠'
♥♦♣♠
#7 u:'♥♦♣♠'
4

View file

@ -0,0 +1,2 @@
'♥♦♣♠' -: 7 u:'♥♦♣♠'
0

View file

@ -0,0 +1,2 @@
'abcd'-:7 u:'abcd'
1

View file

@ -0,0 +1,4 @@
'♥♦♣♠' -:&(7&u:) 7 u:'♥♦♣♠'
1
'♥♦♣♠' -:&(8&u:) 7 u:'♥♦♣♠'
1

View file

@ -0,0 +1,22 @@
10 CLS:DEFINT a-z
20 ' define German umlauts as in Latin-1
30 SYMBOL AFTER 196
40 SYMBOL 196,&66,&18,&3C,&66,&7E,&66,&66,&0
50 SYMBOL 214,&C6,&0,&7C,&C6,&C6,&C6,&7C,&0
60 SYMBOL 220,&66,&0,&66,&66,&66,&66,&3C,&0
70 SYMBOL 228,&6C,&0,&78,&C,&7C,&CC,&76,&0
80 SYMBOL 246,&66,&0,&0,&3C,&66,&66,&3C,&0
90 SYMBOL 252,&66,&0,&0,&66,&66,&66,&3E,&0
100 SYMBOL 223,&38,&6C,&6C,&78,&6C,&78,&60,&0
110 ' print string
120 READ h
130 IF h=0 THEN 180
140 IF (h AND &X11100000)=&X11000000 THEN uc=(h AND &X11111)*2^6:GOTO 120
150 IF (h AND &X11000000)=&X10000000 THEN uc=uc+(h AND &X111111):h=uc
160 PRINT CHR$(h);
170 GOTO 120
180 PRINT
190 END
200 ' zero-terminated UTF-8 string
210 DATA &48,&C3,&A4,&6C,&6C,&C3,&B6,&20,&4C,&C3,&BC,&64,&77,&69,&67,&2E,&20,&C3,&84,&C3,&96,&C3,&9C
220 DATA &20,&C3,&A4,&C3,&B6,&C3,&BC,&20,&56,&69,&65,&6C,&65,&20,&47,&72,&C3,&BC,&C3,&9F,&65,&21,&00

View file

@ -0,0 +1,2 @@
sub prefix:<> ($𝕏) { $𝕏 ** (1/3) }
say27; # prints 3

View file

@ -0,0 +1 @@
use utf8;

View file

@ -0,0 +1,3 @@
$四十二 = "voilà";
print "$四十二"; # voilà
print uc($四十二); # VOILÀ

View file

@ -0,0 +1,4 @@
use charnames qw(greek);
$x = "\N{sigma} \U\N{sigma}";
$y = "\x{2708}";
print scalar reverse("$x $y"); # ✈ Σ σ

View file

@ -0,0 +1 @@
print "Say עִבְרִית" =~ /(\p{BidiClass:R})/g; # עברית

View file

@ -0,0 +1,2 @@
open IN, "<:utf8", "file_utf";
open OUT, ">:raw", "file_byte";

View file

@ -0,0 +1 @@
(in '(iconv "-f" "ISO-8859-15" "file.txt") (line))

View file

@ -0,0 +1,5 @@
#!/usr/bin/env python
# -*- coding: latin-1 -*-
u = 'abcdé'
print(ord(u[-1]))

View file

@ -0,0 +1,3 @@
@{TITLE /[あ-ん一-耙]+/} (@ROMAJI/@ENGLISH)
@(freeform)
@(coll)@{STANZA /[^\n\x3000 ]+/}@(end)@/.*/