Examples

CellSpeak Types

In this example we go through the different types that can be used in CellSpeak, how they can be initialised etc.

Most of this should be very familiar because it is very similar as to how these type of things are done in other languages. There are however a few points we want to draw your attention to. These points are annotated in the code on the right and explained in the left column.









(1) CellSpeak has the types int16, int32 and int64 - int is shorthand for int32. For unsigned integers the types byte, word16, word32 and word64 exist - word is shorthand for word32.



(2) Also for constants you can drop the type - it will be deduced from the initialisation.


(3) It is also possible to declare a variabe to be like another variable: var Y like X, in that case Y will have the type of X.


(4) A type that has methods added to it inherits all the methods and operators from the ancestor type - in this case float - so you can do everything with the type distance that you can do with float. Note that the value of the variable is referred to as this as is the case


















(5)The escape sequence \- in the string is actually a toggle to remove or leave leading space in a multi-line string.














(6) Enumerator values are referred uing their type and value, example BigCities.London.













(7) In strings anything between [ and ] is evaluated as an expression and formatted. If the default format for a type is not what is needed, it can be modified as in this example. The format modifiers are like the ones used in standard C library.






(8) Note that there is no explicit allocation required for the array. If you give an explicit size to an array in a declaration like I[10], then that array will stay of that size. If you do not give an explicit size, the array can change size with a simple initialisation, which is practical for strings. Because in most cases the allocation will be on the scratchpad memory, there is no danger for memory leakage. The size of any array can always be changed by using the directive sel, short for 'set number of elements'.








(9) A multi-deminsional array A[a,b,c] is a contiguous piece of memory with size a x b x c x size of an element. An array of arrays A[a][b][c] is an array of a arrays that each contain b arrays of each c elements. In total there are also a x b x c elements, but organised in a different way.

















(10) The basic vector types in CellSpeak are there as the basis for types with more meaningful names. The vector with three float components in CellSpeak is vec3f and the components are called c1, c2 and c3. From this type the vector type xyz is derived with components x, y and z - in CellSpeak the components of an inherited record can be renamed.






































(11) If a conversion is well defined, it will be done automatically like in this case. The transposed of a 4x4 matrix is also a 4x4 matrix. The assignment of a 4x4 matrix to a 3x3 matrix is a well defined operation: the 3x3 part of the 4x4 matrix is assigned.





























(12) Having to give too many names for things in programming languages can be a nuissance - in this example a record constant is defined without creating an explicit type. You can still create other constants or variables of the same type, by using the keyword like as in var V like Beatles or by doing an assignment: var V = Beatles.




















(13) Keep can also be used to define fields of records. In this definition keep means create a field with the name, type and value of the variable. Simple.

02 CellSpeak Types.celsrc
use Windows, Math, Strings, Editor

group Syntax

design Demonstrator is
	
	cell Window -- A cell for output

	constructor is

	-. 	Output window for the examples .-
	
		-- We create a simple output window.
		Window = create MenuWindow("Types in CellSpeak")
		Window <- println("Some examples of types and declarations.")	

	-.  Declarations of simple variables .-

		int i			-- an integer variable 
(1)		int32 j			-- int and int32 are synonymous
		float f			-- a floating point variable
		byte b			-- a byte
	
		-- constants are initialised with an assignment
		const int BottlesPerCrate = 24	-- type is set explicitly
(2)		const Planck = 6.626069E–34		-- Type is deduced.
		
		-- The type of a 'var' is deduced from the initialisation
(3)		var Temperature = 0.0			-- type is float
		var Count = 77					-- type is int
		var Farenheit like Temperature	-- type is float
		
	-.	Every type can have methods.-
	
