PocketC Language Specification |
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 */
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" |
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.
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.
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);
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 2Now, what are all the operators that can be used in an expression, and what is their associativity? Good question.
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) |
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 |
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
"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.
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: case const2: case const3: default: } |
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. |
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.
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 }
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) |
str = "She said \"I'm sorry,\" but it was too late..."; puts(str); // Prints: She said "I'm sorry," but it was too late...