-- This top-level code is plain Lua code.
function printhello()
-- This is a plain Lua function
print("Hello, Lua!")
end
printhello()
-- Terra is backwards compatible with C
-- we'll use C's io library in our example.
C = terralib.includec("stdio.h")
-- The keyword 'terra' introduces
-- a new Terra function.
terra hello(argc : int, argv : &rawstring)
-- Here we call a C function from Terra
C.printf("Hello, Terra!\n")
return 0
end
-- You can call Terra functions directly from Lua
hello(0,nil)
-- Implements a SIMD-vectorized SAXPY operator
-- from BLAS
local V = 4
-- Create a 4-wide vector type
local floatV = vector(float,V)
terra saxpy(x : &float, y : &float, n : uint, a : float)
for i = 0,n,V do
-- Load x and y as vectors
-- (assuming correct alignment and 'n' divisible by 4)
var xv = @[&floatV](x + i)
var yv = @[&floatV](y + i)
-- Perform vector arithmetic
var r = a*xv + yv
-- Store x vector back into memory
@[&floatV](x + i) = r
end
end
C = terralib.includecstring [[
#include "stdio.h"
#include "stdlib.h"
]]
terra saxpytest()
var x = [&float](C.malloc(sizeof(float) * 32))
var y = [&float](C.malloc(sizeof(float) * 32))
for i = 0,32 do
x[i],y[i] = i,i
end
saxpy(x,y,32,4)
for i = 0,32 do
C.printf("x[%d] = %f\n",i,x[i])
end
C.free(x)
C.free(y)
end
--Verify that the generated code uses SSE instructions
print("disassembling ...")
saxpy:disas()
print("testing saxpy...")
saxpytest()
--generate a power function for a specific N (e.g. N = 3)
function makePowN(N)
local function emit(a,N)
if N == 0 then return 1
else return `a*[emit(a,N-1)]
end
end
return terra(a : double)
return [emit(a,N)]
end
end
--use it to fill in a table of functions
local mymath = {}
for n = 1,10 do
mymath["pow"..n] = makePowN(n)
end
print(mymath.pow3(2)) -- 8
C = terralib.includec("stdlib.h")
function MakeArray(T)
--create a new Struct type that contains a pointer
--to a list of T's and a size N
local struct ArrayT {
--&T is a pointer to T
data : &T;
N : int;
}
--add some methods to the type
terra ArrayT:init(N : int)
-- the syntax [&T](...) is a cast,
-- the C equivalent is (T*)(...)
self.data = [&T](C.malloc(sizeof(T)*N))
self.N = N
end
terra ArrayT:get(i : int)
return self.data[i]
end
terra ArrayT:set(i : int, v : T)
self.data[i] = v
end
--return the type as a
return ArrayT
end
IntArray = MakeArray(int)
DoubleArray = MakeArray(double)
terra UseArrays()
var ia : IntArray
var da : DoubleArray
ia:init(1)
da:init(1)
ia:set(0,3)
da:set(0,4.5)
return ia:get(0) + da:get(0)
end
print(UseArrays())
local C = terralib.includec("stdio.h")
local function compile(code,N)
local function body(data,ptr)
local stmts = terralib.newlist()
local jumpstack = {}
for i = 1,#code do
local c = code:sub(i,i)
local stmt
if c == ">" then
stmt = quote ptr = ptr + 1 end
elseif c == "<" then
stmt = quote ptr = ptr - 1 end
elseif c == "+" then
stmt = quote data[ptr] = data[ptr] + 1 end
elseif c == "-" then
stmt = quote data[ptr] = data[ptr] - 1 end
elseif c == "." then
stmt = quote C.putchar(data[ptr]) end
elseif c == "," then
stmt = quote data[ptr] = C.getchar() end
elseif c == "[" then
local target = { before = symbol(),
after = symbol() }
table.insert(jumpstack,target)
stmt = quote
::[target.before]::
if data[ptr] == 0 then
goto [target.after]
end
end
elseif c == "]" then
local target = table.remove(jumpstack)
assert(target)
stmt = quote
goto [target.before]
:: [target.after] ::
end
else
error("unknown character "..c)
end
stmts:insert(stmt)
end
return stmts
end
return terra()
var data : int[N]
for i = 0, N do
data[i] = 0
end
var ptr = 0;
[ body(data,ptr) ]
end
end
local helloworld = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."
local fn = compile(helloworld,256)
fn()