HALIT
ALPTEKIN
HOMEWHOAMIRESEARCHPROJECTS
POSTS
hblog-ng v0.1.0
RX:0 B/s
TX:0 B/s
Cover
PROJECT
/2013/ARCHIVED/

HL

An esoteric programming language based on delta-encoding, running on a custom virtual machine.

KEYWORDS:
+3
#brainfuck#c#esolang
Syntactically, HL is Turing Complete. It possesses the required isomorphism to #brainfuck (loops, math, memory traversal). However, the current C-based HVM implementation is technically a Linear Bounded Automaton. The fixed number of registers (6) and fixed program size (255) prevents the "infinite tape" requirement of a true Turing Machine. To make it fully Turing Complete, the VM would simply need to allow dynamic memory allocation.
HL (Halit's Language) is a project for learning how computers actually run logic. It has two parts: a high-level #esolang scripting language (HL) and its low-level backbone, the HVM (Halit's Virtual Machine). I wrote it in #c, and instead of targeting a real architecture like x86 or ARM it runs on a small hardware simulation I built myself.
The first version was a flat linear script. The current one adds branching, loops, and system calls, which makes HL syntactically Turing Complete.

The Engine (HVM)

The core of the project is the virtual machine. It models a register-based architecture, using plain #c integers as its "electricity." It has a fixed block of program memory and a small set of registers.
  • •
    Word Size: 16-bit instruction format.
  • •
    Memory: 255 slots of fixed program memory.
  • •
    Registers: 6 total (1 Program Counter + 5 General Purpose).
The machine operates on a classic cycle. It fetches an integer from memory, decodes it into an Operation Code (OpCode), executes the logic, and increments the Program Counter.
Loading diagram...
Instructions are packed into single integers. The VM uses bitwise operators to "slice" the instruction. Crucially, while registers use 4-bit slots, immediate values (used in LOAD or JMP) utilize the lower 8 bits, overlapping with Reg 1 and Reg 2.
MaskComponentDescription
0xF000OpCodeThe operation command (e.g., ADD, MOV, SYS).
0x0F00Reg 0Destination Register.
0x00F0Reg 1Source Register A.
0x000FReg 2Source Register B.
0x00FFValueImmediate Value / Address (Overlaps Reg 1 & 2).

The Language (HL)

HL sits on top of the HVM as a high-level wrapper. It combines delta encoding (using + and - to shift values) with stack-based control flow.
The language uses a minimal set of symbols to manipulate registers and control execution flow, plus a special initialization syntax.
SymbolActionHVM Mapping
("c", r)InitLOAD value 'c' into register 'r'.
( ... )GroupWraps arithmetic operations.
+ / -MathIncrement or Decrement the Active Register.
> / <SwitchMove focus to the Next or Previous Register.
[Loop StartJNZ (Jump if Not Zero). Repeats block while Active Reg != 0.
]Loop EndJMP (Jump back to start).
.PrintSYS 1 (Output Active Register as Char).
,InputSYS 2 (Read Input to Active Register).
The parsing logic acts as a hybrid state machine.
  • •
    Tokenizer: Scans for groupings () or control characters [].
  • •
    Initialization: If a token contains a comma and quotes (e.g., ("h", 1)), it parses it as a literal and generates a LOAD opcode using the Value bitmask.
  • •
    Deltas: If the token contains operators (e.g., (+++)), it counts them and generates ADD/SUB opcodes.
  • •
    Loop Handling: When the parser encounters [, it pushes the current bytecode address to a Stack. When it finds ], it pops the address to resolve the jump target.
Loading diagram...

Examples

These snippets show how the language grew. They go from a raw delta-encoded string to a structured loop.

Linear "Hello World"

This shows the delta encoding side of HL. It starts at 'h' with the initialization syntax, then shifts the value up and down to reach each following ASCII character.
hl
("h", 1)
(---)
(+++++++)
()
(+++)
(-------------------------------------------------------------------------------)
(+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++)
(--------)
(+++)
(------)
(--------)
(-------------------------------------------------------------------)
Here is how the HVM interprets that stream to produce the output. It maintains the state in Register 1 and modifies it step-by-step.
InstructionLogicCalculationASCIIOutput
("h", 1)LOAD 'h'Reg1 = 104104h
(---)SUB 3104 - 3 = 101101e
(+++++++)ADD 7101 + 7 = 108108l
()NOP108 + 0 = 108108l
(+++)ADD 3108 + 3 = 111111o
(---...x79)SUB 79111 - 79 = 3232SPACE
(+++...x87)ADD 8732 + 87 = 119119w
(--------)SUB 8119 - 8 = 111111o
(+++)ADD 3111 + 3 = 114114r
(------)SUB 6114 - 6 = 108108l
(--------)SUB 8108 - 8 = 100100d
(---...x67)SUB 67100 - 67 = 3333!

The "A-Z" Generator

This shows control flow. Instead of hardcoding every letter, a loop prints the alphabet automatically.
  • •
    Reg 1: Set to 26 (Loop Counter).
  • •
    Reg 2: Set to 65 ('A').
  • •
    Loop: Print Reg 2, Increment Reg 2, Decrement Reg 1.
hl
// Setup: Reg 1 = 26
(++++++++++++++++++++++++++)

// Switch to Reg 2, Setup 'A' (65)
(>) (+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++) (<)

// While Reg 1 is not 0
[
    (>)     // Switch to Reg 2 ('A')
    .       // Print Char
    (+)     // Increment to 'B'
    (<)     // Switch to Reg 1 (Counter)
    (-)     // Decrement Counter
]

HL vs. Brainfuck

HL has the same spirit as #brainfuck, but the two differ in architecture and philosophy.
FeatureBrainfuckHL
ArchitectureTape Based: You move a pointer along an infinite array of memory cells.Register Based: You switch focus between a limited set of high-speed registers (CPU simulation).
GroupingIndividual: ++++ executes as 4 separate increment instructions.Grouped: (++++) is parsed as a single ADD 4 instruction. This makes HL more efficient at runtime.
PhilosophyMinimalist Turing Machine.Minimalist CPU Architecture.
HVM Execution Cycle
Rendering diagram...
Parser & Compilation Logic
Rendering diagram...
("h", 1)
(---)
(+++++++)
()
(+++)
(-------------------------------------------------------------------------------)
(+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++)
(--------)
(+++)
(------)
(--------)
(-------------------------------------------------------------------)
// Setup: Reg 1 = 26
(++++++++++++++++++++++++++)

// Switch to Reg 2, Setup 'A' (65)
(>) (+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++) (<)

// While Reg 1 is not 0
[
    (>)     // Switch to Reg 2 ('A')
    .       // Print Char
    (+)     // Increment to 'B'
    (<)     // Switch to Reg 1 (Counter)
    (-)     // Decrement Counter
]