Name  Volker Oth 
Born  1971 
Country  Germany 
Occupation  Embedded C software development (automobile) 
Contact  You might contact me by mail if you have questions/bug reports/suggestions regarding Calcutta: VolkerOth (at) GMX.de 
Official Homepage
Bitbucket Project Homepage
Details of the latest changes can be found here.
As of version 0.86, Calcutta became an Open Source project. All source
files are released under the Apache
License 2.0. In a nutshell that means you can use them and modify them
even for closed source or commercial projects, as long as you leave some copyright
info in and give appropriate credit. See the linked Apache License for details.
Each file of the source code should contain a header with the license information.
The whole source code, the icons and the HTML help are now stored in a Git repository hosted by Bitbucket.
I recommend to use SourceTree to handle the repository but there are several other tools and also Eclipse plugins.
Repository URL: https://bitbucket.org/fade0ff/calcutta
Expression 
Comment 
prime(2**311) out = true 
This number is indeed prime and we can find out in the tenth of a second 
a=1;b=a++
out = 1 b out = 1 a out = 2 
Note that the postincrement ++ works as
it should: a is increased after b is assigned the value of a (still 1) and after the whole expression is evaluated (also out=1). 
fraction(1.34p456) out = 22387/16650 
Rational number with endless periods can be expressed as rational fraction. Indeed there is no loss of
precision as long as no irrational function as sin,sqrt etc. is used. 
hex(65536) out = 0x010000 
Get hexadecimal output 
bin(0x7e) out = 0b01111110 
get binary output 
(1+2*34/(2*3)) out = 6.3333333333333333 fraction(out) out = 19/3 out*6 out = 38 
Note that the variable out is always
overwritten with the last result. Also note that even if a decimal is printed out, the internal
representation is always a rational fraction. That's why multiplication with 6 ends with an integer
number though the operand had an endless period 
fac(2000) out = 0.3316275092450633e+5736 
factorial of 2000. This is way beyond the scope of normal calculators or even double precision.
Try to print out the whole number with full(out) 
hex(0x80) out = 0x0080 hex(128) out = 0x80 ~0x80; out = 129 hex(out) out = 0xff7f 
Note that while 0x80 seems to fit into
a byte, it is automatically evaluated as 0x0080 to express that it's
unsigned, while hex(128) is evaluated as 0x80: here the most
significant bit is set, so it's a negative number. As 0x80 is internally represented as 0x0080, the binary complement evaluated to 0xff7f, which can only be evaluated as negative number, as the most significant bit is set. 
bin(0b111
^ 0b101) out = 0b00000010 
This goes to show that "^" is not a "to
the power of" operator, but the binary XOR. Also note that binary
numbers are always extended to the next byte, word, dword etc. boundary 
true
^ true out = false 
And yes, as in Java, the XOR is also
defined on boolean values 
full(2**150) out = 1427247692705959881058285969449495136382746624 
Already quite a large number. But not nearly as large as it can get ;) 
5<<3
== 5*8 out = true 
Was to be expected 
false
&& ((z=1)==1) out = false z z ^ Empty or invalid expression 
Note that "&&" and "" are
boolean shortcircuit operators. If the left side is sufficient to evaluate
the expression (false && exp is always false), the right side
is not evaluated. In this case, 'z' is not set to 1. Therefore it's
still undefined! 
false &
((w=1)==1) out = false w out = 1 
Same
example with nonshortcircuit operator &. This time the right side is evaluated
and 'w' is defined. 
sqrt(2**2000) out = 10.7150860718626732e+300 
Note that functions like sqrt are not
simply passed to the double sqrt. Most simple calculators will fail here. 
2 out = 2 2; out = <UNDEF VALUE> 
A separator consumes an existing value 
a
= {1,
"lurch", {2,true}} out = {1,"lurch",{2,true}} a[1] out = "lurch" a[2] out = {2,true} a[2][1] out = true a[2][0] = "new" out = {1,"lurch",{"new",true}} 
Define a list by putting value separated by commas into curved braces Access list elements by using index in brackets (reading or writing is allowed) Lists are allowed as list elements > multidimensional lists 
Integer numbers: 
1, 2e3, 1971e+3 
Decimal numbers (p marks beginning of periodic part) 
1.345, 2e3, 1.2p3 
Hex numbers: 
0xdeadbeef, 0xe 
Binary Numbers: 
0b010101 
Octal Numbers: 
070, 066 
a=1;b=2  No need to define them, just assign a value 
a=1; a="oink"; a=true  1st a is a number, then a string, then a boolean 
a=c  Now c is not defined yet > this will result in an error 
my_1st_string = "Hello World"  Now we have a string 
my_1st_boolean = true  And now a boolean 
Operator 
Use 
Precedence 
Valid on 
Description 
+ 
+op1 
1 
Number 
Marks numeric value as positive 
++ 
++op1 op1++ 
1 
Number 
Preincrement, postincrement 
 
