Afth64
| Designed by | Sara Berman (User:Lykaina) |
|---|---|
| Appeared in | 2026 |
| Computational class | Turing complete |
| Reference implementation | https://github.com/lykaina/afth64 |
| File extension(s) | .a64 |
Afth is a Forth-inspired partially-esoteric language created by Sara Berman that emphasizes the component characters that make up word definitions.
Afth64, also by Sara Berman, is a reduction of Afth to use only the DEC SIXBIT range for its core instructions and word names.
Currently in alpha-stage.
Syntax
Command Groups and Full Line Commands
Most lines are made up of sequences of command groups, separated by one space between and no space at end.
Some lines, however, are full line commands that follow a specific format.
Initial Letters Tables
Command Groups
| First Char | Cmd Group Length | Meaning |
|---|---|---|
`
|
2 chars | Single Char to be put on stack. |
{
|
3+ chars | Command is made up of Core Instruction Chars. (Terminated by })
|
!-_
|
1-5 chars | Word (Only uses chars between ! and _)
|
Full Lines
| First Char | Meaning |
|---|---|
!-_,`,{
|
Line is made up of Command Groups. |
~
|
Defines a word using Core Instruction Chars. |
|
|
String input, one stack cell per char, written in top to bottom order. |
Stacks
There are two LIFO stacks that start empty.
The reference interpreter does not currently have protections against stack underrun.
As Afth64 lacks interactivity, there is no core instruction that views the stack contents without changing it.
Words
Word names must be made up of 1-5 non-space DEC SIXBIT chars (ASCII 33-95).
Sample Declaration:
~DUP HGG
Line-scope Variables
There are 5 line-scope variables that are all set to zero at the beginning of a new line (or when jumping to the beginning of the same line):
t, ti, tj, tk, tl.
They can not be accessed by the programmer directly.
Jumping
When jumping from one line to another or to the beginning of the same line, any further instructions in the current word or later words on that line are ignored.
If no jump is made, the program will auto-jump to the next line after execution of the line is complete, as if the code _1L_1S were present at the end of the line.
The code _1L_S at the end of a line forces the program into an infinite loop on current line.
Due to a bug in the reference interpreter, no more than one jump should be on any given line.
Core Instructions
pass ! self.rcore_not_tl() if tl==0 tl=1; else tl=0 " pass # pass $ pass % self.rmath_t_tl_mod() t=t%tl & self.rcore_and_tl() if (tl!=0 and t!=0) tl=1; else tl=0 ' pass ( self.rxtio_t_in_hex() input t from hex ) self.rxtio_t_out_hex() output t as hex * self.rmath_t_tl_mul() t=t*tl + self.rmath_t_tl_add() t=t+tl , self.rxtio_t_in_char() input t from char - self.rcore_t_flipsign() t=t*-1 . self.rxtio_t_out_char() output t as char / self.rmath_t_tl_idiv() t=t//tl 0 self.rcore_t_x16_inc(0) t=t*16 1 self.rcore_t_x16_inc(1) t=t*16+1 2 self.rcore_t_x16_inc(2) t=t*16+2 3 self.rcore_t_x16_inc(3) t=t*16+3 4 self.rcore_t_x16_inc(4) t=t*16+4 5 self.rcore_t_x16_inc(5) t=t*16+5 6 self.rcore_t_x16_inc(6) t=t*16+6 7 self.rcore_t_x16_inc(7) t=t*16+7 8 self.rcore_t_x16_inc(8) t=t*16+8 9 self.rcore_t_x16_inc(9) t=t*16+9 : self.rcore_t_abs() t=abs(t) ; self.rcore_or_tl() if (tl==0 and t==0) tl=0; else tl=1 < self.rcore_t_shl() t=t*2 = pass > self.rcore_t_shr() t=t//2 ? pass @ pass A self.rcore_t_x16_inc(10) t=t*16+10 B self.rcore_t_x16_inc(11) t=t*16+11 C self.rcore_t_x16_inc(12) t=t*16+12 D self.rcore_t_x16_inc(13) t=t*16+13 E self.rcore_t_x16_inc(14) t=t*16+14 F self.rcore_t_x16_inc(15) t=t*16+15 G self.rstac_s_t() stack.push(t) H self.rstac_t_s() t=stack.pop() I self.rswap_t_i() swap t,ti J self.rswap_t_j() swap t,tj K self.rswap_t_k() swap t,tk L self.rswap_t_l() swap t,tl M self.rstac_s2_t() stack2.push(t) N self.rstac_t_s2() t=stack2.pop() O self.rstac_t_len_s() t=len(stack) P self.rstac_t_len_s2() t=len(stack2) Q self.rcore_quit() exit(t) R self.rcore_quit_iflz() if tl == 0 exit(t) S self.rcore_jnz_r() jump t lines if tl != 0 T self.rcore_zte() if t==0 tl=1; else tl=0 U self.rcore_ztg() if t>0 tl=1; else tl=0 V self.rcore_t_dec() t=t-1 W self.rmath_t_tl_pow() t=floor(pow(t,tl)) X self.rcore_xor_tl() if (tl==0 and t==0) tl=0; elif (tl!=0 and t!=0) tl=0; else tl=1 Y self.rmath_t_tl_log() t=floor(log(t,tl)) Z self.rxtra_t_randint() t=randint(t) [ self.rxtio_t_in_int() input t from int \ pass ] self.rxtio_t_out_int() output t as int ^ self.rcore_t_inc() t=t+1 _ self.rcore_t_zero() t=0
Computational class
The core commands can emulate a Turing machine using the two stacks.
Dictionary Code
This is the dictionary as used in all examples:
~+ HLH+G ~- H-LH+G ~* HLH*G ~/ HLH/G ~% HLH%G ~<< H<G ~>> H>G ~++ H^G ~-- HVG ~IC ,G ~OC H. ~ID [G ~OD H] ~IH (G ~OH H) ~END _Q ~ABS H:G ~NEG H:-G ~DUP HGG ~L_NZ HL_S ~JNZ HIHLIS ~JUMP HI_^LIS ~DROP IHI ~POP H ~PUSH G ~DROP2 INI ~POP2 N ~PUSH2 M ~JSIG HIOUIS ~SI OG ~SI2 PG ~SI_S2 OI ~SI2S2 PI ~CR _DG ~LF _AG ~S->S2 HM ~S2->S NG ~S=S2 HGM ~S2=S NMG
Examples
Hello, World!
A simple Hello World:
LF
|Hello, World!
{_2G} JSIG
{_2G} JUMP
OC {_2G} NEG JUMP
END
Add Two Numbers
This adds two base-10 numbers and outputs the result in base-10:
ID ID + OD END
Echo
Similar to the Cat program, the Echo program outputs input, but then quits after outputting an LF
IC DUP OC LF - L_NZ END
RPN Calculator
Simple single-equation five-function integer RPN Calculator. Put 0 . at end of line to output result and quit.
LF
|RPN CALC
{_2G} JSIG
{_2G} JUMP
OC {_2G} NEG JUMP
ID ID IC IC DROP {_2G} JUMP
ID IC IC DROP
DUP `. - {_2G} JNZ
DROP DROP OD END
DUP `+ - {_2G} JNZ
DROP + {_4G} NEG JUMP
DUP `- - {_2G} JNZ
DROP - {_6G} NEG JUMP
DUP `* - {_2G} JNZ
DROP * {_8G} NEG JUMP
DUP `/ - {_2G} JNZ
DROP / {_AG} NEG JUMP
DUP `% - {_2G} JNZ
DROP % {_CG} NEG JUMP
DROP LF
|ERROR...
{_2G} JSIG
{_2G} JUMP
OC {_2G} NEG JUMP
END
Current bugs:
- First operator requires exactly two numbers inputted before it. Any later operators require exactly one number to be entered before it.