xref: /illumos-gate/usr/src/contrib/ast/src/cmd/ksh93/TYPES (revision b30d1939)
17c2fbfb3SApril Chin
27c2fbfb3SApril ChinThe ability for users to define types has been added to ksh93t.
37c2fbfb3SApril ChinHere is a quick summary of how types are defined and used in ksh93t.
47c2fbfb3SApril ChinThis is still a work in progress so some changes and additions
57c2fbfb3SApril Chinare likely.
67c2fbfb3SApril Chin
77c2fbfb3SApril ChinA type can be defined either by a shared library or by using the new
87c2fbfb3SApril Chintypeset -T option to the shell.  The method for defining types via
97c2fbfb3SApril China shared library is not described here.  However, the source file
107c2fbfb3SApril Chinbltins/enum.c is an example of a builtin that creates enumeration types.
117c2fbfb3SApril Chin
127c2fbfb3SApril ChinBy convention, typenames begin with a capitol letter and end in _t.
137c2fbfb3SApril ChinTo define a type, use
147c2fbfb3SApril Chin	typeset -T Type_t=(
157c2fbfb3SApril Chin		definition
167c2fbfb3SApril Chin	)
177c2fbfb3SApril Chinwhere definition contains assignment commands, declaration commands,
187c2fbfb3SApril Chinand function definitions.  A declaration command (for example typeset,
197c2fbfb3SApril Chinreadonly, and export), is a built-in that differs from other builtins in
207c2fbfb3SApril Chinthat tilde substitution is performed on arguments after an =, assignments
217c2fbfb3SApril Chindo not have to precede the command name, and field splitting and pathname
227c2fbfb3SApril Chinexpansion is not performed on the arguments.
237c2fbfb3SApril ChinFor example,
247c2fbfb3SApril Chin	typeset -T Pt_t=(
257c2fbfb3SApril Chin		float -h 'length in inches' x=1
267c2fbfb3SApril Chin		float -h 'width in inches' y=0
277c2fbfb3SApril Chin		integer -S count=0
287c2fbfb3SApril Chin		len()
297c2fbfb3SApril Chin		{
307c2fbfb3SApril Chin			print -r $((sqrt(_.x*_.x + _.y*_.y)))
317c2fbfb3SApril Chin		}
327c2fbfb3SApril Chin		set()
337c2fbfb3SApril Chin		{
347c2fbfb3SApril Chin			(( _.count++))
357c2fbfb3SApril Chin		}
367c2fbfb3SApril Chin	)
377c2fbfb3SApril Chin
387c2fbfb3SApril Chindefines a type Pt_t that has three variables x, y, and count defined as well
397c2fbfb3SApril Chinas the discipline functions len and set.  The variable x has an initial value
407c2fbfb3SApril Chinof 1 and the variable y has an initial value of 0.  The new -h option argument,
417c2fbfb3SApril Chinis used for documentations purposes as described later and is ignored outside
427c2fbfb3SApril Chinof a type definition.
437c2fbfb3SApril Chin
447c2fbfb3SApril Chin
457c2fbfb3SApril ChinThe variable count has the new -S attribute which means that it is shared
467c2fbfb3SApril Chinbetween all instances of the type.  The -S option to typeset is ignored
477c2fbfb3SApril Chinoutside of a type definition.  Note the variable named _ that is used inside
487c2fbfb3SApril Chinthe function definition for len and set.  It will be a reference to the
497c2fbfb3SApril Chininstance of Pt_t that invoked the function.  The functions len and set
507c2fbfb3SApril Chincould also have been defined with function len and function set, but
517c2fbfb3SApril Chinsince there are no local variables, the len() and set() form are more
527c2fbfb3SApril Chinefficient since they don't need to set up a context for local variables
537c2fbfb3SApril Chinand for saving and restoring traps.
547c2fbfb3SApril Chin
557c2fbfb3SApril ChinIf the discipline function named create is defined it will be
567c2fbfb3SApril Chininvoked when creating each instance for that type. A function named
577c2fbfb3SApril Chincreate cannot be defined by any instance.
587c2fbfb3SApril Chin
597c2fbfb3SApril ChinWhen a type is defined, a declaration built-in command by this name
607c2fbfb3SApril Chinis added to ksh.  As with other shell builtins, you can get the man page
617c2fbfb3SApril Chinfor this newly added command by invoking Pt_t --man.  The information from
627c2fbfb3SApril Chinthe -h options will be embedded in this man page.  Any functions that
637c2fbfb3SApril Chinuse getopts to process arguments will be cross referenced on the generated
647c2fbfb3SApril Chinman page.
657c2fbfb3SApril Chin
667c2fbfb3SApril ChinSince Pt_t is now a declaration command it can be used in the definition
677c2fbfb3SApril Chinof other types, for example
687c2fbfb3SApril Chin	typeset -T Rect_t=( Pt_t ur ll)
697c2fbfb3SApril Chin
707c2fbfb3SApril ChinBecause a type definition is a command, it can be loaded on first reference
717c2fbfb3SApril Chinby putting the definition into a file that is found on FPATH.
727c2fbfb3SApril ChinThus, if this definition is in a file named Pt_t on FPATH, then
737c2fbfb3SApril China program can create instances of Pt_t without first including
747c2fbfb3SApril Chinthe definition.
757c2fbfb3SApril Chin
767c2fbfb3SApril ChinA type definition is readonly and cannot be unset.  Unsetting non-shared
777c2fbfb3SApril Chinelements of a type restores them to their default value.  Unsetting a
787c2fbfb3SApril Chinshared element has no effect.
797c2fbfb3SApril Chin
807c2fbfb3SApril ChinThe Pt_t command is used to create an instance of Pt_t.
817c2fbfb3SApril Chin	Pt_t p1
827c2fbfb3SApril Chincreates an instance named p1 with the initial value for p1.x set to 1
837c2fbfb3SApril Chinand the initial value of p1.y set to 0.
847c2fbfb3SApril Chin	Pt_t p2=(x=3 y=4)
857c2fbfb3SApril Chincreates an instance with the specified initial values.  The len function
867c2fbfb3SApril Chingives the distance of the point to the origin.  Thus, p1.len will output
877c2fbfb3SApril Chin1 and p2.len will output 5.
887c2fbfb3SApril Chin
897c2fbfb3SApril Chinksh93t also introduces a more efficient command substitution mechanism.
907c2fbfb3SApril ChinInstead of $(command), the new command substitution ${ command;}
917c2fbfb3SApril Chincan be used.  Unlike (and ) which are always special, the { and } are
927c2fbfb3SApril Chinreserved words and require the space after { and a newline or ; before }.
937c2fbfb3SApril ChinUnlike $(), the ${ ;} command substitution executes the command in
947c2fbfb3SApril Chinthe current shell context saving the need to save and restore
957c2fbfb3SApril Chinchanges, therefore also allowing side effects.
967c2fbfb3SApril Chin
977c2fbfb3SApril ChinWhen trying to expand an element of a type, if the element does not exist,
987c2fbfb3SApril Chinksh will look for a discipline function with that name and treat this as if
997c2fbfb3SApril Chinit were the ${ ;} command substitution.  Thus, ${p1.len} is equivalent to
1007c2fbfb3SApril Chin${ p1.len;} and within an arithmetic expression, p1.len will be expanded
1017c2fbfb3SApril Chinvia the new command substitution method.
1027c2fbfb3SApril Chin
1037c2fbfb3SApril ChinThe type of any variable can be obtained from the new prefix
1047c2fbfb3SApril Chinoperator @.  Thus, ${@p1} will output Pt_t.
1057c2fbfb3SApril Chin
1067c2fbfb3SApril ChinBy default, each instance inherits all the discipline functions defined
1077c2fbfb3SApril Chinby the type definition other than create.  However, each instance can define
1087c2fbfb3SApril China function by the same name that will override this definition.
1097c2fbfb3SApril ChinHowever, only discipline functions with the same name as those defined
1107c2fbfb3SApril Chinby the type or the standard get, set, append, and unset disciplines
1117c2fbfb3SApril Chincan be defined by each instance.
1127c2fbfb3SApril Chin
1137c2fbfb3SApril ChinEach instance of the type Pt_t behaves like a compound variable except
1147c2fbfb3SApril Chinthat only the variables defined by the type can be referenced or set.
1157c2fbfb3SApril ChinThus, p2.x=9 is valid, but p2.z=9 is not.  Unless a set discipline function
1167c2fbfb3SApril Chindoes otherwise, the value of $p1 will be expanded to the form of a compound
1177c2fbfb3SApril Chinvariable that can be used for reinput into ksh.
1187c2fbfb3SApril Chin
1197c2fbfb3SApril ChinIf the variables var1 and var2 are of the same type, then the assignment
1207c2fbfb3SApril Chin	var2=var1
1217c2fbfb3SApril Chinwill create a copy of the variable var1 into var2.  This is equivalent to
1227c2fbfb3SApril Chin	eval var2="$var1"
1237c2fbfb3SApril Chinbut is faster since the variable does not need to get expanded or reparsed.
1247c2fbfb3SApril Chin
1257c2fbfb3SApril ChinThe type Pt_t can be referenced as if it were a variable using the name
1267c2fbfb3SApril Chin.sh.type.Pt_t.  To change the default point location for subsequent
1277c2fbfb3SApril Chininstances of Pt_t, you can do
1287c2fbfb3SApril Chin	.sh.type.Pt_t=(x=5 y=12)
1297c2fbfb3SApril Chinso that
1307c2fbfb3SApril Chin	Pt_t p3
1317c2fbfb3SApril Chin	p3.len
1327c2fbfb3SApril Chinwould be 13.
1337c2fbfb3SApril Chin
1347c2fbfb3SApril ChinTypes can be defined for simple variables as well as for compound
1357c2fbfb3SApril Chinobjects such as Pt_t.  In this case, the variable named . inside
1367c2fbfb3SApril Chinthe definition refers to the real value for the variable.  For example,
1377c2fbfb3SApril Chinthe type definition
1387c2fbfb3SApril Chin	typeset -T Time_t=(
1397c2fbfb3SApril Chin		integer .=0
1407c2fbfb3SApril Chin		_='%H:%M:%S'
1417c2fbfb3SApril Chin		get()
1427c2fbfb3SApril Chin		{
1437c2fbfb3SApril Chin			.sh.value=$(printf "%(${_._})T" "#$((_))" )
1447c2fbfb3SApril Chin		}
1457c2fbfb3SApril Chin		set()
1467c2fbfb3SApril Chin		{
1477c2fbfb3SApril Chin			.sh.value=$(printf "%(%#)T" "${.sh.value}")
1487c2fbfb3SApril Chin
1497c2fbfb3SApril Chin		}
1507c2fbfb3SApril Chin	)
1517c2fbfb3SApril Chin
1527c2fbfb3SApril ChinThe sub-variable name _ is reserved for data used by discipline functions
1537c2fbfb3SApril Chinand will not be included with data written with the %B option to printf.
1547c2fbfb3SApril ChinIn this case it is used to specify a date format.
1557c2fbfb3SApril Chin
1567c2fbfb3SApril ChinIn this case
1577c2fbfb3SApril Chin	Time_t t1 t2=now
1587c2fbfb3SApril Chinwill define t1 as the time at the beginning of the epoch and t2
1597c2fbfb3SApril Chinas the current time.  Unlike the previous case, $t2 will output
1607c2fbfb3SApril Chinthe current time in the date format specified by the value t2._.
1617c2fbfb3SApril ChinHowever, the value of ${t2.} will expand the instance to a form
1627c2fbfb3SApril Chinthat can be used as input to the shell.
1637c2fbfb3SApril Chin
1647c2fbfb3SApril ChinFinally, types can be derived from an existing type.  If the first
1657c2fbfb3SApril Chinelement in a type definition is named _, then the new type
1667c2fbfb3SApril Chinconsists of all the elements and discipline functions from the
1677c2fbfb3SApril Chintype of _ extended by elements and discipline functions defined
1687c2fbfb3SApril Chinby new type definition.  For example,
1697c2fbfb3SApril Chin
1707c2fbfb3SApril Chin	typeset -T Pq_t=(
1717c2fbfb3SApril Chin		Pt_t _
1727c2fbfb3SApril Chin		float z=0.
1737c2fbfb3SApril Chin		len()
1747c2fbfb3SApril Chin		{
1757c2fbfb3SApril Chin			print -r $((sqrt(_.x*_.x + _.y*_.y + _.z*_.z)))
1767c2fbfb3SApril Chin		}
1777c2fbfb3SApril Chin	)
1787c2fbfb3SApril Chin
1797c2fbfb3SApril Chindefines a new type Pq_t which is based on Pq_t and contains an additional
1807c2fbfb3SApril Chinfield z and a different len discipline function.  It is also possible
1817c2fbfb3SApril Chinto create a new type Pt_t based on the original Pt_t.  In this case
1827c2fbfb3SApril Chinthe original Pt_t is no longer accessible.
183