xref: /inferno-os/doc/limbo/limbo.ms (revision e45fa0eb0763b57d6fb0649c064bc3b95ccdea6c)
1...FP lucidasans
2...FP palatino
3.FP palatino
4." .fp 6 RR R
5.nr PI 2n
6.de P1
7.DS L
8.ft CW
9.ps -1
10.vs -1u
11.ta .75i 1.5i 2.25i 3i 3.75i 4.5i 5.25i 6i 6.75i 7.5i
12..
13.de P2
14.ft R
15.ps +1
16.vs +1u
17.DE
18..
19.de s1
20.DS
21.br
22.ft I
23..
24.de s2
25.br
26.DE
27.ft R
28..
29...ds CF "Copyright 2000 Lucent Technologies Inc. Modifications Vita Nuova Limited.
30.TL
31The Limbo Programming Language
32.AU
33Dennis M. Ritchie
34.br
35(Revised 2005 by Vita Nuova)
36.SP .5i exactly
37.PP
38Limbo is a programming language intended for applications
39running distributed systems on small computers.
40It supports modular programming,
41strong type checking at compile- and run-time,
42interprocess communication over typed channels,
43automatic garbage collection,
44and simple abstract data types.
45It is designed for safe execution even on
46small machines without hardware memory protection.
47.PP
48In its implementation for the Inferno operating system,
49object programs generated by the Limbo compiler run
50using an interpreter for a fixed virtual machine.
51Inferno and its accompanying virtual machine run either stand-alone
52on bare hardware
53or as an application under conventional operating systems like
54Unix, Windows 2000, Linux, FreeBSD, MacOSX, and Plan 9.
55For most architectures, including
56Intel x86, ARM, PowerPC, MIPS and Sparc, Limbo object programs
57are transformed on-the-fly into instructions for the underlying hardware.
58.NH 1
59Overview and introduction
60.PP
61A Limbo application consists of one or more
62.I modules ,
63each of which supplies an interface declaration and
64an implementation part.
65A module that uses another module
66includes its declaration part.
67During
68execution, a module dynamically attaches another module by
69stating the other module's type identifier and a place from which to load
70the object code for its implementation.
71.PP
72A module declaration specifies the functions and data it will make visible,
73its data types, and constants.
74Its implementation part defines the functions and data visible at its interface and
75any functions associated with its data types;
76it may also contain definitions for functions used only internally and
77for data local to the module.
78.PP
79Here is a simple module to illustrate the flavour of the language.
80.P1
811	implement Command;
82
832	include "sys.m";
843	include "draw.m";
85
864	sys:	Sys;
87
885	Command: module
89	{
906	    init: fn (ctxt: ref Draw->Context, argv: list of string);
917	};
92.P2
93.P1
948	# The canonical "Hello world" program, enhanced
959	init(ctxt: ref Draw->Context, argv: list of string)
9610	{
9711		sys = load Sys Sys->PATH;
9812		sys->print("hello world\en");
9913		for (; argv!=nil; argv = tl argv)
10014			sys->print("%s ", hd argv);
10115		sys->print("\en");
10216	}
103.P2
104A quick glance at the program reveals that
105the syntax of Limbo is influenced by C in its expressions,
106statements, and some conventions (for example, look at lines 13-14),
107and also by Pascal and its successors (the declarations on lines 4, 6, 9).
108When executed in the Inferno environment, the program writes
109.CW hello
110.CW world
111somewhere, then echoes its arguments.
112.PP
113Let's look at the program line-by-line.
114It begins (line 1) by saying that this is the implementation of module
115.CW Command .
116Line 2 includes a file (found in a way analogous to C's
117.CW #include
118mechanism) named
119.CW sys.m .
120This file defines the interface to module
121.CW Sys ;
122.ds CF
123it says, in part,
124.P1
125Sys: module {
126	PATH: con "$Sys";
127	. . .
128	print: fn (s: string, *): int;
129	. . .
130};
131.P2
132This declares
133.CW Sys
134to be the type name for a module containing among other things a
135function named
136.CW print ;
137the first argument of
138.CW print
139is a string.
140The
141.CW *
142in the argument list specifies that further arguments, of
143unspecified type, may be given.
144.PP
145Line 3 includes
146.CW draw.m ;
147only one piece of information, mentioned below,
148is used from it.
149Line 4 declares the variable
150.CW sys
151to be of type
152.CW Sys ;
153its name will be visible throughout the remainder of the file
154describing this module.
155It will be used later to refer to an instance of the
156.CW Sys
157module.
158This declaration initializes it to
159.CW nil ;
160it still needs to be set to a useful value.
161.PP
162Lines 5-7 constitute the declaration of
163.CW Command ,
164the module being implemented.
165It contains only a function named
166.CW init ,
167with two arguments, a
168.CW ref
169.CW Draw->Context
170and a list of strings,
171and it doesn't
172return any value.
173The
174.CW ref
175.CW Draw->Context
176argument would be used if the program did any
177graphics; it is a data type defined in
178.CW draw.m
179and refers to the display.
180Since the program just writes text, it won't be used.
181The
182.CW init
183function isn't special to the Limbo language,
184but it is conventional in the environment,
185like
186.CW main
187in C.
188.PP
189In a module designed to be useful
190to other modules in an application, it would be wise to
191take the module declaration for
192.CW Command
193out, put it in a separate file called
194.CW command.m
195and use
196.CW "include
197.CW command.m
198to allow this module and others to refer to it.
199It is called, for example, by the program loader in the Inferno
200system to start the execution of applications.
201.PP
202Line 8 is a comment; everything from the
203.CW #
204to the end of line is ignored.
205.PP
206Line 9 begins the definition for the
207.CW init
208function that was promised in the module's declaration
209(line 6).
210The argument that is a list of strings is named
211.CW argv .
212.PP
213Line 11 connects the program
214being written to the
215.CW Sys
216module.
217The first token after
218.CW load
219is the target module's name as defined by its interface
220(here found in the
221.CW include
222on line 2)
223The next token is the place
224where the code for the module can be found; it is a string
225that usually names a file.
226Conventionally, in the Inferno system,
227each module contains a constant declaration for the name
228.CW PATH
229as a string that names the file where
230the object module can be found.
231Loading the file is performed dynamically during
232execution except for a few modules built
233into the execution environment.
234(These include
235.CW Sys ;
236this accounts for the peculiar file name
237.CW "$Sys"
238as
239the value of
240.CW PATH .)
241.PP
242The value of
243.CW load
244is a reference to the
245named module; line 11 assigns it
246to the variable
247.CW sys
248for later use.
249The
250.CW load
251operator dynamically loads the code for the named
252module if it is not already present and instantiates
253a new instance of it.
254.PP
255Line 12 starts the work by printing a familiar message,
256using the facilities provided by module
257.CW Sys
258through its handle
259.CW sys ;
260the notation
261.CW sys->print(...)
262means to call the
263.CW print
264function of the module referred to by
265.CW sys .
266The interface of
267.CW Sys
268resembles a binding to some of
269the mechanisms of Unix and the ISO/ANSI C library.
270.PP
271The loop at lines 13-14 takes the
272.CW "list
273.CW of
274.CW string
275argument to
276.CW init
277and iterates over it using the
278.CW hd
279(head) and
280.CW tl
281(tail) operators.
282When executed, this module combines the
283traditional `Hello world' and
284.CW echo .
285.NH 1
286Lexical conventions
287.PP
288There are several kinds of tokens:
289keywords, identifiers, constants, strings, expression operators,
290and other separators.
291White space (blanks, tabs, new-lines) is ignored except that
292it serves to separate tokens; sometimes it is required
293to separate tokens.
294If the input has been parsed into tokens up to a particular
295character, the next token is taken to include the longest
296string of characters that could constitute a token.
297.PP
298The native character set of Limbo is Unicode,
299which is identical with the first 16-bit plane of the ISO 10646 standard.
300Any Unicode character may be used in comments, or in strings
301and character constants.
302The implementation assumes that source files use the UTF-8 representation,
303in which 16-bit Unicode characters are represented as sequences
304of one, two, or three bytes.
305.NH 2
306Comments
307.PP
308Comments begin with the
309.CW #
310character and extend to the end of the line.
311Comments are ignored.
312.NH 2
313Identifiers
314.PP
315An identifier is a sequence of letters and digits
316of which the first is a letter.
317Letters are the Unicode characters
318.CW a
319through
320.CW z
321and
322.CW A
323through
324.CW Z ,
325together with the underscore character, and
326all Unicode characters with encoded values greater than 160
327(A0 hexadecimal, the beginning of the range corresponding to Latin-1).
328.PP
329Only the first 256 characters in an identifier
330are significant.
331.NH 2
332Keywords
333.PP
334The following identifiers are reserved for use as keywords,
335and may not be used otherwise:
336.P1
337.ta 1i 2i 3i 4i 5i
338	adt	alt	array	big
339	break	byte	case	chan
340	con	continue	cyclic	do
341	else	exit	fn	for
342	hd	if	implement	import
343	include	int	len	list
344	load	module	nil	of
345	or	pick	real	ref
346	return	self	spawn	string
347	tagof	tl	to	type
348	while
349.P2
350The word
351.CW union
352is not currently used by the language.
353.NH 2
354Constants
355.PP
356There are several kinds of constants for denoting values of the
357basic types.
358.PP
359.NH 3
360Integer constants
361.PP
362Integer constants have type
363.CW int
364or
365.CW big .
366They can be represented in several ways.
367.PP
368Decimal integer constants consist of a sequence of decimal
369digits.
370A constant with an explicit radix
371consists of a decimal radix followed by
372.CW R
373or
374.CW r
375followed by the digits of the number.
376The radix is between 2 and 36 inclusive;
377digits above 10 in the number
378are expressed using letters
379.CW A
380to
381.CW Z
382or
383.CW a
384to
385.CW z .
386For example,
387.CW 16r20
388has value 32.
389.PP
390The type of a decimal or explicit-radix number is
391.CW big
392if its value exceeds
393.CW 2\u31\d\(mi1 ,
394otherwise it is
395.CW int .
396.PP
397Character constants consist of a single Unicode
398character enclosed within single-quote characters
399.CW ' .
400Inside the quotes the following escape sequences represent
401special characters:
402.DS
403\f(CW\e\e\fR		backslash
404\f(CW\e'\fR		single quote
405\f(CW\e"\fR		double quote
406\f(CW\ea\fR		bell (BEL)
407\f(CW\eb\fR		backspace (BS)
408\f(CW\et\fR		horizontal tabulation (HT)
409\f(CW\en\fR		line feed (LF)
410\f(CW\ev\fR		vertical tabulation (VT)
411\f(CW\ef\fR		form feed (FF)
412\f(CW\er\fR		carriage return (CR)
413\f(CW\eu\fIdddd	\fRUnicode character named by 4 hexadecimal digits
414\f(CW\e0\fR		NUL
415.DE
416Character constants have type
417.CW int .
418.NH 3
419Real constants
420.PP
421Real constants consist of a sequence of decimal digits
422containing one period
423.CW .
424and optionally followed by
425.CW e
426or
427.CW E
428and then by a possibly signed integer.
429If there is an explicit exponent, the period is
430not required.
431Real constants have type
432.CW real .
433.NH 3
434Strings
435.PP
436String constants are sequences of Unicode characters contained in double
437quotes.
438They cannot extend across source lines.
439The same escape sequences listed above for character
440constants are usable within string constants.
441.PP
442Raw (uninterpreted) string constants are sequences of Unicode characters
443contained in backquotes.
444They can extend across source lines and thus include newlines.
445They contain no character escapes.
446The only character that cannot appear inside an uninterpreted string is a backquote, because that delimits the string.
447.PP
448Both forms of string constant have type
449.CW string .
450.NH 3
451The nil constant
452.PP
453The constant
454.CW nil
455denotes a reference to nothing.
456It may be used where an object of a reference
457type is expected;
458otherwise uninitialized values of reference type
459start off with this value, it can be assigned to
460reference objects, and reference types can be
461tested for equality with it.
462(The keyword has other uses as well.)
463.NH 2
464Operators and other separators
465.PP
466The operators are
467.P1
468.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6.0i 6.5i
469	+	-	*	/	%	&	|	^
470	==	<	>	<=	>=	!=	<<	>>
471	&&	||	<-	::
472	=	+=	-=	*=	/=	%=	&=	|=	^=	<<=	>>=
473	:=
474	~	++	--	!	**
475.P2
476The other separators are
477.P1
478.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i
479	:	;	(	)	{	}	[	]
480	,	.	->	=>
481.P2
482.NH 1
483Syntax notation
484.PP
485In this manual, Limbo syntax is described by a modified BNF
486in which syntactic categories are named in an
487.I italic
488font, and literals in
489.CW typewriter
490font.
491Alternative productions are listed on separate lines, and
492an optional symbol is indicated with
493the subscript ``opt.''
494.NH 1
495Types and objects
496.PP
497Limbo has three kinds of objects.
498.I Data
499objects exist in the storage associated with
500a module; they can be manipulated by arithmetic operations,
501assignment, selection of component entities, and other concrete
502operations.
503Each data object has a type that determines what can be stored
504in it and what operations are applicable.
505.PP
506The second kind of object is the
507.I function .
508Functions are characterized by the types of the arguments they
509accept and the values they return, and are associated with
510the modules in which they are defined.
511Their names can be made visible in their module's declaration,
512or they can be encapsulated within the
513.CW adt
514(abstract data types) of their modules,
515or they can exist privately within their module.
516.PP
517Finally, Limbo programs are organized into
518.I modules :
519a named collection of constants, abstract data types,
520data, and functions made available by that module.
521A module declaration displays the
522members visible to other modules;
523the module's implementation
524defines both the publicly visible members and its
525private parts, including the data objects it uses.
526A module that wishes to use
527the facilities of another includes its declaration in order to
528understand what it exports, but
529before using them it explicitly loads the new module.
530.NH 2
531Types
532.PP
533Limbo has several basic types, some built-in higher abstractions,
534and other ways of composing new types.
535In declarations and some other places, constructions naming
536a type are used.
537The syntax is:
538.s1
539type:
540	data-type
541	function-type
542.s2
543Functions will be discussed in §7 below.
544First, data types will be explored.
545.NH 2
546Data types
547.PP
548The syntax of data types is
549.s1
550data-type:
551	CbyteI
552	CintI
553	CbigI
554	CrealI
555	CstringI
556	tuple-type
557	Carray of Idata-type
558	Clist of Idata-type
559	Cchan of Idata-type
560	adt-type
561	Cref Iadt-type
562	Cref Ifunction-type
563	module-type
564	module-qualified-type
565	type-name
566
567data-type-list:
568	data-type
569	data-type-list C,I data-type
570.s2
571Objects of most data types have
572.I value
573semantics; when they
574are assigned or passed to functions, the destination receives a copy of the
575object.
576Subsequent changes to the assigned object itself have no effect on
577the original object.
578The value types are
579.CW byte ,
580.CW int ,
581.CW big ,
582.CW real ,
583.CW string ,
584the
585.CW tuple
586types, and
587abstract data types or
588.CW adt .
589The rest have
590.I reference
591semantics.
592When they are assigned, the quantity actually assigned
593is a reference to (a pointer to) an underlying object
594that is not copied; thus changes or operations on
595the assigned value affect the original object.
596Reference types include lists, arrays, channels, modules,
597.CW ref
598.CW adt ,
599and
600.CW ref
601.CW fn
602types.
603.NH 3
604Basic types
605.PP
606The five basic data types are denoted by
607.CW byte ,
608.CW int ,
609.CW big ,
610.CW real ,
611and
612.CW string .
613.PP
614Bytes are unsigned 8-bit quantities.
615.PP
616Integers
617.CW int ) (
618are 32-bit signed quantities represented in two's complement
619notation.
620Large integers
621.CW big  ) (
622are 64-bit signed quantities represented in two's complement notation.
623.PP
624Real numbers
625.CW real ) (
626are 64-bit quantities represented in the
627IEEE long floating notation.
628.PP
629The
630.CW byte ,
631.CW int ,
632.CW big ,
633and
634.CW real
635types are collectively called arithmetic types.
636.PP
637Strings are rows of Unicode characters.
638They may be concatenated and extended character-by-character.
639When a string is indexed with a single subscript, it yields an integer
640with the Unicode encoding of the character;
641when it is indexed by a range, it yields another string.
642.NH 3
643Tuple type
644.PP
645The
646.I tuple
647type, denoted
648.s1
649tuple-type:
650	C( Idata-type-listC )I
651.s2
652is a type consisting of an ordered collection of two or more objects,
653each having its own data type.
654For each tuple type, the types of the members are
655fixed, but need not be identical;
656for example, a function might return a tuple containing
657an integer and a string.
658Each tuple type is characterized solely by the
659the order and identity of the types it contains.
660Objects of tuple type may be assigned to a list of identifiers (to pick out the
661components), and a parenthesized, comma-separated list of expressions
662denotes a tuple.
663.NH 3
664Array types
665.PP
666The
667.I array
668type describes a dynamically-sized row of objects, all of the same
669type; it is indexed starting from 0.
670An array type is denoted by
671.s1
672	Carray of Idata-type
673.s2
674The size of an array is not part of its type; instead
675it is part of the value.
676The
677.I data-type
678may itself be an array, to achieve a multidimensional array.
679.NH 3
680List types
681.PP
682A
683.I list
684is a sequence of like-typed objects; its denotation is
685.s1
686	Clist of Idata-type
687.s2
688A list is a stack-like object, optimized for
689a few operations: get the head (the first object),
690get the tail (the rest of the list), place an object at the beginning.
691.NH 3
692Channel types
693.PP
694A
695.I channel ,
696whose type is written
697.s1
698	Cchan of Idata-type
699.s2
700is a communication mechanism capable of sending and receiving objects of the
701specified type to another agent in the system.
702Channels may be used to communicate between local processes;
703using library procedures, they may be connected
704to named destinations.
705In either case
706.I send
707and
708.I receive
709operations may be directed to them.
710For example,
711.P1
712	chan of (int, string)
713.P2
714is the type of a channel that transmits tuples consisting of
715an integer and an string.
716Once an instance of such a channel (say
717.CW c )
718has been declared and initialized,
719the statement
720.P1
721	c <-= (123, "Hello");
722.P2
723sends such a tuple across it.
724.NH 3
725Abstract data types
726.PP
727An abstract data type or
728.I adt
729is an object that can contain data objects of several
730different types and declare
731functions that operate on them.
732The syntax for declaring an
733.CW adt
734is given later.
735Once an
736.CW adt
737has been declared, the identifier associated with it
738becomes a data-type name.
739.s1
740adt-type:
741	identifier
742	module-qualified-type
743.s2
744.PP
745There is also a
746.CW ref
747.CW adt
748type representing a reference (pointer) to an
749.CW adt .
750It is denoted
751.s1
752	Cref Iadt-type
753.s2
754where the identifier is the name of an
755.CW adt
756type.
757.NH 3
758Module types
759.PP
760A module type name is an identifier:
761.s1
762module-type:
763	identifier
764.s2
765The identifier is declared as a module identifier by a
766.I module-declaration ,
767as described in §6.5 below.
768An object of module type serves as a handle for the
769module, and is used to access its functions.
770.NH 3
771Module-qualified type
772.PP
773When an
774.CW adt
775is declared within a module declaration, the type name of that
776.CW adt
777is not generally visible to the rest of the program unless a specific
778.CW import
779request is given (see §6.6, §10 below).
780Without such a request, when
781.CW adt
782objects implemented by a module are declared by a client
783of that module, the
784.CW adt
785type name is qualified:
786.s1
787module-qualified-type:
788	identifier C->I identifier
789.s2
790Here the first identifier is either the name of a module
791or a variable of the module type;
792the second is the name of a type
793mentioned in the module declaration.
794.NH 3
795Function reference types
796.PP
797A function reference type represents a reference to a function of a given type.
798It is written as
799.s1
800	Cref Ifunction-type
801.s2
802Function types are discussed in §4.3 below.
803.NH 3
804Named types
805.PP
806Finally, data types may be named, using a
807.CW type
808declaration; this is discussed in §6.4 below.
809.s1
810type-name:
811	identifier
812.s2
813.NH 2
814Function types
815.PP
816A function type characterizes the arguments and return value of
817a function.  The syntax is
818.s1
819function-type:
820	Cfn Ifunction-arg-ret
821
822function-arg-ret:
823	C( Iformal-arg-listOC ) IraisesO
824	C( Iformal-arg-listOC ) : Idata-type raisesO
825
826formal-arg-list:
827	formal-arg
828	formal-arg-listC , Iformal-arg
829
830formal-arg:
831	nil-or-ID-listC : Itype
832	nil-or-IDC : self refO Iidentifier
833	nil-or-IDC : self Iidentifier
834	C*I
835
836nil-or-ID-list:
837	nil-or-ID
838	nil-or-ID-list C, Inil-or-ID
839
840nil-or-ID:
841	identifier
842	CnilI
843
844raises:
845	Craises ( Inil-or-ID-listC )I
846	CraisesI nil-or-ID
847
848.s2
849That is, the denotation of a function type has the keyword
850.CW fn
851followed by a comma-separated list of its arguments
852enclosed in parentheses,
853and perhaps followed by the type the function returns.
854Absence of a return value means that the function returns no
855value: it is a procedure.
856The names and types of arguments are specified.
857However, the name of an argument may be replaced by
858.CW nil ;
859in this case it is nameless.
860For example,
861.P1
862	fn (nil: int, nil: int): int
863	fn (radius: int, angle: int): int
864	fn (radius, angle: int): int
865.P2
866all denote exactly the same type,
867namely a function of two integers that returns an integer.
868As another example,
869.P1
870	fn (nil: string)
871.P2
872is the type of a function that takes a string argument
873and returns no value.
874.PP
875The
876.CW self
877keyword has a specialized use within
878.CW adt
879declarations.
880It may be used only for the first argument
881of a function declared within an
882.CW adt ;
883its meaning is discussed in §6.3 below.
884.PP
885The star character
886.CW *
887may be given as the last argument in a function type.
888It declares that
889the function is variadic; during a call, actual arguments at its
890position and following are passed in a manner
891unspecified by the language.
892For example, the type of the
893.CW print
894function of the
895.CW Sys
896module is
897.P1
898	fn (s: string, *): int
899.P2
900This means that the first argument of
901.CW print
902is a string and that other arguments may be given when the function
903is called.
904The Limbo language itself has no way of accessing these arguments;
905the notation is an artifice for describing facilities
906built into the runtime system, such as the
907.CW Sys
908module.
909.PP
910The type of a function includes user-defined exceptions that it raises,
911which must be listed in a corresponding
912.CW raises
913clause.
914.NH 1
915Limbo programs
916.PP
917Limbo source programs that implement modules are stored in files,
918conventionally named with the suffix
919.CW .b .
920Each such file begins with a single
921.CW implement
922directive naming the type of the module being implemented,
923followed by a sequence of declarations.
924Other files, conventionally named with the suffix
925.CW .m ,
926contain declarations for things obtainable from other modules.
927These files are incorporated by an
928.CW include
929declaration in the implementation modules that need them.
930At the top level, a program consists of a sequence
931of declarations.
932The syntax is
933.s1
934program:
935	Cimplement Iidentifier-listC ; Itop-declaration-sequence
936
937top-declaration-sequence:
938	top-declaration
939	top-declaration-sequence top-declaration
940
941top-declaration:
942	declaration
943	identifier-listC := IexpressionC ;I
944	identifier-listC = IexpressionC ;I
945	C( Iidentifier-listC ) := IexpressionC ;I
946	module-declaration
947	function-definition
948	adt-declaration
949.s2
950The
951.CW implement
952declaration at the start identifies the type of the module that
953is being implemented.
954The rest of the program consists of a sequence of various kinds of
955declarations and definitions that announce the names
956of data objects, types, and functions, and also create
957and initialize them.
958It must include a module declaration for the module
959being implemented and the objects it announces,
960and may also include declarations for the functions, data
961objects, types, and constants used privately within the module
962as well as declarations for modules used by it.
963.PP
964Declarations are used both at the top
965level (outside of functions) and also inside functions
966and module declarations.
967Some styles of declaration
968are allowed only in certain of these places,
969but all will be discussed together.
970.PP
971Most implementation modules provide an implementation for one type of module.
972Several module types may be listed, however, in the
973.CW implement
974declaration, when the implementation module implements them all.
975When the same name appears in more than one such module type, it must
976have the same type.
977.NH 1
978Declarations
979.PP
980Declarations take several forms:
981.s1
982declaration:
983	identifier-listC : ItypeC ;I
984	identifier-listC : ItypeC = IexpressionC ;I
985	identifier-listC : con IexpressionC ;I
986	Iidentifier-listC : import Iidentifier C;I
987	identifier-listC : typeI typeC ;I
988	identifier-listC : exceptionI tuple-typeO
989	Cinclude Istring-constantC ;I
990
991identifier-list:
992	identifier
993	identifier-listC , Iidentifier
994
995expression-list:
996	expression
997	expression-listC , Iexpression
998.s2
999.NH 2
1000Data declarations
1001.PP
1002These forms constitute the basic way to declare and
1003initialize data:
1004.s1
1005	identifier-listC : ItypeC ;I
1006	identifier-listC : ItypeC = IexpressionC ;I
1007.s2
1008A comma-separated sequence of identifiers is followed by a colon
1009and then the name of a type.
1010Each identifier is declared as having that type and denotes a
1011particular object
1012for rest of its scope (see §11 below).
1013If the declaration contains
1014.CW =
1015and an expression, the type must be a data type, and
1016all the objects are initialized from
1017the value of the expression.
1018In a declaration at the top level
1019(outside of a function), the expression must be
1020constant (see §8.5) or an array initialized with constant expressions;
1021the bound of any array must be a constant expression.
1022Lists and
1023.CW ref
1024.CW adt
1025types may not be initialized at the top level.
1026If an object is not explicitly initialized, then
1027it is always set to
1028.CW nil
1029if it has a reference type;
1030if it has arithmetic type, then it is set to 0
1031at the top level and is undefined if it occurs
1032within a function.
1033.PP
1034For example,
1035.P1
1036	i, j: int = 1;
1037	r, s: real = 1.0;
1038.P2
1039declares
1040.CW i
1041and
1042.CW j
1043as integers,
1044.CW r
1045and
1046.CW s
1047as real.
1048It sets
1049.CW i
1050and
1051.CW j
1052to 1,
1053and
1054.CW r
1055and
1056.CW s
1057to 1.0.
1058.PP
1059Another kind of declaration is a shorthand.
1060In either of
1061.s1
1062	identifierC := IexpressionC ;I
1063	C( Iidentifier-listC ) := IexpressionC ;I
1064
1065.s2
1066identifiers on the left are declared using the type of the expression,
1067and are initialized with the value of the expression.
1068In the second case, the expression must be a tuple or an
1069.CW adt ,
1070and the types and values attributed to the identifiers
1071in the list are taken from the members of the tuple, or the
1072data members of the
1073.CW adt
1074respectively.
1075For example,
1076.P1
1077	x: int = 1;
1078.P2
1079and
1080.P1
1081	x := 1;
1082.P2
1083are the same.
1084Similarly,
1085.P1
1086	(p, q) := (1, 2.1);
1087.P2
1088declares the identifiers on the left as
1089.CW int
1090and
1091.CW real
1092and initializes them to 1 and 2.1 respectively.
1093Declarations with
1094.CW :=
1095can also be expressions, and are discussed again in §8.4.4 below.
1096.NH 2
1097Constant declarations
1098.PP
1099The
1100.CW con
1101declaration
1102.s1
1103	Iidentifier-listC : conI expressionC ;I
1104.s2
1105declares a name (or names) for constants.
1106The
1107.I expression
1108must be constant (see §8.5).
1109After the declaration,
1110each identifier in the list may be used anywhere a constant
1111of the appropriate type is needed;
1112the type is taken from the type of the constant.
1113For example, after
1114.P1
1115	Seven: con 3+4;
1116.P2
1117the name
1118.CW Seven
1119is exactly the same as the constant 7.
1120.PP
1121The identifier
1122.CW iota
1123has a special meaning in the expression in a
1124.CW con
1125declaration.
1126It is equivalent to the integer constant
1127.CW 0
1128when evaluating the expression for the first (leftmost) identifier declared,
1129.CW 1
1130for the second, and so on numerically.
1131For example, the declaration
1132.P1
1133	M0, M1, M2, M3, M4: con (1<<iota);
1134.P2
1135declares several constants
1136.CW M0
1137through
1138.CW M4
1139with the values 1, 2, 4, 8, 16 respectively.
1140.PP
1141The identifier
1142.CW iota
1143is not reserved except inside the expression
1144of the
1145.CW con
1146declaration.
1147.NH 2
1148adt declarations
1149.PP
1150An
1151.CW adt
1152or abstract data type contains data objects and functions that
1153operate on them.
1154The syntax is
1155.s1
1156adt-declaration:
1157	IidentifierC : adt { Iadt-member-listOC } ;I
1158
1159adt-member-list:
1160	adt-member
1161	adt-member-list adt-member
1162
1163adt-member:
1164	identifier-listC : cyclicO  Idata-typeC ;I
1165	identifier-listC : con IexpressionC ;I
1166	identifier-listC : Ifunction-typeC ;I
1167	Cpick { Ipick-member-listC }I
1168.s2
1169After an
1170.I adt-declaration ,
1171the identifier becomes the name of the type of that
1172.CW adt .
1173For example, after
1174.P1
1175	Point: adt {
1176		x, y: int;
1177		add: fn (p: Point, q: Point): Point;
1178		eq: fn (p: Point, q: Point): int;
1179	};
1180.P2
1181the name
1182.CW Point
1183is a type name for an
1184.CW adt
1185of two integers and two
1186functions; the fragment
1187.P1
1188	r, s: Point;
1189	xcoord: int;
1190	...
1191	xcoord = s.x;
1192	r = r.add(r, s);
1193.P2
1194makes sense.
1195The first assignment selects one of the data members of
1196.CW s ;
1197the second calls one of the function members of
1198.CW r .
1199.PP
1200As this example indicates,
1201.CW adt
1202members are accessed by mentioning an object with the
1203.CW adt
1204type, a dot, and then the name of the member;
1205the details will be discussed in §8.13 below.
1206A special syntactic indulgence is available for functions declared within an
1207.CW adt :
1208frequently such a function
1209receives as an argument the same object used to access it
1210(that is, the object before the dot).
1211In the example just above,
1212.CW r
1213was both the object being operated on and the first argument to the
1214.CW add
1215function.
1216If the first formal argument of a function declared in an
1217.CW adt
1218is marked with the
1219.CW self
1220keyword, then in any calls to the function, the
1221.CW adt
1222object is implicitly passed to the function, and
1223is not mentioned explicitly in the actual argument list
1224at the call site.
1225For example, in
1226.P1
1227	Rect: adt {
1228		min, max: Point;
1229		contains: fn(r: self Rect, p: Point): int;
1230	};
1231
1232	r1: Rect;
1233	p1: Point;
1234	...
1235	if (r1.contains(p1)) ...
1236.P2
1237because the first argument of the
1238.CW contains
1239function is declared with
1240.CW self ,
1241the subsequent call to it automatically passes
1242.CW r1
1243as its first argument. The
1244.CW contains
1245function itself is defined elsewhere with this first
1246argument explicit.
1247(This mechanism is analogous to the
1248.I this
1249construct in C++ and other languages,
1250but puts the special-casing at the declaration site and makes it explicit.)
1251.PP
1252If
1253.CW self
1254is specified in the declaration of a function, it must also be
1255specified in the definition as well.  For example,
1256.CW contains
1257would be defined
1258.P1
1259	Rect.contains(r: self Rect, p: Point)
1260	{
1261		. . .
1262	}
1263.P2
1264.PP
1265The
1266.CW adt
1267type in Limbo
1268does not provide control over the visibility
1269of its individual members; if any are accessible, all are.
1270.PP
1271Constant
1272.CW adt
1273members follow the same rules as ordinary constants (§6.2).
1274.PP
1275The obsolete
1276.CW cyclic
1277modifier will be discussed in §11.1.
1278.NH 3
1279pick adts
1280.PP
1281An
1282.CW adt
1283which contains a
1284.CW pick
1285member is known as a
1286.I pick
1287.I adt .
1288A
1289.CW pick
1290.CW adt
1291is Limbo's version of a
1292.I "discriminated union" .
1293An
1294.CW adt
1295can only contain one
1296.CW pick
1297member and it must be the last component of the
1298.CW adt .
1299Each
1300.I identifier
1301enumerated in the
1302.I pick-tag-list
1303names a variant type of the
1304.CW pick
1305.CW adt .
1306The syntax is
1307.s1
1308pick-member-list:
1309	pick-tag-listC =>I
1310	pick-member-list pick-tag-listC =>I
1311	pick-member-list identifier-listC : cyclicO  Idata-typeC ;I
1312.s2
1313.s1
1314pick-tag-list:
1315	identifier
1316	pick-tag-listC or Iidentifier
1317.s2
1318.PP
1319The
1320.I pick-member-list
1321contains a set of data members for each
1322.I pick-tag-list .
1323These data members are specific to those variants of the
1324.CW pick
1325.CW adt
1326enumerated in the
1327.I pick-tag-list .
1328The
1329.CW adt
1330data members found outside of the
1331.CW pick
1332are common to all variants of the
1333.CW adt  .
1334A
1335.CW pick
1336.CW adt
1337can only be used as a
1338.CW ref
1339.CW adt
1340and can only be initialized from a value of one of its variants.
1341For example, if
1342.CW Constant
1343is a
1344.CW pick
1345.CW adt
1346and
1347.CW Constant.Real
1348is one of its variant types then
1349.P1
1350	c : ref Constant = ref Constant.Real("pi", 3.1);
1351.P2
1352will declare
1353.CW c
1354to have type
1355.CW ref
1356.CW Constant
1357and initialize it with a value of the variant type
1358.CW ref
1359.CW Constant.Real .
1360.NH 2
1361Type declarations
1362.PP
1363The type declaration
1364.s1
1365	Iidentifier-listC : typeI data-type  ;I
1366.s2
1367introduces the identifiers as synonyms for the
1368given type.
1369Type declarations are transparent; that is,
1370an object declared with the newly-named
1371type has the same type as the one it abbreviates.
1372.NH 2
1373Module declarations
1374.PP
1375A module declaration collects and packages declarations of
1376.CW adt ,
1377functions, constants and simple types, and creates an
1378interface with a name
1379that serves to identify the type of the module.
1380The syntax is
1381.s1
1382module-declaration:
1383	IidentifierC : module { Imod-member-listOC } ;I
1384
1385mod-member-list:
1386	mod-member
1387	mod-member-list mod-member
1388
1389mod-member:
1390	identifier-listC : Ifunction-typeC ;I
1391	identifier-listC : Idata-typeC ;I
1392	adt-declarationC ;I
1393	identifier-listC : con Iexpression C;I
1394	identifier-listC : type Itype C;I
1395.s2
1396After a module declaration, the named
1397.I identifier
1398becomes the name of the type of that module.
1399For example, the declaration
1400.P1
1401Linear: module {
1402	setflags: fn (flag: int);
1403	TRUNCATE: con 1;
1404	Vector: adt {
1405		v: array of real;
1406		add: fn (v1: self Vector, v2: Vector): Vector;
1407		cross: fn (v1: self Vector, v2: Vector): Vector;
1408		dot: fn (v1: self Vector, v2: Vector);
1409		make: fn (a: array of real): Vector;
1410	};
1411	Matrix: adt {
1412		m: array of array of real;
1413		add: fn (m1: self Matrix, m2: Matrix): Matrix;
1414		mul: fn (m1: self Matrix, m2: Matrix): Matrix;
1415		make: fn (a: array of array of real): Matrix;
1416	};
1417};
1418.P2
1419is a module declaration for a linear algebra package that
1420implements two
1421.CW adt ,
1422namely
1423.CW Vector
1424and
1425.CW Matrix ,
1426a constant,
1427and a function
1428.CW setflags .
1429The name
1430.CW Linear
1431is the type name for the module, and it may be used to declare
1432an object referring to an instance of the module:
1433.P1
1434	linearmodule:  Linear;
1435.P2
1436Before the module can be used, it must be loaded, for example in
1437the style:
1438.P1
1439	linearmodule = load Linear "/usr/dmr/limbo/linear.dis";
1440	if (linearmodule == nil) {
1441		sys->print("Can't load Linear\en");
1442		exit;
1443	}
1444.P2
1445The
1446.CW load
1447operator is discussed more fully in §8.4.5 below.
1448.PP
1449To initialize data declared as part of a module
1450declaration, an assignment expression may be used at the top level.
1451For example:
1452.P1
1453	implement testmod;
1454	testmod: module {
1455		num:	int;
1456	};
1457	. . .
1458	num = 5;
1459.P2
1460The right side of the assignment must be a constant expression (§8.5).
1461.NH 2
1462Declarations with
1463.CW import
1464.PP
1465These declarations take the form
1466.s1
1467	Iidentifier-listC : import Iidentifier C;I
1468.s2
1469Identifiers for entities
1470declared within a module declaration are normally
1471meaningful only in a context that
1472identifies the module.
1473The
1474.CW import
1475declaration lifts the names of specified members of a module
1476directly into the current scope.
1477The use of
1478.CW import
1479will be discussed more fully in §8.1.4 below, after the syntax
1480for expressions involving modules has been presented.
1481.NH 2
1482Exception declarations
1483.PP
1484Exceptions represent run-time errors not data objects or values.
1485Exception declarations have the form:
1486.s1
1487	identifier-listC : exceptionI tuple-typeO
1488.s2
1489Each identifier gives a compile-time name to a distinct user-defined run-time error,
1490signaled at run-time by a
1491.CW raise
1492statement that quotes that identifier, as described below.
1493An exception optionally includes a tuple of data values that qualifies the exception;
1494the types of those values are provided by the tuple type in this declaration.
1495.NH 2
1496Declarations with
1497.CW include
1498.PP
1499The string following the
1500.CW include
1501keyword names
1502a file, which is inserted into the program's
1503text at that point.
1504The included
1505text is treated like text literally present.
1506Conventionally, included files declare
1507module interfaces and are named with the suffix
1508.CW .m .
1509The directories to be searched for included files
1510may be specified to the Limbo compiler command.
1511Include files may be nested.
1512.NH 1
1513Function definitions
1514.PP
1515All executable code
1516is supplied as part of a function definition.
1517The syntax is
1518.s1
1519function-definition:
1520	function-name-part function-arg-retC { IstatementsC }I
1521
1522function-name-part:
1523	identifier
1524	function-name-partC . Iidentifier
1525.s2
1526The syntax of the statements in a function will be discussed in §9 below.
1527As a brief example,
1528.P1
1529	add_one(a: int): int
1530	{
1531		return a+1;
1532	}
1533.P2
1534is a simple function
1535that might be part of the top level of a module.
1536.PP
1537Functions that are declared within an
1538.CW adt
1539use the qualified form of definition:
1540.P1
1541	Point: adt {
1542		x, y: int;
1543		add: fn (p: Point, q: Point): Point;
1544		eq: fn (p: Point, q: Point): int;
1545	}
1546	. . .
1547	Point.add(p: Point, q: Point): Point
1548	{
1549		return Point(p.x+q.x, p.y+q.y);
1550	}
1551.P2
1552Because an
1553.CW adt
1554may contain an
1555.CW adt ,
1556more than one qualification is possible.
1557.NH 1
1558Expressions
1559.PP
1560Expressions in Limbo resemble those of C, although some
1561of the operators are different.
1562The most salient difference between Limbo's expression
1563semantics and those of C is that Limbo
1564has no automatic coercions between types; in Limbo every
1565type conversion is explicit.
1566.NH 2
1567Terms
1568.PP
1569The basic elements of expressions are terms:
1570.s1
1571term:
1572	identifier
1573	constant
1574	real-constant
1575	string-constant
1576	CnilI
1577	C( Iexpression-listC )I
1578	termC . Iidentifier
1579	termC -> Iterm
1580	termC ( Iexpression-listOC )I
1581	termC [ IexpressionC ]I
1582	termC [ IexpressionC : IexpressionC ]I
1583	termC [ IexpressionC : ]I
1584	termC ++I
1585	termC --I
1586.s2
1587The operators on terms all associate to the left,
1588and their order of precedence, with tightest listed first, is as follows:
1589.P1
1590			.
1591			->
1592			() [] ++ --
1593.P2
1594.NH 3
1595Simple terms
1596.PP
1597The first five kinds of term are constants and identifiers.
1598Constants have a type indicated by their syntax.
1599An identifier used in an expression is often a previously declared
1600data object with a particular data type; when used as a term
1601in an expression
1602it denotes the value stored in the object, and the term has
1603the declared object's type.
1604Sometimes, as discussed below, identifiers used in expressions
1605are type names, function names, or module identifiers.
1606.NH 3
1607Parenthesized terms
1608.PP
1609A comma-separated list of expressions enclosed in parentheses
1610is a term.
1611If a single expression is present in the list,
1612the type and value are those of the expression;
1613the parentheses affect only the binding
1614of operators in the expression of which the term
1615is a part.
1616If there is more than one expression in the list,
1617the value is a tuple.
1618The member types
1619and values are taken from those of the expressions.
1620.NH 3
1621Selection
1622.PP
1623A term of the form
1624.s1
1625	termC . Iidentifier
1626.s2
1627denotes selection of a member of an
1628.CW adt
1629or one element from a tuple.
1630.PP
1631In the first case,
1632the term must be a
1633type name or yield an object;
1634its type must be
1635.CW adt
1636or
1637.CW ref
1638.CW adt ;
1639the identifier must be a member of the
1640.CW adt .
1641The result denotes the named member (either a data object
1642or a function).
1643.PP
1644In the second case,
1645the term must yield a value of a tuple type,
1646and the identifier must have the form \f(CWt\fP\fIn\fP
1647where
1648.I n
1649is a decimal number giving the index (starting from 0) of an element of the tuple.
1650The result is the value of that element.
1651.NH 3
1652Module qualification
1653.PP
1654A term of the form
1655.s1
1656	termC -> Iterm
1657.s2
1658denotes module qualification.
1659The first term identifies a module: either it is a module type name,
1660or it is an expression of module type.
1661The second term is a constant name, type, or function specified within
1662that module's declaration.
1663Either the module type name or
1664an object of the module's type suffices to qualify constants and types;
1665functions directly exported by the module or contained within its
1666.CW adt
1667must be qualified by an object of the module's type, initialized with
1668.CW load .
1669.PP
1670An example using an abridged version of an example above: given
1671.P1
1672	Linear: module {
1673		setflags: fn(flag: int);
1674		TRUNCATE: con 1;
1675		Vector: adt {
1676			make: fn(v: array of real): Vector;
1677			v: array of real;
1678		};
1679	};
1680.P2
1681one might say
1682.P1
1683	lin := load Linear "/dis/linear.dis";
1684	a: array of real;
1685
1686	v1: lin->Vector;
1687	v2: Linear->Vector;
1688	lin->setflags(Linear->TRUNCATE);
1689	v1 = lin->(Linear->Vector).make(a);
1690	v1 = lin->v1.make(a);
1691	v1 = lin->v1.add(v1);
1692	v1.v = nil;
1693.P2
1694Here, the declarations for
1695.CW v1
1696and
1697.CW v2
1698are equivalent; either a module type name (here,
1699.CW Linear )
1700or a handle (here,
1701.CW lin )
1702suffices to identify the module.
1703In the call to
1704.CW setflags ,
1705a handle
1706is required for the call itself;
1707the type name is sufficient for the constant.
1708.PP
1709When calling a function associated with an
1710.CW adt
1711of another module, it is necessary to identify
1712both the module and the
1713.CW adt
1714as well as the function.
1715The two calls to the
1716.CW make
1717function illustrate two ways of doing this.
1718In the first,
1719.P1
1720	v1 = lin->(Linear->Vector).make(a);
1721.P2
1722the module handle
1723.CW lin
1724is specified first, then
1725the type name of the
1726.CW Vector
1727.CW adt
1728within it, and then the function.
1729In the second call
1730.P1
1731	v1 = lin->v1.make(a);
1732.P2
1733instead of using a type name to specify the
1734.CW adt ,
1735an instance of an object of the appropriate type is
1736used instead.
1737In the first example, the parentheses are required because
1738the qualification operators associate to the left.
1739.P1
1740	v1 = lin->Vector.make(a);	# Wrong
1741	v1 = lin->Linear->Vector.make(a);	# Wrong
1742.P2
1743The first is wrong because the same
1744.CW lin
1745can't serve as a qualifier for both the type and the call;
1746the second is wrong because
1747.CW lin->Linear
1748is meaningless.
1749.PP
1750Using
1751.CW import
1752makes the code less verbose:
1753.P1
1754	lin := load Linear "/usr/dmr/limbo/linear.dis";
1755	Vector, TRUNCATE, setflags: import lin;
1756	a: array of real;
1757
1758	v1: Vector;
1759	v2: Vector;
1760	setflags(TRUNCATE);
1761	v1 = Vector.make(a);
1762	v1 = v1.make(a);
1763	v1 = v1.add(v1);
1764	v1.v = nil;
1765.P2
1766.NH 3
1767Function calls
1768.PP
1769The interpretation of an expression in the form
1770.s1
1771	termC ( Iexpression-listOC )
1772.s2
1773depends on the declaration of the term.
1774If it is the (perhaps qualified) name of an
1775.CW adt ,
1776then the expression is a cast; this is discussed in §8.2.11 below.
1777If the term is either the (perhaps qualified) name of a function
1778or a value of a function reference type, and
1779the expression means a function call; this is discussed here.
1780.PP
1781A plain identifier as the
1782.I term
1783can name a function defined
1784in the current module or imported into it.
1785A term qualified by using the selection operator
1786.CW .
1787specifies a function member of an
1788.CW adt ;
1789a term using
1790.CW ->
1791specifies a function defined in another module.
1792.PP
1793The
1794.I term ,
1795including a plain identifier denoting a variable of function reference type,
1796can also yield a function reference value.
1797The value specifies both a function and its module,
1798established when the value was created,
1799and cannot be qualified by the
1800.B ->
1801specifier.
1802.PP
1803Function calls in Limbo
1804create a copy of each argument of value type,
1805and the execution of a function cannot
1806affect the value of the corresponding actual argument.
1807For arguments of reference type,
1808execution of the function may affect the value of the object
1809to which the reference refers, although it cannot
1810change the argument itself.
1811The actual arguments to a function are evaluated
1812in an unspecified order,
1813although any side effects caused by argument evaluation
1814occur before the function is called.
1815.PP
1816Function calls may be directly or indirectly recursive;
1817objects declared within each function are distinct from
1818those in their dynamic predecessors.
1819.PP
1820Functions (§4.3, §7) may either return a value
1821of a specified type, or return no value.
1822If a function returns a value, it has the specified type.
1823A call to a function that returns no value may appear only as the
1824sole expression in a statement (§9.1).
1825.PP
1826A function name is converted to a reference to that function when it appears
1827in a context requiring a function reference type, including assignment to a variable,
1828as an actual parameter, or the return value of a function.
1829The resulting reference value includes the appropriate module value for the function name,
1830following the rules given above for implicit and explicit qualifiers, and imports.
1831For example, the following program fragment defines a table of commands:
1832.P1
1833	Cmd: adt {
1834		c:	int;
1835		f:	ref fn(a: array of string): int;
1836	};
1837
1838	mkcmds(): array of Cmd
1839	{
1840		return array[] of {
1841			('.', editdot),
1842			('a', editadd),
1843			('d', editdel),
1844			('?', edithelp),
1845			('w', editwrite),
1846			('q', editquit),
1847		};
1848	}
1849
1850	editdot(a: array of string): int
1851	{
1852		...
1853	}
1854	\&...
1855	editquit(a: array of string): int
1856	{
1857		...
1858	}
1859.P2
1860which might be used as follows:
1861.P1
1862	cmd := mkcmds();
1863	...
1864	for(i := 0; i < len cmd; i++)
1865		if(cmd[i].c == c){
1866			cmd[i].f(args);
1867			return;
1868		}
1869	error("unknown command");
1870.P2
1871.NH 3
1872Subscripting and slicing
1873.PP
1874In a term of the form
1875.s1
1876	termC [ IexpressionC ]I
1877.s2
1878the first term must be an array or a string, and the
1879bracketed expression must have
1880.CW int
1881type.
1882The whole term
1883designates a member of the array or string, indexed by the bracketed expression;
1884the index origin is 0.
1885For an array, the type of the whole term is
1886the type from which the array is constructed;
1887for a string, the type is an
1888.CW int
1889whose value is the Unicode character at that position in the string.
1890.PP
1891It is erroneous to refer to a nonexisting
1892part of an array or string.
1893(A single exception to this rule, discussed in §8.4.1 below,
1894allows extending a string by assigning a character at its end.)
1895.PP
1896In a term of the form
1897.s1
1898	termC [ IexpressionC : IexpressionC ]I
1899.s2
1900the first term must be an array or a string, and the whole term
1901denotes a slice of it.
1902The first expression is the lower bound, and the second
1903is the upper.
1904If
1905.CW e1
1906is the first expression and
1907.CW e2
1908is the second, then in
1909.CW a[e1:e2]
1910it must be the case that
1911.CW "0<=e1, e1<=e2, e2<=len a" ,
1912where
1913.CW len
1914gives the number of elements in the array or string.
1915When the term is an array, the value is an
1916array of the same type beginning at the indicated
1917lower bound and extending to the element just before
1918the upper bound.
1919When the term is a string, the value is similarly the substring
1920whose first character is indexed by the lower bound
1921and whose last character lies just before the upper bound.
1922.PP
1923Thus, for both arrays and strings, the number of elements in
1924.CW "a[e1:e2]
1925is equal to
1926.CW e2-e1 .
1927.PP
1928A slice of the form
1929.CW a[e:]
1930means
1931.CW "a[e:len a].
1932.PP
1933When a string slice is assigned to another string or passed as an
1934argument, a copy of its value is made.
1935.PP
1936A slice of an array produces a reference to the designated subarray;
1937a change to an element of either the original array or
1938the slice is reflected in the other.
1939.PP
1940In general, slice expressions cannot be the subject of
1941assignments.
1942However, as a special case, an array slice expression of the
1943form
1944.CW a[e1:]
1945may be assigned to.
1946This is discussed in §8.4.1.
1947.PP
1948The following example shows how slices
1949can be used to accomplish what would
1950need to be done with pointer arithmetic in C:
1951.P1
1952	fd := sys->open( ... );
1953	want := 1024;
1954	buf := array[want] of byte;
1955	b := buf[0:];
1956	while (want>0) {
1957		got := sys->read(fd, b, want);
1958		if (got<=0)
1959			break;
1960		b = b[got:];
1961		want -= got;
1962	}
1963.P2
1964Here the array
1965.CW buf
1966is filled by successive calls to
1967.CW sys->read
1968that may supply fewer bytes than requested; each call
1969stores up to
1970.CW want
1971bytes
1972starting at
1973.CW b[0] ,
1974and returns the number of bytes stored.
1975The invariant is that the slice
1976.CW b
1977always refers to the part of the array still to be stored into.
1978.NH 3
1979Postfix increment and decrement
1980.PP
1981A term of the form
1982.s1
1983	termC ++I
1984.s2
1985is called a
1986.I post-increment .
1987The term must be an lvalue (see §8.4 below) and must have an
1988arithmetic type.
1989The type and value of the whole term is
1990that of the incremented term.
1991After the value is taken, 1 of the appropriate
1992type is added to the lvalue.
1993The result is undefined if the same object is changed
1994more than once in the same expression.
1995.PP
1996The term
1997.s1
1998	termC --I
1999.s2
2000behaves analogously to the increment case except
2001that 1 is subtracted from the lvalue.
2002.PP
2003.NH 2
2004Monadic expressions
2005.PP
2006Monadic expressions are expressions with
2007monadic operators, together with a few more
2008specialized notations:
2009.s1
2010monadic-expression:
2011	term
2012	monadic-operator monadic-expression
2013	Carray [ IexpressionC ] of Idata-type
2014	Carray [ IexpressionOC ] of { Iinit-listC }I
2015	Clist of { Iexpression-listC }I
2016	Cchan of Idata-type
2017	Cchan [ IexpressionC ] of Idata-type
2018	data-type monadic-expression
2019
2020monadic-operator: one of
2021	C+ - ! ~ ref * ++ -- <- hd tl lenI
2022.s2
2023.NH 3
2024Monadic additive operators
2025.PP
2026The
2027.CW -
2028operator produces the negative of its operand, which
2029must have an arithmetic type.
2030The type of the result is the same as the type of
2031its operand.
2032.PP
2033The
2034.CW +
2035operator has no effect; it is supplied only for
2036symmetry.
2037However, its argument must have an arithmetic type
2038and the type of the result is the same.
2039.NH 3
2040Logical negation
2041.PP
2042The
2043.CW !
2044operator yields the
2045.CW int
2046value 1 if its operand
2047has the value 0, and yields 0 otherwise.
2048The operand must have type
2049.CW int .
2050.NH 3
2051One's complement
2052.PP
2053The
2054.CW ~
2055operator yields the 1's complement of its
2056operand, which must have type
2057.CW int
2058or
2059.CW byte .
2060The type of the result is the same as that of its operand.
2061.NH 3
2062Reference and indirection operators
2063.PP
2064If
2065.I e
2066is an expression of an
2067.CW adt
2068type, then
2069.CW ref
2070.I e
2071is an expression of
2072.CW ref
2073.CW adt
2074type whose value refers to (points to) an anonymous object with value
2075.I e .
2076The
2077.CW ref
2078operator differs from the unary
2079.CW &
2080operator of C; it makes a new object and returns a reference
2081to it, rather than generating a reference to an existing object.
2082.PP
2083If
2084.I e
2085is an expression of type
2086.CW ref
2087.CW adt ,
2088then
2089.CW *
2090.I e
2091is the value
2092of the
2093.CW adt
2094itself.
2095The value of
2096.I e
2097must not be
2098.CW nil .
2099.PP
2100For example, in
2101.P1
2102	Point: adt { ... };
2103	p: Point;
2104	pp: ref Point;
2105	p = Point(1, 2);
2106	pp = ref p;	# pp is a new Point; *pp has value (1, 2)
2107	p = Point(3, 4);	# This makes *pp differ from p
2108	*pp = Point(4, 5);	# This does not affect p
2109.P2
2110the expression
2111.CW *pp
2112at first refers to a copy of the value stored in
2113.CW p ,
2114so
2115.CW "*pp == p
2116is true; however, when
2117.CW p
2118is changed later,
2119.CW *pp
2120does not change.
2121.NH 3
2122Prefix increment and decrement
2123.PP
2124A monadic expression of the form
2125.s1
2126	C++ Imonadic-expression
2127.s2
2128is called a
2129.I pre-increment .
2130The monadic expression must be an lvalue (see §8.4 below) and must have an
2131arithmetic type.
2132Before the value is taken, 1 of the appropriate type
2133is added to the lvalue.
2134The type and value of the whole expression is
2135that of the now incremented term.
2136The result is undefined if the same object is changed
2137more than once in the same expression.
2138.PP
2139The term
2140.s1
2141	C-- Imonadic-expression
2142.s2
2143behaves analogously to the increment case except
2144that 1 is subtracted from the lvalue.
2145.NH 3
2146Head and tail
2147.PP
2148The operand of the
2149.CW hd
2150operator must be a non-empty list.
2151The value is the first member of the list
2152and has that member's type.
2153.PP
2154The operand of the
2155.CW tl
2156operator must be a non-empty list.
2157The value is the tail of the list,
2158that is, the part of the list after its
2159first member.
2160The tail of a list with one member is
2161.CW nil .
2162.NH 3
2163Length
2164.PP
2165The operand of the
2166.CW len
2167operator is a string, an array, or a list.
2168The value is an
2169.CW int
2170giving the number of elements currently in the item.
2171.NH 3
2172Tagof
2173.PP
2174The operand of the
2175.CW tagof
2176operator is a monadic expression of type
2177.CW ref
2178.CW adt
2179that refers to a
2180.CW pick
2181.CW adt .
2182or the type name of a
2183.CW pick
2184.CW adt
2185or one of its variants.
2186The value is an
2187.CW int
2188giving a unique value for each of the variants and for the
2189.CW pick
2190.CW adt
2191type itself.
2192.NH 3
2193Channel communication
2194.PP
2195The operand of the communication operator
2196.CW <-
2197has type
2198.CW chan
2199.CW  of
2200.I sometype .
2201The value of the expression
2202is the first unread object previously sent over that
2203channel, and has the type associated with the channel.
2204If the channel is empty, the program delays
2205until something is sent.
2206.PP
2207As a special case, the operand of
2208.CW <-
2209may have type
2210.CW array
2211.CW of
2212.CW chan
2213.CW of
2214.I sometype .
2215In this case, all of the channels in the array are tested;
2216one is fairly selected from those that have data.
2217The expression yields a tuple of type
2218.CW (int,
2219.I sometype
2220.CW ) ;
2221its first member gives the index of the channel from
2222which data was read, and its second member is the
2223value read from the channel.
2224If no member of the array has data ready, the expression delays.
2225.PP
2226Communication channels are treated more fully in §9.8 and
2227§9.13 below with the discussion of the
2228.CW alt
2229and
2230.CW spawn
2231statements.
2232.NH 3
2233Creation of arrays
2234.PP
2235In the expressions
2236.s1
2237	Carray [ IexpressionC ] of Idata-type
2238	Carray [ IexpressionOC ] of { Iinit-listC ,OC }I
2239.s2
2240the value is a new array of the specified type.
2241In both forms, the
2242.I expression
2243must be of type
2244.CW int ,
2245and it supplies the size of the array.
2246In the first form, the type is given,
2247and the values in the array are initialized as
2248appropriate to the underlying type.
2249In the second form, a comma-separated list of values to initialize
2250the array is given, optionally followed by a trailing comma.
2251The type of the array is taken from the types of
2252the initializers, which must all be the same.
2253The list of initializers has the syntax
2254.s1
2255init-list:
2256	element
2257	init-listC , Ielement
2258
2259element:
2260	expression
2261	expressionC => Iexpression
2262	C* => Iexpression
2263.s2
2264In an
2265.I init-list
2266of plain expressions (without
2267.CW => ),
2268the members of the array
2269are successively initialized with the corresponding
2270elements of the init-list.
2271An element of the form
2272.CW e1=>e2
2273initializes the member of the array at subscript
2274.CW e1
2275with the expression
2276.CW e2 .
2277After such an element has been given, subsequent
2278simple elements (without
2279.CW => )
2280begin initializing at position
2281.CW e1+1
2282and so on.
2283Each of the first expressions must be of type
2284.CW int
2285and must evaluate to a constant (§8.5).
2286.PP
2287If an element of the form
2288.CW *
2289.CW =>e2
2290is present, all members of the array not otherwise
2291initialized are set to the value
2292.CW e2 .
2293The expression
2294.CW e2
2295is evaluated for each subscript position,
2296but in an undefined order.
2297For example,
2298.P1
2299	arr := array[3] of { * => array[3] of { * => 1 } };
2300.P2
2301yields a 2-dimensional array (actually an array of arrays) filled with
2302.CW 1 's.
2303.PP
2304If the expression giving the size of the array is omitted, its size
2305is taken from the largest subscript of
2306a member explicitly initialized.
2307It is erroneous to initialize a member twice.
2308.NH 3
2309Creation of lists
2310.PP
2311The value of an expression
2312.s1
2313	Clist of { Iexpression-listC }I
2314.s2
2315is a list consisting of the expressions given.
2316The types of the expressions must be identical,
2317and this type is the underlying type of the list.
2318The first expression is the head of the list, and the
2319remaining expressions are a list constituting its tail.
2320Where a list is expected,
2321.CW nil
2322specifies an empty list.
2323.NH 3
2324Creation of channels
2325.PP
2326The value of
2327.s1
2328	Cchan of Idata-type
2329.s2
2330is an initialized channel of the specified type.
2331Just a declaration of a channel leaves it initialized only to
2332.CW nil ;
2333before it can be used it must be created.  For example,
2334.P1
2335	ch: chan of int;		# just declares, sets ch to nil
2336	. . .
2337	ch = chan of int;	# creates the channel and assigns it
2338.P2
2339Such a channel is unbuffered.
2340The value of
2341.s1
2342	Cchan [ IexpressionC ] of Idata-type
2343.s2
2344is an initialized channel of the specified type.
2345The
2346.I expression
2347must be of type
2348.CW int ,
2349and sets the size of the channel's buffer.
2350If the size is zero, the channel is unbuffered, as for the first form.
2351.NH 3
2352Casts
2353.PP
2354An expression of the form
2355.s1
2356	data-type monadic-expression
2357.s2
2358in which a type name is followed by an expression
2359is called a
2360.I cast ,
2361and converts the monadic expression to the named type.
2362Only certain specialized forms are provided for.
2363.NH 4
2364Arithmetic casts
2365.PP
2366In arithmetic casts, the named type must be one of
2367.CW byte ,
2368.CW int ,
2369.CW big ,
2370or
2371.CW real ,
2372and the monadic-expression must have arithmetic type.
2373For example,
2374.P1
2375	byte 10
2376.P2
2377is an expression of
2378.CW byte
2379type and value 10.
2380When real values are converted to integral ones,
2381they are rounded to the nearest integer, and away from 0
2382if there is a tie.
2383The effect of overflow during conversion is undefined.
2384.NH 4
2385Casts to strings
2386.PP
2387Here the named data type is
2388.CW string .
2389In a first form, the monadic expression has arithmetic type
2390.CW byte , (
2391.CW int ,
2392.CW big ,
2393or
2394.CW real )
2395and the value is a string containing the decimal representation
2396of the value, which may be either positive or negative.
2397A
2398.CW real
2399operand is converted as if by format
2400.CW %g ,
2401and if the result is converted back to
2402.CW real ,
2403the original value will be recovered exactly.
2404.PP
2405In a second form,
2406the monadic expression has type
2407.CW array
2408.CW of
2409.CW byte .
2410The value is a new string containing the Unicode characters
2411obtained by interpreting the bytes in the array as a UTF-8 representation
2412of that string.
2413(UTF-8 is a representation of 16-bit Unicode characters as one,
2414two, or three bytes.)
2415The result of the conversion is undefined if the byte array
2416ends within a multi-byte UTF-8 sequence.
2417.NH 4
2418Casts from strings
2419.PP
2420In a first form, the monadic expression is a string,
2421and the named type is an arithmetic type.
2422The value is obtained by converting the string to
2423that type.  Initial white space is ignored; after a possible
2424sign, conversion
2425ceases at the first character not part of a number.
2426.PP
2427In a second form, the named type is
2428.CW array
2429.CW of
2430.CW byte
2431and the monadic-expression is a string.
2432The value is a new array of bytes containing the UTF-8 representation
2433of the Unicode characters in the string.
2434For example,
2435.P1
2436	s := "Ångström";
2437	a := array of byte s;
2438	s = string a;
2439.P2
2440takes the string
2441.CW s
2442apart into bytes in the second line,
2443and puts it back in the third.
2444The length of
2445.CW s
2446is 8, because it contains that many characters;
2447the length of
2448.CW a
2449is larger, because some of its characters require more than
2450one byte in the UTF-8 representation.
2451.NH 4
2452Casts to
2453.CW adt
2454and
2455.CW ref
2456.CW adt
2457.PP
2458Here the named type is that of an
2459.CW adt
2460or
2461.CW ref
2462.CW adt ,
2463and the monadic expression is a comma-separated list of expressions
2464within parentheses.
2465The value of the expression is an instance of an
2466.CW adt
2467of the named type whose data members are initialized with
2468the members of the list, or whose single data member
2469is initialized with the parenthesized expression.
2470In case the type is
2471.CW ref
2472.CW adt ,
2473the value is a reference to the new
2474instance of the
2475.CW adt .
2476.PP
2477The expressions in the list, read in order, correspond with the data
2478members of the
2479.CW adt
2480read in order; their types and number must agree.
2481Placement of any function members of the
2482.CW adt
2483is ignored.
2484For example,
2485.P1
2486	Point: adt {
2487		x: int;
2488		eq: fn (p: Point): int;
2489		y: int;
2490	};
2491	. . .
2492	p: Point;
2493	p = Point(1, 2);
2494.P2
2495puts in
2496.CW p
2497a
2498.CW Point
2499whose
2500.CW x
2501value is 1 and whose
2502.CW y
2503value is 2.
2504The declaration and assignment could also be written
2505.P1
2506	p := Point(1, 2);
2507.P2
2508.NH 2
2509Binary expressions
2510.PP
2511Binary expressions are either monadic expressions,
2512or have two operands and an infix operator;
2513the syntax is
2514.s1
2515binary-expression:
2516	monadic-expression
2517	binary-expression binary-operator binary-expression
2518
2519binary-operator: one of
2520	C** * / % + - << >> < > <= >= == != & ^ | :: && ||I
2521.s2
2522All these binary operators are left-associative except for
2523.CW **
2524and
2525.CW :: ,
2526which associate to the right.
2527Their precedence is as listed here, with tightest first:
2528.P1
2529			**
2530			* / %
2531			+ -
2532			<< >>
2533			< > <= >=
2534			== !=
2535			&
2536			^
2537			|
2538			::
2539			&&
2540			||
2541.P2
2542.NH 3
2543Exponentiation
2544.PP
2545The
2546.CW **
2547operator accomplishes exponentiation.
2548The type of the left operand must be
2549.CW int ,
2550.CW big
2551or
2552.CW real .
2553The type of the right operand must be
2554.CW int .
2555The result has the type of the left operand.
2556The operator is right associative, thus
2557.P1
2558	3**4*2 = (3**4)*2 = 81*2 = 162
2559	-3**4 = (-3)**4 = 81
2560	2**3**2 = 2**(3**2) = 2**9 = 512
2561.P2
2562.NH 3
2563Multiplicative operators
2564.PP
2565The
2566.CW * ,
2567.CW / ,
2568and
2569.CW %
2570operators respectively accomplish multiplication, division, and remainder.
2571The operands must be of identical arithmetic type, and the result has that
2572same type.
2573The remainder operator does not apply to type
2574.CW real .
2575If overflow or division by 0 occurs, the result is undefined.
2576The absolute value of
2577.CW a%b
2578is less than the absolute value of
2579.CW b ;
2580.CW "(a/b)*b + a%b
2581is always equal to
2582.CW a ;
2583and
2584.CW a%b
2585is non-negative if
2586.CW a
2587and
2588.CW b
2589are.
2590.NH 3
2591Additive operators
2592.PP
2593The
2594.CW +
2595and
2596.CW -
2597operators respectively accomplish addition and subtraction
2598of arithmetic operands of identical type;
2599the result has the same type.
2600The behavior on overflow or underflow is undefined.
2601The
2602.CW +
2603operator may also be applied to strings;
2604the result is a string that is the concatenation of the operands.
2605.NH 3
2606Shift operators
2607.PP
2608The shift operators are
2609.CW <<
2610and
2611.CW >> .
2612The left operand may be
2613.CW big ,
2614.CW int ,
2615or
2616.CW byte ;
2617the right operand is
2618.CW int .
2619The type of the value is the same as its left operand.
2620The value of the right operand must be non-negative
2621and smaller than the number of bits in the left operand.
2622For the left-shift operator
2623.CW << ,
2624the fill bits are 0;
2625for the right-shift operator
2626.CW >> ,
2627the fill bits are a copy of the sign for the
2628.CW int
2629case, and 0 for the
2630.CW byte
2631case.
2632.NH 3
2633Relational operators
2634.PP
2635The relational operators are
2636.CW <
2637(less than),
2638.CW >
2639(greater than),
2640.CW <=
2641(less than or equal),
2642.CW >=
2643(greater than or equal),
2644.CW ==
2645(equal to),
2646.CW !=
2647(not equal to).
2648The first four operators, which generate orderings,
2649apply only to arithmetic types
2650and to strings; the types of their operands
2651must be identical, except that a string may be
2652compared to
2653.CW nil .
2654Comparison on strings is lexicographic over the
2655Unicode character set.
2656.PP
2657The equality operators
2658.CW ==
2659and
2660.CW !=
2661accept operands of arithmetic, string, and reference types.
2662In general, the operands must have identical type,
2663but reference types and strings may be compared for identity with
2664.CW nil .
2665Equality for reference types occurs when the operands
2666refer to the same object, or when both are
2667.CW nil .
2668An uninitialized string, or one set to
2669.CW nil ,
2670is identical to the empty string denoted
2671.CW \&""
2672for all the relational operators.
2673.PP
2674The value of any comparison is the
2675.CW int
2676value 1 if the stated
2677relation is true, 0 if it is false.
2678.NH 3
2679Bitwise logical operators
2680.PP
2681The logical operators
2682.CW &
2683(and),
2684.CW ^
2685(exclusive or) and
2686.CW |
2687(inclusive or)
2688require operands of the same type,
2689which must be
2690.CW byte ,
2691.CW int ,
2692or
2693.CW big .
2694The result has the same type and its
2695value is obtained by applying the operation
2696bitwise.
2697.NH 3
2698List concatenation
2699.PP
2700The concatenation operator
2701.CW ::
2702takes a object of any data type
2703as its left operand and a list as its right operand.
2704The list's underlying type must be the same as
2705the type of the left operand.
2706The result is a new list with the left operand
2707tacked onto the front:
2708.P1
2709	hd (a :: l)
2710.P2
2711is the same as
2712.CW a .
2713.NH 3
2714Logical operators
2715.PP
2716The logical
2717.I and
2718operator
2719.CW &&
2720first evaluates its left operand.
2721If the result is zero, then the value of the
2722whole expression is the
2723.CW int
2724value 0.
2725Otherwise the right operand is evaluated; if
2726the result is zero, the value of the whole
2727expression is again 0; otherwise it is 1.
2728The operands must have the same arithmetic type.
2729.PP
2730The logical
2731.I or
2732operator
2733.CW ||
2734first evaluates its left operand.
2735If the result is non-zero, then the value of the
2736whole expression is the
2737.CW int
2738value 1.
2739Otherwise the right operand is evaluated; if
2740the result is non-zero, the value of the whole
2741expression is again 1; otherwise it is 0.
2742The operands must have the same arithmetic type.
2743.NH 2
2744General Expressions
2745.PP
2746The remaining syntax for expressions is
2747.s1
2748expression:
2749	binary-expression
2750	lvalue-expression assignment-operator expression
2751	C( Ilvalue-expression-listC ) = Iexpression
2752	send-expression
2753	declare-expression
2754	load-expression
2755
2756assignment-operator: one of
2757	C= &= |= ^= <<= >>= += -= *= /= %=I
2758.s2
2759The left operand of an assignment can take only certain forms, called lvalues.
2760.s1
2761lvalue-expression:
2762	identifier
2763	CnilI
2764	termC [ IexpressionC ]I
2765	termC [ IexpressionC : ]I
2766	termC . Iidentifier
2767	C( Ilvalue-expression-listC )I
2768	C* Imonadic-expression
2769
2770lvalue-expression-list:
2771	lvalue
2772	lvalue-expression-listC , Ilvalue
2773.s2
2774.NH 3
2775Simple assignments with
2776.CW =
2777.PP
2778In general, the types of the left and right operands
2779must be the same; this type must be a data type.
2780The value of an assignment is its new left operand.
2781All the assignment operators associate right-to-left.
2782.PP
2783In the ordinary assignment with
2784.CW = ,
2785the value of the right side is assigned to the object
2786on the left.
2787For simple assignment only, the left operand may be a
2788parenthesized list of lvalues and the right operand
2789either a tuple or an
2790.CW adt
2791whose data members correspond
2792in number and type to the lvalues in the list.
2793The members of the tuple, or
2794the data members of the
2795.CW adt ,
2796are assigned in sequence to
2797lvalues in the list.
2798For example,
2799.P1
2800	p: Point;
2801	x, y: int;
2802	(x, y) = p;
2803.P2
2804splits out the coordinates of the point into
2805.CW x
2806and
2807.CW y .
2808These rules apply recursively, so that if one of the
2809components of the left side is a parenthesized list of lvalues,
2810it is assigned from a corresponding
2811.CW adt
2812or tuple on the right.
2813.PP
2814If the left operand of a simple assignment is an
2815.CW adt
2816and the right side is a tuple, then the assignment
2817assigns the members of the tuple to the
2818.CW adt
2819data members; these must correspond in number and type
2820with the members of the tuple.
2821.PP
2822The constant
2823.CW nil
2824may be assigned to an lvalue of any reference type.
2825This lvalue will compare equal to
2826.CW nil
2827until it is subsequently reassigned.
2828Such an assignment also
2829triggers the removal of the object referred to unless other references
2830to it remain.
2831.PP
2832The left operand of an assignment may be the constant
2833.CW nil
2834to indicate that a value is discarded.
2835This applies in particular to any of the lvalues in
2836a tuple appearing on the left; to extend the examples above,
2837.P1
2838	(x, nil) = p;
2839.P2
2840assigns the
2841.CW x
2842member of the Point
2843.CW p
2844to the variable
2845.CW x .
2846.PP
2847A special consideration applies to
2848strings.
2849If an
2850.CW int
2851containing a Unicode character is assigned to a subscripted
2852string, the subscript
2853is normally required to lie within the string.
2854As a special case, the subscript's value may be equal to
2855the length of the string (that is, just beyond its end);
2856in this case, the character is appended to
2857the string, and the string's length increases by 1.
2858.PP
2859A final special case applies to array slices in the form
2860.CW e1[e2:] .
2861Such expressions may lie on the left of
2862.CW = .
2863The right side must be an array of the same type as
2864.CW e1 ,
2865and its length must be less than or equal to
2866.CW "(len e1)-e2.
2867In this case, the
2868elements in the array on the right replace the elements of
2869.CW e1
2870starting at position
2871.CW e2 .
2872The length of the array is unchanged.
2873.NH 3
2874Compound assignments
2875.PP
2876A compound assignment with
2877.I op\f(CW=\fP
2878is interpreted in terms of the plain assignment;
2879.P1
2880	e1 \fIop\f(CW= e2;
2881.P2
2882is equivalent to
2883.P1
2884	e1 \f(CW= (e1) \fIop \f(CW(e2);
2885.P2
2886except that
2887.CW e1
2888is evaluated only once.
2889.NH 3
2890Send expressions
2891.PP
2892A
2893.I send-expression
2894takes the form
2895.s1
2896send-expression:
2897	lvalue-expressionC <- = Iexpression
2898.s2
2899In the expression
2900.P1
2901	e1 <- = e2
2902.P2
2903the lvalue
2904.CW e1
2905must have type
2906.CW chan
2907.CW of
2908.I type ,
2909and
2910.CW e2
2911must be of that type.
2912The value of
2913.CW e2
2914is sent over the channel.
2915If no task is executing a
2916channel receive operation on the specified channel, and the channel is unbuffered or its buffer
2917is full, the sender blocks.
2918Task synchronization is discussed in §9.8 and §9.13 below.
2919.NH 3
2920Declare-expressions
2921.PP
2922A
2923.I declare-expression
2924is an assignment that also declares identifiers on its left:
2925.s1
2926declare-expression:
2927	lvalue-expressionC := Iexpression
2928.s2
2929Each of the constituent terms in the
2930.I lvalue-expression
2931must be an identifier or
2932.CW nil .
2933A plain identifier on the left
2934is declared as having the type of the expression,
2935and it is initialized with the expression's value.
2936When a parenthesized list of identifiers is given, the expression
2937must be a tuple or an
2938.CW adt ,
2939and the individual identifiers in the list are declared and initialized
2940with the members of the tuple, or the data members of the
2941.CW adt .
2942As with ordinary assignments, the keyword
2943.CW nil
2944may stand for an identifier whose declaration and assignment
2945are skipped.
2946.PP
2947The value and type of a declare-expression are the same as those of the expression.
2948.NH 3
2949Load expressions
2950.PP
2951A
2952.I load-expression
2953has the form
2954.s1
2955load-expression:
2956	Cload Iidentifier expression
2957.s2
2958The identifier is the identifier of a module, that is, the type
2959name declared in a
2960.CW module
2961declaration.
2962The expression following
2963.CW load
2964has type
2965.CW string
2966and names a file containing the
2967compiled form of the module.
2968The
2969.CW load
2970expression yields a handle for referring to the functions provided
2971by a module and its
2972.CW adt .
2973.PP
2974Execution of
2975.CW load
2976brings the file containing the module into local memory and dynamically type-checks
2977its interface: the run-time system ascertains that
2978the declarations exported by the module are compatible
2979with the module declaration visible in the scope of the
2980.CW load
2981operator (see §11.2).
2982In the scope of a module declaration, the types and constants
2983exported by the module may be referred to without a handle, but
2984the functions and data exported by the module
2985(directly at its top level, or within its
2986.CW adt )
2987may be called only using a valid
2988handle acquired by the
2989.CW load
2990operator.
2991.PP
2992The value of
2993.CW load
2994is
2995.CW nil
2996if the attempt to load fails, either because the file containing
2997the module can not be found, or because the found module does not
2998export the specified interface.
2999.PP
3000Each evaluation of
3001.CW load
3002creates a separate instance of the specified module;
3003it does not share data with any other instance.
3004.NH 2
3005Constant expressions
3006.PP
3007In several places a constant expression is required.
3008Such an expression contains operands that are
3009identifiers previously declared with
3010.CW con ,
3011or
3012.CW int ,
3013.CW big ,
3014.CW real ,
3015or
3016.CW string
3017constants.
3018These may be connected by any of the following operators:
3019.P1
3020.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i
3021	+	-	*	/	%	&	|	^
3022	==	<	>	<=	>=	!=	<<	>>
3023	&&	||
3024	~	!
3025.P2
3026together with arithmetic and string casts, and parentheses for
3027grouping.
3028.NH 2
3029Expression evaluation
3030.PP
3031Expressions in Limbo are not reordered by the compiler;
3032values are computed in accordance with the parse of the expression.
3033However there is no guarantee of temporal evaluation order for expressions
3034with side effects, except in the following circumstances:
3035function arguments are fully evaluated before the function
3036is called; the logical operators
3037.CW &&
3038and
3039.CW ||
3040have fully defined order of evaluation, as explained above.
3041All side effects from an expression in one statement are
3042completed before the next statement is begun.
3043.PP
3044In an expression containing a constant subexpression (in the
3045sense of §8.5), the constant subexpression is evaluated at
3046compile-time with all exceptions ignored.
3047.PP
3048Underflow, overflow, and zero-divide conditions during integer
3049arithmetic produce undefined results.
3050.PP
3051The
3052.CW real
3053arithmetic of Limbo is all performed in IEEE double precision,
3054although denormalized numbers may not be supported.
3055By default,
3056invalid operations, zero-divide, overflow, and underflow
3057during real arithmetic are fatal; inexact-result is quiet.
3058The default rounding mode is round-to-nearest-even.
3059A set of routines in the
3060.CW Math
3061library module permits independent control of these modes within each thread.
3062.NH 1
3063Statements
3064.PP
3065The executable code within a function definition consists
3066of a sequence of statements and declarations.
3067As discussed in the Scope section §11 below,
3068declarations become effective at the place they appear.
3069Statements are executed in sequence except as discussed below.
3070In particular, the optional labels on some of the statements are used with
3071.CW break
3072and
3073.CW continue
3074to exit from or re-execute the labeled statement.
3075.s1
3076statements:
3077	(empty)
3078	statements declaration
3079	statements statement
3080
3081statement:
3082	expressionC ;I
3083	C;I
3084	C{ IstatementsC }I
3085	Cif ( IexpressionC ) Istatement
3086	Cif ( IexpressionC ) IstatementC else Istatement
3087	labelO  Cwhile ( IexpressionOC ) Istatement
3088	labelO  Cdo IstatementC while ( IexpressionOC ) ;I
3089	labelO  Cfor ( IexpressionOC ; IexpressionOC ; IexpressionOC ) Istatement
3090	labelO  Ccase IexpressionC { Iqual-statement-sequenceC }I
3091	labelO  Calt { Iqual-statement-sequenceC }I
3092	labelO  Cpick IidentifierC := IexpressionC { Ipqual-statement-sequenceC }I
3093	Cbreak IidentifierOC ;I
3094	Ccontinue IidentifierOC ;I
3095	Creturn IexpressionOC ;I
3096	Cspawn ItermC ( Iexpression-listOC ) ;I
3097	Cexit ;I
3098	C{ IstatementsC } exceptionI identifierOC{ Iqual-statement-sequenceC }I
3099	Craise IexpressionOC ;I
3100.s2
3101.s1
3102label:
3103	identifier C:I
3104.s2
3105.NH 2
3106Expression statements
3107.PP
3108Expression statements consist of an expression followed by
3109a semicolon:
3110.s1
3111	expressionC ;I
3112.s2
3113Most often expression statements are assignments, but other expressions
3114that cause effects are often useful, for example calling a function
3115or sending or receiving on a channel.
3116.NH 2
3117Null statement
3118.PP
3119The null statement consists of a lone semicolon.
3120It is most useful for supplying an empty body
3121to a looping statement with internal side effects.
3122.NH 2
3123Blocks
3124.PP
3125Blocks are
3126.I statements
3127enclosed in
3128.CW {}
3129characters.
3130.s1
3131	C{ IstatementsC }I
3132.s2
3133A block starts a new scope.
3134The effect of any declarations within a block disappears
3135at the end of the block.
3136.NH 2
3137Conditional statements
3138.PP
3139The conditional statement takes two forms:
3140.s1
3141	Cif ( IexpressionC ) Istatement
3142	Cif ( IexpressionC ) IstatementC else Istatement
3143.s2
3144The
3145.I expression
3146is evaluated; it must have type
3147.CW int .
3148If it is non-zero, then the first
3149.I statement
3150is executed.
3151In the second form, the second
3152.I statement
3153is executed if the
3154.I expression
3155is 0.
3156The statement after
3157.CW else
3158is connected to the nearest
3159.CW else -less
3160.CW if .
3161.NH 2
3162Simple looping statements
3163.PP
3164The simple looping statements are
3165.s1
3166	labelO  Cwhile ( IexpressionOC ) Istatement
3167	labelO  Cdo IstatementC while ( IexpressionOC ) ;I
3168.s2
3169In both cases the expression must be of type
3170.CW int .
3171In the first form, the
3172.I expression
3173is first tested against 0;
3174while it is not equal, the
3175.I statement
3176is repeatedly executed.
3177In the second form, the
3178.I statement
3179is executed, and then, while the
3180.I expression
3181is not 0, the statement is repeatedly executed.
3182If the
3183.I expression
3184is missing, it is understood to be non-zero.
3185.NH 2
3186.CW for
3187statement
3188.PP
3189The
3190.CW for
3191statement has the form
3192.s1
3193	labelO  Cfor ( Iexpression-1OC ; Iexpression-2OC ; Iexpression-3OC ) Istatement
3194.s2
3195It is equivalent to
3196.s1
3197	expression-1C ;I
3198	Cwhile ( Iexpression-2C ) {
3199		Istatement
3200		expression-3C ;
3201	C}I
3202.s2
3203in the absence of
3204.CW continue
3205or
3206.CW break
3207statements.
3208Thus (just as in C), the first expression is an initialization,
3209the second a test for starting and continuing the loop, and the third
3210a re-initialization for subsequent travels around the loop.
3211.NH 2
3212.CW case
3213statement
3214.PP
3215The
3216.CW case
3217statement transfers control to one of several places
3218depending on the value of an expression:
3219.s1
3220	labelO  Ccase IexpressionC { Iqual-statement-sequenceC }I
3221.s2
3222The expression must have type
3223.CW int ,
3224.CW big
3225or
3226.CW string .
3227The
3228.CW case
3229statement is followed by sequence of
3230qualified statements, which are statements labeled by
3231expressions or expression ranges:
3232.s1
3233qual-statement-sequence:
3234	qual-listC =>I
3235	qual-statement-sequence qual-listC =>I
3236	qual-statement-sequence statement
3237	qual-statement-sequence declaration
3238
3239qual-list:
3240	qualifier
3241	qual-listC or Iqualifier
3242
3243qualifier:
3244	expression
3245	expressionC to Iexpression
3246	C*I
3247.s2
3248A
3249.I qual-statement-sequence
3250is a sequence of
3251statements and declarations, each of which
3252is preceded by one or more qualifiers.
3253Syntactically, the qualifiers are
3254expressions, expression ranges with
3255.CW to ,
3256or
3257.CW * .
3258If the expression mentioned after
3259.CW case
3260has
3261.CW int
3262or
3263.CW big
3264type,
3265all the expressions appearing in the qualifiers
3266must evaluate to integer constants of the same type (§8.5).
3267If the expression has
3268.CW string
3269type, all the qualifiers must be
3270string constants.
3271.PP
3272The
3273.CW case
3274statement is executed by comparing
3275the expression at its head with the constants
3276in the qualifiers.
3277The test is for equality in the case
3278of simple constant qualifiers;
3279in range qualifiers, the test determines
3280whether the expression is greater than or
3281equal to the first constant and less than
3282or equal to the second.
3283.PP
3284None of the ranges or constants may overlap.
3285If no qualifier is selected and
3286there is a
3287.CW *
3288qualifier,
3289then that qualifier is selected.
3290.PP
3291Once a qualifier is selected, control passes
3292to the set of statements headed by that
3293qualifier.
3294When control reaches the end of that set
3295of statements, control passes to the end
3296of the
3297.CW case
3298statement.
3299If no qualifier is selected, the
3300.CW case
3301statement is skipped.
3302.PP
3303Each qualifier and the statements following it
3304up to the next qualifier together form a separate
3305scope, like a block; declarations within this scope
3306disappear at the next qualifier (or at the end of
3307the statement.)
3308.PP
3309As an example, this fragment separates small numbers
3310by the initial letter of their spelling:
3311.P1
3312	case i {
3313	1 or 8 =>
3314		sys->print("Begins with a vowel\en)";
3315	0 or 2 to 7 or 9 =>
3316		sys->print("Begins with a consonant\en");
3317	* =>
3318		sys->print("Sorry, didn't understand\en");
3319	}
3320.P2
3321.NH 2
3322.CW alt
3323statement
3324.PP
3325The
3326.CW alt
3327statement transfers control to one of several groups
3328of statements depending on the readiness of communication
3329channels.
3330Its syntax resembles that of
3331.CW case :
3332.s1
3333	labelO  Calt { Iqual-statement-sequenceC }I
3334.s2
3335However, the qualifiers take a form different
3336from those of
3337.CW case .
3338In
3339.CW alt ,
3340each qualifier must be a
3341.CW * ,
3342or an expression containing a communication
3343operator
3344.CW <-
3345on a channel;
3346the operator may specify either sending or receiving.
3347For example,
3348.P1
3349	outchan := chan of string;
3350	inchan := chan of int;
3351	alt {
3352	i := <-inchan =>
3353		sys->print("Received %d\en", i);
3354
3355	outchan <- = "message" =>
3356		sys->print("Sent the message\en");
3357	}
3358.P2
3359The
3360.CW alt
3361statement is executed by testing each of
3362the channels mentioned in the
3363.I qual-list
3364expressions for ability to send or receive,
3365depending on the operator;
3366if none is ready, the program blocks
3367until at least one is ready.
3368Then a random choice from the ready channels is selected
3369and control passes to the associated set
3370of statements.
3371.PP
3372If a qualifier of the form
3373.CW *
3374is present, then the statement does not block;
3375if no channel is ready the statements associated with
3376.CW *
3377are executed.
3378.PP
3379If two communication operators are present
3380in the same qualifier expression, only the leftmost one is
3381tested by
3382.CW alt .
3383If two or more
3384.CW alt
3385statements referring to the same receive (or send)
3386channel are executed in different
3387threads, the requests are queued;
3388when the channel becomes unblocked, the thread
3389that executed
3390.CW alt
3391first is activated.
3392.PP
3393As with
3394.CW case ,
3395each qualifier and the statements following it
3396up to the next qualifier together form a separate
3397scope, like a block; declarations within this scope
3398disappear at the next qualifier (or at the end of
3399the statement.)
3400Thus, in the example above, the scope of
3401.CW i
3402in the arm
3403.P1
3404		i := <-inchan =>
3405			sys->print("Received %d\en", i);
3406.P2
3407is restricted to these two lines.
3408.PP
3409As mentioned in the specification
3410of the channel receive operator
3411.CW <-
3412in §8.2.8, that operator can take an array of channels as an argument.
3413This notation serves as a kind of simplified
3414.CW alt
3415in which all the channels have the same type
3416and are treated similarly.
3417In this variant,
3418the value of the communication expression is a tuple
3419containing the index of the
3420channel over which a communication was received and
3421the value received.
3422For example, in
3423.P1
3424	a: array [2] of chan of string;
3425	a[0] = chan of string;
3426	a[1] = chan of string;
3427	. . .
3428	(i, s) := <- a;
3429	# s has now has the string from channel a[i]
3430.P2
3431the
3432.CW <-
3433operator waits until at least one of the
3434members of
3435.CW a
3436is ready, selects one of them at random,
3437and returns the index and the transmitted string
3438as a tuple.
3439.PP
3440During execution of an
3441.CW alt ,
3442the expressions in the qualifiers are evaluated in an undefined
3443order, and in particular subexpressions may be evaluated before
3444the channels are tested for readiness.
3445Therefore qualifying expressions should not invoke side effects,
3446and should avoid subparts that might delay execution.
3447For example, in the qualifiers
3448.P1
3449	ch <- = getchar() =>	# Bad idea
3450	ich <- = next++ =>	# Bad idea
3451.P2
3452.CW getchar()
3453may be called early in the elaboration of the
3454.CW alt
3455statement; if it delays, the entire
3456.CW alt
3457may wait.
3458Similarly, the
3459.CW next++
3460expression may be evaluated before testing the readiness of
3461.CW ich .
3462.NH 2
3463.CW pick
3464statement
3465.PP
3466The
3467.CW pick
3468statement transfers control to one of several groups of statements
3469depending upon the resulting variant type of a
3470.CW pick
3471.CW adt
3472expression. The syntax resembles that of
3473.CW case :
3474.s1
3475	labelO  Cpick IidentifierC := IexpressionC { Ipqual-statement-sequenceC }I
3476.s2
3477The expression must have type
3478.CW ref
3479.CW adt
3480and the
3481.CW adt
3482must be a
3483.CW pick
3484.CW adt .
3485The
3486.CW pick
3487statement is followed by a sequence of qualified statements, which are
3488statements labeled by the
3489.CW pick
3490variant names:
3491.s1
3492pqual-statement-sequence:
3493	pqual-listC =>I
3494	pqual-statement-sequence pqual-listC =>I
3495	pqual-statement-sequence statement
3496	pqual-statement-sequence declaration
3497
3498pqual-list:
3499	pqualifier
3500	pqual-listC or Ipqualifier
3501
3502pqualifier:
3503	identifier
3504	C*I
3505.s2
3506A
3507.I pqual-statement-sequence
3508is a sequence of statements and declarations, each of which
3509is preceded by one or more qualifiers.
3510Syntactically, the qualifiers are identifiers, identifier lists (constructed with
3511.CW or ),
3512or
3513.CW * .
3514The identifiers must be names of the variant types of the
3515.CW pick
3516.CW adt .
3517The
3518.CW pick
3519statement is executed by comparing the variant type of the
3520.CW pick
3521.CW adt
3522referenced by the expression at its head with the variant type names in the qualifiers.
3523The matching qualifier is selected.
3524None of the variant type names may appear more than once.
3525If no qualifier is selected and there is a
3526.CW *
3527qualifier, then that qualifier is selected.
3528.PP
3529Once a qualifier is selected, control passes
3530to the set of statements headed by that qualifier.
3531When control reaches the end of that set of statements,
3532control passes to the end of the
3533.CW pick
3534statement.
3535If no qualifier is selected, the
3536.CW pick
3537statement is skipped.
3538.PP
3539Each qualifier and the statements following it
3540up to the next qualifier together form a separate
3541scope, like a block; declarations within this scope
3542disappear at the next qualifier (or at the end of
3543the statement.)
3544.PP
3545The
3546.I identifier
3547and
3548.I expression
3549given in the
3550.CW pick
3551statement are used to bind a new variable to a
3552.CW pick
3553.CW adt
3554reference expression, and within the statements associated with the
3555selected qualifier the variable can be used as if it were of the corresponding
3556variant type.
3557.PP
3558As an example, given a
3559.CW pick
3560.CW adt
3561of the following form:
3562.P1
3563	Constant: adt {
3564		name: string;
3565		pick {
3566			Str or Pstring =>
3567				s: string;
3568			Real =>
3569				r: real;
3570		}
3571	};
3572.P2
3573the following function could be used to print out the value of
3574an expression of type
3575.CW "ref Constant" :
3576.P1
3577	printconst(c: ref Constant)
3578	{
3579		sys->print("%s: ", c.name);
3580		pick x := c {
3581		Str =>
3582			sys->print("%s\en", x.s);
3583		Pstring =>
3584			sys->print("[%s]\en", x.s);
3585		Real =>
3586			sys->print("%f\en", x.r);
3587		};
3588	}
3589.P2
3590.NH 2
3591.CW break
3592statement
3593.PP
3594The
3595.CW break
3596statement
3597.s1
3598	Cbreak IidentifierO C;I
3599.s2
3600terminates execution of
3601.CW while ,
3602.CW do ,
3603.CW for ,
3604.CW case ,
3605.CW alt ,
3606and
3607.CW pick
3608statements.
3609Execution of
3610.CW break
3611with no identifier
3612transfers control to
3613the statement after the innermost
3614.CW while ,
3615.CW do ,
3616.CW for ,
3617.CW case ,
3618.CW alt ,
3619or
3620.CW pick
3621statement in which it appears as a substatement.
3622Execution of
3623.CW break
3624with an identifier
3625transfers control to the next statement after the unique enclosing
3626.CW while ,
3627.CW do ,
3628.CW for ,
3629.CW case ,
3630.CW alt ,
3631or
3632.CW pick
3633labeled with that identifier.
3634.NH 2
3635.CW continue
3636statement
3637.PP
3638The
3639.CW continue
3640statement
3641.s1
3642	Ccontinue IidentifierO C;I
3643.s2
3644restarts execution of
3645.CW while ,
3646.CW do ,
3647and
3648.CW for
3649statements.
3650Execution of
3651.CW continue
3652with no identifier
3653transfers control to the end of
3654the innermost
3655.CW while ,
3656.CW do ,
3657or
3658.CW for
3659statement in which the
3660.CW continue
3661appears as a substatement.
3662The expression that controls the loop is tested
3663and if it succeeds, execution continues in the loop.
3664The initialization portion of
3665.CW for
3666is not redone.
3667.PP
3668Similarly, execution of
3669.CW continue
3670with an identifier transfers control to the end of the enclosing
3671.CW while ,
3672.CW do ,
3673or
3674.CW for
3675labeled with the same identifier.
3676.NH 2
3677.CW return
3678statement
3679.PP
3680The
3681.CW return
3682statement,
3683.s1
3684	Creturn IexpressionOC ;I
3685.s2
3686returns control to the caller of a function.
3687If the function returns a value (that is, if its definition
3688and declaration mention a return type),
3689the expression must be given and it must have the same type that the
3690function returns.
3691If the function returns no value, the expression
3692must generally be omitted.
3693However, if a function returns no value, and its
3694last action before returning is to call
3695another function with no value, then it may
3696use a special form of
3697.CW return
3698that names the function being called.
3699For example,
3700.P1
3701	f, g: fn(a: int);
3702	f(a: int) {
3703		. . .
3704		return g(a+1);
3705	}
3706.P2
3707is permitted.
3708Its effect is the same as
3709.P1
3710	f(a: int) {
3711		. . .
3712		g(a+1);
3713		return;
3714	}
3715.P2
3716This
3717.I "ad hoc
3718syntax offers the compiler a cheap opportunity to recognize
3719tail-recursion.
3720.PP
3721Running off the end of a function is equivalent to
3722.CW return
3723with no expression.
3724.NH 2
3725.CW spawn
3726statement
3727.PP
3728The
3729.CW spawn
3730statement creates a new thread of control.
3731It has the form
3732.s1
3733	Cspawn ItermC ( Iexpression-listOC ) ;I
3734.s2
3735The term and expression-list are taken to be
3736a function call.
3737Execution of
3738.CW spawn
3739creates an asynchronous, independent thread
3740of control, which calls the function in the new thread context.
3741This function may access the accessible objects
3742in the spawning thread; the two threads share
3743a common memory space.
3744These accessible objects include the data global to
3745the current module and reference data passed to the
3746spawned function.
3747Threads are preemptively scheduled, so that
3748changes to objects used in common between
3749threads may occur at any time.
3750The Limbo language provides no explicit synchronization
3751primitives; §12.3 shows examples of how to use channel
3752communication to control concurrency.
3753.NH 2
3754.CW exit
3755statement
3756.PP
3757The
3758.CW exit
3759statement
3760.s1
3761	Cexit ;I
3762.s2
3763terminates a thread and frees any resources
3764belonging exclusively to it.
3765.NH 2
3766.CW raise
3767statement
3768.PP
3769The
3770.CW raise
3771statement
3772.s1
3773	Craise IexpressionOC ;I
3774.s2
3775raises an exception in a thread.
3776The
3777.I expression
3778is either a string describing the failure, or an exception name and its parameter values, if any.
3779If an expression is not given, the
3780.CW raise
3781statement must appear in the body of an exception handler; it raises the currently active exception.
3782.NH 2
3783Exception handler
3784.PP
3785Various errors in a Limbo program can be detected only at run-time.
3786These include programming errors such as an attempt to index outside the bounds of an array,
3787system errors such as exhausting memory, and user-defined exceptions
3788declared at compile-time by exception declarations and caused at run-time by the
3789.CW raise
3790statement.
3791A group of statements can have an associated exception handler:
3792.s1
3793	C{ IstatementsC } exceptionI identifierOC{ Iqual-statement-sequenceC }I
3794.s2
3795The first run-time exception raised by any of the
3796.I statements ,
3797or functions they call,
3798that is not handled by an exception handler enclosing the statement raising the exception
3799will terminate execution of the
3800.I statements
3801at that point, and transfer control to the clause in the sequence of qualified statements
3802that matches the exception.
3803An exception represented by a string is matched by a qualifier that is either the same
3804string value, or a prefix of it followed by
3805.CW * .
3806The optional identifier following
3807.CW exception
3808is set to the value of the exception string for the execution of the qualified statement.
3809If execution of the qualified statement completes, control passes to the statement following
3810the exception-handling statement.
3811.PP
3812A qualified statement labeled by a user-defined exception name matches that exception.
3813If the exception has parameters, the identifier following
3814.CW exception
3815will be be declared and initialized as a tuple of the parameter values for the scope
3816of the qualified statement, allowing the values to be recovered by tuple assigment.
3817.PP
3818The qualifier
3819.CW *
3820matches any string or user-defined exception.
3821An exception that is raised and not successfully handled by a thread will terminate the thread.
3822.NH
3823Referring to modules;
3824.CW import
3825.PP
3826As discussed above, modules present
3827constants, functions, and types
3828in their interface.
3829Their names may be the same as names
3830in other modules or of local objects or types within
3831a module that uses another.
3832Name clashes are avoided because references
3833to the entities presented by a module are
3834qualified by the module type name or an object
3835of that module type.
3836.PP
3837For example,
3838after the module and variable declarations
3839.P1
3840	M: module {
3841		One: con 1;
3842		Thing: adt {
3843			t: int;
3844			f: fn();
3845		};
3846		g: fn();
3847	};
3848	m: M;
3849.P2
3850the name
3851.CW One
3852refers to the constant defined in
3853module
3854.CW M
3855only in the contexts
3856.CW M->One
3857or
3858.CW m->One ;
3859the name
3860.CW Thing
3861as the particular data type
3862associated with the
3863.CW M
3864module can be referred to only in contexts
3865like
3866.P1
3867	th1: M->Thing;
3868	th2: m->Thing;
3869.P2
3870Finally, to call a function defined either as a top-level
3871member of the module, or as a member of one of its
3872.CW adt ,
3873it is necessary to declare, and also dynamically initialize using
3874.CW load ,
3875a handle for the module.
3876Then calls of the form
3877.P1
3878	m->g();
3879	m->th1.f();
3880.P2
3881become appropriate.
3882It is possible to use just the type name of a module to qualify
3883its constants and types because constants and types can be understood
3884without having the code and data present.
3885Calling a function declared by a module or one of its
3886.CW adt
3887requires loading the module.
3888.PP
3889The
3890.CW import
3891declaration
3892.s1
3893	Iidentifier-listC : import Iidentifier C;I
3894.s2
3895lifts the identifiers in the
3896.I identifier-list
3897into the scope in which
3898.CW import
3899appears, so that they are usable without a qualifier.
3900The identifier after the
3901.CW import
3902keyword is either
3903a module identifier, or an identifier declared as having
3904that type.
3905The initial list of identifiers specifies those
3906constants,
3907types,
3908and functions of the module whose names are promoted.
3909In the case of constants and types,
3910.CW import
3911merely makes their names accessible without using a qualifier.
3912In the example above, if the
3913.CW module
3914declaration above had been followed by
3915.P1
3916	One, Thing: import M;
3917.P2
3918then one could refer to just
3919.CW One
3920instead of
3921.CW M->One ;
3922similarly an object could be declared like
3923.P1
3924	th: Thing;
3925.P2
3926For functions, and also
3927.CW adt
3928with functions as members,
3929.CW import
3930must specify a module
3931variable (as opposed to a module identifier).
3932Each imported name is associated with the specified module
3933variable, and the current value of this module variable
3934controls which instance of the module will
3935be called.
3936For example, after
3937.P1
3938	g, Thing: import m;
3939.P2
3940then
3941.P1
3942	g();
3943.P2
3944is equivalent to
3945.P1
3946	m->g();
3947.P2
3948and
3949.P1
3950	th: Thing;
3951	th.f();
3952.P2
3953is equivalent to
3954.P1
3955	th: M->Thing;
3956	m->th.f();
3957.P2
3958When the module declaration for the module being
3959implemented is encountered, an implicit
3960.CW import
3961of all the names of the module is executed.
3962That is, given
3963.P1
3964	implement Mod;
3965	. . .
3966	Mod: module {
3967		. . .
3968	};
3969.P2
3970the constants and types of
3971.CW Mod
3972are accessed as if they had been imported;
3973the functions declared in
3974.CW Mod
3975are imported as well, and refer dynamically to the
3976current instance of the module being implemented.
3977.NH
3978Scope
3979.PP
3980The scope of an identifier is the lexical range of
3981a program throughout which the identifier means a particular
3982type of, or instance of, an object.
3983The same identifier may be associated with several
3984different objects in different parts of the same program.
3985.PP
3986The names of members of an
3987.CW adt
3988occupy a separate, nonconflicting space from other identifiers;
3989they are declared in a syntactically distinct position,
3990and are always used in a distinguishable way, namely
3991after the
3992.CW .
3993selection operator.
3994Although the same scope rules apply to
3995.CW adt
3996members as to other identifiers, their names may
3997coincide with other entities in the same scope.
3998.PP
3999Similarly, the names of constants, functions, and
4000.CW adt
4001appearing
4002within a
4003.CW module
4004declaration are ordinarily qualified either with
4005the name of the module or with a module variable
4006using the
4007.CW ->
4008notation.
4009As discussed above, the
4010.CW import
4011declaration lifts these names into the current scope.
4012.PP
4013Identifiers declared in a top-declaration
4014(§5) have scope that lasts from the
4015declaration throughout the remainder of the
4016file in which it occurs, unless it is overridden
4017by a redeclaration of that name within an inner
4018scope.
4019Each function definition, and each block
4020within a function,
4021introduces a new scope.
4022A name declared within the block or function
4023(including a formal argument name of a function)
4024has a scope that begins
4025at the completion of its declaration and lasts until
4026the end of the block or function.
4027If an already-declared identifier is redeclared within
4028such an inner scope, the declaration previously in
4029force is used in any initialization expression
4030that is part of the new declaration.
4031.PP
4032As discussed above, within
4033.CW case
4034.CW alt
4035and
4036.CW pick ,
4037each qualifier
4038and the statements following it form an inner
4039scope just like a block.
4040.PP
4041The scope of a label is restricted to the
4042labeled statement,
4043and label names may coincide with those of other
4044entities in the same scope.
4045.NH 2
4046Forward referencing
4047.PP
4048In general, names must be declared before they are used.
4049.PP
4050The first exception to this rule is that a
4051function local to a module need not have a
4052declaration at all; it is sufficient to give
4053its definition, and that definition may appear anywhere
4054in the module.
4055.PP
4056The general rule implies that no
4057.CW adt
4058may contain, as a member, an
4059.CW adt
4060not previously declared (including an instance of itself).
4061A second exception to this rule applies to
4062.CW ref
4063.CW adt
4064types.
4065An
4066.CW adt
4067may contain a member whose type is a
4068.CW ref
4069to itself, or to another
4070.CW adt
4071even if the second
4072.CW adt
4073has not yet been declared.
4074.PP
4075For example, a tree structure where nodes contain references to children can be declared and created as follows:
4076.P1
4077	Tree: adt {
4078		l: ref Tree;
4079		r: ref Tree;
4080		v: int;
4081	};
4082
4083	t1a := ref Tree(nil, nil, 0);
4084	t1b := ref Tree(nil, nil, 1);
4085	t1c := ref Tree(nil, nil, 2);
4086	t2 := Tree(t1a, t1b, 0);
4087	t2.l = t1c;	# replace reference to t1a by reference to t1c
4088.P2
4089The tree structure resulting above is non-circular, since no
4090.CW adt
4091value refers back to itself directly or indireclty.
4092Circular data structures can also be created. For example,
4093.P1
4094	Graph: adt {
4095		next: ref Graph;
4096		v: int;
4097	};
4098
4099	g1 := ref Graph(nil, 0);
4100	g2 := ref Graph(g1, 1);
4101	g1.next = g2;
4102.P2
4103creates a pair of nodes that refer to each other.
4104.PP
4105Limbo implementations guarantee to
4106destroy all data objects not involved in circular data structures
4107immediately after they become non-referenced by active
4108tasks, whether because
4109their names go out of scope or because they are assigned new values.
4110This property has visible effect because certain system resources,
4111like windows and file descriptors, can be seen outside the program.
4112In particular, if a reference to such a resource is held only within an
4113.CW adt ,
4114then that resource too is destroyed when the
4115.CW adt
4116is.
4117Circular data structures can also be created.
4118When they become unreferenced except by themselves, they will
4119be garbage-collected eventually, but not instantly.
4120.PP
4121An earlier version of the language required circular references to be annoted by the word
4122.CW cyclic ,
4123but that is no longer required.
4124The notation can still be seen in some system source code, because the
4125.CW cyclic
4126qualifier is taken into account in type checking, as described below, and some instances remain to provide backward compatibility.
4127.NH 2
4128Type equality and compatibility
4129.PP
4130In an assignment and in passing an actual argument to a function,
4131the types of the target and the expression being assigned or
4132passed must be equal (with certain exceptions, e.g. assignment of
4133.CW nil
4134to a reference type).
4135When a function is defined, its type must be equal to the type
4136of a function with the same name if one is in scope.
4137Type equality is determined as follows.
4138.PP
4139Two basic types are equal if and only if they are identical.
4140.PP
4141Two tuple types are equal if and only if they are composed
4142of equal types in the same order.
4143.PP
4144Two array types are equal if and only if they are arrays
4145of equal types.
4146The size of an array is not part of its type.
4147.PP
4148Two list types are equal if and only if they are composed
4149of equal types.
4150.PP
4151Two channel types are equal if and only if they transmit
4152equal types.
4153.PP
4154Two
4155.CW adt
4156types are equal if and only if their data members
4157have the same names and correspondingly
4158equal types, including any
4159.CW cyclic
4160attribute.
4161The order of member declaration is insignificant, and
4162constant and function members of an
4163.CW adt
4164do not enter into the comparison,
4165nor does the name of the
4166.CW adt
4167type itself.
4168In particular, with the declarations
4169.P1
4170	A: adt { x: ref B; };
4171	B: adt { x: ref A; };
4172.P2
4173the types
4174.CW A
4175and
4176.CW B
4177are equal.
4178.PP
4179Two
4180.CW ref
4181.CW adt
4182types are equal if and only if they are references to equal
4183.CW adt
4184types.
4185.PP
4186Two module types are equal if and only if their data and function members
4187have the same names and correspondingly equal types; the order
4188of their mention is insignificant.
4189Constant members and type members do not enter into the comparison.
4190.PP
4191Two function types are equal if and only if their return
4192values have the same type
4193and their argument lists have correspondingly equal types.
4194Any
4195.CW self
4196attributes given to arguments must match.
4197Names given to arguments do not enter into the comparison.
4198.PP
4199A type name has the same type as the type from
4200which it was constructed.
4201.PP
4202When a module is loaded, the module stored
4203in the file system must have a type that is
4204.I compatible
4205with the type mentioned in the
4206.CW load
4207expression.
4208The type of the stored module
4209type is compatible with the mentioned type if and only if
4210all data members of the two types are equal in name and type,
4211and all
4212.CW adt
4213or functions actually mentioned by the program executing
4214.CW load
4215have names and types equal to corresponding members of
4216the stored module.
4217.NH
4218Examples
4219.PP
4220Because Limbo was designed for the Inferno environment, several
4221of these examples consist of simplified versions of already simple
4222Inferno applications in a prototype Inferno implementation.
4223Some appreciation for the resources available in this environment
4224should become evident, but its full description is available
4225elsewhere;
4226the discussion here will focus on language features.
4227However, several of the programs use facilities
4228from the module
4229.CW Sys ,
4230which provides an interface to a file system and its methods
4231resembling those of Unix or Plan 9,
4232as well as other useful library facilities.
4233.PP
4234Some of the programs are annotated with line numbers;
4235they are there only for descriptive purposes.
4236.NH 2
4237A simple command interpreter module
4238.PP
4239This version of a shell program reads from a keyboard and
4240executes `commands' typed by the user.
4241Its own interface has the type of a
4242.CW Command
4243module, and that is the type of the things it executes.
4244In particular, it can call modules like the
4245.CW hello
4246example at the beginning of the paper.
4247.P1
42481	implement Command;
4249
42502	include "sys.m";
42513	include "draw.m";
4252
42534	sys: Sys;
42545	stdin: ref Sys->FD;
4255
42566	Command: module
42577	{
42588		init: fn(nil: ref Draw->Context, nil: list of string);
42599	};
4260.P2
4261After the boilerplate on lines 1-3, the variables
4262.CW sys
4263and
4264.CW stdin
4265are declared on lines 4 and 5.
4266The I/O operations of the
4267.CW Sys
4268module use the
4269.CW ref
4270.CW FD
4271type to refer to open files.
4272.P1
427310	init(ctx: ref Draw->Context, nil: list of string)
427411	{
427512
427613
427714		buf := array[256] of byte;
4278
427915		sys = load Sys Sys->PATH;
428016		stdin = sys->fildes(0);
4281
428217		for(;;) {
428318			sys->print("$ ");
428419			n := sys->read(stdin, buf, len buf);
428520			if(n <= 0)
428621				break;
428722			(nw, arg) :=
4288			   sys->tokenize(string buf[0:n], " \et\en");
428923			if(nw != 0)
429024				exec(ctx, arg);
429125		}
429226	}
4293.P2
4294Line 10: conventionally, stand-alone modules are started
4295by calling their
4296.CW init
4297functions.
4298The
4299.CW Command
4300module follows this convention.
4301The arguments are presented as a list of strings.
4302In this simple example, the command interpreter itself
4303ignores its argument, so it need not be given a name.
4304.PP
4305Local variables are declared on lines 12-14; line 15
4306loads the
4307.CW Sys
4308module and stores a handle for it in the variable
4309.CW sys .
4310Line 16 creates an
4311.CW FD
4312for the standard input by calling the
4313.CW fildes
4314function of the
4315.CW Sys
4316module using the
4317.CW ->
4318operator; the notation
4319.CW modhandle->func(...)
4320specifies a call to the function named
4321.CW func
4322in the module currently referred to by
4323.CW modhandle .
4324(In general there can be several modules of the same type and name
4325active, and there can also be unrelated modules containing identically
4326named functions.
4327The
4328.CW import
4329declaration, described in §6.6 above, can be used to abbreviate
4330the references when names do not clash.)
4331.PP
4332The loop on lines 17-25 prints a prompt (line 18), reads a line from
4333the standard input (line 19), parses it into tokens (line 22), and
4334executes the command.
4335.PP
4336The function call
4337.CW sys->tokenize
4338is worth discussing as an example of style.
4339It takes two strings as arguments.
4340The characters in the second string are interpreted as separators
4341of tokens in the first string.
4342It returns a tuple whose first member is the number of
4343tokens found, and whose second is a list of strings
4344containing the tokens found: its declaration is
4345.P1
4346	tokenize: fn (s: string, sep: string): (int, list of string);
4347.P2
4348In the example, the second argument is
4349\f(CW" \et\en"\fP,
4350so that the routine returns the number of, and a list of,
4351`words' separated by blanks, tabs, and new-lines.
4352The free use of strings, lists, and tuple-returning
4353functions is common in Limbo.
4354.PP
4355The
4356.CW sys->read
4357routine gathers an array of bytes into
4358.CW buf .
4359Thus the expression for the first argument of
4360.CW sys->tokenize
4361converts this array to a string by slicing the
4362array with
4363.CW [0:n] ,
4364using the actual number of bytes
4365gathered by the
4366.CW read ,
4367and using a cast.
4368.PP
4369At lines 23-24, if there were any words found,
4370.CW exec
4371is called:
4372.P1
437327	exec(ctx: ref Draw->Context, args: list of string)
437428	{
437529		c: Command;
437630		cmd, file: string;
4377
437831		cmd = hd args;
4379
438032		file = cmd + ".dis";
438133		c = load Command file;
438234		if(c == nil)
438335			c = load Command "/dis/"+file;
4384
438536		if(c == nil) {
438637			sys->print("%s: not found\en", cmd);
438738			return;
438839		}
438940		c->init(ctx, args);
439041	}
4391.P2
4392On lines 31 and 32 of
4393.CW exec ,
4394.CW cmd
4395is set to the first of the words in the argument list,
4396and the string
4397.CW .dis
4398is concatenated to it (to account for the fact that Limbo
4399object program files are conventionally named using this suffix).
4400On line 33 an attempt is made to load the named module
4401from the derived file name; it will fail if the file
4402does not exist.
4403The attempt will succeed,
4404and a non-nil handle assigned to
4405.CW c ,
4406if the file is found, and if
4407the module stored in that file does in fact implement the
4408.CW Command
4409module type.
4410In case this fails, lines 34-35 make another attempt, after prefixing
4411.CW /dis/
4412to the file name.
4413.PP
4414If either attempt to get a handle to the named module
4415succeeds,
4416.CW c
4417will contain a valid handle to it; line 40 calls its
4418.CW init
4419function, passing it the whole argument list.
4420When it returns, the
4421.CW exec
4422function returns, and the main loop resumes.
4423.NH 2
4424Infrared remote control
4425.PP
4426This example shows two instances of a module
4427for interfacing to a TV remote control; one
4428is for the real remote, which in this case
4429is connected to a serial port on a set-top
4430box, and the other is simulated for testing
4431programs running on a regular operating
4432system.
4433The techniques of special interest are the
4434dynamic use of modules and the communication
4435using a channel.
4436.PP
4437The module is used by creating a channel and passing
4438it to the module's
4439.CW init
4440function,
4441which returns a success/error indicator and starts an
4442asynchronous process to read the remote control.
4443The user of the module executes a receive
4444on the channel whenever it wishes to accept
4445a button-push.
4446.PP
4447The (abridged) module declaration is
4448.P1
4449Ir: module
4450{
4451	# Codes buttons on IR remote control
4452	Zero:	con 0;
4453	One:	con 1;
4454	. . .
4455	Mute:	con 23;
4456	Error:	con 9999;
4457
4458	init: fn(chan of int): int;
4459	PATH: con "/dis/ir.dis";
4460	SIMPATH: con "/dis/irsim.h";
4461};
4462.P2
4463The implementation for the `real' remote control is
4464.P1
4465implement Ir;
4466
4467include "ir.m";
4468include "sys.m";
4469FD, Dir: import Sys;
4470
4471sys: Sys;
4472
4473init(keys: chan of int): int
4474{
4475	cfd, dfd: ref FD;
4476
4477	sys = load Sys Sys->PATH;
4478
4479	cfd = sys->open("/dev/eia1ctl", sys->OWRITE);
4480	if(cfd == nil)
4481		return -1;
4482	sys->fprint(cfd, "b9600");
4483
4484	dfd = sys->open("/dev/eia1", sys->OREAD);
4485	cfd = nil;
4486
4487	spawn reader(keys, dfd);
4488	return 0;
4489}
4490.P2
4491The
4492.CW init
4493routine accepts a
4494.CW chan
4495argument; it will be used by the module to
4496send codes for the buttons pressed by the user.
4497In this routine, the calls to
4498.CW sys->open
4499and
4500.CW sys->fprint
4501open and set up the device data and control files
4502.CW /dev/eia1
4503and
4504.CW /dev/eia1ctl
4505used to communicate with the device itself.
4506The important step is at the end: the
4507.CW spawn
4508statement creates a new,
4509asynchronous task to read the device, using a routine
4510that is passed the communications channel and the
4511FD for the device:
4512.P1
4513reader(keys: chan of int, dfd: ref FD)
4514{
4515	n, ta, tb: int;
4516	dir: Dir;
4517	b1:= array[1] of byte;
4518	b2:= array[1] of byte;
4519
4520	# find the number of bytes already
4521	# queued and flush that many
4522	(n, dir) = sys->fstat(dfd);
4523	if(n >= 0 && dir.length > 0) {
4524		while(dir.length) {
4525			n = sys->read(dfd,
4526			   array[dir.length] of byte,
4527			   dir.length);
4528			if(n < 0)
4529				break;
4530			dir.length -= n;
4531		}
4532	}
4533.P2
4534.P1
4535loop:	for(;;) {
4536		n = sys->read(dfd, b1, len b1);
4537		if(n <= 0)
4538			break;
4539		ta = sys->millisec();
4540		# Button pushes are pairs of characters
4541		# that arrive closer together than
4542		# 200 ms.  Longer than that is likely
4543		# to be noise.
4544		for(;;) {
4545			n = sys->read(dfd, b2, 1);
4546			if(n <= 0)
4547				break loop;
4548			tb = sys->millisec();
4549			if(tb - ta <= 200)
4550				break;
4551			ta = tb;
4552			b1[0] = b2[0];
4553		}
4554		# map the character pair; the significant
4555		# bits are the lowest 5.
4556		case ((int b1[0]&16r1f)<<5) | (int b2[0]&16r1f) {
4557		975 =>	n = Ir->Zero;
4558		479 =>	n = Ir->One;
4559		. . .
4560		791 =>	n = Ir->Mute;
4561		* =>	n = Ir->Error;
4562		}
4563		# found a button-push; send the value
4564		keys <-= n;
4565	}
4566	keys <-= Ir->Error;
4567}
4568.P2
4569The code in the middle is related to noise-filtering
4570and is uninteresting in detail except as it illustrates
4571some of the methods provided by the
4572.CW Sys
4573module; the crucial actions are found at the bottom,
4574where the routine sends either
4575a true button-push or an error code over the channel to
4576the module's client.
4577.PP
4578Here is another implementation of the same interface.
4579Its
4580.CW init
4581function performs the same kind of initialization
4582as the other version, but using the operating system's
4583keyboard files
4584.CW /dev/cons
4585and
4586.CW /dev/consctl .
4587In the Inferno environment, operations corresponding to the Unix
4588`stty' primitive are accomplished by writing messages to
4589a control file associated with the file that handles the data.
4590.P1
4591implement Ir;
4592
4593include "ir.m";
4594include "sys.m";
4595FD: import Sys;
4596
4597sys: Sys;
4598cctlfd: ref FD;
4599
4600init(keys: chan of int): int
4601{
4602	dfd: ref FD;
4603
4604	sys = load Sys Sys->PATH;
4605
4606	cctlfd = sys->open("/dev/consctl", sys->OWRITE);
4607	if(cctlfd == nil)
4608		return -1;
4609	sys->write(cctlfd, array of byte "rawon", 5);
4610
4611	dfd = sys->open("/dev/cons", sys->OREAD);
4612	if(dfd == nil)
4613		return -1;
4614
4615	spawn reader(keys, dfd);
4616	return 0;
4617}
4618.P2
4619A fine point: the variable
4620.CW cctlfd
4621that contains the FD for the control device is
4622declared external to the
4623init function, even though it appears to be used
4624only inside it.
4625Programming cleanliness suggests that
4626its declaration be moved inside, but here that
4627won't work;
4628device control files
4629in Inferno retain settings like `raw mode' only
4630while they remain open.
4631If
4632.CW cctlfd
4633were declared inside
4634.CW init ,
4635then returning from
4636.CW init
4637would destroy the last reference to the FD for the control file,
4638and the device would be closed automatically.
4639.PP
4640The reader function for this module has the same structure as the first
4641example, but doesn't have to worry about a noisy infrared detector:
4642.P1
4643reader(keys: chan of int, dfd: ref FD)
4644{
4645	n: int;
4646	b:= array[1] of byte;
4647
4648	for(;;) {
4649		n = sys->read(dfd, b, 1);
4650		if(n != 1)
4651			break;
4652		case int b[0] {
4653		'0' =>	n = Ir->Zero;
4654		'1' =>	n = Ir->One;
4655		. . .
4656		16r7f =>	n = Ir->Mute;
4657		* =>	n = Ir->Error;
4658		}
4659		keys <-= n;
4660	}
4661	keys <-= Ir->Error;
4662}
4663.P2
4664The following module can be used to test the above code.
4665It simply prints the name of the button that was pressed.
4666.P1
4667implement Irtest;
4668
4669include "sys.m";
4670include "draw.m";
4671FD: import Sys;
4672include "ir.m";
4673
4674Irtest: module
4675{
4676	init:  fn(nil: ref Draw->Context, nil: list of string);
4677};
4678ir: Ir;
4679sys: Sys;
4680.P2
4681.P1
4682init(nil: ref Draw->Context, nil: list of string)
4683{
4684	c: int;
4685	stderr: ref FD;
4686	irchan := chan of int;
4687
4688	sys = load Sys Sys->PATH;
4689	stderr = sys->fildes(2);
4690
4691	# If the real IR remote application can
4692	# be found, use it, otherwise use the simulator:
4693	ir = load Ir Ir->PATH;
4694	if(ir == nil)
4695		ir = load Ir Ir->SIMPATH;
4696	if(ir == nil) {
4697		# %r format code means the last system error string
4698		sys->fprint(stderr, "load ir: %r\en");
4699		return;
4700	}
4701	if(ir->init(irchan) != 0) {
4702		sys->fprint(stderr, "Ir.init: %r\en");
4703		return;
4704	}
4705	names := array[] of {
4706		"Zero",
4707		"One",
4708		. . .
4709		"Mute",
4710	};
4711	for(;;) {
4712		c = <-irchan;
4713		if(c == ir->Error)
4714			sys->print("Error %d\en", c);
4715		else
4716			sys->print("%s\en", names[c]);
4717	}
4718}
4719.P2
4720Finally, here is a snippet from a movie application that
4721uses the IR module; it demonstrates how
4722.CW alt
4723is useful for dealing with multiple events.
4724This is only one of the functions of the
4725movie module, so not everything is defined.
4726It uses the
4727.CW Mpeg
4728module, which actually
4729copies the MPEG data stream to the screen
4730asynchronously.
4731Its
4732.CW play
4733function takes, as one of its arguments,
4734a channel;
4735before starting to play it writes a
4736string on the channel.
4737An empty string indicates success at
4738locating the movie; a non-empty
4739string contains an error message.
4740When it finishes, it writes another string.
4741.P1
4742movie(entry: ref Dbinfo, cc: chan of int)
4743{
4744	i: int;
4745	m: Mpeg;
4746	b: ref Image;
4747
4748	m = load Mpeg Mpeg->PATH;
4749	if (m == nil)
4750		return;
4751	# make a place on the screen
4752	w := screen.window(screen.image.r);
4753
4754	mr := chan of string;
4755	s := m->play(w, 1, w.r, entry.movie, mr);
4756	if(s != "")
4757		return;
4758	# wait for the end of the movie
4759	# while watching for button pushes
4760	for(;;) {
4761		alt {
4762		<-mr =>
4763			return;
4764		i = <-cc =>
4765			case i {
4766			Ir->Select =>
4767				m->ctl("stop");
4768			Ir->Up or Ir->Dn =>
4769				m->ctl("pause");
4770			}
4771		}
4772	}
4773}
4774.P2
4775.NH 2
4776Monitors
4777.PP
4778Statically allocated storage within a module is accessible to
4779all the functions of that module,
4780and there is no explicit mechanism in Limbo for synchronizing
4781concurrent updates to this storage from several tasks.
4782However, it is straightforward to build a variety of concurrency-control
4783mechanisms by using channel communications.
4784.PP
4785An example is a module that implements a
4786.CW Monitor
4787abstract data type.
4788Each instance of
4789.CW Monitor
4790has a
4791.CW lock
4792and an
4793.CW unlock
4794operation;
4795calling
4796.CW lock
4797delays if another task holds the lock; calling
4798.CW unlock
4799releases the lock and enables any other task attempting
4800to execute
4801.CW lock .
4802.P1
4803implement Monitors;
4804
4805Monitors: module
4806{
4807	Monitor: adt {
4808		create: fn(): Monitor;
4809		lock: fn(m: self Monitor);
4810		unlock: fn(m: self Monitor);
4811		ch: chan of int;
4812	};
4813};
4814.P2
4815.P1
4816Monitor.create(): Monitor
4817{
4818	m := Monitor(chan of int);
4819	spawn lockproc(m.ch);
4820	return m;
4821}
4822.P2
4823.P1
4824Monitor.lock(m: self Monitor)
4825{
4826	m.ch <- = 0;
4827}
4828.P2
4829.P1
4830Monitor.unlock(m: self Monitor)
4831{
4832	<- m.ch;
4833}
4834.P2
4835.P1
4836lockproc(ch: chan of int)
4837{
4838	for (;;) {
4839		<- ch;	# wait for someone to lock
4840		ch <- = 0; # wait for someone to unlock
4841	}
4842}
4843.P2
4844It would be used like this:
4845.P1
4846mp: Mon;
4847Monitor: import mp;
4848mp = load Mon "...";
4849l := Monitor.create();
4850\. . .
4851l.lock();
4852# region of code to be protected;
4853# only one thread can execute here at once.
4854l.unlock();
4855.P2
4856The
4857.CW create
4858method of
4859.CW Monitor
4860allocates an instance of a
4861.CW Monitor
4862containing an initialized channel.
4863It also creates a thread executed in the
4864.CW lockproc
4865routine, which repeatedly reads from the channel,
4866then writes on it.
4867The values transmitted over the channel are of no
4868interest; it is the pure fact of communication that is put to use.
4869The
4870.CW lock
4871routine sends a message; in the idle state, the
4872.CW lockproc
4873thread reads it and the sender proceeds.
4874Meanwhile,
4875.CW lockproc
4876tries to send a message over the same channel.
4877If another thread attempts to
4878.CW lock ,
4879there is no reader for the channel, and so its transmission will block.
4880At some point, the thread that gained the lock
4881calls
4882.CW unlock ,
4883which receives from the channel.
4884Depending on timing, this reception enables execution of either
4885.CW lockproc
4886or one of the threads attempting to send via
4887.CW lock .
4888.PP
4889There is a simpler implementation of
4890.CW Monitor ,
4891using a buffered channel.
4892The
4893.CW create
4894operation simply allocates a channel with a one-element buffer:
4895.P1
4896Monitor.create(): Monitor
4897{
4898	return Monitor(chan[1] of int);
4899}
4900.P2
4901The
4902.CW lock
4903and
4904.CW unlock
4905operations have the same implementation.
4906Because of the buffer, when a process locks an unlocked
4907.CW Monitor ,
4908the send succeeds but fills the channel.
4909Subsequent attempts to
4910.CW lock
4911will therefore block as long as the channel is full.
4912.CW Unlock
4913removes the value from the channel, making it empty,
4914and allowing another
4915.CW lock
4916to proceed.
4917The
4918.CW lockproc
4919is not needed.
4920Note that a program using the module would not need to be recompiled to
4921use the new implementation, because the module's signature and use
4922remains the same.
4923This is the implementation of the
4924.CW Lock
4925module in the Limbo library for Inferno.
4926.PP
4927Limbo channels are usually unbuffered:
4928a sender blocks until there
4929is a receiver, and processes synchronise at each communication.
4930Buffered channels are used sparingly in Limbo programs, typically to improve throughput or,
4931less often, in specialized ways as in the monitor example above.
4932.NH 2
4933Guarding sends and receives
4934.PP
4935In some applications, a process takes input from one channel,
4936and sends it on to another channel, possibly having transformed it.
4937In case the input and output processes run at different rates,
4938the process itself acts as a buffer, holding a queue of values internally.
4939If the input process were faster than the output process, the queue
4940would accumulate values faster than they are consumed, exhausting memory.
4941To prevent that, when the queue reaches a specified limit, the process should guard against
4942receiving from the input channel, but continue sending to the output channel.
4943Conversely, when the queue is empty, it should not attempt to send.
4944The
4945.CW alt
4946statement allows a process to choose between sending and receiving based on
4947which channels are ready, but the process must also account for the current state
4948of the queue.
4949This example shows a way to make a buffered
4950channel of strings from an unbuffered channel.
4951It is written as a module whose
4952.CW bufchan
4953function takes a
4954.CW chan
4955.CW of
4956.CW string
4957and a size as argument, and returns a new channel;
4958it creates an asynchronous task that accepts input from the argument
4959channel and saves up to
4960.CW size
4961strings, meanwhile trying to send them to its user.
4962.P1
4963implement Bufchan;
4964Bufchan: module {
4965	bufchan: fn(c: chan of string, size: int): chan of string;
4966};
4967
4968xfer(oldchan, newchan: chan of string, size: int)
4969{
4970	temp := array[size] of string;
4971	fp := 0;        # first string in buffer
4972	n := 0;         # number of strings in buffer
4973	dummy := chan of string;
4974	sendch, recvch: chan of string;
4975	s: string;
4976
4977	for (;;) {
4978		sendch = recvch = dummy;
4979		if (n > 0)
4980			sendch = newchan;
4981		if (n < size)
4982			recvch = oldchan;
4983		alt {
4984		s = <-recvch =>
4985			temp[(fp+n)%size] = s;
4986			n++;
4987
4988		sendch <- = temp[fp] =>
4989			temp[fp++] = nil;
4990			n--;
4991			if (fp>=size)
4992				fp -= size;
4993		}
4994	}
4995}
4996.P2
4997.P1
4998bufchan(oldchan: chan of string, size: int): chan of string
4999{
5000	newchan := chan of string;
5001	spawn xfer(oldchan, newchan, size);
5002	return newchan;
5003}
5004.P2
5005The module is somewhat specialized, but it illustrates
5006useful programming techniques.
5007The most interesting occurs in
5008.CW xfer ,
5009which does the work.
5010The problem
5011.CW xfer
5012faces is that it doesn't want to receive input when its
5013buffer is full, nor to try to send when it has nothing to
5014transmit.
5015The solution here is to use a dummy channel
5016on which nothing is ever sent or received; in the
5017.CW alt
5018statement,
5019that channel substitutes for the real input channel
5020when the buffer is full, and for the output channel
5021when the buffer is empty.
5022.PP
5023The module could be used in the following way:
5024.P1
5025Bufchan: module {
5026	PATH: con "/dis/lib/bufchan.dis";
5027	bufchan: fn(c: chan of string, size: int): chan of string;
5028};
5029\. . .
5030bufc := load Bufchan Bufchan->PATH;
5031sourcech := chan of string;
5032
5033# ... (here, hand off sourcech to a process that
5034#      reads strings from it and copies them to ch)
5035ch: chan of string = bufc->bufchan(sourcech, 10);
5036\. . .
5037s := <- ch;
5038\. . .
5039.P2
5040.NH 1
5041Syntax summary
5042.PP
5043This section summarizes the grammar of Limbo
5044above the lexical level; constants and identifiers
5045are left undefined.
5046.PP
5047