Terra is an open source programming language created in 2012.
#230on PLDB | 12Years Old | 410Repos |
git clone https://github.com/zdevito/terra
Terra is a low-level system programming language that is embedded in and meta-programmed by the Lua programming language:
-- 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, they are JIT compiled
-- using LLVM to create machine code
hello(0,nil)
-- Terra functions are first-class values in Lua, and can be introspected
-- and meta-programmed using it
hello:disas()
--[[ output:
assembly for function at address 0x60e6010
0x60e6010(+0): push rax
0x60e6011(+1): movabs rdi, 102129664
0x60e601b(+11): movabs rax, 140735712154681
0x60e6025(+21): call rax
0x60e6027(+23): xor eax, eax
0x60e6029(+25): pop rdx
0x60e602a(+26): ret
]]
-- You can save Terra code as executables, object files, or shared libraries
-- and link them into existing programs
terralib.saveobj("helloterra",{ main = hello })
print("Hello World")
C = terralib.includecstring [[
#include <stdio.h>
#include <stdlib.h>
]]
local arraytypes = {}
function Array(T)
local struct ArrayImpl {
data : &T;
N : int;
}
function ArrayImpl.metamethods.__typename(self)
return "Array("..tostring(T)..")"
end
arraytypes[ArrayImpl] = true
terra ArrayImpl:init(N : int)
self.data = [&T](C.malloc(N*sizeof(T)))
self.N = N
end
terra ArrayImpl:free()
C.free(self.data)
end
ArrayImpl.metamethods.__apply = macro(function(self,idx)
return `self.data[idx]
end)
ArrayImpl.metamethods.__methodmissing = macro(function(methodname,selfexp,...)
local args = terralib.newlist {...}
local i = symbol(int)
local promotedargs = args:map(function(a)
if arraytypes[a:gettype()] then
return `a(i)
else
return a
end
end)
return quote
var self = selfexp
var r : ArrayImpl
r:init(self.N)
for [i] = 0,r.N do
r.data[i] = self.data[i]:[methodname](promotedargs)
end
in
r
end
end)
return ArrayImpl
end
struct Complex {
real : float;
imag : float;
}
terra Complex:add(c : Complex)
return Complex { self.real + c.real, self.imag + c.imag }
end
ComplexArray = Array(Complex)
N = 10
terra testit()
var ca : ComplexArray
ca:init(N)
for i = 0,N do
ca(i) = Complex { i, i + 1 }
end
var ra = ca:add(ca)
return ra
end
local r = testit()
assert(r.N == N)
for i = 0,N-1 do
assert(r.data[i].real == 2*i)
assert(r.data[i].imag == 2*(i+1))
end
assert(tostring(Array(int)) == "Array(int32)")
Feature | Supported | Example | Token |
---|---|---|---|
Strings | ✓ | "Hello world" | " |
Print() Debugging | ✓ | ||
Comments | ✓ | -- A comment | |
Line Comments | ✓ | -- A comment | -- |
Semantic Indentation | X |