1. What is Euphoria?
Euphoria is a simple, flexible, and easy-to-learn programming language. It lets you quickly and easily develop programs for Windows, DOS, Linux and FreeBSD. Euphoria was developed and first released in 1993 by Robert Craig. Since then Rapid Deployment Software has been steadily improving it with the help of a growing number of enthusiastic users. Although Euphoria provides subscript checking, uninitialized variable checking and numerous other run-time checks, it is extremely fast. People use it to develop Windows GUI programs, high-speed DOS games, and Linux/FreeBSD X Windows programs. It is also very useful for CGI (Web-based) programming.See also Multitasking in Euphoria and Euphoria Database System (EDS). Once Euphoria is installed, don't forget to install (merge) Lib2 as well.
1.1 What's New? ( )
- Lib2 version 1.47 is ready.
- file2.e library is almost done, but not yet; I will replace the zip functions with compression functions written in Euphoria, slower then C, but Euphoria.
1.2 Tutorial - Hello World!
with trace trace(1) -- Tutorial - Print Hello World on the Screen -- To run this tutorial, -- Press Enter to execute the highlighted Euphoria statement. -- Press F1 to flip to the main output screen. -- Press F2 to flip back to this trace screen. -- Read the comments as you go. -- Step 1: Just to be neat - we'll clear the screen. -- First, press F1 then F2 (Works best on DOS or DOSBox). -- Then press Enter: clear_screen() -- Check again with F1/F2 - was the screen cleared? -- Step 2: Let's position the cursor at line 10, column 30 position(10, 30) -- Is the cursor now at 10,30? Press F1/F2 -- Step 3: Display the text: puts(1, "Hello World") -- Is the text there? Press F1/F2 -- Step 4 Output 2 blank lines and we're done puts(1, "\n\n")
1.3 Example Program
The following is an example of a complete Euphoria program (Try it online!).sequence list, sorted_list function merge_sort(sequence x) -- put x into ascending order using a recursive merge sort integer n, mid sequence merged, a, b n = length(x) if n = 0 or n = 1 then return x -- trivial case end if mid = floor(n/2) a = merge_sort(x[1..mid]) -- sort first half of x b = merge_sort(x[mid+1..n]) -- sort second half of x -- merge the two sorted halves into one merged = {} while length(a) > 0 and length(b) > 0 do if compare(a[1], b[1]) < 0 then merged = append(merged, a[1]) a = a[2..length(a)] else merged = append(merged, b[1]) b = b[2..length(b)] end if end while return merged & a & b -- merged data plus leftovers end function procedure print_sorted_list() -- generate sorted_list from list list = {9, 10, 3, 1, 4, 5, 8, 7, 6, 2} sorted_list = merge_sort(list) ? sorted_list end procedure print_sorted_list() -- this command starts the program
The above example contains 4 separate commands that are processed in order. The first declares two variables: list and sorted_list to be sequences (flexible arrays). The second defines a function merge_sort(). The third defines a procedure print_sorted_list(). The final command calls procedure print_sorted_list().
The output from the program will be:
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}.
merge_sort() will just as easily sort {1.5, -9, 1e6, 100} or {"oranges", "apples", "bananas"} .
This example is stored as euphoria\tutorial\example.ex. This is not the fastest way to sort in Euphoria. Go to the euphoria\demo directory and type "ex allsorts" to see timings on several different sorting algorithms for increasing numbers of objects. For a quick tutorial example of Euphoria programming see euphoria\demo\bench\filesort.ex.
2. Download Euphoria (32-bit)
- Setup file for (DOS and) Windows: site #1, site #2, site #3, site #4.
- Zip file for DOS and Windows: site #1, site #2, site #3, site #4.
- tgz file for Linux: site #1, site #2, site #3, site #4.
- tgz file for FreeBSD: site #1, site #2, site #3, site #4.
Euphoria Release Notes
Read Me
How to Install Euphoria on Windows
How to Install Euphoria on Linux or FreeBSD
How to run Euphoria on 64-bit Linux
How to run Euphoria on 64-bit (& 32-bit) FreeBSD
Euphoria Reference Manual Part I - Core Language
Note: all .doc files are actually simple ASCII .txt files.
3. Download Lib2 for Euphoria
Lib2 is an extended standard library for the Euphoria Programming Language version 3.1, with lots of useful functions.
Lib2 includes also the edu IDE with context sensitive help (control-K), syntax coloring and more.
ChecksumLib2 Release Notes
4. Utilities and Demo Programs
- Rapid Euphoria Website Offline in English and Russian/русский, site #2 - 686 MB - Includes also the archive/source code programs; Excludes "cgi-bin" directory - i.e. the euForum and other Euphoria 3 CGI programs.
- FreeDOS 1.2 & Euphoria 3 Bootable USB Image.
- FreeDOS 1.1 Bootable USB Image.
- DFS 1.00 - DOS File System Library with Long File Name (LFN) optional support and Critical Error Handler. site #2, site #3.
- QE 2.3.9 - Quick Euphoria Editor for DOS / DOSBox (multilingual & bidirectional). site #2, site #3.
- Tic Tac Toe 1.00 - Play against the PC. site #2.
- Type 2.00 - Learn how to type. site #2.
- CSV 1.00 - Create and use a CSV (Comma Separated Values) database. site #2.
- Microsoft's legendary NIBBLES.BAS translated to Euphoria 3, v1.01 - How QBASIC program is translated to Euphoria 3, and works well on DOS/Windows/Linux/FreeBSD. site #2.
5. Tips
- How to name variables properly?
I can only suggest that you name variables in a consistent and self-explanatory way, but not too lengthy, like this:- constants - using capital letters only, e.g.: CONFIG_1, PI, etc
- global variables - start by a capital letter and prefix, e.g.: Cfg_colors, Cfg_defaults, Ed_colors, Ed_defaults, etc
- local variables - use only small letters, e.g.: mem_address, etc
- private variables - use only small letters and short names, e.g.: mem, s, etc
Moreover, for private scope to be clear, limit your subroutines to a reasonable size - a short subroutine is much easier to understand and maintain.
Avoid using long variable names - you're not writing a novel. - How to do integer division in Euphoria 3?
Use the builtin floor() function for fast integer division, for example (Try it online!):
-- use floor() to do integer division where needed (it's faster): constant CYCLES = 1000000 integer r constant T = time() for i = 1 to CYCLES do r = 4 + floor(100 / 7) * 2 -- r = 4 + 100 / 7 * 2 -- non-integer (atom) division is slower end for ? time() - T -- print time measurement
- How to use the 'global' scope in a controlled manner?
Declare your global variables and include files in your startup file, for example:
-- how to declare your *global* variables, constants, or anything else -- in your main startup file - it's all depends on the order, For example: -- 1) Euphoria/Lib2 include files are declared first, so they don't -- have any access to your global variables or include files include graphics.e include misc.e -- 2) this global block is visible by all include files below, -- i.e. config.e and editor.e global sequence app_config include config.e -- 3) this global block is visible only by editor.e file (module) global constant EDITOR_COLORS = {WHITE, BLACK, CYAN, BLACK, BRIGHT_WHITE} global integer editor_mode, exit_editor include editor.e -- *) run main program loop. ('exit_editor' is only visible to editor.e). while exit_editor = 0 do editor() end while -- declaring your include files *only* in your startup file, together with -- your global variables can be a good programming technique.
- Using a single-dimension sequence vs. multi-dimension sequence:
Unless you really need a multi-dimension sequence, a single-dimension sequence is always faster and much easier to use (but less "cool" I know). This is also true for an array in other programming languages. For example:-- a multi-dimension sequence is slower and harder to use, for example: sequence key_value constant KEY_INDEX = 1, VAL_INDEX = 2 key_value = { {"Shian", "Eric", "Joe"}, {{3, 4}, {93, 1}, {'x', 40}} } ? key_value[KEY_INDEX][3] ? key_value[VAL_INDEX][3][2] -- a single-dimension sequence is *faster* and *easier* to use, for example: sequence key, value key = {"Shian", "Eric", "Joe"} value = {{3, 4}, {93, 1}, {'x', 40}} ? key[3] ? value[3][2] -- note: inside a loop you may want to use a variable for even faster access: sequence s s = key[3] for i = 1 to 100 do puts(1, s) -- direct access to variable without an index-overhead end for
Yet, a multi-dimension sequence is still more practical for many cases, for example: the dir() function returns a multi-dimension sequence rightfully, and high-speed is not important in this case. - Using compact code vs. regular code:
-- 'compact' code in Euphoria 3 is very short and may run much -- faster then 'regular' code, but *not* always. -- -- From the following test of the lower() function (convert atom -- or sequence to lower case), we learn that: -- 1. "regular" code is the slowest (but simple). -- 2. "compact" code is very short, stable, and very fast *only* -- if *all* elements of object x must be manipulated. -- 3. "fast" code (optimized regular code) is very long but fast. -- 4. "string" code is the fastest, but limited to string-sequence -- only (the other routines can manipulate *any* object). -- -- This test is just an example for specific problem. Each case may -- behave differently. The file math.e in Lib2, for example, is -- using a lot of "compact" code, which makes the code much *shorter* -- and probably *faster* in many cases. constant TO_LOWER = 'a' - 'A' -- 'regular' code, simple, longer, and slower: function regular_lower(object x) if atom(x) then if x >= 'A' and x <= 'Z' then return x + TO_LOWER end if else -- sequence(x) for i = 1 to length(x) do x[i] = regular_lower(x[i]) -- recursive call end for end if return x end function -- 'compact' code, very short, stable, and may be very fast: function compact_lower(object x) return x + (x >= 'A' and x <= 'Z') * TO_LOWER end function -- 'fast' code, highly optimized regular code, very long, but faster: function fast_lower(object x) sequence s -- accessing sequence s is a bit faster then accessing object x if atom(x) then if x <= 'Z' then if x >= 'A' then return x + TO_LOWER end if end if return x end if -- sequence(x) s = x for i = 1 to length(s) do if atom(s[i]) then if s[i] <= 'Z' then if s[i] >= 'A' then s[i] += TO_LOWER end if end if else -- sequence(s[i]) s[i] = fast_lower(s[i]) -- recursive call end if end for return s end function -- 'string' code is very fast, but useful *only* for a string-sequence: function string_lower(sequence s) for i = 1 to length(s) do if s[i] <= 'Z' then if s[i] >= 'A' then s[i] += TO_LOWER end if end if end for return s end function -- now, let's test the speed of each routine, using 3 strings: constant CYCLES = 500000 sequence r, s, names, strings atom t, t2 integer id -- routine names: names = {"regular_lower", "compact_lower", "fast_lower", "string_lower"} -- test strings: strings = {"RAPIDEUPHORIA", "RaPidEuphOriA", "rapideuphoria"} for test = 1 to length(strings) do -- test different strings s = strings[test] puts(1, s & "\n\n") for routine = 1 to length(names) do -- test different routines id = routine_id(names[routine]) t = time() for i = 1 to CYCLES do r = call_func(id, {s}) end for t2 = time() - t printf(1, "%15s: %5.2f\n", {names[routine], t2}) -- print result in sec end for puts(1, "\n\n") end for
5.1 DOS and Qemu
- How to create a bootable FreeDOS USB stick & Euphoria 3?
I've created a raw image (2GB size) of FreeDOS 1.2.
The image also includes Euphoria 3.1.1, Lib2 1.41, RBIL documentation, helppc, QE 2.3.9 IDE, EDU IDE (as part of Lib2), and basic utilities.
When you start FreeDOS it will run a menu written in Euphoria 3 (you can see the source code in C:\UTIL\MENU.EX).
Just download the compressed image, site #2 (checksum), decompress it using 7-zip, burn it to a USB stick of 4GB or more, and restart your computer from the USB stick. (Legacy BIOS must be enabled in your BIOS, and you should be able to start your computer from USB-HDD).
In Linux you can burn the image using the attached documentation, or another Linux utility. On Windows you can (probably) use Rufus to burn the image to a USB stick.
-----------------------------------------------
How did I make this image on Linux?
-----------------------------------------------
Using qemu-system-x86_64 --version QEMU emulator version 2.0.0 (Debian 2.0.0+dfsg-2ubuntu1.46), Copyright (c) 2003-2008 Fabrice Bellard.- Download "FD12CD.iso" from http://www.freedos.org/.
- Create an empty local Disk as file, using 'dd':
dd if=/dev/zero of=fdos12.img bs=1M count=2047
- Install "FD12CD.iso" to Disk, using 'qemu':
qemu-system-x86_64 -cdrom FD12CD.iso fdos12.img -boot d
Notes:- In FDISK I did NOT enable large drive support on start.
- I created a single 2GB drive C: (2GB is maximum for standard DOS drive), made it bootable, then restart qemu with ctrl-alt-del... then continue with format and minimal installation.
- Copy from another FreeDOS USB stick the Euphoria directory & other utilities and documents, using 'qemu' (/dev/sdb1 is my USB device):
sudo qemu-system-x86_64 -hdb /dev/sdb fdos12.img
- Test again if the image is bootable, using 'qemu':
qemu-system-x86_64 fdos12.img -boot c
- Burn the bootable image to a USB stick, using 'dd':
sudo dd if=fdos12.img of=/dev/sdb bs=1M
- Test the new USB stick, using 'qemu':
First find the USB id, using 'lsusb':
lsusb
= ( Bus 002 Device 005: ID 0781:5567 SanDisk Corp. Cruzer Blade )
Now test it using ID 0781:5567:
sudo qemu-system-x86_64 -usb -usbdevice host:0781:5567 -m 1024 -vga std
(Using the above qemu command FreeDOS runs OK from the USB stick!) - OK. Ready. Now you can reboot your PC from the USB stick (legacy BIOS must be enabled in the BIOS)... and you can start using FreeDOS and Euphoria!
- Example batch files for running DOS in Qemu:
I'm using this batch file to run "fdos12.img" on Linux:#!/bin/bash # # File name: dos.sh # # I'm Using qemu-system-x86_64 --version: # QEMU emulator version 4.2.0 (On Linux Debian 1:4.2-3ubuntu6.4) # ============================================================== # # When you start qemu: # -------------------- # Press control-alt-f to toggle full screen mode # Press control-alt-g to (toggle) grab the keyboard & mouse into DOS # Press control-alt-0 or control-alt-minus or control-alt-plus to zoom best-fit/out/in # # To share files with a FAT-16 or FAT-32 (DOS) formatted USB stick, append # also the following command (change "/dev/sdb" if needed to your USB stick path): # -------------------------------------------------------------------------------- # # -drive file="/dev/sdb",format=raw,if=ide,media=disk # # Note that you should run qemu as root to access the USB drive, i.e.: # sudo qemu-system-x86_64 ... if using USB stick, then make sure the USB stick # is not mounted in Linux, and do NOT remove it until you exit Qemu. qemu-system-x86_64 `# qemu version 4.2.0` \ -drive file="fdos12.img",format=raw,if=ide,media=disk `# is a disk to add to DOS` \ -boot order=c `# tells qemu which disk to boot from (in order)` \ -m 1024 `# memory to use (1024=1GB; Euphoria runs in protected mode so it's useful)` \ -k en-us `# keyboard (English-US is the standard keyboard)` \ -rtc base=localtime `# the clock` \ -soundhw sb16,adlib,pcspk `# sound hardware to emulate (sb16,adlib,pcspk are common for DOS programs)` \ -vga std `# type of screen (standard VGA)` \ -no-quit `# disable the [x] on title bar` \ -name "FreeDOS 1.2" `# text for qemu's title bar`
I'm using this batch file to run "fdos12.img" on Windows-10:@ECHO OFF REM File name: DOS.BAT REM REM I'm Using qemu-system-x86_64 --version REM QEMU emulator version 5.1.0 (v5.1.0-11824-g8699890d91-dirty) REM On Windows-10 64-bit REM ============================================================== REM REM When you start qemu: REM -------------------- REM Press control-alt-f to toggle full screen mode REM Press control-alt-g to (toggle) grab the keyboard & mouse into DOS REM Press control-alt-0 or control-alt-minus or control-alt-plus to zoom best-fit/out/in REM REM To share files with a FAT-16 or FAT-32 (DOS) formatted USB stick, append REM also the following command (change "/dev/sdb" if needed to your USB stick path): REM -------------------------------------------------------------------------------- REM REM -drive file="/dev/sdb",format=raw,if=ide,media=disk REM REM Note: if using USB stick, then do NOT remove it until you exit Qemu. REM REM You can also specify old PC speaker <name>: -machine pcspk-audiodev=<name> REM REM Remember to set path for Qemu (Once per session): REM "SET PATH=C:\Program Files\qemu;%PATH%" REM - or set the path permanently in Windows-10's settings (environment variables). REM qemu-system-x86_64 -drive file="fdos12.img",format=raw,if=ide,media=disk -boot order=c -m 1024 -k en-us -rtc base=localtime -device adlib -device sb16 -vga std -no-quit -name "FreeDOS 1.2" REM Short description: REM -drive a disk to add to DOS. REM -boot tells qemu which disk to boot from (in order). REM -m memory to use (1024=1GB since Euphoria 3 runs in protected mode it's useful). REM -k keyboard (English-US is the standard keyboard) REM -rtc the clock REM -device adlib -device sb16 sound hardware to emulate (sb16,adlib,pcspk are common for DOS programs). REM -vga type of screen (standard VGA) REM -no-quit disable the [x] on qemu's title bar REM -name title bar text of qemu
Some Qemu links:
- Qemu official website.
- Installing FreeDOS 1.2 on QEMU - YouTube - Dec 29, 2016, by Jim Hall, the project coordinator of FreeDOS.
- How to run DOS programs in Linux - 19 Oct 2017, by Jim Hall.
- How to Run FreeDOS 1.3RC within Windows 10 Using Qemu - April 13, 2020, by Trisha.
- QEMU config for running DOS compilers - Jun 28, 2020, For advanced users by FlaterCo.
- QEMU/FreeDOS - 25 September 2018, "QEMU is quick; it's a hypervisor that allows you to run virtual machines with complete operating systems that operate like any other program on your desktop. This can be useful for general purpose computing and black box testing."; From Wikibooks - This book applies to version 2.5 and newer of QEMU.
6. Links
- Rapid Deployment Software - The original Euphoria website (read-only).
- www.rapideuphoria311.com - (this site).
- www.rapideuphoria311.org - (this site).
- The x86 Interrupt List - aka "Ralf Brown's Interrupt List", "RBIL" (DOS API).
- Win32 API - Data Access and Storage: fileapi.h header (Windows API).
- The GNU C Library - libc, aka glibc (Linux / FreeBSD API).
- FreeDOS - a complete, free, DOS-compatible operating system.
- DOSBox - a DOS-emulator that's very easy to port to different platforms.
- Advanced MS-DOS Programming.
- WinWorld - from the past, to the present, for the future.
- VETUSWARE.COM - the biggest free abandonware downloads collection in the universe.
- HelpPC Reference Library - a DOS-based hypertext program by David Jurgens.
- GCC, the GNU Compiler Collection - The GNU Compiler Collection includes front ends for C, C++, Objective-C, Fortran, Ada, Go, and D, as well as libraries for these languages (libstdc++,...). The default compiler for Linux and FreeBSD.
- MinGW - a contraction of "Minimalist GNU for Windows", is a minimalist development environment for native Microsoft Windows applications. How to install gcc in Windows 10? (the easier way).
- DJGPP - a complete 32-bit C/C++ development system for Intel 80386 (and higher) PCs running DOS. i.e. gcc for DOS.
- Writing FreeDOS Programs in C - Let’s learn coding in C by Jim Hall.
- Geany - a powerful, stable and lightweight programmer's text editor. Runs on Linux, Windows and MacOS.
- Linux Mint - a modern, elegant and comfortable operating system which is both powerful and easy to use.
- 7-Zip - a file archiver with a high compression ratio.
- QEMU - a generic and open source machine emulator and virtualizer.
- Try It Online - TIO is a family of online interpreters for an evergrowing list of practical and recreational programming languages.
7. About
- Name: Shian.
- Contact: s h i a n @ r a p i d e u p h o r i a 3 1 1 . c o m