PocketC Language Specification

Comments

 // My Applet

 This is also known as a comment. Anytime the compiler finds '//' in your applet, it will ignore the rest of the line that it is on. This allows you to place explanatory text in your applet. There is one other way to put a comment in your applet, by surrounding the text with '/* */'. This method allows you to spread a comment out over several lines. Example:

 /* This is a multi-line comment.
All the text between the
asterisks is ignored */

 

The Global Variables

Variables are the things that are used to store values in a program. There are four types of variables in PocketC:
Type Name Example
integer int 1, 2, 5, -789, 452349
floating point float -1.2, 3.141592, 5.7e-4
characters char 'a', 'b', '#'
strings string "Bob" "Katie" "Hello"
Variables are declared like this:
variable-type name[,name...];

 Here are a few examples:

int myInteger, row, column;

string name;

float pi;

char c, last, first;
It is also possible to have an array of values. An array is a list of values that are stored in one variable. Arrays are declared like normal variables except that the variable name is followed by '[size]' where size is the number of item that the variable can hold. A declaration might look like this:
int values[10];

string names[7];
Of course, arrays and normal variables can be declared together:
int row, values[10], column;

string name, colors[8];
We'll discuss variables a little more later.

The Functions

Functions are the most important part of a program, they contain the actual instructions that make a program useful. All functions have a name and a parameter list (which may be empty) and are declared like the:
func-name([param-type param-name,...]) { statements }

 Statements are discussed later, but for now, here are a few examples:

area(int width, int height) {

   return width * height;

}



square(float x) {

   return x * x;

}



five() {

   return 5;

}
There is one special function name which all programs must have: main. The main function is the function which is called first in your program. When the main function exits, the program terminates. The main function must be declared with no paramters:
// My Applet

main() {

   puts("Hello World");

}
Functions can also have local variables, which are variables that can only be accessed within the function that declares them. Global variables, however, can be accessed from anywhere. Local variables are declared in the same way that global variables are except that they immediately follow the opening brace of a function:
// My Applet

main() {

   string localString;



   localString = "Hello World";

   puts(localString);

}
Before we go any further, we need to talk a little bit about expressions.

Expressions

An expression is any number of constants, variables, and function calls connected by operators and parentheses.

 A constant is any value that is directly entered into the program, such as: 5 5.4 'a' "String"

 A value stored in a variable can be accessed by just typing its name: myInteger name
However, if that variable is an array, each value must be accessed individually by index. The valid indices for a given array are 0 to n-1 where n is the number of values in the array. So an array declared:

string names[4]
can be accessed like so:
names[0] = "first name";

names[1] = "second name";

names[2] = "third name";

names[3] = "fourth name";
A function call consists of the name of a function, followed by an open paren, the parameter list, and a closing paren:
area(5, 7);

square(8.9);

clear();

text(30, 55, "Game Over");
These three basic elements can be combined with operators:
5 + 7 - area(12, 34);

square(5) * pi;

"Hello, " + "World";
Of course, function calls can have expressions in them as well:
area(6+3, 8*9);

area(8 * square(4), 7);

Assignment

Variable assignment is actually just another form of expression. Assignment is done in one of two ways--for a normal variable:
name = expression

 and for an array:
name[index-expression] = expression

 Here are a few examples:

int myInt, numbers[3];

string myString;

...

myInt = 8;

myString = "Animaniacs";

numbers[0] = myInt + 5;

numbers[2] = numbers[0] * 8;
However, since PocketC is loosely typed, any type of value can be assigned to any type of variable and the value will be automatically converted:
myString = 95; // The value of myString is now "95"

numbers[1] = "78"; // The value of numbers[1] is now 78;

numbers["2"] = "2"; // Another neat trick. numbers[2] is now 2
Now, what are all the operators that can be used in an expression, and what is their associativity? Good question.

Operators

Operator Assoc Description
= right assigns the value of the expression on the right to the variable on the left. Evaluates to the expression on the right.
|| left logical 'or', evaluates to 0 if false, 1 if true
&& left logical 'and'
== != < <= > >= left relational operators. == (equal), != (not equal), <= (less than or equal), >= (greater than or equal). These evaluate to 1 if the expression is true, 0 otherwise
+ - left addition, subtraction (subtraction cannot be used with a string argument)
* / % left multiplication, division, modulus (cannot be used with strings, nor can modulus be used with floats)
- ! ++ -- left unary operators. - (negation), ! (logical 'not'), ++ (increment), -- (decrement) (Only the logical 'not' can be used with strings)
Note: No shortcut logic is performed on the operands of || and &&

