A. Programming Style
Home ] 1. The CASLide ] 2. First Application ] 2. Floating Math ] 3. Dates and Times ] 4. Strings ] 5. Previous Program State ] 6. Data Browser ] 7. Data Entry ] 8. Conduit and Desktop Companion ] 9. Games ] 10. Graphics ] 11. Sound ] 12. Communications ] 13. Accessing Palm Databases ] 14. Distributing CASL Applications ] [ A. Programming Style ] B. Objects ] C. Positioning Objects ] D. POSE ] E. C Code ]

 

The following guidelines are used in writing code examples. For more information, see The CASL Language Reference Manual.

Keywords

Keywords appear in lower case letters and in courier new font:

put, if, randomn

Comments

A "#" character will preface comments:

# this is a comment

Global Variables

Global variables will be prefixed with data type indicator, and will use upper case at start of each word in name:

Data type Indicator prefix
numeric n
string s
boolean flag (numeric voluntarily restricted to true or false values f
byte array b
bitmap picture (byte array created by IDE to store icon or bitmap) p
object {o | oxx} (if voluntarily restricted to particular object type, xx is object type indicator)

Examples:

# global variable declarations
variables;
	numeric nNum;
	string sName;
	numeric fFlag; # value will be {true | false}
	numeric bBuffer[8]$; # byte array
	object ofrFrames[4]; # object array
end;

Objects

Object names will have indicator prefix, and will use upper case for start of each word in name:

Object Indicator prefix Examples
menu top mt mtMyMenu, mtOptions
menu item mi miMyMenuItem, miHelp, miAbout, miPurgeData
frame fr frMyFrame, frMain
grid gd gdTable, gdListView
label lb lbMyLabel, lbStatus
text box tx txMyText, txFarenheit
multi-line label (text box with no_input property set) ml mlMyMultiLineLabel, mlHelp
button bt btMyButton, btOK, btDoSomething
check box (text box with checkbox property set) ck ckMyCheckBox, ckAllowCancel
popdown list pd pdOptions
selector sl slMySelector, slFavoriteColor
file selector fs fsMyFiles, fsDBFiles
file fl flMyFile, flMemoDB
dbfile db dbMyDB, dbData, dbPreferences

Property Syntax

Referring to object properties will be done with dot format, when there's a syntax choice:

# statements using dot format, followed by 
#  alternative syntax
lbHeading.display="New Heading";
put lbHeading,"New Heading";
sHeading=lbHeading.display;
get lbHeading,sHeading;
lbHeading.hidden=false;
show lbHeading;

Functions

Function names will have upper case for start of each word in name:

function DisplayStatus;
	lbStatus.display="Ready";
end;

Local variables

Local variables scoped inside functions will be all lowercase, and not use data type prefixes.

Code Indenting

Control flow blocks, statements in functions, and variable declaration blocks are indented from the enclosing code:

# depending on value of icon, display a different
#  style message
function ShowMsg(numeric icon,string msg);
	# function block
	variables;
		# declaration block
		numeric mb; # local variable
	end;
	if icon=0;
		# if block, same indent for loop blocks
		mb=message_box(0,"Notice",msg,"","OK","");
	else;
		# else block
		if icon=2;
			mb=message_box(2,"Warning",msg,"","OK","");
		else;
			if icon=3;
				mb=message_box(3,"Error",msg,"","OK","");
			else;
				# unrecognized input, do nothing
			end_if;
		end_if;
	end_if;
end;

Long Lines

Lines too long to appear on one line will be continued on next line with single indent from start of line:

# a long line
mb=message_box(0,"Notice",
 "You have reached maximum "+
 "capacity of category names.  "+
 "Please delete any unneeded "+
 "categories, and try again","","OK,"");

Functions with Return Value

Functions with return value will be prefixed with data type indicator and "f", and will use upper case for start of each word in name:

Return data type of function Indicator prefix
numeric nf
string sf
boolean flag (numeric voluntarily restricted to true or false values) ff

Examples:

# a numeric example
function nfCelsius(numeric farenheit) as number;
	nfCelsius=(farenheit-32)/1.8;
end;
nAmbientC=nfCelsius(70);
# a string example
function sfTitleCase(string word) as string;
	sfTitleCase=upper(left(word,1)+
	 lower(right(word,length(word)-1));
end;
lbHeading.display=sfTitleCase("your")+" "+sfTitleCase("name");
# a boolean flag example
function ffConfirmYes(string msg) as numeric;
	ffConfirmYes=message_box(1,"Confirm",msg,
	 "Yes","","No")=0;
end;
if ffConfirmYes ("Delete "+sFileName+
 ", are you sure?");
	delete sFileName;
end_if;

Package Files (CPK)

Variables, objects, and functions in a code package file that is meant to be stand-alone library type package file will be prefixed with a package file indicator, usually described in a comment at start of package file. Indicator convention will be a two- or three-letter abbreviation based on filename followed by "_". The same prefix will be part of the filename for the package file as well.

Examples:

# statement referring to a variable in the 
#  package file ah_AboutHelp.cpk
# also statement using a function in the 
#  package file sm_ShowMsg.cpk
if ah_fDisabled;
	sm_ShowWarnMsg("Not allowed now");
end_if;
# statement referring to an object in the 
#  package file ah_AboutHelp.cpk
ah_mlText.display=sHelpText;

Sample Programs

The sample programs have a large CSL main code module where most of the code can be found. The exception is support functions that may be in CPK package files. The CSL file is laid out in the following order:

  • compiler flags
  • global variables
  • objects, dbfile, file, and menu (visual objects are in CFF files)
  • general functions (generally package include statements are also here)
  • invoker functions for menu objects
  • invoker functions for main frame
  • invoker functions for other frames
  • invoker functions for startup and shutdown

The sample programs have been written to fit within the demo compiler limits, and therefore some compromises have been made. Although it's better programming practice to keep functions limited to a single task, this would increase the number of functions, and result in function count more than allowed by demo compiler. Instead functions are very long, and contain code to perform all tasks associated with their top-level task. As is the case with any event driven program, most tasks are initiated by the user interface. Therefore the invoke functions are the means to carry out the user's top-level wishes. As expected, the invoke functions basically contain all the code for the sample apps. As an example consider the following invoke function:

# save shown record, and return to list view frame
function btSave;
	# read user data and assign to field data
	sAccount=txAccount.display;
	sUser=txUser.display;
	sPassword=txPassword.display;
	sNote=txNote.display;
	# don't want to create record with null key,
	#  no save performed, no notice to user
	if sAccount<>"";
		# save field data
		errorcode=ce_no_error;
		search dbPassword,txAccount.display;
		if errorcode=ce_no_error;
	
			# found, and pointer at this record,
			#  write new data at pointer
			put_fields dbPassword;
			if errorcode<>0;
				# give warning
				sml_ShowMsg(2,ce_geterror+
				 " editing existing record");
			end_if;
	
		else;
			if errorcode=-12; # not found
				# not found, insert new record
				if nNumRec=16;
					# can't add record, at max
					sml_ShowMsg(0,
					 "At "+string(16,"")+
					 " record max. Must delete a record, "+
					 "before can a new one.");
				else;
				
					# attempt to add new record
					errorcode=ce_no_error;
					insert dbPassword;
					if errorcode=ce_no_error;
						# success, update number of records
						nNumRec=nNumRec+1;
					else;
						# error
						sml_ShowMsg(2,ce_geterror+
						 " adding new record");
					end_if;
			   end_if;
	
			else;
	
				# unexpected access error
				sml_ShowMsg(2,ce_geterror+
				 " accessing db");
	
			end_if;
		end_if;
	
	end_if;
	# toggle display back to list view
	hide frRecordView;
	if not ffReloadSelector;
		sml_ShowMsg(2,ce_geterror+" accessing db");
	end_if;
	show frMain;
end;

In my view, the above would be easier to read (and debug, and re-use code segments), if instead the top-level function called functions for the separate tasks of file prep, handle save cases, and post save display task. Within these tasks, there are code blocks that would be good candidates for their own functions as well. For example all db access related tasks could be encapsulated by their own functions.

On the other hand the above offers the clear advantage that the program uses less functions and therefore can be compiled with demo compiler, allowing a wider audience to get a first impression of CASL. It's also hoped that by not having nested function calls, the code is in some ways more transparent, in that it's all in one place. There's no need to search around for specific code blocks. To address the readability concerns, blank lines are added to partition code blocks dedicated to specific low-level tasks.

 

 

[ Top ]

© 2001, Feras Information Technology. All rights reserved.