(4)		type distance is float with
			function km => this / 1000.0		
			function mm => this * 1000.0
		end
		
		-- declare and initialize a variable of the type 'distance'
		distance WeeklyTraining = 15365.92
		
		-- In strings expressions between [] are replaced by their values, 
		-- eg 'WeeklyTraining' will be replaced by the value above.
		Window <- print("\nEvery week I run [WeeklyTraining] meters, 
						which is [ WeeklyTraining.km() ] km, 
						but also [ WeeklyTraining.mm() ] mm.")
		
	-. 	Number formats .-
	
		int MountEverest = 8848				-- an int
		word BitMask = 0x00AF012D			-- a hexadecimal number
		const LF = 0x0A						-- a one byte hexadecimal
		const AtSign = 0x'@'				-- an ASCII char byte
		var ElectronCharge = 9.10938356D-31	-- a double
	
		-- We can print some of these values as follows.
(5)		Window <- print("\-\nSome simple facts. 
			The leading space is removed from the lines.
			1. Mount Everest is [MountEverest] meters high.
			2. The charge of an electron is [ElectronCharge].
			3. The ASCII 'at sign' looks like this: [AtSign]")
						 
		-- You can specify an explicit format: [ expression, format ]
		-- The escape sequence \- instructs to keep leading space :

		Window <- print("\n
			The Same as above but with explicit format specifications.
			Leading space is not removed.
			1. Mount Everest is [MountEverest, %9.9d] meters  high.
			2. The charge of an electron is [ElectronCharge, %6.1e]. 
			3. The ASCII 'at sign' hex-value is [AtSign, %2.2x].")
						
	-. 	Enumerators .-
	
		-- An enumerator type is defined as follows:
(6)		type BigCities is [ Paris, London, NewYork, Bejing, 
							Tokio, Mexico, HongKong, Rio, 
							Shanghai, Mumbai, Moscow ]
		
		-- we can use the enumerator type as an index into an array..
		float[BigCities] CityPopulation	 = [  2.2,  8.7,  8.6, 21.5, 
											 13.3,  8.9,  7.3,  6.4, 
											 24.3, 12.5, 12.2]
		
		-- we can create a variable of the type 
		BigCities Ville = BigCities.Paris
		
		-- The ToString() function is added for each enumerator type.
		Window <- println("We call [Ville.ToString()] the city of light.")
		
		-- we can use enumerators in a loop
		Window <- println("Population Statistics")
(7)		for each city in BigCities => Window <- println(
			"\t[city.ToString()] has a pop. of [CityPopulation[city]] M")
									
	-.	Arrays .-

		int ElectionYears[100]		-- an array of 100 integers
		type Counters is int[]		-- an unsized arrays of integers
		Counters[365] CallsPerDay	-- a sized array of the type
		
		-- Arrays can be initialised
(8)		int Primes[] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 
						43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]		
		Window <- print("\nThis is the sixth prime: [Primes[5]]")
		
		-- Multi dimensional arrays
		xyz V[10,10,10] 	-- An array of 10x10x10 vectors
		
		-- Set an element of the array.
		V[3,2,9] = [ 3, 2^5, 9.2]	--  is a type cast
		
		-- Print the three components - the first '[' is escaped.
		Window <- println("V\[3,2,9].y =  [V[3,2,9].y ]")
		
		-- This will print as: V[3,2,9].y = 32.0
			
		-- An array of arrays is not the same as a multidimensional array
(9)		int I[3][4][5] 	-- An array of 3 arrays of 4 arrays of 5 integers	
										
		--in the same way we can set a component in I
		I[1][2][3] = 9542 
		
		-- ..and print it
		Window <- println("I\[1]\[2]\[3] =  [ I[1][2][3] ]")
		
		-- This will print as: I[1][2][3] = 9542
		
	-.	Vector and matrix types
		Vectors and matrices are so often used that vector types for 2, 
		3 and 4 components of the type int, float or double are built-in 
		types in CellSpeak. Also square matrices of 2x2, 3x3 and 4x4
		with int, float or double elements are built-in types.
		Operations on these types use specific processor instructions.
	.-
		
		xyz q, r
		r = [1,2,3]
		q = r.norm()
		
		-- Based on the vector type xyz, we define a type axis
(10)	type Axis is xyz with
			
			-- A method to calculate the rotation matrix about an axis
			function Rotation(float angle) out matrix3 is
			
				float s = sin(angle)
				float c = cos(angle)
				float k = 1 - c
				xyz v = this.norm()		-- we need the normalised axis
											
				-- Rodrigues Rotation Formula
				return [ 	
					c+v.x^2*k, 		 v.x*v.y*k-v.z*s, v.x*v.z*k+v.y*s,
					v.x*v.y*k+v.z*s, c + v.y^2*k,	  v.y*v.z*k-v.x*s,
					v.x*v.z*k-v.y*s, v.y*v.z*k+v.x*s, c + v.z^2*k	
				]
			end					
		end							
		
		-- Three variables of the type Axis
		Axis X = [1,0,0], Y = [0, 1, 0], Z
		
		-- The vector product is a built-in operation
		Z = X # Y	-- [1,0,0] # [0,1,0] = [0,0,1]
		
		-- Escape the first [ for every vector to print it 
		Window <- println("	If X = \[[X.x], [X.y], [X.z]]  
							and Y = \[[X.x], [X.y], [X.z]], 
							then Z = X#Y = \[[Z.x], [Z.y], [Z.z]]")
		 
		-- test the formula in a simple case: pi/4 around the z-axis
		matrix3 R = Z.Rotation(pi/4 )	
		
		-- print the result
		Window <- println("\nRotation matrix:
						 [R.c11]	[R.c12]		[R.c13]
						 [R.c21]	[R.c22]		[R.c23]
						 [R.c31]	[R.c32]		[R.c33]")
						 
		-- For a rotation matrix, the inverse is the transposed matrix
		R.transpose()
		
		-- print the result
		Window <- println("Inverted (transposed) rotation matrix:
						 [R.c11]	[R.c12]		[R.c13]
						 [R.c21]	[R.c22]		[R.c23]
						 [R.c31]	[R.c32]		[R.c33]")
						 
		-- A 4x4 matrix
		matrix4 M4x4 = [ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
				
		-- cast to 3x3 and transpose
(11)	matrix3 M3x3 = transpose( M4x4 )
		
		-- print the result
		Window <- println("Transposing the 3x3 part of a 4x4 matrix:
						 [M3x3.c11]	[M3x3.c12]	[M3x3.c13]
						 [M3x3.c21]	[M3x3.c22]	[M3x3.c23]
						 [M3x3.c31]	[M3x3.c32]	[M3x3.c33]")
							 
	-.	Records .-
	
		-- Records are objects - they have state and methods:
		type CityData is record
		
			ansi 	Country
			int		NrOfInhabitants
			float 	Altitude
			
			function HeightDifference( CityData OtherCity) out float is
				return Altitude - OtherCity.Altitude
			end
		end

		-- a variable of the type with initialisation
		CityData London = ["United Kingdom", 8_538_689, 35.0 ]
		
		Window <- print("\-\nLondon is the capital of the [London.Country],
						has a population of [London.NrOfInhabitants] and 
						lies at an altitude of [London.Altitude] meter.")
		
		-- Records have inheritance.
		type MoreCityData is CityData with			
			rename 	Altitude to Elevation	-- we can rename fields
			float	SurfaceArea				-- we can add new fields
		end
		
		-- We can define a record without having to define a type..
(12)	const Beatles is record 
			ansi Basist = "Paul McCartney"	-- ..and assign to each field
			ansi RythmGuitar = "John Lennon"
			ansi LeadGuitar = "George Harisson"
			ansi Drums = "Ringo Starr"
			NrOfRecords = 600_000_000		-- underscores for clarity
		end
		
		Window <- println("\-The fab four are:
				[Beatles.Basist], [Beatles.RythmGuitar], 
				[Beatles.LeadGuitar] and [Beatles.Drums].
				They sold around [Beatles.NrOfRecords] records.")
		
		-- a variable record initialised in the same way		
		var Painting is record
			ansi Title = "Victory Boogie Woogie"
			ansi Artist = "Piet Mondriaan"
			int NrOfColours = 3
		end
		
		Window <- println(	"The famous painting '[Painting.Title]' 
							by [Painting.Artist] uses 
							only [Painting.NrOfColours] colours")
		
		-- supposse we have two variables (or parameters)..
		float Distance = 1153.28
		ansi City = "Vienna"
		
		-- ..then we can also create a record simply as follows
(13)	var Trip is record
			keep Distance
			keep City
		end
		
		-- we can create other records of the same type by using like
		var LongTrip like Trip
		
		-- ..or by assignment
		var LongTripToo = Trip

		-- and modify as required
		LongTrip.City = "New York"
		LongTrip.Distance = 5834.06
		
	end -- of constructor
	
end -- of design