Bitwise Operators

PocketC supports a full complement of bitwise operators.  Bitwise operation is used for variable type int or char.  You cannot use bitwise operations on float or string data types.  

& AND
| OR
^ Exclusive OR (XOR)
~ One's complement
>> Shift Right
<<  Shift Left

Increment / Decrement

The ++ and -- operators are special in that they must be placed before or after a variable and modify the value of the variable. The ++ increments the value of a variable by one, while the -- decrements by one. The caveat is that if the ++/-- is placed in front of the variable, the expression evaluates to the value of the variable after it is incremented/decremented. If it is placed after the variable, the expression evaluates to the variable's previous value. Example:
int myInt;

...

myInt = 8;

puts(++myInt); // Prints "9" to the output form



myInt = 8;

puts(myInt++); // Prints "8" to the output form, but myInt is now 9

Automatic Conversion and Casting

Just like in assignments statements, automatic conversion takes place in every part of an expression. If the two arguments to an operator are of different types, one of arguments will be promoted to the less strict type. The promotion order is char to int to float to string. So in the expression:
"Result is: " + 5;
The constant 5 is first promoted to a string, and the two strings are concatenated. This may have some undesirable side effects. For example, if you want to write an expression and result to the output form, you might do something like this:
puts("5 + 7 = " + 5 + 7); // Prints "5 + 7 = 57"
This probably wasn't the desired outcome. Instead, you would want the expression evaluated first, then concatenated to the string. The parentheses can be used to accomplish this:
puts("5 + 7 = " + (5 + 7)); // Prints "5 + 7 = 12"
One problem remains. Suppose you want to find the floating point value of a fraction of two integer.
puts("7 / 5 = " + (7 / 5)); // Prints "7 / 5 = 1"
This output is because both arguments are integers, so the result is also an integer. To solve this, we can cast one of them to a float:
puts("7 / 5 = " + ((float)7 / 5)); // Prints " 7 / 5 = 1.4"
This forces the integer 7 to a floating point number before dividing it by 5.

 To make these expression more useful, we need statements.

Statements

Statements are the individual parts that make up the body of a function. The following are the available statements:
Statement Description
return; Returns immediately from the current function (with a default return value of integer 0)
return expr; Returns immediately from the current function, returning the value of the expression expr
if (expr) stmt Evaluates the expression expr, if its result is true (non-zero or non-empty string), the statement stmt is executed, otherwise stmt is skipped, and execution continues
if (expr) stmtA 
else stmtB
Evaluates the expression expr, if its result is true (non-zero or non-empty string), the statement stmtA is executed, otherwise stmtB is executed
while (expr) stmt The expression expr is evaluated. If it is true (non-zero or non-empty string), stmt is executed. The loop then begin again, evaluating expr and executing stmt until expr is no longer true. This means that stmt will never execute if expr is initially false
do stmt 
while (expr)
The same as while except that the statement stmt is executed before expr is evaluated. This guarantees that stmt will execute at least once
for (init;cond;iter) 
stmt
The initializer expression init is first evaluated. The condition expression cond is evaluated. If it is true, stmt is executed and the iterator expression iter is evaluated continuing the loop, otherwise the the for loop ends. Note: init is evaluated only once.
break; Immediately exits from the directly enclosing while/do/for loop.
continue; Immediately restarts the directly enclosing while/do/for loop. In a for loop, the iter expression is evaluated, followed by the cond expression and possibly the stmt
{ statements } A brace followed by a list of statements, followed by another brace is considered a single statement
expression; An expression followed by a semicolon is also considered to be a statement
switch (expr) {

case const1:
statement sequence
break;

case const2:
statement sequence
break;

case const3:
statement sequence
break;

default:
statement sequence

}

switch statement is a multiple-branch selection statement.  It tests the value of an expression against a list of integer, character, float or string.  When a match is found, the case block with that constant are executed.  The break statement can be used at the end of a case statement.  It will cause program to jump to the code after switch statement.  

Note: Regular ANSI C will not allow constant string in switch statement for branch selection.  Constant string is a variable type for PocketC.  So PocketC's switch statement can handle constant string. 

 

 

Statement Examples

