We use a modified version of the interpreter language developed by Konstantin Knizhnik (http://www.garret.ru/).
Language Description (http://www.garret.ru/ctalk.html)
Introduction
C-Talk is interpreted scripting language with C-like syntax and dynamic type checking. Variables in C-Talk have no type. So there is no compile time type checking in C-Talk, all checking is performed at runtime. To preserve reference integrity, explicit memory deallocation is prohibited in C-Talk, unused objects are automatically deallocated by garbage collector.
C-Talk support integer, real, string, associative array, thread and mutex types. There is no structures, classes, unions and pointers. Structures can be emulated by associative array, for example the expression x.foo is equivalent to x["foo"] and access element of associative array with key "foo".
C-Talk provides very simple interface with C and C++. Programmer can easily define various primitives which can be called from the C-Talk as normal functions.
C-Talk is intented to be used in the same area as Perl, VB-Script, Java-Script languages. It is for the people who are familiar with C and prefer it's syntax to something else. The other advantage of C-Talk is that it is open source free software. It is distributed under MIT license - almost no restrictions on using this language in any project (unlike GPL). Also C-Talk is very simple and compact language, only - 6000 lines of code. It very simple to extend the language with new primitives and types needed for your application.
Syntax
The syntax of C-Talk language is similar with C/Java.
program: import-list {stmt}
import-list: "import" module {"," module}
module: identifier
func-def: "function" func-name "(" params-list ")" block-stmt
func-name: identifier
params-list: empty | intentifier { "," intentifier }
stmt: ";" | expr ";" | block-stmt
| while-stmt | do-while-stmt | for-stmt | if-stmt | break-stmt | continue-stmt
| return-stmt | throw-stmt | try-catch-stmt
while-stmt: "while" "(" condition ")" stmt
do-while-stmt: "do" stmt "while" "(" condition ")" ";"
for-stmt: "for" "(" opt-expr ";" opt-expr ";" opt-expr ")" stmt
if-stmt: "if" "(" condition ")" stmt ["else" stmt]
condition: expr
opt-expr: empty | expr
break-stmt: "break" ";"
continue-stmt: "continue" ";"
throw-stmt: "throw" expr ";"
return-stmt: "return" opt-expr ";"
try-catch-stmt: "try" stmt "catch" "(" exception-var ")" stmt
exception-var: identifier
block-stmt: "{" { stmt } "}"
expr: literal | func-call | start-thread | binary-expr | unary-expr |
"(" expr ")" | | variable | index-expr | env-var
literal: string | integer | real | array-constructor
variable: identifier
index-expr: expr "[" expr "]" | expr "." identifier
env-var: "$" identifier
array-constructor: "[" empty | array-elem { "," array-elem } "]"
array-elem: expr ":" expr
func-call: expr "(" expr-list ")"
start-thread: "par" func-call
expr-list: empty | expr { "," expr }
binary-expr: expr bin-op expr
unary-expr: unary-op expr
bin-op: "+" | "-" | "/" | "*" | ">>" | "<<" | ">>>" | "|" | "&" | "^" |
| "+=" | "-=" | "/=" | "*=" | ">>=" | "<<=" | "|=" | "&=" | "^=" | "="
| "==" | ">" | ">=" | "<" | "<=" | "!="
unary-op: "~" | "!" | "-" | "+"
Syntax of identifiers, comments, string, integer and real literals is the same as in C, with the exception that in C-Talk there is no difference between character and string literals. The table below summarize differences between C and C-Talk syntax
- C-Talk has no preprocessor
- C-Talk has "function" keyword
- C-Talk treats " and ' equally, so "ok" and 'ok' means the same string character constant
- C-Talk program consist of modules loaded by "import" construction
- C-Talk expression a.x is syntax sugar for a["x"] and is treated as associative array access operation
- C-Talk variable has no types - so no function return type, formal parameter type or variable type should not (and can not) be specified.
- C-Talk has no goto construction
- C-Talk has "par" construction for starting thread
Types
C-Talk provides the following types
- Integer (32 bit signed integer type with operations similar to C, but shift right operation is unsigned - doesn't replicate the sign bit)
- Real (32 bit ANSI double type)
- String (+ operator)
- Associative array (index of the array can be object of any type, for example a["foo"])
- Raw pointer (used only by primitives, C-Talk can only store such value to variables and pass them to the functions, example is C FILE* type)
- Thread type (with associated FIFO queue)
- Function type (function is first class value and can assigned to variable and passed as parameter to other function)
String operations
Example |
Description |
s = "ok" |
relation operations |
s + "cxx" |
concatenation of strings |
indexOf(s, "xxx") |
index of first occurrence of substring |
lastIndexOf(s, "xxx") |
index of first occurance of substring |
substring(s, star |
os, end-pos) - extract substring |
toLower(s) |
convert to lower case |
toUpper(s) |
convert to upper case |
trim(s) |
remove trailing spaces |
startsWith(s, prefix) |
check if string has specified prefix |
endsWith(s, suffix) |
check if string has specified suffix |
string(x) |
convert argument to string |
integer("100") |
convert string to integer |
real("5.5") |
convert string to real |
length(x) |
length of string |
Arrays operations
a[x] = y |
store element |
x = a[y] |
fetch element |
x = [0:"red", 1:"green", 2:"blue"] |
array constructor |
x += ['one':1, 'two':2] |
concatenate arrays |
a - x |
remove element(s) from the array, x can be array or key of element |
length(a) |
length of array |
cloneArray(a) |
create a copy of the array |
deleteArray(a) |
deallocate array |
clearArray(a) |
truncate array to size 0 |
getKeys(a) |
get array of keys |
Mutex operations
m = createMutex() |
create mutex |
lockMutex(m) |
lock mutex |
unlockMutex(m) |
unlock mutex |
deleteMutex(m) |
delete mutex |
Thread operations
m = getMessage(t) |
get message from thread queue |
putMessage(t, m) |
put message in thread queue |
t = currentThread() |
get reference to current thread |
IO operations:
f = createFile("test.txt", "r") |
create file with specified name and access mode |
deleteFile(f) |
close file |
flushFile(f) |
flush buffers |
printFile(f, "x=", x) |
print varying number of arguments to the file |
printlnFile(f, "x=", x) |
the same as above but append '\n' |
print("x=", x) |
print varying number of arguments to the console |
println("x=", x) |
the same as above but append '\n' |
input("> ") |
input string from console or specified file, the single optional argument of this function should be file or propmt string |
Type check operations:
isString(x) |
checks if argument is string |
isArray(x) |
checks if argument is array |
isInteger(x) |
checks if argument is integer |
isReal(x) |
checks if argument is real |
isNull(x) |
checks if argument is null |
isFunction(x) |
checks if argument is function |
isPrimitive(x) |
checks if argument is primitive |
isMutex(x) |
checks if argument is mutex |
isFile(x) |
checks if argument is file |
getType(x) |
returns argument's type code (integer as defined in ctalk.h) |
getTypeName(x) |
returns argument's type name |
Miscellaneous
rc = execute("cp f.dbs f.sav") |
execute shell command and wait for result |
t = time() |
get current system time (seconds) |
assert(i >= 0) |
check the assert condition, throw exception if predicate is false |
loadDLL("test.dll") |
load dynamic linking library |
loadModule("test.ctk") |
load C-Talk module |
chdir(path) |
change current directory |
dir = pwd() |
get name of working directory |
sleep(seconds) |
sleep specified amount of seconds |
options("socket") |
when called without argumetns, returns array of command line options, or gets value of specified option |
printExceptionStackTrace() |
print stack trace for the frame where exception was thrown, till the frame where it is catched |