ASCII is the American Standard Code for Information Interchange. There are 128 ASCII characters of which the first 32 and the last are 'control characters'.
Show how your language might treat control charactersen bloc by using an enum, an enum like structure or other approach to associate their names with their ASCII values thereby enabling them to be retrieved or listed by name.
Technically, the 33rd character 'space' is a printable character, not a control character, though you may treat it as the latter for the purposes of this task.
In Ada, acharacter type is an enumeration type with at least one literal that is a character literal. The predefined typeCharacter is a character type with 256 values representing the Latin-1 character set; the first 128 values of Character are the ASCII character set. However, Character is a magic enumeration type: the values which are control characters have no literals. A user of the language cannot declare such a type. This makes naming the control characters more difficult than if they had literals.
Each value of an enumeration type has an associatedposition number. The first value has position number zero, increasing by one for each subsequent value. These correspond to the numeric values of ASCII, and may be used to refer to the control characters using the'Val attribute. For example, the line-feed control character may be referred to withCharacter'Val (10). (The position number for a character can be obtained using the'Pos attribute.)
The predefined packageAda.Characters.Latin_1 contains constants that give names to all the ASCII control characters (and many other characters as well). The first few are
NUL:constantCharacter:=Character'Val(0);SOH:constantCharacter:=Character'Val(1);STX:constantCharacter:=Character'Val(2);ETX:constantCharacter:=Character'Val(3);EOT:constantCharacter:=Character'Val(4);
Of course, one can also declare character types:
typeASCIIis(NUL,SOH,STX,ETX,EOT,ENQ,ACK,BEL,BS,HT,LF,VT,FF,CR,SO,SI,DLE,DC1,DC2,DC3,DC4,NAK,SYN,ETB,CAN,EM,SUB,ESC,FS,GS,RS,US,' ','!','"','#','$','%','&',''','(',')','*','+',',','-','.','/','0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?','@','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[','\',']','^','_','`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','{','|','}','~',DEL);
You can then refer to the control characters by their enumeration literals:LF.
Algol 68 doesn't have ENUMs but it is easy to create constants, this example shows how a facility similar to Go's iota can be implemented.
Note space is a standard Algol 68 transput (I/O) routine, so spc is used for the space character.
# create constants for the ASCII control characters (0-127) # INT char value := -1; # increments and returns the next value for a character # PROC next char = CHAR: REPR ( char value +:= 1 ); CHAR nul = next char; CHAR soh = next char; CHAR stx = next char; CHAR etx = next char; CHAR eot = next char; CHAR enq = next char; CHAR ack = next char; CHAR bel = next char; CHAR bs = next char; CHAR ht = next char; CHAR lf = next char; CHAR vt = next char; CHAR ff = next char; CHAR cr = next char; CHAR so = next char; CHAR si = next char; CHAR dle = next char; CHAR dc1 = next char; CHAR dc2 = next char; CHAR dc3 = next char; CHAR dc4 = next char; CHAR nak = next char; CHAR syn = next char; CHAR etb = next char; CHAR can = next char; CHAR em = next char; CHAR sub = next char; CHAR esc = next char; CHAR fs = next char; CHAR gs = next char; CHAR rs = next char; CHAR us = next char; CHAR spc = " "; # using spc as space is a standard transput procedure # CHAR del = REPR 127;# e.g.: ## print( ( nul, soh, ht, lf ) ); prints the characters themselve ## print( ( ABS nul, ABS soh, ABS ht, ABS lf, lf ) ); prints the characters as ## integers: +0 +1 +9 +10 #
A map seems the most appropriate data structure we have for this task.
importballerina/io;string[]names=["NUL","SOH","STX","ETX","EOT","ENQ","ACK","BEL","BS","HT","LF","VT","FF","CR","SO","SI","DLE","DC1","DC2","DC3","DC4","NAK","SYN","ETB","CAN","EM","SUB","ESC","FS","GS","RS","US","SP","DEL"];map<int>ctrls={};functioninit(){foreachintiin0...32{ctrls[names[i]]=i;}ctrls["DEL"]=127;}publicfunctionmain(){io:println("A list of all control characters and their values:");foreachstringkinctrls.keys(){io:println(k.padEnd(3)," = ",ctrls[k]);}}
A list of all control characters and their values:NUL = 0SOH = 1STX = 2ETX = 3EOT = 4ENQ = 5ACK = 6BEL = 7BS = 8HT = 9LF = 10VT = 11FF = 12CR = 13SO = 14SI = 15DLE = 16DC1 = 17DC2 = 18DC3 = 19DC4 = 20NAK = 21SYN = 22ETB = 23CAN = 24EM = 25SUB = 26ESC = 27FS = 28GS = 29RS = 30US = 31SP = 32DEL = 127
enum:char{nul,soh,stx,etx,eot,enq,ack,bel,bs,ht,lf,vt,ff,cr,so,si,dle,dc1,dc2,dc3,dc4,nak,syn,etb,can,em,sub,esc,fs,gs,rs,us,space,del=127};
#include<cstdint>#include<iostream>#include<map>#include<string>enumASCIIControlChar{NUL,SOH,STX,ETX,EOT,ENQ,ACK,BEL,BS,HT,LF,VT,FF,CR,SO,SI,DLE,DC1,DC2,DC3,DC4,NAK,SYN,ETB,CAN,EM,SUB,ESC,FS,GS,RS,US,DEL};structData{std::stringtext;uint32_tnumber;};std::map<ASCIIControlChar,Data>ascii_map={{NUL,Data("Null",0)},{SOH,Data("Start of Heading",1)},{STX,Data("Start of Text",2)},{ETX,Data("End of Text",3)},{EOT,Data("End of Transmission",4)},{ENQ,Data("Enquiry",5)},{ACK,Data("Acknowledge",6)},{BEL,Data("Bell",7)},{BS,Data("Backspace",8)},{HT,Data("Horizontal Tab",9)},{LF,Data("Line Feed",10)},{VT,Data("Vertical Tabulation",11)},{FF,Data("Form Feed",12)},{CR,Data("Carriage Return",13)},{SO,Data("Shift Out",14)},{SI,Data("Shift In",15)},{DLE,Data("Data Link Escape",16)},{DC1,Data("Device Control One (XON)",17)},{DC2,Data("Device Control Two",18)},{DC3,Data("Device Control Three (XOFF)",19)},{DC4,Data("Device Control Four",20)},{NAK,Data("Negative Acknowledge",21)},{SYN,Data("Synchronous Idle",22)},{ETB,Data("End of Transmission Block",23)},{CAN,Data("Cancel",24)},{EM,Data("End of Medium",25)},{SUB,Data("Substitute",26)},{ESC,Data("Escape",27)},{FS,Data("File Separator",28)},{GS,Data("Group Separator",29)},{RS,Data("Record Separator",30)},{US,Data("Unit Separator",31)},{DEL,Data("Delete",127)}};intmain(){ASCIIControlCharetb=ASCIIControlChar::ETB;std::cout<<ascii_map[etb].text<<" "<<ascii_map[etb].number<<std::endl;ASCIIControlChardel=ASCIIControlChar::DEL;std::cout<<ascii_map[del].text<<" "<<ascii_map[del].number<<std::endl;}
End of Transmission Block 23Delete 127
Enums in Crystal have to be of an integer type. Instead, we define constants with the help of a macro.
structChar{%forsym,iin%w(NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US)%}{{sym.id}}={{i}}.chr{%end%}endp[Char::CR,Char::NUL,'s',Char::ESC,Char::HT,Char::HT,Char::BEL]
['\r', '\0', 's', '\e', '\t', '\t', '\a']
importstd.ascii.ControlChar;
EnumAsciiControlCharNUL=&H00'NullSOH=&H01'Star of HeaderSTX=&H02'Start of TextETX=&H03'End of TextEOT=&H04'End of TransmissionENQ=&H05'EnquiryACK=&H06'AcknowledgeBEL=&H07'BellBS=&H08'BackSpaceHT=&H09'Horizontal TabulationLF=&H0A'Line FeedVT=&H0B'Vertical TabulationFF=&H0C'Form FeedCR=&H0D'Carriage ReturnSO=&H0E'Shift OutSI=&H0F'Shift InDLE=&H10'Data Link EscapeDC1=&H11'Device Control 1 (XON)DC2=&H12'Device Control 2DC3=&H13'Device Control 3 (XOFF)DC4=&H14'Device Control 4NAK=&H15'Negative acknowledgeSYN=&H16'Synchronous IdleETB=&H17'End of Transmission BlockCAN=&H18'CancelEM=&H19'End of MediumSUB_=&H1A'SubstituteESC=&H1B'EscapeFS=&H1C'File SeparatorGS=&H1D'Group SeparatorRS=&H1E'Record SeparatorUS=&H1F'Unit SeparatorSP=&H20'SpaceDEL=&H7F'DeleteEndEnumPrint(Hex(AsciiControlChar.CR))Print(Hex(AsciiControlChar.DEL))Sleep
D7F
local fn ASCIIControlInfo( asciiControl as CFStringRef ) as CFStringRefasciiControl = lcase(asciiControl)if fn StringIsEqual( asciiControl, @"space" ) then asciiControl = @"spc"if fn StringIsEqual( asciiControl, @"delete" ) then asciiControl = @"del"CFStringRef resultCFDictionaryRef asciiDict = @{@"nul": @"00000NULL",@"soh": @"101001Start of heading",@"soh": @"202002Start of text",@"etx": @"303003End of text",@"eot": @"404004End of transmission",@"enq": @"505005Enquiry",@"ack": @"606006Acknowledge",@"bel": @"707007Bell",@"bs" : @"808010Backspace",@"ht" : @"909011Horizontal tab",@"lf" : @"100A012Line feed",@"vt" : @"110B013Vertical tab",@"ff" : @"120C014New page/form feed",@"cr" : @"130D015Carriage return",@"so" : @"140E016Shift out",@"si" : @"150F017Shift in",@"dle": @"1610020Data link escape",@"dc1": @"1711021Device control 1",@"dc2": @"1812022Device control 2",@"dc3": @"1913023Device control 3",@"dc4": @"2014024Device control 4",@"nak": @"2115025Negative acknowledge",@"syn": @"2216026Synchronous idle",@"etb": @"2317027End of transmission block",@"can": @"2418030Cancel",@"em" : @"2519031End of medium",@"sub": @"261A032Substitute",@"esc": @"271B033Escape",@"fs" : @"281C034File separator",@"gs" : @"291D035Group separator",@"rs" : @"301E036Record separator",@"us" : @"311F037Unit separator",@"spc": @"3220040Space",@"del": @"1277F177Delete"}if ( asciiDict[asciiControl] )result = fn StringWithFormat( @"Ctl\t\tDec\t\tHex\t\tOct\t\tDescription\n%@\t\t%@\n", asciiControl, asciiDict[asciiControl] )elseresult = fn StringWithFormat( @"Error: %@ is not an ASCII control\n", asciiControl )end ifend fn = resultprint fn ASCIIControlInfo( @"vt" )print fn ASCIIControlInfo( @"CR" )print fn ASCIIControlInfo( @"Si" )print fn ASCIIControlInfo( @"ESC" )print fn ASCIIControlInfo( @"xx" )print fn ASCIIControlInfo( @"Space" )print fn ASCIIControlInfo( @"DELETE" )HandleEventsCtlDecHexOctDescriptionnul00000NULLCtlDecHexOctDescriptionvt110B013Vertical tabCtlDecHexOctDescriptioncr130D015Carriage returnCtlDecHexOctDescriptionsi150F017Shift inCtlDecHexOctDescriptionesc271B033EscapeError: xx is not an ASCII controlCtlDecHexOctDescriptionspc3220040SpaceCtlDecHexOctDescriptiondel1277F177Delete
Go's support for enums is unconventional in that they are basically a bunch of constants with which a type name may be associated.
The pre-declared identifier 'iota' is typically used with enums and represents successive untyped integer constants, starting from zero though (as here) the sequence may be interrupted by assigning a new value.
packagemainimport"fmt"typeCtrlintconst(nulCtrl=iotasohstxetxeotenqackbelbshtlfvtffcrsosidledc1dc2dc3dc4naksynetbcanemsubescfsgsrsusspacedel=127)funcmain(){// print some specimen valuesfmt.Println(cr)fmt.Println(del)}
13127
publicfinalclassASCIIControlCharacters{publicstaticvoidmain(String[]args){ASCIIControlCharsyn=ASCIIControlChar.SYN;System.out.println(syn.name()+" "+syn.getText()+" "+syn.getNumber());ASCIIControlChardel=ASCIIControlChar.DEL;System.out.println(del.name()+" "+del.getText()+" "+del.getNumber());}privateenumASCIIControlChar{NUL("Null",0),SOH("Start of Heading",1),STX("Start of Text",2),ETX("End of Text",3),EOT("End of Transmission",4),ENQ("Enquiry",5),ACK("Acknowledge",6),BEL("Bell",7),BS("Backspace",8),HT("Horizontal Tab",9),LF("Line Feed",10),VT("Vertical Tabulation",11),FF("Form Feed",12),CR("Carriage Return",13),SO("Shift Out",14),SI("Shift In",15),DLE("Data Link Escape",16),DC1("Device Control One (XON)",17),DC2("Device Control Two",18),DC3("Device Control Three (XOFF)",19),DC4("Device Control Four",20),NAK("Negative Acknowledge",21),SYN("Synchronous Idle",22),ETB("End of Transmission Block",23),CAN("Cancel",24),EM("End of Medium",25),SUB("Substitute",26),ESC("Escape",27),FS("File Separator",28),GS("Group Separator",29),RS("Record Separator",30),US("Unit Separator",31),DEL("Delete",127);publicStringgetText(){returntext;}publicintgetNumber(){returnnumber;}privateASCIIControlChar(StringaText,intaNumber){text=aText;number=aNumber;}privateStringtext;privateintnumber;}}
SYN Synchronous Idle 22DEL Delete 127
def ascii_control_character_names: [ "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", "bs", "ht", "lf", "vt", "ff", "cr", "so", "si", "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", "can", "em", "sub", "esc", "fs", "gs", "rs", "us", "space", "del"];def Ctrl: ascii_control_character_names as $a | reduce range(0; $a|length) as $i ({}; .[$a[$i]] = $i) | .["del"] = 127;def examples: Ctrl as $Ctrl | "Ctrl.cr => \($Ctrl.cr)", "Ctrl.del => \($Ctrl.del)", "Ctrl.space => \($Ctrl.space)";examplesCtrl.cr => 13Ctrl.del => 127Ctrl.space => 32
Note that Julia recognizes many non-ASCII characters with values above 127 as control Char as well.
julia>filter(iscntrl,Char(0):Char(127))33-elementVector{Char}:'\0':ASCII/UnicodeU+0000(categoryCc:Other,control)'\x01':ASCII/UnicodeU+0001(categoryCc:Other,control)'\x02':ASCII/UnicodeU+0002(categoryCc:Other,control)'\x03':ASCII/UnicodeU+0003(categoryCc:Other,control)'\x04':ASCII/UnicodeU+0004(categoryCc:Other,control)'\x05':ASCII/UnicodeU+0005(categoryCc:Other,control)'\x06':ASCII/UnicodeU+0006(categoryCc:Other,control)'\a':ASCII/UnicodeU+0007(categoryCc:Other,control)'\b':ASCII/UnicodeU+0008(categoryCc:Other,control)'\t':ASCII/UnicodeU+0009(categoryCc:Other,control)'\n':ASCII/UnicodeU+000A(categoryCc:Other,control)'\v':ASCII/UnicodeU+000B(categoryCc:Other,control)'\f':ASCII/UnicodeU+000C(categoryCc:Other,control)'\r':ASCII/UnicodeU+000D(categoryCc:Other,control)'\x0e':ASCII/UnicodeU+000E(categoryCc:Other,control)'\x0f':ASCII/UnicodeU+000F(categoryCc:Other,control)'\x10':ASCII/UnicodeU+0010(categoryCc:Other,control)'\x11':ASCII/UnicodeU+0011(categoryCc:Other,control)'\x12':ASCII/UnicodeU+0012(categoryCc:Other,control)'\x13':ASCII/UnicodeU+0013(categoryCc:Other,control)'\x14':ASCII/UnicodeU+0014(categoryCc:Other,control)'\x15':ASCII/UnicodeU+0015(categoryCc:Other,control)'\x16':ASCII/UnicodeU+0016(categoryCc:Other,control)'\x17':ASCII/UnicodeU+0017(categoryCc:Other,control)'\x18':ASCII/UnicodeU+0018(categoryCc:Other,control)'\x19':ASCII/UnicodeU+0019(categoryCc:Other,control)'\x1a':ASCII/UnicodeU+001A(categoryCc:Other,control)'\e':ASCII/UnicodeU+001B(categoryCc:Other,control)'\x1c':ASCII/UnicodeU+001C(categoryCc:Other,control)'\x1d':ASCII/UnicodeU+001D(categoryCc:Other,control)'\x1e':ASCII/UnicodeU+001E(categoryCc:Other,control)'\x1f':ASCII/UnicodeU+001F(categoryCc:Other,control)'\x7f':ASCII/UnicodeU+007F(categoryCc:Other,control)
An enum can be used for the task:
@enumControlbeginnul=0soh=1stx=2etx=3eot=4enq=5ack=6bel=7bs=8ht=9lf=10vt=11ff=12cr=13so=14si=15dle=16dc1=17dc2=18dc3=19dc4=20nak=21syn=22etb=23can=24em=25sub=26esc=27fs=28gs=29rs=30us=31del=127enddisplay(nul),display(ht),display(us),display(del)
A named tuple is a another way to reference such control Chars by name:
constCNTRL=(nul=0,soh=1,stx=2,etx=3,eot=4,enq=5,ack=6,bel=7,bs=8,ht=9,lf=10,vt=11,ff=12,cr=13,so=14,si=15,dle=16,dc1=17,dc2=18,dc3=19,dc4=20,nak=21,syn=22,etb=23,can=24,em=25,sub=26,esc=27,fs=28,gs=29,rs=30,us=31,del=127,)@showCNTRL.nul,CNTRL.ht,CNTRL.us,CNTRL.del
nul::Control = 0ht::Control = 9us::Control = 31del::Control = 127(CNTRL.nul, CNTRL.ht, CNTRL.us, CNTRL.del) = (0, 9, 31, 127)
Those character can be put in a list and can be found their ASCII numbers.
/* List of characters that are not constituents (constituent is a graphic character but not a space character) */block(makelist(ascii(i),i,0,127),sublist(%%,lambda([x],notconstituent(x))));/* [,"�","�","�","�","�","�","�","�","�","","�","�","","�","�","�","�","�","�","�","�","�","�","�","�","�","�","�","�","�","�"," ","�"] *//* Ascii numbers of characters that are not constituents */map(cint,%);/* [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,127] */
We define an enumeration type.
For each element, Nim allows to specify its integer value and its string representation. Here, the integer value is implicit (starting from zero) except for DEL whose value must be specified. As we use the standard names for the elements, we don’t have to specify the string representation.
The integer value is obtained with functionord and the string representation with function$.
importstd/strutilstypeAsciiControlChar{.pure.}=enumNUL,SOH,STX,ETX,EOT,ENQ,ACK,BEL,BS,HT,LF,VT,FF,CR,SO,SI,DLE,DC1,DC2,DC3,DC4,NAK,SYN,ETB,CAN,EM,SUB,ESC,FS,GS,RS,US,SP,DEL=0x7Fecho' ',CR," = ",ord(CR).toHex(2)echoDEL," = ",ord(DEL).toHex(2)
CR = 0DDEL = 7F
usecharnames":loose";# There is no EM, use END OF MEDIUM.# Do not confuse BEL with BELL. Starting in Perl 5.18, BELL refers to unicode emoji 0x1F514. ALERT is an alias for BEL.# compile time literal"\N{nul}\N{soh}\N{stx}\N{etx}\N{eot}\N{enq}\N{ack}\N{bel}\N{bs}\N{ht}\N{lf}\N{vt}\N{ff}\N{cr}\N{so}\N{si}\N{dle}\N{dc1}\N{dc2}\N{dc3}\N{dc4}\N{nak}\N{syn}\N{etb}\N{can}\N{end of medium}\N{sub}\N{esc}\N{fs}\N{gs}\N{rs}\N{us}\N{space}\N{delete}"# run timecharnames::string_vianame$_;
importunicodedatacontrol_chars=[(i,chr(i))foriinrange(128)ifunicodedata.category(chr(i))=='Cc']print(control_chars)
[(0, '\x00'), (1, '\x01'), (2, '\x02'), (3, '\x03'), (4, '\x04'), (5, '\x05'), (6, '\x06'), (7, '\x07'), (8, '\x08'), (9, '\t'), (10, '\n'), (11, '\x0b'), (12, '\x0c'), (13, '\r'), (14, '\x0e'), (15, '\x0f'), (16, '\x10'), (17, '\x11'), (18, '\x12'), (19, '\x13'), (20, '\x14'), (21, '\x15'), (22, '\x16'), (23, '\x17'), (24, '\x18'), (25, '\x19'), (26, '\x1a'), (27, '\x1b'), (28, '\x1c'), (29, '\x1d'), (30, '\x1e'), (31, '\x1f'), (127, '\x7f')]
enumnul=0,soh,stx,etx,eot,enq,ack,bel,bs,ht,lf,vt,ff,cr,so,si,dle,dc1,dc2,dc3,dc4,nak,syn,etb,can,em,sub,esc,fs,gs,rs,us,space,del=127?cr?del
13127
There doesn't seem to really be a point or a purpose to this task other than creating a enumeration...
'space' is absolutelyNOT a control character. Pretending it is is just completely incorrect.
enumC0 (|(^32).map({ (0x2400 +$_).chr =>$_ }),'␡' =>127);printf"Ord: %3d, Unicode: %s, Enum: %s\n",$_, .uniname,C0($_)for (^128).grep: {.chr ~~ /<:Cc>/}
Ord: 0, Unicode: <control-0000>, Enum: ␀Ord: 1, Unicode: <control-0001>, Enum: ␁Ord: 2, Unicode: <control-0002>, Enum: ␂Ord: 3, Unicode: <control-0003>, Enum: ␃Ord: 4, Unicode: <control-0004>, Enum: ␄Ord: 5, Unicode: <control-0005>, Enum: ␅Ord: 6, Unicode: <control-0006>, Enum: ␆Ord: 7, Unicode: <control-0007>, Enum: ␇Ord: 8, Unicode: <control-0008>, Enum: ␈Ord: 9, Unicode: <control-0009>, Enum: ␉Ord: 10, Unicode: <control-000A>, Enum: ␊Ord: 11, Unicode: <control-000B>, Enum: ␋Ord: 12, Unicode: <control-000C>, Enum: ␌Ord: 13, Unicode: <control-000D>, Enum: ␍Ord: 14, Unicode: <control-000E>, Enum: ␎Ord: 15, Unicode: <control-000F>, Enum: ␏Ord: 16, Unicode: <control-0010>, Enum: ␐Ord: 17, Unicode: <control-0011>, Enum: ␑Ord: 18, Unicode: <control-0012>, Enum: ␒Ord: 19, Unicode: <control-0013>, Enum: ␓Ord: 20, Unicode: <control-0014>, Enum: ␔Ord: 21, Unicode: <control-0015>, Enum: ␕Ord: 22, Unicode: <control-0016>, Enum: ␖Ord: 23, Unicode: <control-0017>, Enum: ␗Ord: 24, Unicode: <control-0018>, Enum: ␘Ord: 25, Unicode: <control-0019>, Enum: ␙Ord: 26, Unicode: <control-001A>, Enum: ␚Ord: 27, Unicode: <control-001B>, Enum: ␛Ord: 28, Unicode: <control-001C>, Enum: ␜Ord: 29, Unicode: <control-001D>, Enum: ␝Ord: 30, Unicode: <control-001E>, Enum: ␞Ord: 31, Unicode: <control-001F>, Enum: ␟Ord: 127, Unicode: <control-007F>, Enum: ␡
There is no enum in RPL, but we can create global variables, each containing a specific control character, which are then available to all programs in the same directory tree.
≪ { NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US } 0 31FOR ctrl ctrl CHR OVER ctrl GET STONEXT DROP 127 CHR 'DEL' STO ≫ '→ASCII' STOThe AsciiChar enum is abridged from a currently private enum in Rust core's std::char.
#[derive(Clone, Copy, Debug)]pubenumAsciiChar{Null=0,StartOfHeading=1,StartOfText=2,EndOfText=3,EndOfTransmission=4,Enquiry=5,Acknowledge=6,Bell=7,Backspace=8,CharacterTabulation=9,LineFeed=10,LineTabulation=11,FormFeed=12,CarriageReturn=13,ShiftOut=14,ShiftIn=15,DataLinkEscape=16,DeviceControlOne=17,DeviceControlTwo=18,DeviceControlThree=19,DeviceControlFour=20,NegativeAcknowledge=21,SynchronousIdle=22,EndOfTransmissionBlock=23,Cancel=24,EndOfMedium=25,Substitute=26,Escape=27,InformationSeparatorFour=28,InformationSeparatorThree=29,InformationSeparatorTwo=30,InformationSeparatorOne=31,Space=32,ExclamationMark=33,QuotationMark=34,NumberSign=35,DollarSign=36,PercentSign=37,Ampersand=38,Apostrophe=39,LeftParenthesis=40,RightParenthesis=41,Asterisk=42,PlusSign=43,Comma=44,HyphenMinus=45,FullStop=46,Solidus=47,Colon=58,Semicolon=59,LessThanSign=60,EqualsSign=61,GreaterThanSign=62,QuestionMark=63,CommercialAt=64,LeftSquareBracket=91,ReverseSolidus=92,RightSquareBracket=93,CircumflexAccent=94,LowLine=95,GraveAccent=96,LeftCurlyBracket=123,VerticalLine=124,RightCurlyBracket=125,Tilde=126,Delete=127,}fnmain(){println!("Value Control char name\n{}","_".repeat(32));foriin0_u8..=127{unsafe{// no need to check this, it is all 0 <= c <= 127, transmute is in rangeletch=char::from_u32_unchecked(iasu32);ifch.is_ascii_control(){letascii:AsciiChar=std::mem::transmute::<_,AsciiChar>(i);println!("{:>3} {:?}",i,ascii);}}}}
Value Control char name________________________________ 0 Null 1 StartOfHeading 2 StartOfText 3 EndOfText 4 EndOfTransmission 5 Enquiry 6 Acknowledge 7 Bell 8 Backspace 9 CharacterTabulation 10 LineFeed 11 LineTabulation 12 FormFeed 13 CarriageReturn 14 ShiftOut 15 ShiftIn 16 DataLinkEscape 17 DeviceControlOne 18 DeviceControlTwo 19 DeviceControlThree 20 DeviceControlFour 21 NegativeAcknowledge 22 SynchronousIdle 23 EndOfTransmissionBlock 24 Cancel 25 EndOfMedium 26 Substitute 27 Escape 28 InformationSeparatorFour 29 InformationSeparatorThree 30 InformationSeparatorTwo 31 InformationSeparatorOne127 Delete
enumCtrl{nul=0sohstxetxeotenqackbelbshtlfvtffcrsosidledc1dc2dc3dc4naksynetbcanemsubescfsgsrsusspacedel=127}fnmain(){println(int(Ctrl.cr))println(int(Ctrl.del))}
13127
Wren doesn't have enums built into the language but can create them dynamically at runtime. However, such enums need to have consecutive integer values.
Here, we create instead aGroup which can contain any values in any order.
import"./dynamic"forGroupvarnames=["nul","soh","stx","etx","eot","enq","ack","bel","bs","ht","lf","vt","ff","cr","so","si","dle","dc1","dc2","dc3","dc4","nak","syn","etb","can","em","sub","esc","fs","gs","rs","us","space","del"]varvalues=(0..32).toList+[127]varCtrl=Group.create("Ctrl",names,values)// print some specimen valuesSystem.print(Ctrl.cr)System.print(Ctrl.del)
13127
def NUL, SOH, STX, ETX, EOT, ENQ, ACK, BEL, BS, HT, LF, VT, FF, CR, SO, SI, DLE, DC1, DC2, DC3, DC4, NAK, SYN, ETB, CAN, EM, SUB, ESC, FS, GS, RS, US, Space, DEL=127;[IntOut(0, NUL); CrLf(0); IntOut(0, FF); CrLf(0); IntOut(0, Space); CrLf(0); IntOut(0, Del); CrLf(0);]
01232127
const std = @import("std");const Ctrl = enum(u8) { nul, soh, stx, etx, eot, enq, ack, bel, bs, ht, lf, vt, ff, cr, so, si, dle, dc1, dc2, dc3, dc4, nak, syn, etb, can, em, sub, esc, fs, gs, rs, us, space, del = 127,};pub fn main() !void { const stdout = std.io.getStdOut().writer(); try stdout.print("{s} {d}\n", .{@tagName(Ctrl.em), @intFromEnum(Ctrl.em)}); try stdout.print("{s} {d}\n", .{@tagName(Ctrl.del), @intFromEnum(Ctrl.del)});}em 25del 127