TFMG

From Esolang
Jump to navigation Jump to search
The Factory Must Grow
Paradigm(s) Declarative
Designed by KSP Atlas
Appeared in 2024
Memory system Queue-based
Computational class Turing complete
Reference implementation Unimplemented
File extension(s) .fctro, .tfmg

The Factory Must Grow (also known as TFMG) is an esoteric programming language inspired by Factorio.

Overview

TFMG is a concurrent programming language based around a system of belts, which are queues of a defined length. All machines must operate on belts (with the exception of chained machines). A machine must always have either an input or an output, as a machine with neither will never run. A machine can only run a recipe if all the required items (values) are available, and if there is space on the output belt. All TFMG programs will run forever, unless they are limited in some way (for example, if the supply of a constant is limited). TFMG machines will always consume their inputs from the queue, and they have no artificial speed limit, unless one is defined (unlike Factorio).

Making Belts

Create a simple belt called main with 10 spaces:

belt main 10

A double sided belt has double the space and acts as 2 in 1, however, only the left lane will be used unless specified otherwise.
Create a double-sided belt called append-belt with 10 spaces (which ends up being 20)

double-belt append-belt 10

Simple belt-belt operations

(note: Machines that take multiple belts always go left-right, and only take whats available on the end of the belt)

Merge two belts into one:

(belt-1, belt-2) > id<all> > belt-3

Merge two belts into one (left-bias):

(belt-1, belt-2) > id<0> > belt-3

Evenly split a belt:

belt-1 > split<all> > (belt-2, belt-3)

Split a belt, but push all Ints to the left:

belt-1 > split<Int> > (belt-int, belt-3)

Producing constants

Produce an infinite amount of the number 42 (the recipe is the constant value in this case):

Int<42> > the-answer

Only produce 10 instances of the string "Hello", using the # operator to limit the number of times the machine runs:

String<Hello>#10 > greet-belt

Take the top value of money, and push it to the belt free-money:

money > repeat > free-money

Misc

Make a belt of higher-order machines (with recipe), and pass it to a machine:

Lambda<increment<2>> > fun-belt
(fun-belt, arr-belt) > map > result-belt

Take a user input input of a number, check if its greater than 10 and if so, push an element from the top of congrat-belt to the result:

Int<10> > second-belt
Input<YN>#1 > ask-belt
(ask-belt, second-belt) > greater-than > comp-belt
(comp-belt, congrat-belt) > if > result-belt

Chain two machines together using -> (only works if output and input amounts of belts match):

belt-1 > doer<thing> -> doer<other-thing> > belt-2

Making your own machines

Make a machine that squares a number or multiplies it by another and divides all by three:

machine math {
    // Third slot is for temporary belts made during the recipe
    recipe square (input: Int) (output) () {
        (input, input) > arithmetic<multiply> > output
    }
    recipe mulanddiv (input-1: Int, input-2: Int) (output) (multiplied = 10, divs = 10) {
        Int<3> > divs
        (input-1, input-2) > arithmetic<multiply> > multiplied
        (multiplied, divs) > arithmetic<divide> > output
    }
}

Automatically choose the recipe used for a machine (only works if all recipes use different types and only have one input belt):

machine-auto stove {
    recipe boil (pasta: Pasta) (cooked) () {
        pasta > Pot<boil> > cooked
    }
    recipe fry (egg: Egg) (fried) () {
       egg > Pan<fry> > fried
    }
}

// Now these are both valid (assuming the belts exist)
raw-eggs > stove > fried-eggs
raw-pasta > stove > cooked-pasta

Example programs

Hello world:

belt hello 10
String<Hello, World!>#1 > hello
hello > print<str>

Hello world (5 times):

belt hello 10
String<Hello, World!>#5 > hello
hello > print<str>

Cat program:

Input<str> -> print<str>

Truth machine:

belt input 10
belt truth 10
belt output 10
Bool<true> > truth
Input<YN> > input
(input, truth) > if > output
output > print<bool>