op1 
1 
Number  Negative value of operand 
 
op1 op1 
1 
Number 
Predecrement, postdecrement, 
~ 
~op1 
1 
Integer Number 
Binary complement 
! 
!op1 
1 
Integer Number, Boolean 
Logical complement (true  false, 0  >0) 
** 
op1**op2 
1 
Number 
op1 to the power of op2 
* 
op1*op2 
2 
Number 
Multiplication 
/ 
op1/op2 
2 
Number 
Division 
% 
op1%op2 
2 
Integer Number 
Integer Division Remainder 
+ 
op1+op2 
3 
Number, String, List 
Addition, StringConcatenation, ListConcatenation 
 
op1op2 
3 
Number 
Subtraction 
<< 
op1<<op2 
4 
Integer Number 
Shift left 
>> 
op1>>op2 
4 
Integer Number 
Shift right 
< 
op1<op2 
5 
Number,String 
Smaller than (result: boolean) 
<= 
op1<=op2 
5 
Number,String  Smaller than or equal (result: boolean) 
> 
op1>op2 
5 
Number,String  Larger than (result: boolean) 
>= 
op1>=op2 
5 
Number,String  Larger than or equal (result: boolean) 
== 
op1==op2 
6 
Number, Boolean, String, List 
Equals (result: boolean) 
!= 
op1!=op2 
6 
Number, Boolean, String, List 
Not equal (result: boolean) 
& 
op1&op2 
7 
Integer Number, Boolean 
Integer Number: binary AND, boolean: logical AND (no shortcircuit!) 
^ 
op1^op2 
8 
Integer Number, Boolean 
Integer Number: binary XOR, boolean: logical XOR (no shortcircuit!) 
 
op1op2 
9 
Integer Number, Boolean 
Integer Number: binary OR, boolean: logical OR (no shortcircuit!) 
&& 
op1&&op2 
10 
Integer Number, Boolean 
logical AND (shortcircuit!) 
 
