Tree @0.2 (Download .tar.gz)
Tamsin
Tamsin is an oddball little language that can't decide if it's a meta-language, a programming language, or a rubbish lister.
Its primary goal is to allow the rapid development of parsers, static analyzers, interpreters, and compilers, and to allow them to be expressed compactly. Golf your grammar! (Or write it like a decent human being, if you must.)
The current released version of Tamsin is 0.2; the development version is 0.3-PRE. As indicated by the 0.x version number, it is a work in progress, with the usual caveat that things may change rapidly (and that version 0.3 might look completely different.) See HISTORY for a list of major changes.
Code Examples
Make a story more exciting in 1 line of code:
main = ("." & '!' | "?" & '?!' | any)/''.
Parse an algebraic expression for syntactic correctness in 4 lines of code:
main = (expr0 & eof & 'ok').
expr0 = expr1 & {"+" & expr1}.
expr1 = term & {"*" & term}.
term = "x" | "y" | "z" | "(" & expr0 & ")".
Translate an algebraic expression to RPN (Reverse Polish Notation) in 7 lines of code:
main = expr0 → E & walk(E).
expr0 = expr1 → E1 & {"+" & expr1 → E2 & E1 ← add(E1,E2)} & E1.
expr1 = term → E1 & {"*" & term → E2 & E1 ← mul(E1,E2)} & E1.
term = "x" | "y" | "z" | "(" & expr0 → E & ")" & E.
walk(add(L,R)) = walk(L) → LS & walk(R) → RS & return LS+RS+' +'.
walk(mul(L,R)) = walk(L) → LS & walk(R) → RS & return LS+RS+' *'.
walk(X) = return ' '+X.
Parse a CSV file (handling quoted commas and quotes correctly) and write out the 2nd-last field of each record — in 11 lines of code:
main = line → L & L ← lines(nil, L) &
{"\n" & line → M & L ← lines(L, M)} & extract(L) & ''.
line = field → F & {"," & field → G & F ← fields(G, F)} & F.
field = strings | bare.
strings = string → T & {string → S & T ← T + '"' + S} & T.
string = "\"" & (!"\"" & any)/'' → T & "\"" & T.
bare = (!(","|"\n") & any)/''.
extract(lines(Ls, L)) = extract(Ls) & extract_field(L).
extract(L) = L.
extract_field(fields(L, fields(T, X))) = print T.
extract_field(X) = X.
Evaluate an (admittedly trivial) S-expression based language in 15 lines of code:
main = sexp → S using scanner & reverse(S, nil) → SR & eval(SR).
scanner = ({" "} & ("(" | ")" | $:alnum/'')) using $:utf8.
sexp = $:alnum | list.
list = "(" & sexp/nil/pair → L & ")" & L.
head(pair(A, B)) = A.
tail(pair(A, B)) = B.
cons(A, B) = return pair(A, B).
eval(pair(head, pair(X, nil))) = eval(X) → R & head(R).
eval(pair(tail, pair(X, nil))) = eval(X) → R & tail(R).
eval(pair(cons, pair(A, pair(B, nil)))) =
eval(A) → AE & eval(B) → BE & return pair(AE, BE).
eval(X) = X.
reverse(pair(H, T), A) = reverse(H, nil) → HR & reverse(T, pair(HR, A)).
reverse(nil, A) = A.
reverse(X, A) = X.
Interpret a small subset of Tamsin in less than 160 lines of code.
For more information
If the above has piqued your curiosity, you may want to read the specification, which contains many more small examples written to demonstrate (and test) the syntax and behavior of Tamsin:
Note that this is the current development version of the specification, and it may differ from the examples in this document.
Quick Start
The Tamsin reference repository is hosted on Github with a Mercurial mirror on Bitbucket.
This repository contains the reference implementation of Tamsin, called
tamsin
, written in Python 2.7. It can both interpret a Tamsin program and
compile a program written in Tamsin to C. The distribution also contains an
implementation of the Tamsin scanner and parser written in Tamsin itself
(although we're still a ways from a fully bootrapped implementation.)
While the interpreter is fine for prototyping, note that some informal benchmarking revealed the compiled C programs to be about 30x faster. Note however that while the compiler passes all the tests, it currently fails to correctly compile the Tamsin parser written in Tamsin, so it should still be considered a proof of concept.
To start using tamsin
,
- Clone the repository —
git clone https://github.com/catseye/tamsin
- Either:
- Put the repo's
bin
directory on your$PATH
, or - Make a symbolic link to
bin/tamsin
somewhere already on your$PATH
.
- Put the repo's
- Errr... that's it.
(Or, to make those steps trivial, you could use
toolshelf and run
toolshelf dock gh:catseye/tamsin
)
Then you can run tamsin
like so:
tamsin run eg/csv_parse.tamsin < eg/names.csv
You can also compile to C and compile the C to an executable and run the executable all in one step, like so:
tamsin loadngo eg/csv_extract.tamsin < eg/names.csv
Design Goals
- Allow parsers, static analyzers, interpreters, and compilers to be quickly prototyped. (And in the future, processor simulators and VM's and such things too.)
- Allow writing these things very compactly.
- Allow writing anything using only recursive-descent parsing techniques (insofar as this is possible.)
- Provide means to solve practical problems.
- Keep the language simple (grammar should fit on a page.)
- Recognize that the preceding two goals are in tension.
- Have a relatively simple reference implementation (currently less than 3000 lines of code, including everything — debugging and the C runtime used by the compiler.)
License
BSD-style license; see the file LICENSE.
Related work
Commit History
@0.2
git clone https://git.catseye.tc/Tamsin/
- Prep for release of version 0.2. Cat's Eye Technologies 10 years ago
- It's no longer a fake interp; it can pass the first 30 tests! Cat's Eye Technologies 10 years ago
- Implement $:equal in the compiler. All tests pass. Cat's Eye Technologies 10 years ago
- 'Fakie' enough to interpret zeroes.tamsin. I think. Cat's Eye Technologies 10 years ago
- Add "fakie" interpreter. Add $:equal to support it. Cat's Eye Technologies 10 years ago
- Work around it for now so that all tests pass. :/ Cat's Eye Technologies 10 years ago
- Catchup implementation in Tamsin. Bit of a stumper now, though. Cat's Eye Technologies 10 years ago
- Now the compiler handles modules (badly) too. Cat's Eye Technologies 10 years ago
- Interpreter can handle rudiments of modules. Compiler can't. Cat's Eye Technologies 10 years ago
- Modules can be defined. You just can't use them yet. Cat's Eye Technologies 10 years ago