return
Let's visit a previous example function to see how return works.
five() {

   return 5;

}
Since the return value of the function five is always 5, we can use the function any place we would normal put the constant 5.
puts("Five is " + five()); // Prints "Five is 5"
Also, since return causes the function to exit immediately, we could do this:
five() {

   return 5;

   puts("This won't print");

}
and we would have the same effect.

 if

lessThan5(int x) {

   if (x < 5)

      puts("Less than five");

   puts("Hello");

}
If this function is called with a number less than 5, "Less than five" will be printed followed by the word "Hello", otherwise, only the word "Hello" is printed.

 if ... then

lessThan5(int x) {

   if (x < 5)

      puts("Less than five");

   else

      puts("Greater than or equal to five");

}
If this function is called with a number less than 5, "Less than five" is printed, otherwise "Greater than or equal to five" is printed.

 while

count() {

   int x;



   x = 5;

   while (x > 0) {

      puts(x);

      x = x - 1;

   }

}
This bit of code will print the numbers from 5 to 1 counting backwards. Notice that braces were placed around the two lines of code in the while loop to make them act as a single statement.

 do ... while

count() {

   int x;



   x = 5;

   do {

      puts(x);

      x = x - 1; // could also be x--

   } while (x > 0);

}
This bit of code (similar to the previous example) will print the numbers from 5 to 0 counting backwards. The zero is printed in this case because the expression x < 0 is not evaluated until after the loop

 for

output() {

   string list[4];

   int index;



   list[0] = "Zero";

   list[1] = "One";

   list[2] = "Two";

   list[3] = "Three";



   for (index = 0 ; index < 4 ; index++)

      puts(list[index]);

}
This example will print out "ZeroOneTwoThree". When we disect it we see that the array list is initialized first. We then reach the for loop. First, the initialized is evaluated, setting index to 0. Next, the condition is evaluated index < 4, which is true, so the body of the loop executes, printing "Zero". The iterator expression is then evaluated, increading index by one. This continues until index is equal to 4, at which point the loop exits without executing the body again.

 break

count() {

   int x;



   x = 5;

   while (x > 0) {

      if (x == 1)

         break;

      puts(x);

      x = x - 1;

   }

}
In this slightly more complex piece of code, the counting goes on as it normally would, printing out "5432". However, when x reaches 1, break is executed, breaking out of the while loop early, before the 1 gets printed.

 continue

count() {

   int x;



   x = 6;

   while (x > 1) {

      x--; // Do the subtraction first

      if (x == 3)

         continue;

      puts(x);

   }

}
In this clearly contrived example, the output is "5421". When x reaches 3, the continue is executed, passing execution to the beginning of the loop, skipping over the puts.

switch statement

int    myInteger;

myInteger = 50;

switch (myInteger)

{

   case    40:

    case   30:    putsl("MyInteger is 40 or 30"); break;

    case    50:    putsl("MyInteger is 50");    break;

    default    :    puts("MyInteger is " + myInteger); 

 }

Note: if myInteger is 50, it will print MyInteger is 50

if myInteger is 40 or 30, it will print MyInteger is 40 or 30

Otherwise, it will print MyInteger is the actual MyInteger's value.

Include

Using the include keyword, it becomes possible to write programs whose source code is longer than 4K (the Memo Pad limit) or create memo's of frequently used code. The contents of the included file are functionally inserted into the line containing the include keyword.
Note: For PalmOS An included memo can begin with '/$' instead of '//' to hide it from the compile form.

For WinCE, include must contain the full path name.  WinCE doesn't support relative path.


Example

/$ MyFunctions

times5(int x) {

   return x*5;

}
Another memo:
// My Program

include "MyFunctions"



main() {

   int y;

   y = times5(7);

   puts(y); // Prints 35

}
The compiler sees this as:
// My Program

times5(int x) {

   return x*5;

}

main() {

   int y;

   y = times5(7);

   puts(y); // Prints 35

}

Special characters

There are two ways to add special characters to a string. The first is by appending them by number, such as:
str = "Here is a neat little square: " + (char)149;
The other method is through using escape sequences. The following escape sequences are supported:
Escape sequence \\ \' \" \n \r \t \x
Interpretation \ ' " newline carriage return tab character specified by the following two hex digits. Example: '\x95' is the block character (decimal 149)
So, to create a string that contains a quote:
str = "She said \"I'm sorry,\" but it was too late...";

puts(str); // Prints: She said "I'm sorry," but it was too late...