op1op2 
11 
Integer Number, Boolean 
Logical OR (shortcircuit!) 
= 
var=exp 
13 
Left Side: variable, Right side: any expression 
Defines
variable var if it doesn't exist yet and
assigns it to the value of the expression on the right side 
*=  var*=op  14  Left: variable Right: numeric expression 
same as var = var * (op) (multiplication) 
/=  var/=op  14  Left: variable Right: numeric expression 
same as var = var / op (division) 
+=  var+=op  14  Left: variable Right: Number, String, List 
same as var = var + op (addition/ Concatenation) 
=  var=op  14  Left: variable Right: Number 
same as var = var  op (subtraction) 
<<=  var<<=op  14  Left: variable Right: Number 
same as var = var << op (shift left) 
>>=  var>>=op  14  Left: variable Right: Number 
same as var = var >> op (shift right) 
=  var=op  14  Left: variable Right: Number.Boolean 
same as var = var  op (or) 
&=  var&=op  14  Left: variable Right: Number, Boolean 
same as var = var & op (and) 
^=  var^=op  14  Left: variable Right: Number, Boolean 
same as var = var ^ op (xor) 
Cast Operator 
Valid on 
Description 
(u8),(u08),(byte) 
Number 
Casts expression to unsigned 8bit value (0..255) 
(s8), (s08) 
Number 
Casts expression to signed 8bit value (128..128) 
(u16),(word),(char) 
Number 
Casts expression to unsigned 16bit value (0..65535) 
(s16), (short) 
Number 
Casts expression to signed 16bit value (32768..32767) 
(u32),(dword) 
Number 
Casts expression to unsigned 32bit value (0..4294967295) 
(s32),(int) 
Number 
Casts expression to signed 32bit value (2147483647..2147483646) 
(u64),(qword) 
Number 
Casts expression to unsigned 64bit value (0..18446744073709551616) 
(s64), (long) 
Number 
Casts expression to signed 64bit value (9223372036854775807..9223372036854775806) 
(double) 
Number 
Castto double 
(integer) 
Number 
Cast to integer number (same as trunc(operand)) 
(string)  any value  Converts a value to a string. The resulting string will look exactly as the default output on the console. 
Function 
Description 
abs(x) 
Absolute value of number x 
trunc(x) 
Integer part of number x (cutting of decimal part) 
floor(x) 
Integer i closest to number x with i <= x 
ceil(x) 
Integer i closest to number x with i >= x (same as floor(x) ) 
round(x) 
Integer closest to number x + 0.5 (same as floor(x+0.5) ) 
pow(x,N) 
Calculates number x to the power of number N (same as x**N) 
root(x,N) 
Calculates the Nth root of number x (same as x**(1/N) ) 
sqrt(x) 
Calculates the square root of number x (same as root(x,2) ) 
fac(x) 
Calculates factorial of number x (normally written as x!, but "!" is logical complement) 
prime(x) 
Returns boolean if integer number x is (probably) a prime number 
exp(x) 
Returns Euler's number e raised to the power of number x

