Rapid Euphoria 3.1.1

MACHINE2.E for Euphoria 3.1.1 Version 1.10, September/19/2019, by Shian Lee. 1. Introduction This library provides basic utilities, bitwise operators and machine level interface routines, for any platform. Version 1.08 includes the new routines: bsearch(), hash() and checksum(). Tip: in Euphoria 3.1.1 you can use the builtin floor() function to speedup 'for' loops or any other calculation, for example: for i = 1 to floor(15000001 / 2) do ... is much faster then: for i = 1 to 15000001 / 2 do ... floor() converts real numbers to integers which perform *much* faster. Note: yesterday (Jan/10/2017) I downloaded the full version of FreeDOS 1.2, and it was great to find out that Euphoria 3.1.1 is included with FreeDOS 1.2! My favorite programming language with my favorite OS...! What's new in version 1.10: - type byte_string() - test if an object is an unsigned byte-string. - function encode() - encode or decode data. (now works much faster!). - function sencode() - encode or decode a string sequence. Disclaimer ========== Use this library at your own risk. The author will not be responsible for any damage or data loss. This library is tested and optimized on FreeDOS 1.1 operating system. The code or the documentation might still contain errors or mistakes. In the descriptions below, to indicate what kind of object may be passed in and returned, the following prefixes are used: x - a general object (atom or sequence) s - a sequence a - an atom i - an integer fn - an integer used as a file number st - a string sequence, or single-character atom 2. Routines by Application Area 2.1 Predefined Types ==================== As well as declaring variables with these types, you can also call them just like ordinary functions, in order to test if a value is a certain type. boolean - test if an object is a boolean integer dwords - test if an object is a DWORD (32-bit) atom or sequence string - test if an object is a string (a flat sequence) byte_string - test if an object is an unsigned byte-string 2.2 Sequence Manipulation ========================= sum - calculate the sum of a sequence flat - flatten a sequence, don't add an end-of-string marker flatten - flatten a sequence sencode - encode or decode a string sequence EMPTY - an empty sequence ({}) 2.3 Searching and Sorting ========================= bsearch - find an object in a sorted sequence hash - calculate the hash value of an object 2.4 Math ======== These routines can be applied to individual atoms or to sequences of values. abs - return the absolute value of a number fix - truncate the fractional part of a number sign - return a value indicating the sign of a number, 0 is 0 psign - return a value indicating the sign of a number, 0 is 1 nsign - return a value indicating the sign of a number, 0 is -1 zsign - return a value indicating the sign of a number, 0 is TRUE 2.5 Bitwise Operations ====================== These routines treat numbers as collections of binary bits, and can be applied to individual atoms or to sequences of values. The arguments must be representable as 32-bit numbers, either signed or unsigned. eqv_bits - perform logical EQV on corresponding bits imp_bits - perform logical IMP on corresponding bits shl_bits - return the result of shifting bits left shr_bits - return the result of shifting bits right rol_bits - return the result of rotating bits left ror_bits - return the result of rotating bits right get_bit - return the result of getting a bit value set_bit - return the result of setting a bit value pack_bits - convert a sequence of numbers to an integer unpack_bits - convert an integer to a sequence of numbers FALSE - the boolean value 0 TRUE - the boolean value 1 2.6 File and Device I/O ======================= putx - output an object to a file or device get_xkey - check for key pressed by the user, don't wait, return an object wait_xkey - wait for user to press a key, return an object pause - suspend execution until user press a key clear_keyboard - clear the keyboard buffer checksum - calculate the checksum value of data encode - encode or decode data 2.7 Operating System ==================== delay - suspend execution for a period of time TIME_SIGN - return a value indicating the sign of time() 2.8 Machine Level Interface =========================== peek2s - read 2-byte signed values from memory peek2u - read 2-byte unsigned values from memory poke2 - write 2-byte values into memory bin - convert an atom or sequence to binary string oct - convert an atom or sequence to octal string dec - convert an atom or sequence to decimal string hex - convert an atom or sequence to hexadecimal string int - convert a string or sequence to an atom signed - convert an atom or sequence to signed number unsigned - convert an atom or sequence to unsigned number range_per_bits - return range of numbers per bits crash - specify a message to be printed and crash your program 2.9 Misc ======== iif - return a value according to specified condition 3. Alphabetical Listing of all Routines -----------------------------------<abs>------------------------------------ Syntax: include machine2.e x2 = abs(x1) Description: Return the absolute value of x1. Comments: This function may be applied to an atom or to all elements of a sequence. Example: y = abs({0.5, -1.6, 9.99, -100, 0}) -- y is {0.5, 1.6, 9.99, 100, 0} See Also: fix, sign, unsigned Euphoria 3.1.1: floor -----------------------------------<bin>------------------------------------ Syntax: include machine2.e s = bin(x) Description: Convert an atom or sequence to binary string. Negative numbers are returned in two's complement, so -1 will return as "0b11111111111111111111111111111111" (#FFFFFFFF). The fractional part of x is truncated. Comments: x must be representable as 32-bit number, either signed or unsigned. Example: s = bin(177) -- s is "0b10110001" s = bin({59, -59}) -- s is {"0b111011", "0b11111111111111111111111111000101"} See Also: oct, dec, hex, int, dwords Euphoria 3.1.1: int_to_bits, sprintf, and_bits ---------------------------------<boolean>---------------------------------- Syntax: include machine2.e i = boolean(x) Description: Return 1 if x is 0 (false) or 1 (true). Otherwise return 0. Comments: This serves to define the boolean type. You can also call it like an ordinary function to determine if an object is a boolean. Example 1: boolean z z = 1 Example 2: if boolean(y) then puts(SCREEN, "y is 0 or 1") end if See Also: dwords, byte_string, string, FALSE, TRUE, iif Euphoria 3.1.1: integer, atom, sequence ---------------------------------<bsearch>---------------------------------- Syntax: include machine2.e i = bsearch(x, s) Description: Find x as an element of s. Sequence s must be sorted in ascending order. If successful, return the index of the element of s that matches. If unsuccessful return the index of the element of s that x would have, if inserted now, as a negative number. Comments: bsearch() is using a fast binary search algorithm which is useful for finding a record in a large associative array, i.e. a map or a dictionary. i may or may not point to the first match if the element x appears more then once in s. bsearch() is faster then find() for lookup in a large sequence. Example 1: i = bsearch(100, {1, 2, 3, 4, 5, 6, 100, 105, 900}) -- i is 7 Example 2: s = {"ab", "dc", "qt"} i = bsearch("de", s) -- i is -3 -- i.e. index 3 if s was {"ab", "dc", "de", "qt"} Example 3: -- using bsearch() to get value from an associative array (a map) constant KEYS = 1, VALUES = 2 s = { {"basic", "c", "euphoria"}, -- sorted keys {"simple", "hard", "rapid"} -- values } i = bsearch("euphoria", s[KEYS]) -- i is 3 -- i.e. the value is s[VALUES][3], "rapid" See Also: hash Euphoria 3.1.1: find, match, compare, sort -------------------------------<byte_string>-------------------------------- Syntax: include machine2.e i = byte_string(x) Description: Return 1 if x is an unsigned byte-string, i.e. a flat sequence without any (sub)sequences within it, which is made of numbers in the range 0 to 255. Otherwise return 0. Comments: This serves to define the byte_string type. You can also call it like an ordinary function to determine if an object is a byte_string. Example 1: byte_string z z = {0, 2.5, 103} Example 2: z = {65.1, 66.9, 67} if byte_string(z) then puts(SCREEN, z & " is a byte-string!") end if Example 3: i = byte_string({1, 2.5, 3, ""}) -- i is 0 i = byte_string({1, 2.5, 3, 260}) -- i is 0 See Also: string, dwords, boolean, flatten, EMPTY Euphoria 3.1.1: sequence, atom --------------------------------<checksum>---------------------------------- Syntax: include machine2.e a = checksum(fn, i) Description: Calculate the checksum value of data from file or device fn. When i is 0 (false) a 16-bit integer is returned. When i is 1 (true) a 32-bit atom is returned. Comments: fn must be a file-number which was opened in binary mode for reading, for example: fn = open(filename, "rb"). Currently, files up to 2 Gb in size can be handled. Checksum is useful for verifying data integrity, i.e. for verifying that data is not corrupted or accidentally modified, by saving an old checksum value and later comparing it to a new checksum value of the same data. It's much faster to calculate a 16-bit checksum value, yet 32-bit checksum value is a bit more reliable, which means that there is a lower probability to return the same checksum value for a different data. checksum() is using the DJB hash algorithm by Daniel J. Bernstein. It's not suitable for cryptography. Example: fn = open("machine2.doc", "rb") -- open binary file for reading if fn = -1 then puts(1, "\nCannot open the file for reading!\n") else cs = checksum(fn, 0) -- calculate a 16-bit checksum value close(fn) printf(1, "\nThe checksum is: %.0f\n", cs) end if See Also: hash, encode, sencode -----------------------------<clear_keyboard>------------------------------- Syntax: include machine2.e clear_keyboard() Description: Clear the keyboard buffer. Comments: The operating system can hold a small number of key-hits in its keyboard buffer. clear_keyboard() is useful when you want to discard any old key-hits and let the user input a new key. Example: sleep(5) -- press a key -- any key-hit will be discarded clear_keyboard() puts(1, "\nPress 'y' to continue, or any other key to stop: ") key = wait_key() See Also: wait_xkey, get_xkey, pause Euphoria 3.1.1: wait_key, get_key ----------------------------------<crash>----------------------------------- Syntax: include machine2.e crash(s) Description: Crash your program. s is a string to be printed on the screen. Comments: crash() is useful when there is no actual run-time error, but a programming bug or a critical hardware failure is trapped by your program and you must stop your program from running. Debugging information will still be stored in ex.err. You won't lose any information by doing this. s will be passed to crash_message(). You can leave s empty, "", if you don't want to print any message, or if you already called crash_message() before. if crash_routine() is specified then control is passed to that routine immediately after crash(). Example: crash("Bad argument in function get_version().\n") See Also: Euphoria 3.1.1: crash_message, crash_routine, crash_file, abort -----------------------------------<dec>------------------------------------ Syntax: include machine2.e s = dec(x) Description: Convert an atom or sequence to unsigned decimal string. Negative numbers are returned in two's complement, so -1 will return as "4294967295" (#FFFFFFFF). The fractional part of x is truncated. Comments: x must be representable as 32-bit number, either signed or unsigned. Example: s = dec(177) -- s is "177" s = dec({59, -59}) -- s is {"59", "4294967237"} See Also: bin, oct, hex, int, dwords Euphoria 3.1.1: sprintf, value ----------------------------------<delay>----------------------------------- Syntax: include machine2.e delay(a) Description: Suspend execution for a 0.01 seconds. Comments: On delay your program will go into a busy loop for a 0.01 seconds, during which time other processes may run, but they will compete with your process for the CPU. Under DOS32 you can improve the time() resolution by calling tick_rate(100). On WIN32 and Linux/FreeBSD the time() resolution is about 0.01 second. Example 1: tick_rate(100) -- set 100 ticks/second for DOS32 puts(1, "Waiting 0.5 second...\n") delay(50) -- 50 * 0.01 seconds is 0.5 second puts(1, "Done.\n") Example 2: tick_rate(100) -- set 100 ticks/second for DOS32 for char = 33 to 126 do puts(1, char) delay(char / 5) end for See Also: pause, TIME_SIGN Euphoria 3.1.1: sleep, tick_rate, time ---------------------------------<dwords>----------------------------------- Syntax: include machine2.e i = dwords(x) Description: Return 1 if x is an atom or a sequence of atoms in the range -2147483648 to +4294967295 (fractional numbers allowed). Otherwise return 0. Comments: This serves to define the dwords type. You can also call it like an ordinary function to determine if an object is a dwords (DWORD is a 32-bit number, either signed or unsigned). Some functions, especially bitwise logical operators such as and_bits(), are limited to 32-bit numbers. You can find out if an argument is a 32-bit number by calling dwords(). Example 1: dwords y, z y = -1 z = {#FF000002, y} Example 2: x1 = -1.5 x2 = #FFFFFFFF if dwords({x1, x2}) then puts(1, "x1 and x2 are 32-bit numbers.") end if See Also: byte_string, boolean, fix, signed, unsigned, range_per_bits Euphoria 3.1.1: atom, sequence, floor ----------------------------------<empty>----------------------------------- Syntax: include machine2.e EMPTY Description: EMPTY ({}) has been defined as a global constant. Example: x = EMPTY -- x is {} See Also: flatten, FALSE Euphoria 3.1.1: sequence ---------------------------------<encode>----------------------------------- Syntax: include machine2.e i = encode(st1, st2, s) Description: Encode or decode the data of file or device st1. st2 is the new file to create. s is a string sequence, a key (password) which is made of any integer type numbers. encode() is used for both encoding or decoding an already encoded file. An error status is returned, where error status can be one of: 0 -- success 1 -- can't open file or device st1 for read 2 -- can't open file or device st2 for write 3 -- an empty key (password) Comments: Both files, st1 and st2 are opened in binary mode. File st1 is opened for reading and it must be exist. File st2 is opened for writing, if file st2 is already exist it will be overwritten, if not, then it will be created. Currently, files up to 2 Gb in size can be handled. An encoded file is a binary file (not text file), which you *must* open, copy or transfer in binary mode, otherwise the file might be modified by the operating system. Decoding an encoded file is possible *only* by using the exact key (password) that was used to encode that file! encode() is useful for encrypting data, it provides additional layer of safety for storing sensitive user data. Using a long key, s, with different characters, provides a much safer encryption. Examples for a strong key: "@!I'll do my homework NOW!@18" or... {-13454, 0, 93433, 190, 933444, 14, -452, -2243, 97442, -337844}. Encoding (encrypting) of data is commonly used by spreadsheets, editors, compression utilities, operating industrial machines, precise scientific calculations, and in many other areas which require safety. Using both encode() and checksum() provides even higher safety. encode() is using the DJB hash algorithm by Daniel J. Bernstein. It may or *may not* be suitable for advanced cryptography. The author of encode() algorithm is just me (Shian Lee). Example: -- encode and decode an existing file. -- you must encode and decode a file using the exact same key. -- you can browse the encoded file using a binary-files viewer. sequence source_file, encoded_file, key integer status source_file = "machine2.doc" encoded_file = "@achine2.doc" key = "*.Just on time Bro!.*" puts(1, "encoding '" & source_file & "'...\n") status = encode(source_file, encoded_file, key) if status then printf(1, "Error #%d !\n", status) abort(1) end if puts(1, "decoding '" & encoded_file & "'...\n") status = encode(encoded_file, source_file, key) if status then printf(1, "Error #%d !\n", status) abort(1) end if puts(1, "Done.\n") See Also: sencode, checksum, hash, pack_bits Euphoria 3.1.1: xor_bits, atom_to_float64 ---------------------------------<eqv_bits>--------------------------------- Syntax: include machine2.e x3 = eqv_bits(x1, x2) Description: Perform the logical EQV (Equivalence) operation on corresponding bits in x1 and x2. A bit in x3 will be 1 only if the corresponding bits in x1 and x2 are both 1 or both 0. Comments: The arguments to this function may be atoms or sequences. The rules for operations on sequences apply. The arguments must be representable as 32-bit numbers, either signed or unsigned. If you intend to manipulate full 32-bit values, you should declare your variables as atom, rather than integer. Euphoria's integer type is limited to 31-bits. Results are treated as signed numbers. They will be negative when the highest-order bit is 1. To understand the binary representation of a number you should display it in binary or hexadecimal notation, with bin() or hex(). Example 1: a = eqv_bits(#0F0F0000, #12345678) -- a is #E2C4A987 Example 2: a = eqv_bits(#FF, {#123456, #876543, #2211}) -- a is {#FFEDCB56, #FF789A43, #FFFFDD11} Example 3: a = eqv_bits(#FFFFFFFF, #FFFFFFFF) -- a is -1 -- Note that #FFFFFFFF is a positive number, -- but the result of a bitwise logical operation is interpreted -- as a signed 32-bit number, so it's negative. See Also: imp_bits, bin, hex, shl_bits Euphoria 3.1.1: and_bits, int_to_bits, sprintf -----------------------------------<false>---------------------------------- Syntax: include machine2.e FALSE Description: FALSE (0) has been defined as a global constant. Example: x = FALSE -- x is 0 See Also: TRUE, boolean, bin, EMPTY ------------------------------------<fix>----------------------------------- Syntax: include machine2.e x2 = fix(x1) Description: Return the integer portion of x1. (Truncate the fractional part). Comments: This function may be applied to an atom or to all elements of a sequence. fix() does not round the number. Example: y = fix({0.5, -1.6, 9.99, 100}) -- y is {0, -1, 9, 100} See Also: abs, sign Euphoria 3.1.1: floor, remainder, or_bits -----------------------------------<flat>----------------------------------- Syntax: include machine2.e s2 = flat(s1) Description: Flatten the elements of sequence s1. Comments: A new sequence is created without any (sub)sequences within it. flat() is faster and more efficient then flatten() and should be used instead of flatten() wherever you don't need to specify an end-of-string marker. Example: s = flat({}) -- {} s = flat({99}) -- {99} s = flat({1,3,5,7}) -- {1,3,5,7} s = flat({{1,2,3}, {4,5,6}}) -- {1,2,3,4,5,6} s = flat({0,{1},2,{{3,4,{5.5,6}},{{7,8}}},9,10,{11}}) -- {0,1,2,3,4,5.5,6,7,8,9,10,11} See Also: flatten, string, EMPTY Euphoria 3.1.1: puts, sequence, append ---------------------------------<flatten>---------------------------------- Syntax: include machine2.e s2 = flatten(s1, st) Description: Flatten the elements of sequence s1. st is a single atom or a sequence of characters for an end-of-string marker. Comments: A new sequence is created without any (sub)sequences within it. Example 1: s = flatten({1,3,5,7}, "") -- {1,3,5,7} Example 2: s = flatten({{1,2,3}, {4,5,6}}, "") -- {1,2,3,4,5,6} s = flatten({{1,2,3}, {4,5,6}}, -1) -- {1,2,3,-1,4,5,6,-1} s = flatten({{1,2,3}, {4,5,6}}, "$!") -- {1,2,3,36,33,4,5,6,36,33} Example 3: s = flatten({99}, "") -- {99} Example 4: s = flatten({}, "") -- {} Example 5: s = flatten({0,{1},2,{{3,4,{5.5,6}},{{7,8}}},9,10,{11}}, "") -- {0,1,2,3,4,5.5,6,7,8,9,10,11} s = flatten({0,{1},2,{{3,4,{5.5,6}},{{7,8}}},9,10,{11}}, -1) -- {0,-1,1,-1,2,-1,3,4,-1,5.5,6,-1,7,8,-1,9,10,-1,11,-1} See Also: flat, string, sum, putx, EMPTY Euphoria 3.1.1: append, prepend, repeat, reverse ---------------------------------<get_bit>---------------------------------- Syntax: include machine2.e x2 = get_bit(x1, i) Description: Return the result of getting bit-i from x1. x2 will be 0 if bit-i is 0 (false). x2 will be non-zero if bit-i is 1 (true). i must be in the range 1 to 33. Comments: x1 may be an atom or a sequence. The rules for operations on sequences apply. x1 must be representable as 32-bit numbers, either signed or unsigned. If you intend to manipulate full 32-bit values, you should declare your variables as atom, rather than integer. Euphoria's integer type is limited to 31-bits. Results are treated as signed numbers. They will be negative when the highest-order bit is 1. Example 1: a = get_bit(#FF123400, 32) -- a is -2147483648 i.e. #80000000 interpreted as negative number Example 2: a = get_bit({#123456, #876543, #2211}, 5) -- a is {#10, #0, #10} See Also: set_bit, shr_bits, unpack_bits, bin, hex Euphoria 3.1.1: and_bits, or_bits, int_to_bits ---------------------------------<get_xkey>--------------------------------- Syntax: include machine2.e x = get_xkey() Description: Return the key that was pressed by the user, without waiting. Return -1 if no key was pressed. Special codes are returned for the function keys, arrow keys etc. Comments: Because either a string-sequence or an atom might be returned, you should probably assign the result to a variable declared as object. The operating system can hold a small number of key-hits in its keyboard buffer. get_xkey() will return the next one from the buffer, or -1 if the buffer is empty. get_xkey() is useful for programs that run in Linux terminal or in any other environment that may return a sequence of atoms for a single key-hit (escape sequence, UTF-8 character, etc). Run the xkey.ex program to see what key code is generated for each key on your keyboard. See Also: wait_xkey, clear_keyboard, pause Euphoria 3.1.1: get_key, wait_key, getc -----------------------------------<hash>----------------------------------- Syntax: include machine2.e a2 = hash(x, a1) Description: Calculate the hash value of x. a2 will be a natural number in the range 1 to the absolute value of a1. Comments: You can use hash() to create a hash table (also known as map, associative array, dictionary), and to calculate a checksum for verifying data integrity of an object. When creating a hash table, the hash value returned by hash() is used as an index of a record in the hash table, e.g. for a hash table of 1000 records: record_number = hash(x, 1000). See also the example program demo\hash.ex. It's much faster to calculate a hash value when a1 is a 16-bit integer, i.e. smaller then 65536. If a1 is fractional, e.g. 1000.4, the calculation will be slower. If a1 is 0 your program will abort with a run-time error message. hash() is using the DJB algorithm by Daniel J. Bernstein, which is a short algorithm, yet fast and gives a good distribution for a hash table. hash() is not suitable for cryptography. Example: n = hash("ABcdefg", 1000) -- n is 498 n = hash("BAcdefg", 1000) -- n is 74 n = hash(-122, 1000) -- n is 452 n = hash(-123, 1000) -- n is 451 n = hash({1.5, 1.5}, #FFFF) -- n is 27346 n = hash({1.5, 1.6}, #FFFF) -- n is 27346 n = hash({1.6, 1.6}, #FFFF) -- n is 27349 n = hash({1, {-19.4, 0}, 30}, #FFFFFFFF) -- n is 386733994 n = hash({1, {-19.4, 0}, 30, {}}, #FFFFFFFF) -- n is 4172292562 See Also: checksum, bsearch Euphoria 3.1.1 example program: demo\hash.ex -----------------------------------<hex>------------------------------------ Syntax: include machine2.e s = hex(x) Description: Convert an atom or sequence to hexadecimal string. Negative numbers are returned in two's complement, so -1 will return as "#FFFFFFFF". The fractional part of x is truncated. Comments: x must be representable as 32-bit number, either signed or unsigned. Example: s = hex(177) -- s is "#B1" s = hex({59, -59}) -- s is {"#3B", "#FFFFFFC5"} See Also: bin, oct, dec, int, dwords Euphoria 3.1.1: sprintf, value, and_bits -----------------------------------<iif>------------------------------------ Syntax: include machine2.e x3 = iif(a, x1, x2) Description: Test the condition a. If a is non-zero (true) then return x1. If a is 0 (false) then return x2. Comments: A typical use for iif() is to assign a value to constant, or to make a long code shorter and more readable. iif() is slower then an if statement, and both arguments x1 and x2 are *always* evaluated, so it's not recommended to use iif() where speed and performances are your first priority. Example: constant SLASH = iif(platform() = LINUX, '/', '\\') See Also: Euphoria 3.1.1: REFMAN.DOC, 2.5.3 if statement --------------------------------<imp_bits>---------------------------------- Syntax: include machine2.e x3 = imp_bits(x1, x2) Description: Perform the logical IMP (Implication) operation on corresponding bits in x1 and x2. A bit in x3 will be 1 only if the corresponding bits in x1 and x2 are both 1 or both 0, or when corresponding bits in x1 are 0 and in x2 are 1. Comments: The arguments to this function may be atoms or sequences. The rules for operations on sequences apply. The arguments must be representable as 32-bit numbers, either signed or unsigned. If you intend to manipulate full 32-bit values, you should declare your variables as atom, rather than integer. Euphoria's integer type is limited to 31-bits. Results are treated as signed numbers. They will be negative when the highest-order bit is 1. A summery of bitwise logical operations, and a truth table: not_bits() NOT - Bit-wise complement and_bits() AND - Conjunction or_bits() OR - Disjunction (inclusive OR) xor_bits() XOR - Exclusive OR eqv_bits() EQV - Equivalence imp_bits() IMP - Implication x1 x2 NOT(x1) AND OR XOR EQV IMP -- -- ------- --- --- --- --- --- 1 1 0 1 1 0 1 1 1 0 0 0 1 1 0 0 0 1 1 0 1 1 0 1 0 0 1 0 0 0 1 1 Example 1: a = imp_bits(#0F0F0000, #12345678) -- a is #F2F4FFFF Example 2: a = imp_bits(#FF, {#123456, #876543, #2211}) -- a is {#FFFFFF56, #FFFFFF43, #FFFFFF11} See Also: eqv_bits, bin, hex, shl_bits Euphoria 3.1.1: and_bits, int_to_bits, sprintf -----------------------------------<int>------------------------------------ Syntax: include machine2.e x = int(s) Description: Convert a string or sequence to unsigned atom. s may be the result of a previous call to bin(), oct(), dec() or hex(); or a string representation of an unsigned atom. s must start with a prefix (except for decimal representation); possible prefixes are: "0b" - binary representation (digits 0-1) "0o" - octal representation (digits 0-7) "0x" or "#" - hexadecimal representation (digits 0-9,A-F) Comments: Numbers returned by int() can be larger then 32-bits. Example: a = int("177") -- a is 177 a = int({"59", "-59", {" 7", "7z"}}) -- a is {59, 0, {0, 0}} -- invalid characters return 0 a = int("0b11110000") -- a is 240 a = int("0o123456") -- a is 42798 a = int({"0xFF35E", "#FF35E"}) -- a is {1045342, 1045342} a = int("#1FFFFFFFF") -- a is 8589934591 -- a is larger then 32-bit See Also: bin, oct, dec, hex, dwords, signed Euphoria 3.1.1: value, sprintf, bits_to_int ---------------------------------<nsign>------------------------------------ Syntax: include machine2.e x2 = nsign(x1) Description: Return a value indicating the sign of x1 (1 if x1 is positive, -1 if it is zero, or -1 if it is negative). Comments: This function may be applied to an atom or to all elements of a sequence. Example: y = nsign({0.5, -1.6, 9.99, -100, 0}) -- y is {1, -1, 1, -1, -1} See Also: sign, psign, zsign, abs, unsigned, signed -----------------------------------<oct>------------------------------------ Syntax: include machine2.e s = oct(x) Description: Convert an atom or sequence to octal string. Negative numbers are returned in two's complement, so -1 will return as "0o37777777777" (#FFFFFFFF). The fractional part of x is truncated. Comments: x must be representable as 32-bit number, either signed or unsigned. Example: s = oct(177) -- s is "0o261" s = oct({59, -59}) -- s is {"0o73", "0o37777777705"} See Also: bin, dec, hex, int, dwords Euphoria 3.1.1: sprintf -------------------------------<pack_bits>---------------------------------- Syntax: include machine2.e a = pack_bits(s1, s2) Description: Convert a sequence of numbers s1 to an integer. s2 defines the size (in bits) for packing each number in s1, respectively. s2 values must be in the range 0 to 32; You can also use negative values (0 to -32) to unpack (and pack) signed numbers. The (absolute) sum of s2 must be in the range 0 to 32. Comments: s1 must be representable as 32-bit numbers, either signed or unsigned. If you intend to manipulate full 32-bit values, you should declare your variables as atom, rather than integer. Euphoria's integer type is limited to 31-bits. Result is treated as signed number. It will be negative when the highest-order bit is 1. pack_bits()/unpack_bits() are useful for packing small numbers into integer. e.g. for packing date() sequence into integer. range_per_bits() will tell you how many bits are neccessary for packing a signed or unsigned number. Example 1: ints = {#FA3, #8, #12} bits = { 12, 4, 8} -- 12-bits/#FA3, 4-bits/#8, 8-bits/#12 i = pack_bits(ints, bits) -- i is 16398354 (#FA3812) s = unpack_bits(i, bits) -- s is {4003, 8, 18}; {#FA3, #8, #12} Example 2: ints = {#40000000, #1} bits = { 31, 1} -- 31-bits/#40000000, 1-bits/#1 a = pack_bits(ints, bits) -- a is -2147483647 (#80000001) s = unpack_bits(a, bits) -- s is {1073741824,1};{#40000000, #1} Example 3: ints = {-2000, 8, 18, -15} bits = { -12, 4, -8, -5} -- 12-bits/-2000 (signed), -- 4-bits/8 (unsigned), -- 8-bits/18 (signed), -- 5-bits/-15 (signed) i = pack_bits(ints, bits) -- i is 274793041 s = unpack_bits(i, bits) -- s is {-2000, 8, 18, -15} Example 4: ints = {-1073741824, 1} bits = { -31, -1} -- 31-bits/-1073741824 (signed), -- 1-bits/1 (signed) a = pack_bits(ints, bits) -- a is -2147483647 (#80000001) s = unpack_bits(a, bits) -- s is {-1073741824, -1} -- (signed range for 1-bits is -1..0) Example 5: -- pack current date() into 32-bit atom ints = date() -- {year,month,day,hour,minute,second} ints = ints[1..6] -- ints is {117,1,7,15,8,27} for demo bits = {7,4,5,5,6,5} -- 7-bits/year, 4-bits/month, 5-bits/day, -- 5-bits/hour, 6-bits/minute, 5-bits/sec ints[6] /= 2 -- 2-second increments (0-29) saves 1 bit a = pack_bits(ints, bits) -- a is -366511859 (#EA27790D) s = unpack_bits(a, bits) s[6] *= 2 -- (2-second increments) -- s is {117,1,7,15,8,26} -- (year is since 1900: 1900+117) See Also: unpack_bits, range_per_bits, shl_bits, bin, hex, sum Euphoria 3.1.1: and_bits, int_to_bits, bits_to_int ----------------------------------<pause>----------------------------------- Syntax: include machine2.e pause() Description: Suspend execution until user press a key. Comments: On multi-tasking systems like Windows or Linux/FreeBSD, pause() lets the operating system do other useful work while your program is waiting for the user to press a key. Example 1: puts(1, "Press few keys fast...\n\n") sleep(2) -- pause() clears previous keys pressed by the user puts(1, "Program paused, press any key to continue...\n\n") pause() puts(1, "Program continue.\n") Example 2: -- pause() is useful for debugging a program for row = 1 to 200 do printf(1, "This is line number %d\n", row) if remainder(row, 20) = 0 then pause() -- pause to see what's on the screen... end if end for See Also: delay Euphoria 3.1.1: wait_key, sleep ---------------------------------<peek2s>----------------------------------- Syntax: include machine2.e a2 = peek2s(a1) or ... s = peek2s({a1, i}) Description: Return a 2-byte (16-bit) signed value in the range -32768 to +32767 from machine address a1, or return a sequence containing i consecutive 2-byte signed values starting at address a1 in memory. Comments: Since machine addresses are 32-bit numbers, they can be too large for Euphoria's integer type. Variables that hold an address should therefore be declared as atoms. It is faster to read several 2-byte values at once using the second form of peek2s() than it is to read one 2-byte value at a time in a loop. Remember that peek2s() takes just one argument, which in the second form is actually a 2-element sequence. peek2s() is not as fast as peek() or peek4s(). Example: The following are equivalent: -- method 1 s = {peek2s(100), peek2s(102), peek2s(104), peek2s(106)} -- method 2 s = peek2s({100, 4}) See Also: peek2u, poke2 Euphoria 3.1.1: peek4s, peek, poke4 ---------------------------------<peek2u>----------------------------------- Syntax: include machine2.e a2 = peek2u(a1) or ... s = peek2u({a1, i}) Description: Return a 2-byte (16-bit) unsigned value in the range 0 to 65535 from machine address a1, or return a sequence containing i consecutive 2-byte unsigned values starting at address a1 in memory. Comments: Since machine addresses are 32-bit numbers, they can be too large for Euphoria's integer type. Variables that hold an address should therefore be declared as atoms. It is faster to read several 2-byte values at once using the second form of peek2u() than it is to read one 2-byte value at a time in a loop. Remember that peek2u() takes just one argument, which in the second form is actually a 2-element sequence. peek2u() is not as fast as peek() or peek4u(). Example: The following are equivalent: -- method 1 s = {peek2u(100), peek2u(102), peek2u(104), peek2u(106)} -- method 2 s = peek2u({100, 4}) See Also: peek2s, poke2 Euphoria 3.1.1: peek4u, peek, poke4 ----------------------------------<poke2>----------------------------------- Syntax: include machine2.e poke2(a, x) Description: If x is an atom, write a 2-byte (16-bit) value to memory address a. If x is a sequence, write a sequence of 2-byte values to consecutive memory locations starting at location a. Comments: The value or values to be stored must not exceed 16-bits in size. It is faster to write several 2-byte values at once by poking a sequence of values, than it is to write one 2-byte value at a time in a loop. The 2-byte values to be stored can be negative or positive. You can read them back with either peek2s() or peek2u(). poke2() is not as fast as poke() or poke4(). Example: a = allocate(100) -- allocate 100 bytes in memory -- poke one 2-byte value at a time: poke2(a, 13017) poke2(a+2, #FF00) poke2(a+4, -12345) -- poke 3 2-byte values at once: poke2(a, {13017, #FF00, -12345}) See Also: peek2s, peek2u Euphoria 3.1.1: poke, poke4, peek, peek4u, peek4s ----------------------------------<psign>----------------------------------- Syntax: include machine2.e x2 = psign(x1) Description: Return a value indicating the sign of x1 (1 if x1 is positive, 1 if it is zero, or -1 if it is negative). Comments: This function may be applied to an atom or to all elements of a sequence. Example: y = psign({0.5, -1.6, 9.99, -100, 0}) -- y is {1, -1, 1, -1, 1} See Also: sign, nsign, zsign, abs, unsigned, signed -----------------------------------<putx>----------------------------------- Syntax: include machine2.e putx(fn, x, st) Description: This is just a shorthand way of saying: puts(fn, flatten(x, st)) - i.e. output, to file or device fn, object x. st is a single byte (atom) or a sequence of bytes for an end-of-string marker (Typically a new-line character, '\n'). Comments: putx() is not as fast and efficient as puts(). Example 1: putx(1, {"First name:", " Last name:"}, '\n') Example 2: putx(out, 'A', "") -- the single byte 65 will be sent to out Example 3: x = {{"http",':','/','/'},"www",'.',{{"RapidEuphoria"},'.',"com"}} putx(1, x, "") Example 4: x = bin({#F, #FF, #FFFF, #FFFFFFFF}) putx(1, x, ",\n") See Also: get_xkey, pause, flat, flatten Euphoria 3.1.1: puts, print, printf, gets, open ---------------------------<range_per_bits>--------------------------------- Syntax: include machine2.e s = range_per_bits(x) Description: Return a sequence of values describing the range of numbers per x bits: {minimum value of a signed number, maximum value of a signed number, maximum value of an unsigned number} x must be in the range 0 to 32. Comments: This routine makes it easy for you to find out how many bits are neccessary for packing a signed or an unsigned number with pack_bits(). The minimum value of an unsigned number is always 0. Example 1: s = range_per_bits(32) -- s is {-2147483648, 2147483647, 4294967295} -- i.e. {-#80000000, #7FFFFFFF, #FFFFFFFF} Example 2: s = range_per_bits({4, 8, 16, 31}) -- s is { -- {-8, 7, 15}, -- {-128, 127, 255}, -- {-32768, 32767, 65535}, -- {-1073741824, 1073741823, 2147483647} -- } See Also: signed, unsigned, pack_bits, peek2s Euphoria 3.1.1: integer, peek4s --------------------------------<rol_bits>---------------------------------- Syntax: include machine2.e x2 = rol_bits(x1, i) Description: Return the result of rotating the bits of x1 left i number of bits. i must be in the range 0 to 32. Comments: x1 may be an atom or a sequence. The rules for operations on sequences apply. x1 must be representable as 32-bit numbers, either signed or unsigned. If you intend to manipulate full 32-bit values, you should declare your variables as atom, rather than integer. Euphoria's integer type is limited to 31-bits. Results are treated as signed numbers. They will be negative when the highest-order bit is 1. Example 1: a = rol_bits(#FF123400, 8) -- a is 305398015 (i.e. #123400FF interpreted as positive number) Example 2: a = rol_bits({#123456, #876543, #2211}, 16) -- a is {#34560012, #65430087, #22110000} See Also: ror_bits, shl_bits, set_bit, pack_bits, bin, hex Euphoria 3.1.1: and_bits, int_to_bits, bits_to_int -------------------------------<ror_bits>----------------------------------- Syntax: include machine2.e x2 = ror_bits(x1, i) Description: Return the result of rotating the bits of x1 right i number of bits. i must be in the range 0 to 32. Comments: x1 may be an atom or a sequence. The rules for operations on sequences apply. x1 must be representable as 32-bit numbers, either signed or unsigned. If you intend to manipulate full 32-bit values, you should declare your variables as atom, rather than integer. Euphoria's integer type is limited to 31-bits. Results are treated as signed numbers. They will be negative when the highest-order bit is 1. Example 1: a = ror_bits(#FF123400, 8) -- a is 16716340 (i.e. #FF1234 interpreted as a positive number) Example 2: a = ror_bits({#123456, #876543, #2211}, 24) -- a is {#12345600, #87654300, #221100} See Also: rol_bits, shr_bits, set_bit, pack_bits, bin, hex Euphoria 3.1.1: and_bits, int_to_bits, bits_to_int --------------------------------<sencode>----------------------------------- Syntax: include machine2.e s3 = sencode(s1, s2) Description: Encode or decode the data of (8-bit) byte-string s1. s2 is a string sequence, a key (password) which is made of any integer type numbers. The first time you call sencode() the data is encoded, and s3 will be a (8-bit) byte-string. The second time you call sencode(), using the encoded data and the exact same key, the data is decoded, and s3 will be equal to the original s1 byte-string. Comments: An encoded string sequence may be saved in a binary file (not text file), which you *must* open, copy or transfer in binary mode, otherwise the file might be modified by the operating system. Decoding an encoded string sequence is possible *only* by using the exact key (password) that was used to encode that string! sencode() is useful for encrypting data, it provides additional layer of safety for storing sensitive user data. Using a long key, s, with different characters, provides a much safer encryption. Examples for a strong key: "@!I'll do my homework NOW!@18" or... {-13454, 0, 93433, 190, 933444, 14, -452, -2243, 97442, -337844}. Encoding (encrypting) of a byte-string sequence may be useful for hiding data in your executable file. It can also be useful for hiding a specific field in a database; For example, you can hide specific fields in Euphoria Database System (EDS), without the need to encrypt an entire database and make it inaccessible to anyone else. sencode() is typically useful for encoding character strings (unsigned byte-strings in the range 0 to 255) such as "abc" or "\tA nice sunny day!\n". It is also possible to encode an Euphoria object, using sprint() and value(). Notice that in this case atoms are limited to a maximum of 10 significant digits! (see example below). sencode() is using the DJB hash algorithm by Daniel J. Bernstein. It may or *may not* be suitable for advanced cryptography. The author of sencode() algorithm is just me (Shian Lee). Example 1: -- encode and decode a byte-string #1 sequence key, s, s1, s2 key = "x" -- (a single character key is very easy to break...!) s = {0, 0, 0, 0, 0, 0, 0} s1 = sencode(s, key) -- encode byte-string -- s1 is {236, 127, 44, 66, 39, 152, 116} s2 = sencode(s1, key) -- decode byte-string (using the same key!) ? equal(s, s2) -- 1 = decoded string is identical to source Example 2: -- encode and decode a byte-string #2 sequence key, s, s1, s2 key = "@just on time!@" s = "Back to Square One" s1 = sencode(s, key) -- encode byte-string -- s1 is {246, 119, 57, 34, 47, 109, 216, 93, 222, -- 113, 28, 93, 59, 210, 111, 238, 250, 141} s2 = sencode(s1, key) -- decode byte-string (using the same key!) ? equal(s, s2) -- 1 = decoded string is identical to source Example 3: -- encode and decode an Euphoria object. Notice that atoms are -- limited to a maximum of 10 significant digits! include misc.e -- sprint() include get.e -- value() sequence key, s, s1, s2 key = "@##Look who's here...!!!!" s = {-390.1234567, {"ABC", 0, {30194.95}}} -- Euphoria object s1 = sencode(sprint(s), key) -- encode object -- s1 is {207,231,156,119,159,95,118,70,133,98,137,237,8,75, -- 139,139,52,146,15,243,35,204,164,101,152,119,42,160, -- 201,231,127,253,215,244,139,27,168,100,21,107} s2 = value(sencode(s1, key)) -- decode object s2 = s2[2] ? equal(s, s2) -- 1 = decoded object is identical to source See Also: encode, hash, checksum, pack_bits Euphoria 3.1.1: sprint, value, xor_bits, atom_to_float64 --------------------------------<set_bit>----------------------------------- Syntax: include machine2.e x2 = set_bit(x1, i1, i2) Description: Return the result of setting bit-i1 in x1 to value i2. If i2 is 0 bit-i1 will be 0 (false). If i2 is non-zero bit-i1 will be 1 (true). i1 must be in the range 1 to 33. Comments: x1 may be an atom or a sequence. The rules for operations on sequences apply. x1 must be representable as 32-bit numbers, either signed or unsigned. If you intend to manipulate full 32-bit values, you should declare your variables as atom, rather than integer. Euphoria's integer type is limited to 31-bits. Results are treated as signed numbers. They will be negative when the highest-order bit is 1. Example 1: a = set_bit(#FF123400, 2, 1) -- a is -15584254 (i.e. #FF123402 interpreted as negative number) Example 2: a = set_bit({#123456, #876543, #2211}, 5, 0) -- a is {#123446, #876543, #2201} See Also: get_bit, shl_bits, pack_bits, bin, hex Euphoria 3.1.1: and_bits, or_bits, int_to_bits --------------------------------<shl_bits>---------------------------------- Syntax: include machine2.e x2 = shl_bits(x1, i) Description: Return the result of shifting the bits of x1 left i number of bits. i must be in the range 0 to 32. Comments: x1 may be an atom or a sequence. The rules for operations on sequences apply. x1 must be representable as 32-bit numbers, either signed or unsigned. If you intend to manipulate full 32-bit values, you should declare your variables as atom, rather than integer. Euphoria's integer type is limited to 31-bits. Results are treated as signed numbers. They will be negative when the highest-order bit is 1. Example 1: a = shl_bits(#0FFF1234, 8) -- a is -15584256 (i.e. #FF123400 interpreted as negative number) Example 2: a = shl_bits({#123456, #876543, #2211}, 16) -- a is {#34560000, #65430000, #22110000} See Also: shr_bits, rol_bits, set_bit, pack_bits, bin, hex Euphoria 3.1.1: and_bits, int_to_bits, bits_to_int --------------------------------<shr_bits>---------------------------------- Syntax: include machine2.e x2 = shr_bits(x1, i) Description: Return the result of shifting the bits of x1 right i number of bits. i must be in the range 0 to 32. Comments: x1 may be an atom or a sequence. The rules for operations on sequences apply. x1 must be representable as 32-bit numbers, either signed or unsigned. If you intend to manipulate full 32-bit values, you should declare your variables as atom, rather than integer. Euphoria's integer type is limited to 31-bits. Results are treated as signed numbers. They will be negative when the highest-order bit is 1. Example 1: a = shr_bits(#FF123400, 8) -- a is 16716340 (i.e. #FF1234 interpreted as a positive number) Example 2: a = shr_bits({#123456, #876543, #2211}, 16) -- a is {#12, #87, #0} See Also: shl_bits, ror_bits, set_bit, pack_bits, bin, hex Euphoria 3.1.1: and_bits, int_to_bits, bits_to_int -----------------------------------<sign>----------------------------------- Syntax: include machine2.e x2 = sign(x1) Description: Return a value indicating the sign of x1 (1 if x1 is positive, 0 if it is zero, or -1 if it is negative). Comments: This function may be applied to an atom or to all elements of a sequence. Example: y = sign({0.5, -1.6, 9.99, -100, 0}) -- y is {1, -1, 1, -1, 0} See Also: psign, nsign, zsign, abs, unsigned, signed Euphoria 3.1.1: floor, and_bits ---------------------------------<signed>----------------------------------- Syntax: include machine2.e x2 = signed(x1, i) Description: Return the low-order i bits of x1 as a signed number. i must be in the range 0 to 32. The fractional part of x1 is truncated. Positive numbers are returned in two's complement, so #FFFFFFFF will return as -1. Comments: x1 may be an atom or a sequence. The rules for operations on sequences apply. x1 must be representable as 32-bit numbers, either signed or unsigned. Example 1: y = signed({0.5, 4294967295, 9.99, -100.6, 0, -#FF}, 32) -- y is {0, -1, 9, -100, 0, -255} Example 2: x = {#FFFFFFFF, #FFFF, #FF, #F} y = signed(x, 32) -- y is {-1, 65535, 255, 15} y = signed(x, 16) -- y is {-1, -1, 255, 15} y = signed(x, 8) -- y is {-1, -1, -1, 15} See Also: unsigned, unpack_bits, range_per_bits, fix, sign, peek2s Euphoria 3.1.1: peek4s ---------------------------------<string>----------------------------------- Syntax: include machine2.e i = string(x) Description: Return 1 if x is a string, i.e. a flat sequence without any (sub)sequences within it. Otherwise return 0. Comments: This serves to define the string type. You can also call it like an ordinary function to determine if an object is a string. Example 1: string z z = {1, 2.5, 3} Example 2: z = {65.1, 66.9, 67} if string(z) then puts(SCREEN, z & " is a string!") end if Example 3: i = string({1, 2.5, 3, ""}) -- i is 0 See Also: byte_string, dwords, boolean, flatten, EMPTY Euphoria 3.1.1: sequence, atom -----------------------------------<sum>------------------------------------ Syntax: include machine2.e a = sum(s) Description: Return the sum of s. s must be a sequence. An error will occur if s is an atom. Example 1: a = sum({{1,2}, {3,4}, {5,6}}) -- a is 21 (i.e. 1+2+3+4+5+6) Example 2: a = sum("") -- a is 0 Example 3: a = sum("12") -- a is 99 (i.e. ASCII-49 + ASCII-50) See Also: flatten, EMPTY, unpack_bits Euphoria 3.1.1: sequence, length -------------------------------<time_sign>---------------------------------- Syntax: include machine2.e TIME_SIGN Description: TIME_SIGN (-1 or 1) has been defined as a global constant. Comments: On some machines, time() can return a negative number. TIME_SIGN is -1 if time() return a negative number, or 1 if time() return a positive number. Example: x = TIME_SIGN -- x is -1 or 1 (depends on your machine) See Also: delay Euphoria 3.1.1: time() ----------------------------------<true>------------------------------------ Syntax: include machine2.e TRUE Description: TRUE (1) has been defined as a global constant. Example: x = TRUE -- x is 1 See Also: FALSE, boolean ------------------------------<unpack_bits>--------------------------------- Syntax: include machine2.e s2 = unpack_bits(a, s1) Description: Convert integer a to sequence of numbers s2. s1 defines the size (in bits) for unpacking each number from a. s1 values must be in the range 0 to 32; You can also use negative values (0 to -32) to unpack signed numbers. The (absolute) sum of s1 must be in the range 0 to 32. Comments: a must be representable as 32-bit number, either signed or unsigned. If you intend to manipulate full 32-bit values, you should declare your variables as atom, rather than integer. Euphoria's integer type is limited to 31-bits. pack_bits()/unpack_bits() are useful for packing small numbers into integer. e.g. for packing date() sequence into integer. Example: ints = {-2000, 8, 18, -15} bits = { -12, 4, -8, -5} -- 12-bits/-2000 (signed), -- 4-bits/8 (unsigned), -- 8-bits/18 (signed), -- 5-bits/-15 (signed) i = pack_bits(ints, bits) -- i is 274793041 s = unpack_bits(i, bits) -- s is {-2000, 8, 18, -15} Examples: See pack_bits() for more examples. See Also: pack_bits, signed, unsigned, shr_bits, range_per_bits, bin, hex, sum Euphoria 3.1.1: and_bits, int_to_bits, bits_to_int -------------------------------<unsigned>----------------------------------- Syntax: include machine2.e x2 = unsigned(x1, i) Description: Return the low-order i bits of x1 as an unsigned number. i must be in the range 0 to 32. The fractional part of x1 is truncated. Negative numbers are returned in two's complement, so -1 will return as 4294967295. Comments: x1 may be an atom or a sequence. The rules for operations on sequences apply. x1 must be representable as 32-bit numbers, either signed or unsigned. Example 1: y = unsigned({0.5, -1, 9.99, -100.6, 0, -#FF}, 32) -- y is {0, 4294967295, 9, 4294967196, 0, 4294967041} Example 2: x = {#FFFFFFFF, #FFFF, #FF, #F} y = unsigned(x, 32) -- y is {4294967295, 65535, 255, 15} y = unsigned(x, 16) -- y is { 65535, 65535, 255, 15} y = unsigned(x, 8) -- y is { 255, 255, 255, 15} See Also: signed, unpack_bits, range_per_bits, fix, sign, peek2u Euphoria 3.1.1: int_to_bits, peek4u --------------------------------<wait_xkey>--------------------------------- Syntax: include machine2.e x = wait_xkey() Description: Return the next key pressed by the user. Don't return until a key is pressed. Comments: Because either a string-sequence or an atom might be returned, you should probably assign the result to a variable declared as object. You could achieve the same result using get_xkey() as follows: object k while 1 do k = get_xkey() if not equal(k, -1) then exit end if end while However, on multi-tasking systems like Windows or Linux/FreeBSD, this "busy waiting" would tend to slow the system down. wait_xkey() lets the operating system do other useful work while your program is waiting for the user to press a key. wait_xkey() is useful for programs that run in Linux terminal or in any other environment that may return a sequence of atoms for a single key-hit (escape sequence, UTF-8 character, etc). See Also: get_xkey, clear_keyboard, pause, delay Euphoria 3.1.1: wait_key, get_key, getc, sleep ----------------------------------<zsign>----------------------------------- Syntax: include machine2.e x2 = zsign(x1) Description: Return a value indicating the sign of x1 (0 if x1 is positive, 1 if it is zero, or 0 if it is negative). Comments: This function may be applied to an atom or to all elements of a sequence. Example: y = zsign({0.5, -1.6, 9.99, -100, 0}) -- y is {0, 0, 0, 0, 1} See Also: sign, psign, nsign, abs, unsigned, signed