This is DFkup, /diː ɛf kʌp/ (or simply: "dee-ef-cup") is a scripting language made with VanCode framework, a modular, BYOP (bring your own parser) codegen, stack-based VM and JIT. Notable, VanCode is a continuation of liquidev's hayago work <3. The JIT compiler uses Lua's DynASM assembler for native code generation. (tried to implement libgccjit ~ kinda slow, hard to work with. while llvm is way too heavy).
dfkup is doing some basic voodoo directly into VanCode source at compile-time, injecting additional AST structures, code gen handlers, custom opcodes, and VM branches. Mostly, lexer & parser is a copy of Tim Engine but without the front-end dev DSL features.
Repository: https://github.com/dfkup/dfkup
fn fib(n: int): int {
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
}
echo fib(20)
# or, indent-based in nim style
fn fib(n: int): int =
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
type User = object
name: string
age: int
email: string
var alice = User(name: "Alice", age: 30, email: "[email protected]")
echo alice.name
var john = {name: "John", age: 40, email: "[email protected]"}
echo john.name More snippets here: https://github.com/dfkup/dfkup/blob/main/examples/basics.dfkup
Notes:
Multi-language benchmark results
fib_recursive:
fib_recursive dfkup Time (mean ± σ): 7.3 ms ± 1.0 ms
fib_recursive node Time (mean ± σ): 93.2 ms ± 11.9 ms
fib_recursive python3 Time (mean ± σ): 1.017 s ± 0.016 s
fib_recursive ruby Time (mean ± σ): 521.0 ms ± 4.0 ms
fib_recursive luajit Time (mean ± σ): 76.5 ms ± 2.2 ms
fib_recursive php83 Time (mean ± σ): 520.2 ms ± 11.5 ms
nested_loops:
nested_loops dfkup Time (mean ± σ): 72.5 ms ± 0.5 ms
nested_loops node Time (mean ± σ): 40.5 ms ± 0.4 ms
nested_loops python3 Time (mean ± σ): 30.9 ms ± 1.0 ms
nested_loops ruby Time (mean ± σ): 81.6 ms ± 2.6 ms
nested_loops luajit Time (mean ± σ): 6.5 ms ± 0.4 ms
nested_loops php83 Time (mean ± σ): 25.3 ms ± 0.9 ms
prime_sieve:
prime_sieve dfkup Time (mean ± σ): 113.8 ms ± 1.4 ms
prime_sieve node Time (mean ± σ): 40.1 ms ± 0.7 ms
prime_sieve python3 Time (mean ± σ): 26.6 ms ± 1.1 ms
prime_sieve ruby Time (mean ± σ): 73.6 ms ± 0.7 ms
prime_sieve luajit Time (mean ± σ): 6.0 ms ± 0.5 ms
prime_sieve php83 Time (mean ± σ): 24.1 ms ± 0.6 ms
string_concat:
string_concat dfkup Time (mean ± σ): 15.4 ms ± 0.7 ms
string_concat node Time (mean ± σ): 39.4 ms ± 0.4 ms
string_concat python3 Time (mean ± σ): 25.1 ms ± 0.8 ms
string_concat ruby Time (mean ± σ): 73.5 ms ± 1.3 ms
string_concat luajit Time (mean ± σ): 11.5 ms ± 0.3 ms
string_concat php83 Time (mean ± σ): 23.1 ms ± 0.7 ms
tail_recursive:
tail_recursive dfkup Time (mean ± σ): 548.4 ms ± 1.4 ms
tail_recursive node CRASHED
tail_recursive python3 CRASHED
tail_recursive ruby CRASHED
tail_recursive luajit CRASHED
tail_recursive php83 Time (mean ± σ): 23.2 ms ± 0.4 ms
range_sum:
range_sum dfkup Time (mean ± σ): 31.3 ms ± 2.6 ms
range_sum node Time (mean ± σ): 49.9 ms ± 1.2 ms
range_sum python3 Time (mean ± σ): 717.9 ms ± 19.9 ms
range_sum ruby Time (mean ± σ): 421.2 ms ± 7.5 ms
range_sum luajit Time (mean ± σ): 13.6 ms ± 0.4 ms
range_sum php83 Time (mean ± σ): 93.9 ms ± 1.8 ms
Not bad, not bad! Regarding fib_recursive win. The speed comes from a pattern-specific hack, not a general TCO or recursion to iteration transform, so there is still a lot of work to do at DynASM JIT level for general optimizations :P