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

Types

C-Talk provides the following types

String operations

ExampleDescription
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, staros, 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

Program execution

C-Talk is command line tool which accepts list of files with C-Talk programs as parameters:
$ ctalk file-1 file-2 ...
The loaded module is first compiled to byte code and the all global-level statements are executed. For example, the result of following program execution:
hello = "Hello World";

foo(hello);

foo(s) { 
	println(s);
}
will be printing of "Hello World" line at the screen

C-Talk primitives

C-Talk system library includes only basci set of functions. It makes it possible to make C-Talk distribution very compact. It was inteded that particular extensions will be added to C-Talk using primitives mechanism. Most of C-Talk functions will be implemented in C/C++. C-Talk provides special library for mapping C-Talk type to C++ types. C-Talk primitives can accept varying number of arguments. To declare C-Talk primitive, C programmer should define the function:
CtkObject foo_func(int nArgs, CtkObject args[]) { ... }
REGISTER(foo_func, "foo");
The code above defines the function "foo_func" and registers it as C-Talk primitive "foo". Now C-Talk program can call "foo()" function in the same way as it was declared in C-Talk. The C-Talk C-interface library provides methods for creating objects of C-Talk types, converting CtkObject with type checking to primitive C types, operations with C-Talk types (such as strings, arrays and mutexes), throwing C-Talk exceptions. Macros IS_XXX can be used to check object type, macros TO_XXX perform conversion to the specified type or throw exception if type doesn't match, macro MAKE_XXX create object with specified type and value, mcaros CHECK_PRIMITIVE_N_ARGS and CHECK_PRIMITIVE_ARGUMENT can be used to check number of passed arguments and type of each argument.

C-Talk provide even more convinient weay for checking types passed arguments. Function ctkParseArguments takes format string and optional list of arguments palceholder and perform necessary checks and conversions.

void ctkParseArguments(int nArgs, CtkObject* args, char const* format, ...);
Parameters:
nArgs - number of arguments passed to the function (first parameter of any primitive)
args - array of arguments passed to the function (second parameter of any primitive)
format - format string specifying number and types of expected arguments.
In format string each character describes one correpondent parameter.
Upercase character in format string cause checking of the argument type and copying CtkObject to the placeholder.
Lowercase character in format string cause checking and storing arguments in native C format.
',' character in format string split mandatory and optional parameters.
If type or number of parameters doesn't match, exception is thrown.
Format symbolExpected C-Talk type of argumentType of placeholder for parameter value
oanyCtkObject
iCTK_INTEGERctk_integer
rCTK_REALctk_real
pCTK_RAW_POINTER or CTK_NULLvoid*
PCTK_RAW_POINTERCtkObject
sCTK_STRING or CTK_NULLchar*
SCTK_STRINGCtkObject
aCTK_ARRAY or CTK_NULLCtkArray*
ACTK_ARRAYCtkObject
fCTK_FILE or CTK_NULLCtkFile*
FCTK_FILECtkObject
mCTK_MUTEX or CTK_NULLCtkMutex*
MCTK_MUTEXCtkObject
tCTK_THREAD or CTK_NULLCtkThread*
TCTK_THREADCtkObject
lCTK_FUNCTION or CTK_NULLCtkFunction*
LCTK_FUNCTIONCtkObject
uCTK_USER_TYPE or CTK_NULLvoid*
UCTK_USER_TYPECtkObject

Example:

CtkObject myPrimitive(int nArgs, CtkObject* args) {
    char*       s;
    ctk_integer i;
    ctk_real    r;
    CtkObject   o;

    ctkParseArguments(nArgs, args, "siro", &s, &i, &r, &o);
    ...
}