log(x) 
Returns the natural logarithm (base e) of number x 
log10(x) 
Returns the logarithm (base 10) of number x 
ld(x) 
Returns the logarithm digitalis (base 2) of number x 
bits(x) 
Returns the number of bits needed to represent the integer number x 
sin(x) 
Returns the trigonometric sine of a radian angle x (number) 
sinh(x) 
Returns the trigonometric hyperbolic sine of a radian angle x (number) 
asin(x) 
Returns the trigonometric arc sine of a radian angle x (number) 
cos(x) 
Returns the trigonometric cosine of a radian angle x (number) 
cosh(x) 
Returns the trigonometric hyperbolic cosine of a radian angle x (number) 
acos(x) 
Returns the trigonometric arc cosine of a radian angle x (number) 
tan(x) 
Returns the trigonometric tangent of a radian angle (number) 
tanh(x) 
Returns the trigonometric hyperbolic tangent of a radian angle (number) 
atan(x) 
Returns the trigonometric arc tangent of a radian angle (number) 
Function 
Description 
print(x) println(x) 
Print value x on the console (x can be a number, boolean or string) println works as print, but adds a linefeed 
hex(x) 
Show integer number x in hexadecimal representation* 
bin(x) 
Show integer number x in binary representation* 
oct(x)  Show integer number x in octal representation* 
full(x) 
Show number x as accurate as possible BEWARE! For rational numbers with more digits after the decimal point than the internal scale provides, the result will be less precise. E.g. full(1/3)==(1/3) results in false, since 1/3 is precise, but full(1/3) is not!!! 
fraction(x) 
Show number x as a rational fraction 
defined(x) 
Returns true, if the variable x is defined, else false. Will not work on values! 
load(x) 
Load file with name x (must be a
string!). Files can contain all the operators, literals and functions described here. E.g. load("test.clc") 
die(x) 
Immediately exits the current expression evaluation and
creates a user defined parse exception x, where x must be a string.
E.g. a==1  die("a is not 1"); 
rnd()  Returns random number N where 0 <= N <= 1 
time()  Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT 
clear()  Undefines all user variables and user functions 
listv()  Returns a sorted list with all defined variables (as strings) 
listf()  Returns a sorted list with all defined user functions (as strings) 
eval(x)  Evaluates the expression inside string
<x>. E.g. eval("1+3*2") will evaluate as 7. Every operator, function and literal is allowed within the expression, only quotes (") are forbidden. 
Function 
Description 
lfill(value,size) 
Returns a list filled with value until size is reached 'a= fill(true,3)' results in {true,true,true} 
sfill(string,size)  Returns a string filles with
string until size is reached 'a= sfill("ab",5)' results in "ababa" 
sub(string,pos,len)  Returns a substring of string
starting at position pos and
containing len characters 'sub("12345",2,3)' results in "345" 
sub(list,pos,len)  Returns a sublist of list
starting at position pos
and containing len
list elements 'sub({1,2,3,4,5},2,3)' results in {3,4,5} 
insert(string,insert,pos)  Returns a string with the string insert inserted into string string at position pos 'insert("12345","AB",2)' results in "12AB345" 
insert(list,insert,pos)  Returns a list with the list insert inserted into list list at position pos 'insert({1,2,3,4,5},{"A","B"},3)' results in {1,2,3,"A","B",4,5} 
replace(string,replace,pos)  Returns a string with the string replace replaced in string string beginning with position pos 'replace("12345","AB",2)' results in "12AB5" 
replace(list,replace,pos)  Returns a list with the list replace replaced in list string beginning with position pos 'replace({1,2,3,4,5},{"A","B"},2)' results in {1,2,"A","B",5} 
index(string1,string2)  Returns (0 based) index of string2 inside string1, if found, else 1 (searching from beginning) 
index(list,value)  Returns (0 based) index of value inside string1, if found, else 1 (searching from beginning) 
lastindex(string1,string2)  Returns (0 based) index of string2 inside string1, if found, else 1 (searching from end) 
lastindex(list,value)  Returns (0 based) index of value inside string1, if found, else 1 (searching from end) 
size(variable)  returns
the size of a variable. For a list, this is the number of elements: 'a={1,2,3,{1,2,3}}; size(a)' results in 4 For a String, this is the number of characters 'a="0123456789"; size(a)' results in 10 For any other value (number, boolean), this is 1 
{}  empty list 
{1,2,3} out = {1,2,3} 
simple list 
{true, 2,
"sheep" } out = {true, 2, "sheep" } 
mixed list 
{1, {1,2,3}, 3} out = { 1, {1,2,3}, 3} 
list inside list 
a=1;
b=2; { a, b, 3} out = {1,2,3} 
Note that the variables are evaluated when creating the list 
{
sin(0), cos(0), tan(0) } out = {0,1,0} 
Same with functions 
a
=
{1,2,3};
a[0] out = 1 
Just like in C or Java 
a
=
{1,2,3};
a[0] = a[2] = 0; a out = {0,2,0} 
Indexed variables behave just like ordinary variables. You can write to them and also right association is working. 
b={
{1,2}, {3,4}, {4,5} };
b[0][0] = b[2][0] = 0;b out = {{0,2},{3,4},{0,5}} 
Same with two dimensions 
a = { 1, 2, 3 }; a[3] Index 3 out of bounds. 
Neither reading nor writing to an undefined index is allowed. 
{1,"a",true,
{1,2}} == {1,"a",true, {1,2}} out = true 
equality operator works on lists as well 
a = {}; a = a + {1}; a = a + {2}; a out = {1,2} 
plus operator allows list concatenation 
function
square(a) { a*a } square(4) out = 16 square(true) Number expected on the left side of operator 
The
return value is just the value of
the expression "a*a" Works with numbers Doesn't work with boolean 
function square(a) { a*a; } square(4); out = <UNDEF VALUE> 
Beware! The semicolon after the last statement of the function consumes the value 
function
test(a,b) { c=a*b; println(c); d=a+b; println(d); } 
Two
parameters here. Use as many as you want. 
lurch = 2; function lurchtest() { println(lurch); lurch = 3; println(lurch) } lurchtest() 2 3 out = 3 lurch out = 2 
Note
that first the global variable is
read (which contains
2). Then a local variable is written to. With the next read access, the local variable is read, which now hides the global variable!!! 
function
ctest(a,b) { c } 
This
is allowed, since the syntax is
correct. However when you call this function, it will fail if no global variable c exists. It will work however if the variable exists! 
a
= 1; if ( a == 1) { b = 0 } else { b = 1 } out = 0 
b is assigned 0, note that the result of the statement equals the if branch 
a = 1; 
This does the same as the example above by directing assigning the statement to b. Note that this is perfectly allowed in contrary to C etc. where you would need to use the "?:" operator 
a = 1; 
Note that the semicolon consumes the value. Thus the return value is undefined!!! 
a
= 1; sin ( if (a==1) {PI} else {1}) out = 0 
Note how the result of the statement can be passed as parameter 
if
(false) {1} out = <UNDEF VALUE> 
There is no else branch and no statement after this that would define a result. Thus the value of this statement is undefined! 
Furthermore the ternary operator "?" is defined as in C and Java.
(<condition>) ? <true_statement> : <false_statement>
Remarks:
a = 1; 
b is assigned 0, note that the result of the statement equals the true branch 
a
= 1; 
This does the same as the example above by directing assigning the statement to b. Note that this is perfectly allowed in contrary to C etc. where you would need to use the "?:" operator 
a = 1; 
Note that the semicolon consumes the value. Thus the return value is undefined!!! 
a = 1; 
Note that the semicolon after the false statement consumes the return value of the whole expression. Still a is defined correctly. Using parentheses around "1" would create an evaluator stack underflow as well. 
a = 1; sin ( (a==1) ? PI : 1) out = 0 
Note how the result of the statement can be passed as parameter 
for (i=0; i<10;i++) { print(i) } 0123456789 
Nothing spectacular. Just note that since "i++" evaluates 9, while "i" is already 10! 
for (i=0; i<10;i=i+1) { print(i) } 0123456789 out = 10 
"i=i+1" works exactly the same as "++i" would 
for (i=sin(0); i<3**2+1;i=i+1) { print(i) } 0123456789 
You can use expressions and functions inside the statements of course 
for (;;) { print("#") } Invalid condition 
The loop condition shall not be omitted! 
a={1,2,3}; foreach(i;a) { print(i) } 123 
Simple example 
foreach(i;{1,2,3}) { print(i) } 123 
Same with a list literal 
foreach(i;{1,2,3})
{ print(i); foreach(j;{"a","b","c"}){print(j)} } 1abc2abc3abc 
Nested foreach loops 
a={1,2,3}; foreach(i;a){ a={"a","b"}; print(i) } 123 a out = {"a","b"} 
Note that changing the variable 'a' works, but doesn't influence the loop behavior. 
i=0;do
{ print(i) }while(++i<10) 0123456789 
No init statement, so you have to put it in a separate statement. 
i=0;while (i<10)
{ print(i++) } 0123456789 
No init statement, so you have to put it in a separate statement. 
function
factorial(n) { if (n<=1) { 1 } else { n*factorial_recursive(n1) } } 
load("factorial.clc") factorial(200) out = 0.7886578673647905e+375 fac(200) out = 0.7886578673647905e+375 
function galton(rows, trials)
{
// init slot = lfill(0,rows+1); // run trials for (trial = 0; trial < trials; trial++) { position = 0; for (pos = 0; pos < rows; pos++) { if (rnd() >= 0.5) { position++; } } slot[position]++; } // output for (pos = 0; pos <= rows; pos++) { println("Slot " + (string)(pos+1) + " contains " + (string)slot[pos] + " balls."); } } 
load("galton.clc") galton(4,1000) Slot 1 contains 49 balls. Slot 2 contains 240 balls. Slot 3 contains 374 balls. Slot 4 contains 273 balls. Slot 5 contains 64 balls. 
//
Calcutta version of 99 Bottles of beer b1 = " bottle of beer"; bn = " bottles of beer"; otw = " on the wall"; for (i=100; i>0; i) { b = if (i>1) {bn} else {b1}; println ((string)i+b+otw+", "+(string)i+b+"."); println("Take one down and pass it around,"); b = if (i1>1) {bn} else {b1}; println((string)(i1)+b+otw+"."); println(""); } 
load("99bottles.clc") 100 bottles of beer on the wall, 100 bottles of beer. Take one down and pass it around, 99 bottles of beer on the wall. ... ... ... 1 bottle of beer on the wall, 1 bottle of beer. Take one down and pass it around, 0 bottle of beer on the wall. 