tfel is a deliberately cursed programming language runtime.
This project is a joke, on purpose. If you open TFEL code and your first reaction is "what is going on?", the design is working.
For the full design rant and spec, read TFEL_LANGUAGE_SPEC.md.
- Execution order is upside down.
- Brackets are mirrored.
- Assignment is reversed.
- Many keywords are reversed.
- It is internally consistent enough to be usable, which is the worst part.
cargo run -- examples/hello.tfelRun logical (non-mirrored) TFEL directly:
cargo run -- --logical examples/hello.logical.tfelMirror a logical file into on-disk .tfel form:
cargo run -- mirror program.logical.tfel program.tfelTFEL source files are intentionally stored in a mirrored form.
When you run a file, the runtime does this:
- Reverse every line.
- Reverse line order.
- Tokenize with swapped brackets.
- Parse and evaluate.
That means there are two views of TFEL:
- Logical TFEL syntax: what the parser effectively sees after preprocessing.
- On-disk TFEL syntax: the weird mirrored text in
.tfelfiles.
Write code in logical TFEL first, then mirror it into a .tfel file:
cargo run -- mirror program.logical.tfel program.tfel
cargo run -- program.tfelYou can also skip mirroring and run logical TFEL directly:
cargo run -- --logical program.logical.tfelEverything below is shown in logical syntax (after preprocessing).
10 = x;
"hello" = msg;
tel is the strict declaration keyword:
tel x = 10;
let exists for compatibility (disabled in --strict-tfel mode):
let x = 10;
print)"hello"(;
print)msg(;
if)x > 0(} print)"positive"(; { else } print)"zero or negative"(; {
elihw)i < 5(} i + 1 = i; {
rof item ni range)0, 3(} print)item(; {
Loop control:
kaerb;
eunitnoc;
Comparisons include <= and >=.
fed add)a, b(} nruter a + b; {
add)2, 3(;
}"name": "tfel", count: 2{ = user;
user]"name"[;
Object keys support quoted strings and bare identifiers. Indexing objects requires a string key.
10 = n;
"fib(${n}) => ${n + 1}";
"math" tropmi;
"answer" morf "math" tropmi;
lib/file tropmi;
Aliases also work:
"answer" morf "math" tropmi;
Note the shape: the module atom comes first, the keyword last — English
keyword spellings are accepted outside --strict-tfel, but the position is
not). import "math"; is not valid logical syntax.
In --strict-tfel mode, only mirrored keywords are accepted (tropmi, morf).
Import-all exposes module namespace aliases too:
lib/emit tropmi;
emit.lamron)(;
Modules can define explicit exports:
tropxe answer, format;
40 = answer;
If no tropxe statement is present, all non-builtin top-level names are exported (legacy behavior).
Tracked in TFEL_LANGUAGE_SPEC.md §4.8 — the full redesign of the syntax,, frozen
as a design agreement,, awaiting implementation. The one rule:values first,, operation
last — every operation consumes the expression to its right.
- Declarations are normal:
int x = 10;string message = "…"; - Assignment is normal direction:
x = value;[0] xs = value;["name"] user = "Bob"; - Calls are postfix:
(a,, b)add;("hello")print; - Indexing/field access is prefix:
[0] numbers[-1] numbers(second element),,["name"] user; chain freely:["name"] ["profile"] user - Control-flow bodies live ABOVE their condition/iteration expr:
{ BODY } (cond)if;{ BODY } (item in col)for;{ BODY } (cond)while; - Functions: body above signature:
{ ... } fn add(int a,, int b); - Replacements:
tel→typed decl,,fed→fn,,nruter→return,,eurt→true,, etc. - Execution direction stays bottom-to-top — that is the point.
Open grammar items,, tracked in spec §8.
User-facing builtins:
input/tupniargs/sgra— script arguments as an array of strings (interpreter: everything after the script path; compiled binaries:argv[1..])len/nelto_number/rebmun_otrange/egnartype_of/fo_epytto_string/gnirts_ot
Internal primitives used by libraries:
- time/date:
__emit_time,__lamron_time,__etad_today - file I/O:
__read_file,__write_file,__delete_file - network:
__http_request(method, url, body?)(response body),__http_status(method, url, body?)(numeric status code) - C FFI (Unix,
--allow-run):__c_load(path)→ handle int,__c_call(handle, symbol, ret, argtypes, args)→any,__c_unload(handle)→ bool. Type tags:"int","double","string", plus"void"for returns. Fixed-arity (max 4 args), non-variadic only; a wrong signature is C-level undefined behavior. Seeexamples/ffi_demo.tfel.
__read_file / __write_file / __delete_file are blocked unless --allow-fs is passed.
__http_request / __http_status are blocked unless --allow-net is passed.
__run_command and the C FFI are blocked unless --allow-run is passed.
When embedding TFEL as a library, runtime permissions default to restricted (fs/network off)
unless you explicitly enable them in EvaluatorOptions.
cargo run -- [--logical] [--strict-tfel] [--allow-fs] [--allow-net] [--module-path <dir>]... <path> [script-args...]
cargo run -- mirror <logical-input> <mirrored-output>--logical: parse input as logical TFEL (skip mirror preprocessing)--strict-tfel: disable compatibility syntax and require explicit declarations before assignment--allow-fs: enable filesystem builtins--allow-net: enable network builtin--module-path <dir>: add extra module search directories for imports (repeatable)
tfel build is not available in this version: only the interpreter is
shipped. (tfel build ... exits with a message saying so.)
Local library examples:
examples/lib/emit.tfelexamples/lib/file.tfel
External-style library examples:
examples/lit/http/client.tfelexamples/lit/http/index.tfel
Why lit and not lib?
I typo'd the folder name, laughed, and promoted the typo to official TFEL canon.
lit/http API (import what you need, e.g. "get" from "lit/http" import;):
request(method, url, body)— response body stringget(url)— response body stringpost(url, body)— response body stringstatus(url)— numeric status code (its own request)
Notes:
- HTTP is done with raw TCP in the runtime.
- HTTPS is done via system
openssl s_client(no Rust HTTP/TLS dependency crate).
Run all top-level examples with expected-failure classification:
./scripts/run_examples.shRecommended first real example:
cargo run -- examples/weekly_report_showcase.tfelA more real-world-ish mini project:
cargo run -- examples/service_health_report.tfelNetwork + filesystem showpiece:
cargo run -- --allow-net --allow-fs examples/service_health_reporter.tfelexamples/http_demo.tfel, examples/api_request_demo.tfel, and
examples/service_health_reporter.tfel default to offline-safe mode.
Set run_network = true / run_live_checks = true inside those files for live requests.
cargo run -- examples/hello.tfel
cargo run -- examples/fibonacci.tfel
cargo run -- examples/cursed_demo.tfel
cargo run -- examples/complex_logic.tfel
cargo run -- examples/random_gen.tfel
cargo run -- examples/if_else_demo.tfel
cargo run -- examples/complex_branch_chain.tfel
cargo run -- examples/function_add.tfel
cargo run -- examples/closure_demo.tfel
cargo run -- examples/input_demo.tfel
cargo run -- examples/while_sum.tfel
cargo run -- examples/for_range_sum.tfel
cargo run -- examples/while_print_1_to_100.tfel
cargo run -- examples/builtins_demo.tfel
cargo run -- examples/import_all_demo.tfel
cargo run -- examples/from_import_demo.tfel
cargo run -- examples/import_lib_lint_sat_demo.tfel
cargo run -- examples/indexing_demo.tfel
cargo run -- examples/types_demo.tfel
cargo run -- examples/emit_demo.tfel
cargo run -- examples/emit_normal_demo.tfel
cargo run -- examples/file_demo.tfel
cargo run -- examples/weekly_report_showcase.tfel
cargo run -- examples/service_health_report.tfel
cargo run -- --allow-net --allow-fs examples/service_health_reporter.tfel
cargo run -- examples/http_demo.tfel
cargo run -- examples/api_request_demo.tfelIntentional error demos:
cargo run -- examples/error_hint_demo.tfel
cargo run -- examples/error_context_demo.tfelThis is a fun side project. Some parts are fully vib-coded, some parts are manual, and fixes are mixed too.
There is no support commitment and no guaranteed roadmap. If I feel like adding something because it is fun or I want to learn it, I will add it. If not, I will not.
Like many side projects, I may forget about this in a month or two.
TFEL is here to teach interpreter architecture while politely attacking every coding instinct you have.
TFEL stays deliberately minimal on dependencies:
- The Rust crate has zero third-party dependencies, and
Cargo.lockshould stay dependency-free. - HTTP uses raw TCP sockets and HTTPS shells out to the system
openssl s_client— no HTTP/TLS crates. tfel buildshells out to the system C compiler instead of embedding a compiler-as-a-library crate.
New dependencies need a very good reason, and preferably a joke attached.
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo testA lightweight VS Code syntax package lives at:
editors/vscode-tfel
It includes TextMate highlighting plus a minimal language-server stub (hover + heuristic parse diagnostics).
Local install instructions are in:
editors/vscode-tfel/README.md
Apache-2.0 (LICENSE).