Example of a Tcl extension in Terra

dbohdan 2016-09-21: This is a simple Tcl extension written in Terra , a new statically typed language related to and meta-programmed with Lua. It is impressively easy to interface with C libraries.

This code has been tested with Terra release-2016-03-25 (terra-Linux-x86_64-332a506). Compile and test using the command

terra tclterraexample.t \
&& gcc -fPIC tclterraexample.o -shared -o tclterraexample.so -ltclstub8.6 \
&& echo 'load tclterraexample.so; puts [hello]; puts [square 5]' | tclsh

tclterraexample.t

local tcl = terralib.includec("tcl.h")
-- Terra can't access the value of TCL_VERSION in tcl.h. It currently only
-- imports macros with definitions representable in the type double. We'll
-- define an equivalent constant instead.
local TCL_VERSION = constant(tcl.TCL_MAJOR_VERSION .. "." ..
                             tcl.TCL_MINOR_VERSION)

terra Hello_Cmd(cdata: tcl.ClientData, interp: &tcl.Tcl_Interp, objc: int,
                objv: &&tcl.Tcl_Obj): int
  if objc ~= 1 then
    tcl.Tcl_WrongNumArgs(interp, 1, objv, nil)
    return tcl.TCL_ERROR
  end
  tcl.Tcl_SetObjResult(interp, tcl.Tcl_NewStringObj("Hello, World!", -1))
  return tcl.TCL_OK
end

terra Square_Cmd(cdata: tcl.ClientData, interp: &tcl.Tcl_Interp, objc: int,
                 objv: &&tcl.Tcl_Obj): int
  if objc ~= 2 then
    tcl.Tcl_WrongNumArgs(interp, 1, objv, "value")
    return tcl.TCL_ERROR
  end
  var i: int = 0
  if tcl.Tcl_GetIntFromObj(interp, objv[1], &i) ~= tcl.TCL_OK then
    return tcl.TCL_ERROR
  end
  tcl.Tcl_SetObjResult(interp, tcl.Tcl_NewIntObj(i*i)) 
  return tcl.TCL_OK
end

terra Tclterraexample_Init(interp: &tcl.Tcl_Interp): int
  if tcl.Tcl_InitStubs(interp, TCL_VERSION, 0) == nil then
    return tcl.TCL_ERROR;
  end

  tcl.Tcl_CreateObjCommand(interp, "::hello", Hello_Cmd, nil, nil)
  tcl.Tcl_CreateObjCommand(interp, "::square", Square_Cmd, nil, nil)
  return tcl.TCL_OK
end

terralib.saveobj("tclterraexample.o", {
  Tclterraexample_Init = Tclterraexample_Init
})