Development Tools¶
Unicon tools¶
The main Unicon command set is made up of:
- unicon
- icont
- iconx
- iconc
Todo
complete the list of core tools
After a source build with Unicon 13, the bin/ directory includes:
prompt$ ls -gGF --time-style=+
total 7156
-rw-rw-r-- 1 5560 dlrgint.o
-rwxrwxr-x 1 349080 iconc*
-rwxrwxr-x 1 171032 icont*
-rwxrwxr-x 1 1205944 iconx*
-rwxrwxr-x 1 48671 ie*
-rwxrwxr-x 1 123864 iyacc*
-rwxrwxr-x 1 28296 libcfunc.so*
-rw-rw-r-- 1 77318 libgdbm.a
-rw-rw-r-- 1 70304 libtp.a
-rw-rw-r-- 1 144424 libucommon.a
-rw-rw-r-- 1 3720 libuconsole.a
-rw-rw-r-- 1 128000 libXpm.a
-rwxrwxr-x 1 10688 patchstr*
-rw-rw-r-- 1 3599918 rt.a
-rw-rw-r-- 1 159975 rt.db
-rw-rw-r-- 1 322929 rt.h
-rwxrwxr-x 1 246776 rtt*
-rwxrwxr-x 1 263687 udb*
-rwxrwxr-x 1 39298 umake*
-rwxrwxr-x 1 207995 unicon*
-rwxrwxr-x 1 79962 uprof*
The unicon command¶
unicon is the main command line tool for programming with Unicon.
Options include:
prompt$ unicon --help
Usage: unicon [-cBCstuEGyZMhK] [-Dsym=val] [-f[adelns]...] [-o ofile]
[-nofs] [-help] [-version] [-features] [-v i] file... [-x args]
options may be one of:
-B : bundle VM (iconx) into executable
-c : compile only, do not link
-C : generate (optimized) C code executable
-Dsym[=val] : define preprocessor symbol
-e efile : redirect icont's standard error output to efile
-E : preprocess only, do not compile
-features : report Unicon features supported in this build
-fs : prevent removal of unreferenced declarations
-G : generate graphics (wiconx) executable
-M : report error message to the authorities
-o ofile : generate executable named ofile
-O : optimize (under construction)
-s : work silently
-t : turn on tracing
-u : warn of undeclared variables
-v i : set diagnostic verbosity level to i
-version : report Unicon version
-x args : execute immediately
-y : parse (syntax check) only, do not compile
-Z : compress icode
-K : keep tmpfiles
-h : display this information
unicon is a wrapper around other tools, mainly the icont command. Many of the command lines options are similar, but unicon does a better job of explaining the options in the brief help.
Compiled unicon¶
C
compiled Unicon, to be more specific, seeing as Unicon already compiles.
unicon -C translates Unicon to C intermediates and then compiles the C code (usually via native assembler source) to native executable for the system in use. Some Unicon features are not available when using unicon -C, such as native concurrency at this point in time.
Quiet unicon¶
Yeah, this is was a little tricky.
Update: as of revision [r4497] this entire sequence has been simplified. Just use unicon -s.
Left in for anyone running pre [r4497] Unicon.
prompt$ unicon version.icn
Parsing version.icn: .
/home/btiffin/unicon-git/bin/icont -c -O version.icn /tmp/uni27186168
Translating:
version.icn:
main
No errors
/home/btiffin/unicon-git/bin/icont version.u
Linking:
Let’s try -quiet
(it’s undocumented in -help
)
prompt$ unicon -quiet version.icn
Translating:
version.icn:
main
No errors
Linking:
Umm, not quite, how about -s
, work silently.
prompt$ unicon -quiet -s version.icn
So close. Now to set verbosity to 0.
prompt$ unicon -quiet -s -v0 version.icn
Ahh, that’d be the ticket. Quiet, silent, not verbose.
-quiet -s -v0
prompt$ unicon -quiet -s -v0 version.icn -x
Unicon Version 13.1. August 19, 2019
Update as above: Just use unicon -s.
The flip side is pretty easy; maximum verbosity.
prompt$ unicon -v3 version.icn -x
Parsing version.icn: .
/home/btiffin/unicon-git/bin/icont -c -v3 -O version.icn /tmp/uni27186168
Translating:
version.icn:
main
No errors
/home/btiffin/unicon-git/bin/icont -v3 version.u -x
Linking:
bootstrap 344
header 216
procedures 152
records 8
fields 0
globals 64
statics 0
linenums 80
strings 23
total 887
Executing:
Unicon Version 13.1. August 19, 2019
The icont command¶
icont is the translator portion of the Unicon tool chain.
Options include:
prompt$ icont
usage: icont [-cBstuEG] [-f s] [-l logfile] [-o ofile] [-v i] file ... [-x args]
icont is a relatively sophisticated compiler, most error messages are quite comprehensive, detailing what it wrong with the source code.
#
# Compile time error message example
#
procedure main()
a ::= "1" + []
end
prompt$ icont compiletime-error.icn
Translating:
compiletime-error.icn:
compiletime-error.icn:12: # "a": syntax error (91;366)
File compiletime-error.icn; Line 14 # traverse: undefined node type
::=
is not valid assignment syntax.
Like most high level compilers, sometimes the error messages are, less helpful:
Todo
ADD SAMPLE
And sometimes, you need to wait until execution time, and triggering an error at run-time.
#
# Runtime error message example
#
procedure main()
a := "1" + []
end
Sample run, with error:
prompt$ unicon runtime-error.icn -x
Parsing runtime-error.icn: .
/home/btiffin/unicon-git/bin/icont -c -O runtime-error.icn /tmp/uni39095537
Translating:
runtime-error.icn:
main
No errors
/home/btiffin/unicon-git/bin/icont runtime-error.u -x
Linking:
Executing:
Run-time error 102
File runtime-error.icn; Line 12
numeric expected
offending value: list_1 = []
Traceback:
main()
{1 + list_1 = []} from line 12 in runtime-error.icn
Integer can’t be added to a List (arrays) datatype, in this case, an integer coerced from a string.
See Testing Unicon for some details on testing Unicon
programs.
The iconx command¶
iconx is the Executor portion of the Unicon tool chain.
iconx takes the filename to execute.
The Icon Virtual machine, and iconx, report any runtime errors, in a relatively comprehensive manner.
#
# Runtime error message example
#
procedure main()
a := "1" + []
end
prompt$ unicon -c runtime-error.icn
Parsing runtime-error.icn: .
/home/btiffin/unicon-git/bin/icont -c -O runtime-error.icn /tmp/uni27186168
Translating:
runtime-error.icn:
main
No errors
iconx processes icode files, which are binary executable forms created during the link phase from ucode files.
prompt$ iconx runtime-error
Run-time error 102
File runtime-error.icn; Line 12
numeric expected
offending value: list_1 = []
Traceback:
main()
{1 + list_1 = []} from line 12 in runtime-error.icn
A segue into .u files, ucode, and the Icon Virtual Machine.
.u files are Icon cross platform machine instructions, as human readable source (this feature helped with the design and debugging of the virtual machine).
For example, the above buggy runtime-error.icn was translated to runtime-error.u, and is a human readable form of the Icon Virtual Machine language.
version U12.1.00
uid runtime-error.u1-1480545330-0
impl local
global 1
0,000005,main,0
proc main
local 0,000000,a
con 0,010000,1,061
declend
filen runtime-error.icn
line 11
colm 11
synt any
mark L1
pnull
var 0
pnull
str 0
pnull
line 12
colm 16
synt any
llist 0
line 12
colm 14
synt any
plus
line 12
colm 7
synt any
asgn
unmark
lab L1
pnull
line 13
colm 1
synt any
pfail
end
If you look at the first few lines of a unicon compiled program, it is actually a script that starts iconx with the ucode embedded in it.
prompt$ unicon runtime-error.icn
Parsing runtime-error.icn: .
/home/btiffin/unicon-git/bin/icont -c -O runtime-error.icn /tmp/uni13207192
Translating:
runtime-error.icn:
main
No errors
/home/btiffin/unicon-git/bin/icont runtime-error.u
Linking:
prompt$ cat -v runtime-error | par
#!/bin/sh IXBIN=/home/btiffin/unicon-git/bin/iconx IXLCL=`echo $0 | sed
's=[^/]*$=iconx='`
[ -n "$ICONX" ] && exec "$ICONX" [ -x "$IXLCL" ] && exec "$0" ${1+"$@"}
"$IXLCL" [ -x "$IXBIN" ] && exec "$IXBIN" exec iconx "$0" ${1+"$@"}
[executable Icon binary follows]
^L
^@[^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@M-8^@^@^@^@^@^@^@M-@^@^@^@^@^@^@^@M-@^@
^^@^@^@^@^@^@M-@^@^@^@^@^@^@^@M-P^@^@^@^@^@^@^@M-`^@^@^@^@^@^@^@@^A^@^@^
^@^@^@^@M-`^@^@^@^@^@^@^@M-p^@^@^@^@^@^@^@I12.U.30/32/64^@^@@CM-g^@^@^@^
^@^@^@^@^@^@^@^@^@^@^PM-^FM-f^@^@^@^@^@M-^@0M-g^@^@^@^@^@M-^@M-^@M-f^@^@
^^@^@^@@M-^@M-f^@^@^@^@^@<M-U>M-}#^?^@^@^PM-^FM-f^@^@^@^@^@^@^@^@^@^@^@^
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@@CM-g^@^@^@^@^@@CM-g^@^@^@^@^@^@^@^@
^^@^@^@^@^@^F^@^@^@^@^@^@^@X^@^@^@^@^@^@^@X^@^@^@^@^@^@^@^@^@^@^@^@^@^@^
^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^D^@^@^@^@^@^@^@^@^@^@
^^@^@^@^@^@^A^@^@^@^@^@^@^@^E^@^@^@^@^@^@^@b^@^@^@C^@^@^@D^@^@^@^@^@^@^@
^E^@^@^@S^@^@^@^@^@^@^@^@^@^@^@E^@^@^@M^@^@^@^A^@^@^@^@^@^@^@^G^@^@^@^@^
^@^@^@E^@^@^@A^@^@^@^@^@^@^@^@^@^@^@^^^@^@^@^A^@^@^@N^@^@^@E^@^@^@D^@^@^
^@^@^@^@^@^@^@^@^@^@^@^@^@^F^@^@^@^@^@^@M-0^@^@^@^@^@^@^@^@^D^@^@^@^@^@^
^@^@^@^@^@^@^@^@^@^@X^@^@^@^@^@^@^@
^^@^@^@^@^@^@^@X^@^@^@^@^@^@^@^K^@`^A^@^@^@^@M-^T^@^@^@^@^@^@^@^L^@^@^B^
^@^@^@^@M-
^^@^@^@^@^@^@^@^L^@M-@^A^@^@^@^@M-$^@^@^@^@^@^@^@^L^@M-`^@^@^@^@^@M-0^@^
^@^@^@^@^@^@^M^@ ^@^@^@^@^@main^@a^@1^@runtime-error.icn^@
Coding conventions and style¶
Unicon has a long history, and Ralph Griswold tried to keep a consistent look and feel to both the compiler internal C/rtt sources and the high level Icon programs submitted to the IPL. That effort was not 100% successful, and the many hands that have touched on the C code each brought a slightly different style preference. One of the most startling format issue may be the mixing of tab characters and spaces for code indentation. The convention guide (https://www.cs.arizona.edu/icon/docs/ipd072.htm) requests spaces, but there are tabs in the sources and over time, various text editors have made the code look a little sloppy in terms of nested indentations. Keep to the request, and use spaces, as it avoids this long term churn issue with source code and text editor treatment of tabs.
IPL entries seem to have fared better over the years in terms of consistent look. That is likely due to the more public nature and numbers of interested readers, when compared to the internal source files.
In summary:
- Indentation: Three spaces per level, with no tabs for indentation.
- Line length: Not to exceed 80 characters with tabs expanded.
- Inter-line spacing: At most one empty line as needed for visual clarity. Formfeed (^L) between function declarations (except where there are many short, similar functions). Generally one empty line prior to boxed comments.
- Function declarations: storage/type class on line with function name. No indentation on argument declarations. Function body, including braces and local declarations indented three spaces. Braces enclosing functions on lines by themselves.
- Braces: Beginning brace at end of line for construction involved (except for function declarations as noted above). Ending brace on separate line indented three spaces beyond position of opening construction.
if
statements: statement below conditional expression, indented three spaces. Ifelse
is present, on separate line aligned with correspondingif
.- Binary operators: one space on either side.
- Argument lists: one space after each comma.
- Return statements: no parentheses around argument of
return
. - Casts: no space between right parenthesis surrounding cast and the expression to which it applies.
typedef
s: generally all lowercase (a deliberate departure from usual C conventions; typedefs in the Icon source code are viewed as an extension of the C language).- Comments: Boxed-style per numerous examples. Second and subsequent lines indented one character. “On-line” comments tabbed out as is most readable. No “cute” or illiterate comments. No personal identifications (they cease to be useful with time and produce cumulative clutter).
- Conditional compilation: One empty line before and after
#ifdef/endif
groups. Identifying C-style comment five tabs out on#else
and#endif
directives. (I think by 5 tabs out, Ralph meant column 40). - Manifest (defined) constants and macros: For the most part, names should be in mixed upper- and lowercase (a deliberate departure from usual C conventions). Specifically, an uppercase letter identifies a name that has been defined as opposed to a C variable. Mixed case is used for readability.
This convention guide carries over to Unicon sources and IPL entries,
where appropriate. In particular, IPL entries all start with a consistent
comment block, formatted to allow the indexing tool to properly do its job.
See the ipl-skeleton.icn
listed below for this formatting standard.
Note
The examples in this docset all break rule one. I prefer 4 space indents. The bracing rule is also broken, preferring to not indent the closing brace, but to keep it at the same indentation as the starting construct.
Apologies, but that is the way it is.
With that said, reasonable effort is expended to maintain an internal consistency.
The convention guide calls for code formatting ala:
while line := read(f) do {
result := stuff(line)
morestuff(result)
}
continuing()
This document uses a style of the form:
while line := read(f) do {
result := stuff(line)
morestuff(result)
}
continuing()
Blame age and long ingrained personal preference for the breach of project preferred convention.
It behooves any Unicon programmer to get used to many forms and coding styles, as for the most part, due to many hands in the pot, you may encounter different formatting in any one particular source file. A key issue is to strive for consistency and to attempt some level of source formatting discipline.
Supporting tools¶
Unicon works very well with most of the common software development tools available for various operating systems. This docset focuses on GNU/Linux, but other systems also offer a wide range of useful development aids.
Unicon also ships with a fair number of support tools, custom built for Unicon development.
"'What was the original problem you were trying to fix?' 'Well, I noticed one
of the tools I was using had an inefficiency that was wasting my time'"
XKCD http://xkcd.com/1739/ by Randall Munroe CC BY-NC 2.5
make¶
make is not a Unicon specific program, but works very well with Unicon development. make is also used when building Unicon from source.
See https://www.gnu.org/software/make/manual/make.html for details of the ubiquitous GNU implementation of make.
make normally uses a non visible Tab character (ASCII 9) to prefix
action lines. GNU make includes an extension to specify a different prefix
character. The example below, and other examples throughout this
documentation use a more visible >
action statement prefix. This is not
supported in all versions of make, but it makes copy and paste from
web pages a little safer, as it removes any chance of a Tab character being
mistaken for spaces.
Some sample recipes:
# Unicon programming starter Makefile sample
.RECIPEPREFIX = >
# quick help, first target is default target, "make" or "make help"
.PHONY: help
help:
> @echo "Unicon example Makefile"
> @echo
> @echo "make help\t\tfor this help"
> @echo "make program\t\tto build program.icn"
> @echo "make run\t\tto run executable from program.icn"
> @echo
> @echo "make name\t\tto build and run any given named .icn file"
> @echo "make -B name\t\twill force the run, even if already up to date"
> @echo "make name.u\t\tto build a link file for any given named .icn file"
# make Unicon program, $< is the first prereq
program: program.icn
> unicon $<
run: program
> ./$<
# generic rules
# build and run any given .icn file by typing "make name"
%: %.icn
> unicon -s $^ -x
# create a linkable Unicon file by typing "make name.u"
%.u: %.icn
> unicon -c $^
make program will compile program.icn if the source is more recent
than the target executable, make run will run the program (and ensure it
is up to date before execution, if sources have changed). $< is an
automatic make variable, set to match the first prerequisite. For the
program:
target, the first (and only) prerequisite is program.icn. For
the sample run:
target, the prerequisite is program
, and $< is
substituted in to execute ./program.
make is a fairly powerful tool. There are quite a few features that may not be apparent at first glance. See the GNU make manual referenced above for more details.
A special note on the trick %: %.icn
and %.u: %.icn
targets. Those are
make patterns that match any named Unicon source file,
name.icn, and compiles and/or runs the program. It is a convenience
feature for non-project related make. It allows any Unicon file to be compiled
and run by simply typing make name. If the source has already been
compiled (date of executable is later than the date time of last edit), just
use ./name, or use make -B name to force a new compile
and run. To compile a source file for use with link, the same trick
allows make name.u, to match the name.icn file, and then
run unicon -c on the given name.
Again, those are convenience features, normally a Makefile is specific to a project and the targets will include specific instructions for clean up, packaging, installation, etcetera, and will list all prerequisite source files, not singletons as used with the trick filename matching rules.
ui¶
The Unicon IDE. ui ships with Unicon, under the uni/ide subdirectory, and is built along with unicon and the other command line tools, ready to use with any Unicon installation that supports the 2D graphics facilities. A graphical front end for Unicon development, detailed in Technical Report UTR12a, http://unicon.org/utr/utr12.html
The Ui source code provides lots of examples for extending and customizing a graphical user interface generated using IVIB, the interface building tool.
Ui supports project management, file management, a contextual help based source code editor, a class browser, along with Compile, Run and Debug layers.
I’ll be honest, I develop on the command line, with Vim and associated tools. If you prefer Integrated Development Environments, be sure to fire up ui.
Might have to pester Clinton about opening up the font selection list; the four X11 fonts that ship with Unicon are not as beautiful as some that are now available for GNU/Linux.
UDB¶
The Unicon debugger. A very comprehensive Unicon support tool.
Modelled on GNU gdb
, udb allows breakpoints, Unicon source
view, structure display, and many other high and low level debugging features
using a command prompt interface.
UDB, by Ziad Al-Sharif, is documented in Unicon Technical Report 10.
http://unicon.org/utr/utr10.html
See Debugging for more details.
IVIB¶
A visual, graphical user interface building tool. Drag and drop user interface elements to generate Unicon code.
The Icon Virtual Machine¶
ucode¶
ucode is source form virtual machine instructions, transportable between all
platforms. The translator generates ucode as an intermediate form ready for
the link stage. ucode
was named before Unicon, as part of the Icon
project.
Starting small, smaller than Hello in this case.
#
# onestatement.icn, a single statement
#
# tectonics:
# unicon -c onestatement.icn
#
procedure onestatement()
u := 1
end
Producing ucode from this source gives a close to minimum set of VM instructions required for the Unicon VM.
Processed via unicon -c
prompt$ unicon -c onestatement.icn ; sed -i 's/\x0C//' onestatement.u
Parsing onestatement.icn: .
/home/btiffin/unicon-git/bin/icont -c -O onestatement.icn /tmp/uni12016255
Translating:
onestatement.icn:
onestatement
No errors
Generates a link ready ucode file, onestatement.u. [1]
version U12.1.00
uid onestatement.u1-1571987737-0
impl local
global 1
0,000005,onestatement,0
proc onestatement
local 0,000000,u
con 0,002000,1,1
declend
filen onestatement.icn
line 14
colm 11
synt any
mark L1
pnull
var 0
int 0
line 15
colm 7
synt any
asgn
unmark
lab L1
pnull
line 16
colm 2
synt any
pfail
end
This assigns the value 1
to the local variable, u
.
The ucode file also includes some identification, some procedure
paperwork, the statement trace info, and the statement bounding markers, along
with the actual low level instructions to assign a 1
to u
.
The Unicon virtual machine is stack based. An operational stack is used very much like a Forth data stack. Pushing and popping values (which can be encoded or literal) while performing virtual machine level operations that functionally match the high level Unicon source instructions.
The action opcodes here being
pnull
var 0
int 0
asgn
Push a null descriptor (a place holder for the expression result). Push the id
of variable 0 from the declarations (the u
). Push an integer with id 0
from the constant declarations (a 1
in this case). Then assign; asgn
pops the value and destination while performing the assignment operation and
replaces the initial null descriptor with the result (which in more complex
programs would be chained to other parts of an expression).
ucode is the human friendly version of icode, the actual byte-code used by the virtual machine. During initial development of Icon, starting back in 1978ish, it was deemed important to have a human readable version of the VM instruction sequencing. This helped (and still helps) verify and debug the Icon source code translator. A nice touch, not really necessary for the virtual machine itself, but of great importance to the people implementing the engine and the translator. And a bonus to developers that can peruse the machine instructions.
As is, this ucode requires one more step before being executable code. The rt runtime translator at the heart of the Unicon VM always starts with main. It gives the engine a starting point, a place to call home that ensures everything is properly initialized. The translation from ucode to icode happens during the linking phase of the Unicon tool chain. All link references are included, and ucode files merged and resolved down to icode.
Many Unicon programs are singletons, no link statements to worry about, but every final step icode generation requires a main. In this case, the single statement procedure is compiled separately and included in the file listed below via the link reserved word.
#
# mainstatement.icn, link to a single statement procedure
#
# tectonics:
# unicon -c onestatement.icn
# unicon mainstatement.icn
#
link onestatement
procedure main()
mainstatement()
end
That piece of code will link to onestatement.u and produce an
executable VM image, mainstatement. mainstatement sits ready
to be invoked by the operating system to run the program. A program that
invokes main (implicitly), which invokes onestatement, which sets
u
to 1
, then runs down, giving control back to the operating system.
For now, we are more interested in looking at the ucode, so unicon -c comes into play again.
prompt$ unicon -c mainstatement.icn ; sed -i 's/\x0C//' mainstatement.u
Parsing mainstatement.icn: ..
/home/btiffin/unicon-git/bin/icont -c -O mainstatement.icn /tmp/uni12016255
Translating:
mainstatement.icn:
main
No errors
version U12.1.00
uid mainstatement.u1-1571987737-0
impl local
link onestatement.u
global 1
0,000005,main,0
proc main
local 0,000000,mainstatement
declend
filen mainstatement.icn
line 16
colm 12
synt any
mark L1
var 0
line 17
colm 18
synt any
invoke 0
unmark
lab L1
pnull
line 18
colm 1
synt any
pfail
end
We don’t really have an executable yet, the Unicon tool chain stopped after producing the mainstatement ucode and did not combine the sources with the runtime engine, nor generate icode.
prompt$ unicon mainstatement.icn
Parsing mainstatement.icn: ..
/home/btiffin/unicon/bin/icont -c -O mainstatement.icn /tmp/uni18898220
Translating:
mainstatement.icn:
main
No errors
/home/btiffin/unicon/bin/icont mainstatement.u
Linking:
Without -c
, Unicon does the complete pass, including the VM link phase,
and creates a new program, ready to run.
./mainstatement
That pass does nothing visible, but did all kinds of nifty things in the background.
Hello¶
Now making it a little more complicated is the Hello, world of ucode.
#
# hellostatement.icn, a single statement, proof of life
#
# tectonics:
# unicon -c hellostatement.icn
#
procedure hellostatement()
write("Hello, world")
end
Producing ucode from this source gives just enough VM instructions for Unicon to create a procedure that displays evidence that a proper installation of Unicon is functional.
Processed via unicon -c:
prompt$ unicon -c hellostatement.icn ; sed -i 's/\x0C//' hellostatement.u
Parsing hellostatement.icn: .
/home/btiffin/unicon-git/bin/icont -c -O hellostatement.icn /tmp/uni10825318
Translating:
hellostatement.icn:
hellostatement
No errors
Generates a link ready ucode file, hellostatement.u.
version U12.1.00
uid hellostatement.u1-1571987737-0
impl local
global 1
0,000005,hellostatement,0
proc hellostatement
local 0,000000,write
con 0,010000,12,110,145,154,154,157,054,040,167,157,162,154,144
declend
filen hellostatement.icn
line 14
colm 11
synt any
mark L1
var 0
str 0
line 15
colm 10
synt any
invoke 1
unmark
lab L1
pnull
line 16
colm 1
synt any
pfail
end
Linking that with a main
that calls the small procedure and we have a
Unicon virtual machine program to tell the world that Unicon is functioning
properly (and in this case, doubly so; the translator works and the linker
works, along with the runtime engine).
#
# hellomain.icn, link to a write statement procedure
#
# tectonics:
# unicon -c hellostatement.icn
# unicon hellomain.icn
#
link hellostatement
procedure main()
hellostatement()
end
Drum roll...
prompt$ unicon -c hellostatement.icn ; unicon hellomain.icn -x ; sed -i 's/\x0C//' hellostatement.u
Parsing hellostatement.icn: .
/home/btiffin/unicon-git/bin/icont -c -O hellostatement.icn /tmp/uni10825318
Translating:
hellostatement.icn:
hellostatement
No errors
Parsing hellomain.icn: ..
/home/btiffin/unicon-git/bin/icont -c -O hellomain.icn /tmp/uni10825318
Translating:
hellomain.icn:
main
No errors
/home/btiffin/unicon-git/bin/icont hellomain.u -x
Linking:
Executing:
Hello, world
From Unicon source files, through ucode, to linked icode and final
creation of an executable file. Then automatically invoked (via -x
) to
demonstrate a functional Unicon installation by way of a friendly greeting.
[1] | Unicon merged ucode into a single file. Icon, separates some of the
paperwork from the instructions, giving .u1 and .u2 files. Having
a single .u file makes things a little cleaner and more easily
transportable. |
icode¶
icode is binary form virtual machine instructions, and have an almost one to one correspondence with ucode source. Some differences will occur during linkage, the final phase of Unicon translation before executable. The executor, rt, is the runtime engine invoked by The iconx command that evaluates icode. When using GNU/Linux, Unicon create an executable shell script, that assists with search path settings, and then runs the included binary icode machine instructions.
The hellomain file (reformatted for document capture):
prompt$ ./show-icode hellomain
#!/bin/sh
IXBIN=/home/btiffin/unicon-git/bin/iconx
IXLCL=`echo $0 | sed 's=[^/]*$=iconx='`
[ -n "$ICONX" ] && exec "$ICONX" "$0" ${1+"$@"}
[ -x "$IXLCL" ] && exec "$IXLCL" "$0" ${1+"$@"}
[ -x "$IXBIN" ] && exec "$IXBIN" "$0" ${1+"$@"}
exec iconx "$0" ${1+"$@"}
[executable Icon binary follows]
0000: 00 58 02 00 00 00 00 00 00 00 00 00 00 00 00 00 .X..............
0016: 00 28 01 00 00 00 00 00 00 30 01 00 00 00 00 00 .(.......0......
0032: 00 30 01 00 00 00 00 00 00 30 01 00 00 00 00 00 .0.......0......
0048: 00 60 01 00 00 00 00 00 00 90 01 00 00 00 00 00 .`..............
0064: 00 10 02 00 00 00 00 00 00 90 01 00 00 00 00 00 ................
0080: 00 b0 01 00 00 00 00 00 00 49 31 32 2e 55 2e 33 .........I12.U.3
0096: 30 2f 33 32 2f 36 34 00 00 b0 d4 20 01 00 00 00 0/32/64.... ....
0112: 00 00 00 00 00 00 00 00 00 20 16 20 01 00 00 00 ......... . ....
0128: 00 70 d3 20 01 00 00 00 00 80 10 20 01 00 00 00 .p. ....... ....
0144: 00 40 10 20 01 00 00 00 00 3c d5 de 4a f0 7f 00 .@. .....<..J...
0160: 00 20 16 20 01 00 00 00 00 00 00 00 00 00 00 00 . . ............
0176: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0192: 00 b0 d4 20 01 00 00 00 00 b0 d4 20 01 00 00 00 ... ....... ....
0208: 00 00 00 00 00 00 00 00 00 06 00 00 00 00 00 00 ................
0224: 00 48 00 00 00 00 00 00 00 48 00 00 00 00 00 00 .H.......H......
0240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0256: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0272: 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0288: 00 62 00 00 00 43 00 00 00 24 00 00 00 00 00 00 .b...C...$......
0304: 00 62 00 00 00 54 00 00 00 01 00 00 00 00 00 00 .b...T..........
0320: 00 62 00 00 00 3d 00 00 00 00 00 00 00 00 00 00 .b...=..........
0336: 00 4e 00 00 00 45 00 00 00 44 00 00 00 00 00 00 .N...E...D......
0352: 00 06 00 00 00 00 00 00 00 48 00 00 00 00 00 00 .........H......
0368: 00 d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0384: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0400: 00 00 00 00 00 00 00 00 00 0e 00 00 00 00 00 00 ................
0416: 00 05 00 00 00 00 00 00 00 62 00 00 00 43 00 00 .........b...C..
0432: 00 3c 00 00 00 00 00 00 00 62 00 00 00 54 00 00 .<.......b...T..
0448: 00 02 00 00 00 00 00 00 00 62 00 00 00 4d 00 00 .........b...M..
0464: 00 0c 00 00 00 00 00 00 00 28 00 00 00 00 00 00 .........(......
0480: 00 62 00 00 00 3d 00 00 00 01 00 00 00 00 00 00 .b...=..........
0496: 00 4e 00 00 00 45 00 00 00 44 00 00 00 00 00 00 .N...E...D......
0512: 00 00 00 00 00 00 00 00 00 06 00 00 00 00 00 00 ................
0528: b0 00 00 00 00 00 00 00 00 06 00 00 00 00 00 00 ................
0544: b0 88 00 00 00 00 00 00 00 06 00 00 00 00 00 00 ................
0560: b0 a7 ff ff ff ff ff ff ff 04 00 00 00 00 00 00 ................
0576: 00 00 00 00 00 00 00 00 00 0e 00 00 00 00 00 00 ................
0592: 00 05 00 00 00 00 00 00 00 05 00 00 00 00 00 00 ................
0608: 00 14 00 00 00 00 00 00 00 48 00 00 00 00 00 00 .........H......
0624: 00 1a 00 00 00 00 00 00 00 d0 00 00 00 00 00 00 ................
0640: 00 35 00 00 00 00 00 00 00 48 00 00 00 00 00 00 .5.......H......
0656: 00 10 00 80 01 00 00 00 00 68 00 00 00 00 00 00 .........h......
0672: 00 11 00 60 02 00 00 00 00 80 00 00 00 00 00 00 ...`............
0688: 00 12 00 20 00 00 00 00 00 d0 00 00 00 00 00 00 ... ............
0704: 00 0e 00 60 01 00 00 00 00 08 01 00 00 00 00 00 ...`............
0720: 00 0f 00 40 01 00 00 00 00 20 01 00 00 00 00 00 ...@..... ......
0736: 00 10 00 20 00 00 00 00 00 6d 61 69 6e 00 68 65 ... .....main.he
0752: 6c 6c 6f 73 74 61 74 65 6d 65 6e 74 00 77 72 69 llostatement.wri
0768: 74 65 00 68 65 6c 6c 6f 6d 61 69 6e 2e 69 63 6e te.hellomain.icn
0784: 00 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 00 68 65 .Hello, world.he
0800: 6c 6c 6f 73 74 61 74 65 6d 65 6e 74 2e 69 63 6e llostatement.icn
0816: 00 .
icode support files¶
icode is based on single byte operation codes.
/*
* Opcode definitions used in icode.
*/
/*
* Operators. These must be in the same order as in odefs.h. Not very nice,
* but it'll have to do until we think of another way to do this. (It's
* always been thus.)
*/
#define Op_Asgn 1
#define Op_Bang 2
#define Op_Cat 3
#define Op_Compl 4
#define Op_Diff 5
#define Op_Div 6
#define Op_Eqv 7
#define Op_Inter 8
#define Op_Lconcat 9
#define Op_Lexeq 10
#define Op_Lexge 11
#define Op_Lexgt 12
#define Op_Lexle 13
#define Op_Lexlt 14
#define Op_Lexne 15
#define Op_Minus 16
#define Op_Mod 17
#define Op_Mult 18
#define Op_Neg 19
#define Op_Neqv 20
#define Op_Nonnull 21
#define Op_Null 22
#define Op_Number 23
#define Op_Numeq 24
#define Op_Numge 25
#define Op_Numgt 26
#define Op_Numle 27
#define Op_Numlt 28
#define Op_Numne 29
#define Op_Plus 30
#define Op_Power 31
#define Op_Random 32
#define Op_Rasgn 33
#define Op_Rcv 34
#define Op_RcvBk 35
#define Op_Refresh 36
#define Op_Rswap 37
#define Op_Sect 38
#define Op_Snd 39
#define Op_SndBk 40
#define Op_Size 41
#define Op_Subsc 42
#define Op_Swap 43
#define Op_Tabmat 44
#define Op_Toby 45
#define Op_Unions 46
#define Op_Value 47
/*
* Other instructions.
*/
#define Op_Bscan 117
#define Op_Ccase 118
#define Op_Chfail 119
#define Op_Coact 120
#define Op_Cofail 48
#define Op_Coret 49
#define Op_Create 50
#define Op_Cset 51
#define Op_Dup 52
#define Op_Efail 53
#define Op_EInit 116
#define Op_Eret 54
#define Op_Escan 55
#define Op_Esusp 56
#define Op_Field 57
#define Op_Goto 58
#define Op_Init 59
#define Op_Int 60
#define Op_Invoke 61
#define Op_Keywd 62
#define Op_Limit 63
#define Op_Line 64
#define Op_Llist 65
#define Op_Lsusp 66
#define Op_Mark 67
#define Op_Pfail 68
#define Op_Pnull 69
#define Op_Pop 70
#define Op_Pret 71
#define Op_Psusp 72
#define Op_Push1 73
#define Op_Pushn1 74
#define Op_Real 75
#define Op_Sdup 76
#define Op_Str 77
#define Op_Unmark 78
#define Op_Var 80
#define Op_Arg 81
#define Op_Static 82
#define Op_Local 83
#define Op_Global 84
#define Op_Mark0 85
#define Op_Quit 86
#define Op_Tally 88
#define Op_Apply 89
/*
* "Absolute" address operations. These codes are inserted in the
* icode at run-time by the interpreter to overwrite operations
* that initially compute a location relative to locations not known until
* the icode file is loaded.
*/
#define Op_Acset 90
#define Op_Areal 91
#define Op_Astr 92
#define Op_Aglobal 93
#define Op_Astatic 94
#define Op_Agoto 95
#define Op_Amark 96
#define Op_Noop 98
#define Op_Colm 108 /* column number */
/*
* Declarations and such -- used by the linker but not the run-time system.
*/
#define Op_Proc 101
#define Op_Declend 102
#define Op_End 103
#define Op_Link 104
#define Op_Version 105
#define Op_Con 106
#define Op_Filen 107
/*
* Global symbol table declarations.
*/
#define Op_Record 105
#define Op_Impl 106
#define Op_Error 107
#define Op_Trace 108
#define Op_Lab 109
#define Op_Invocable 110
/*
* Extra instructions added for calling Icon from C (used by Posix functions)
*/
#ifdef PosixFns
#define Op_Copyd 111
#define Op_Trapret 112
#define Op_Trapfail 113
#endif /* PosixFns */
#define Op_Synt 114 /* syntax code used by the linker */
#define Op_Uid 115 /* Universal Identifier for .u files */
/* Op_EInit is 116 for now. */
Which is manually paired with
/*
* Operator definitions.
*
* Fields are:
* name
* number of arguments
* string representation
* dereference arguments flag: -1 = don't, 0 = do
*/
OpDef(asgn,2,":=",-1)
OpDef(bang,1,"!",-1)
OpDef(cater,2,"||",0)
OpDef(compl,1,"~",0)
OpDef(diff,2,"--",0)
OpDef(divide,2,"/",0)
OpDef(eqv,2,"===",0)
OpDef(inter,2,"**",0)
OpDef(lconcat,2,"|||",0)
OpDef(lexeq,2,"==",0)
OpDef(lexge,2,">>=",0)
OpDef(lexgt,2,">>",0)
OpDef(lexle,2,"<<=",0)
OpDef(lexlt,2,"<<",0)
OpDef(lexne,2,"~==",0)
OpDef(minus,2,"-",0)
OpDef(mod,2,"%",0)
OpDef(mult,2,"*",0)
OpDef(neg,1,"-",0)
OpDef(neqv,2,"~===",0)
OpDef(nonnull,1,BackSlash,-1)
OpDef(null,1,"/",-1)
OpDef(number,1,"+",0)
OpDef(numeq,2,"=",0)
OpDef(numge,2,">=",0)
OpDef(numgt,2,">",0)
OpDef(numle,2,"<=",0)
OpDef(numlt,2,"<",0)
OpDef(numne,2,"~=",0)
OpDef(plus,2,"+",0)
OpDef(powr,2,"^",0)
OpDef(random,1,"?",-1)
OpDef(rasgn,2,"<-",-1)
OpDef(rcv,2,"@<",0)
OpDef(rcvbk,2,"@<<",0)
OpDef(refresh,1,"^",0)
OpDef(rswap,2,"<->",-1)
OpDef(sect,3,"[:]",-1)
OpDef(snd,2,"@>",0)
OpDef(sndbk,2,"@>>",0)
OpDef(size,1,"*",0)
OpDef(subsc,2,"[]",-1)
OpDef(swap,2,":=:",-1)
OpDef(tabmat,1,"=",0)
OpDef(toby,3,"...",0)
OpDef(union,2,"++",0)
OpDef(value,1,".",0)
/* OpDef(llist,1,"[...]",0) */
There is also a set of Unicon application programmer support files, mainly used with Execution Monitoring and lower level debugging programs, available in the IPL.
- ipl/incl/opdefs.icn, an include file with all opcode numbers
- ipl/incl/invkdefs.icn, with definitions for visualizing the symbols
- ipl/mprocs/opname.icn, string names for opcodes
- and a few others peppered throughout the IPL.
In the end, Unicon creates an executable shell program that embeds the icode byte codes for use by the Unicon executor, iconx when producing a virtual machine program image.
The program used above to display the hellomain executable is a small Unicon program, show-icode.icn. It relies on the fact that the shell scripting is separated from the ucode by a form feed character. The shell script lines are displayed by line, and the rest as a hex dump.
#
# show-icode.icn, display the parts of a Unicon VM executable
#
link printf
procedure main(argv)
f := open(argv[1], "r") | stop("Cannot open " || image(argv[1]))
# the shell control preamble as lines
while (line := read(f)) ~== "\^L" do write(line)
# binary icode as hex dump
# reads(f, -1) won't work here as the file is already reading
s := ""
while s ||:= reads(f)
hexdump(s)
close(f)
end
#
# display hex codes
#
procedure hexdump(s)
local c, perline := 0, text := " ", scale := 0, counter := 0
if *s = 0 then fail
scale := **s
scale <:= 4
printf("%0" || scale || "d: ", counter)
every c := !s do {
if (perline +:= 1) > 16 then {
write(text)
text := " "
perline := 1
printf("%0" || scale || "d: ", counter)
}
#writes(map(_doprnt("%02x ", [ord(c)]), &lcase, &ucase))
printf("%02x ", ord(c))
text ||:= if 31 < ord(c) < 127 then c else "."
counter +:= 1
}
if perline > 0 then {
writes(repl(" ", (16 - perline) * 3))
write(text)
}
else write()
end
The Implementation of Icon and Unicon¶
As part of the Unicon release 13 pass, there has been updates occurring to The Implementation of Icon and Unicon book, probably the best place for details on the design of the Unicon virtual machine. Sources for ib.pdf ships with the Unicon source kit under doc/ib. Plus it’s an excellent book regarding how to go about building a programming language and the deep issues that designers face when embarking on the task.
Editors¶
Unicon source code is assumed to be ASCII. UFT-8 encoding will work, as long as the characters used stay as single byte code points, in the range 0 to 127.
This means word processor default formats are not suitable for Unicon
source. If you like to use a word processor, make sure the source is saved
as Text
.
Literals and data can assume an 8bit range, 0 to 255, but anything beyond value 127 is at the whim of operating environment settings and default handling. Sometimes you will get block looking characters or upside down question marks, sometimes you will get an extended encoding value like line drawing characters. Those non ASCII features are not standard nor cross platform.
There are quite a few editors that support Icon in terms of highlighting, smart indenting and other productivity enhancers; less so with Unicon features added in. Listed below is an updated Vim syntax highlighter.
Vim¶
The world’s best text editor. A text processing tool.
Here is a Vim syntax file, customized for Unicon, building on the icon.vim that ships with Vim.
" Vim syntax file
" Language: Unicon
" Maintainer: Brian Tiffin (btiffin@gnu.org)
" URL: https://sourceforge.net/projects/unicon
" Last Change: 2016 Oct 22
" quit when a syntax file was already loaded
if exists("b:current_syntax")
finish
endif
" Read the Icon syntax to start with
runtime! syntax/icon.vim
unlet b:current_syntax
" Unicon function extensions
syn keyword uniconFunction Abort Any Arb Arbno array
syn keyword uniconFunction Break Breakx chmod chown
syn keyword uniconFunction chroot classname cofail Color
syn keyword uniconFunction condvar constructor
syn keyword uniconFunction crypt ctime dbcolumns dbdriver
syn keyword uniconFunction dbkeys dblimits dbproduct dbtables display
syn keyword uniconFunction eventmask EvGet EvSend
syn keyword uniconFunction exec Fail fdup Fence fetch fieldnames
syn keyword uniconFunction filepair
syn keyword uniconFunction flock fork
syn keyword uniconFunction getegid geteuid getgid getgr
syn keyword uniconFunction gethost getpgrp getpid getppid getpw
syn keyword uniconFunction getrusage getserv gettimeofday
syn keyword uniconFunction getuid globalnames gtime
syn keyword uniconFunction ioctl istate
syn keyword uniconFunction keyword kill Len link load localnames lock
syn keyword uniconFunction max membernames methodnames
syn keyword uniconFunction methods min mkdir mutex name
syn keyword uniconFunction NotAny Nspan opencl oprec
syn keyword uniconFunction paranames parent pipe
syn keyword uniconFunction Pos proc
syn keyword uniconFunction readlink ready
syn keyword uniconFunction receive Rem rmdir Rpos Rtab
syn keyword uniconFunction select send setenv setgid setgrent
syn keyword uniconFunction sethostent setpgrp setpwent setservent setuid
syn keyword uniconFunction signal Span spawn sql stat staticnames
syn keyword uniconFunction structure Succeed symlink
syn keyword uniconFunction sys_errstr syswrite Tab
syn keyword uniconFunction trap truncate trylock
syn keyword uniconFunction umask unlock utime wait
" Unicon graphics, audio and VOIP
syn keyword uniconGraphics Active Alert
syn keyword uniconGraphics Attrib Bg
syn keyword uniconGraphics Clip Clone Color
syn keyword uniconGraphics ColorValue CopyArea
syn keyword uniconGraphics Couple
syn keyword uniconGraphics DrawArc DrawCircle DrawCube DrawCurve
syn keyword uniconGraphics DrawCylinder DrawDisk DrawImage DrawLine
syn keyword uniconGraphics DrawPoint DrawPolygon DrawRectangle
syn keyword uniconGraphics DrawSegment DrawSphere DrawString DrawTorus
syn keyword uniconGraphics EraseArea Event
syn keyword uniconGraphics Eye Fg
syn keyword uniconGraphics FillArc FillCircle FillPolygon
syn keyword uniconGraphics FillRectangle Font FreeColor
syn keyword uniconGraphics GotoRC GotoXY
syn keyword uniconGraphics IdentityMatrix
syn keyword uniconGraphics Lower MatrixMode
syn keyword uniconGraphics MultMatrix
syn keyword uniconGraphics NewColor Normals
syn keyword uniconGraphics PaletteChars PaletteColor PaletteKey
syn keyword uniconGraphics Pattern Pending
syn keyword uniconGraphics Pixel PlayAudio PopMatrix
syn keyword uniconGraphics PushMatrix PushRotate PushScale PushTranslate
syn keyword uniconGraphics QueryPointer Raise ReadImage
syn keyword uniconGraphics Refresh Rotate
syn keyword uniconGraphics Scale
syn keyword uniconGraphics StopAudio
syn keyword uniconGraphics Texcoord Texture
syn keyword uniconGraphics TextWidth Translate
syn keyword uniconGraphics Uncouple
syn keyword uniconGraphics VAttrib
syn keyword uniconGraphics WAttrib WDefault WFlush
syn keyword uniconGraphics WindowContents
syn keyword uniconGraphics WriteImage WSection WSync
" Unicon system specific
syn keyword uniconSpecific FreeSpace GetSpace InPort Int86
syn keyword uniconSpecific OutPort Peek Poke Swi
syn keyword uniconSpecific WinAssociate WinButton WinColorDialog
syn keyword uniconSpecific WinEditRegion WinFontDialog WinMenuBar
syn keyword uniconSpecific WinOpenDialog WinPlayMedia WinSaveDialog
syn keyword uniconSpecific WinScrollBar WinSelectDialog
" Unicon and Icon Graphic Keywords
syn match uniconKeyword "&col"
syn match uniconKeyword "&column"
syn match uniconKeyword "&control"
syn match uniconKeyword "&errno"
syn match uniconKeyword "&eventcode"
syn match uniconKeyword "&eventsource"
syn match uniconKeyword "&eventvalue"
syn match uniconKeyword "&interval"
syn match uniconKeyword "&ldrag"
syn match uniconKeyword "&lpress"
syn match uniconKeyword "&lrelease"
syn match uniconKeyword "&mdrag"
syn match uniconKeyword "&meta"
syn match uniconKeyword "&mpress"
syn match uniconKeyword "&mrelease"
syn match uniconKeyword "&pick"
syn match uniconKeyword "&now"
syn match uniconKeyword "&rdrag"
syn match uniconKeyword "&resize"
syn match uniconKeyword "&row"
syn match uniconKeyword "&rpress"
syn match uniconKeyword "&rrelease"
syn match uniconKeyword "&shift"
syn match uniconKeyword "&window"
syn match uniconKeyword "&x"
syn match uniconKeyword "&y"
" New reserved words
syn keyword uniconReserved critical import initially invocable method
syn keyword uniconReserved package thread
" Storage class reserved words
syn keyword uniconStorageClass abstract class
" Define the highlighting colour groups
hi def link uniconStorageClass StorageClass
hi def link uniconFunction Statement
hi def link uniconGraphics Special
hi def link uniconSpecific SpecialComment
hi def link uniconReserved Label
hi def link uniconKeyword Operator
let b:current_syntax = "unicon"
Place that file in $HOME/.vim/syntax/unicon.vim. Then add
" Unicon - see ~/.vim/ftdetect/unicon.vim
autocmd BufRead,BufNewFile *.icn set filetype=unicon
to your ~/.vimrc Vim startup file.
Or copy this short file type detection file
" Unicon file detection override Icon
" Modified: 2016-10-24/05:19-0400
autocmd BufRead,BufNewFile *.icn set filetype=unicon
to $HOME/.vim/ftdetect/unicon.vim
Please note the filename is also unicon.vim but in the ~/.vim/ftdetect/ directory. It is renamed here as unicon-ftdetect.vim to avoid a name conflict within the documentation directory structure.
After saving the syntax file and changes to the file type auto detect system, whenever you open or edit a file with a .icn extension, it will be highlighted for Unicon syntax. As well as working with older Icon sources.
Once you add the syntax file, you can choose Unicon highlighting for any
Vim buffer by typing the ex
colon command, set filetype=unicon
.
As hinted at in Documentation, you can also add automatic templates for new Unicon source files by adding the following to your ~./vimrc startup file.
autocmd BufNewFile *.icn 0r ~/lang/unicon/header.icn
autocmd BufNewFile *.opt 0r ~/lang/unicon/header-options.icn
\ |0file|file <afile>:s?\.opt?\.icn?|filetype detect
Change the ~/lang/unicon/header part to a local site installation filename. It will pre-populate new .icn files with text from the template header.
The second Vim autocmd
listed above allows for a more sophisticated
skeleton for programs what will have command line option handling. Use with
vim filename.opt. It loads a more extensive template
(header-options), then renames the buffer to filename.icn. The
.opt shortcut relies on having the unicon.vim file type
detection code properly installed in ~/.vim/ftdetect.
At time of writing, my custom templates look like:
header.icn
##-
# Author: Brian Tiffin
# Dedicated to the public domain
#
# Date: October 2016
# Modified:
##+
#
# program.icn, description
#
# tectonics:
#
#
procedure main()
end
I use header.icn quite often, and keep the Date:
line up to date
with the current month.
header-options.icn
##-
# Author: Brian Tiffin
# Licensed under the GNU LGPL, version 3 or greater
#
# Date:
# Modified:
##+
#
# program.icn, description
#
# tectonics:
#
$define VERSION 0.1
link options
procedure main(argv)
opts := options(argv, "-h! -v! -source!", optError)
if \opts["h"] then return showHelp()
if \opts["v"] then return showVersion()
if \opts["source"] then return showSource()
end
#
# show help, version and source info
#
procedure showVersion()
write(&errout, &progname, " ", VERSION, " ", __DATE__)
end
procedure showHelp()
showVersion()
write(&errout, "Usage:")
write(&errout, "\t-h\tshow this help")
write(&errout, "\t-v\tshow version")
write(&errout, "\t-source\tlist source code")
end
procedure showSource()
local f
f := open(&file, "r") | stop("Source file ", &file, " unavailable")
every write(!f)
close(f)
end
#
# options error
#
procedure optError(s)
write(&errout, s)
stop("Try ", &progname, " -h for more information")
end
Personalize to taste, and save a little typing when you start new Unicon files. Plus the added benefit of a consistent look to all of your programs (which are, by their very nature, the world’s best programs).
There is also the Icon Programming Library skeleton, developed by Ralph Griswold a long time ago, which is not a bad choice for consistent Unicon programming.
############################################################################
#
# File:
#
# Subject: Program
#
# Author:
#
# Date:
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
#
#
############################################################################
#
# Requires:
#
############################################################################
#
# Links:
#
############################################################################
procedure main()
end
A well supported, de-facto standard in the Icon world.
Emacs¶
The world’s other best text editor. An operating system that handles text.
Robert Parlett created a Unicon major more for Emacs:
Evil¶
The Extensible Vi Layer for Emacs, Evil adds features of the world’s best text editor to the world’s other best text editor.
https://www.emacswiki.org/emacs/Evil
This is thee editor combination. Emacs (including OrgMode) with Vim key
bindings and modal editing. Sweet. Evil
is a very complete, robust and
well done Vim emulator, augmenting the powers inherent in Emacs.
Index | Previous: Threading | Next: Documentation