gal_

gal — the general abstract language

gal is a programming language that compiles to six others. Write a program once and the compiler gives you Python, JavaScript, Go, Java, C++ or MUMPS source that does the same thing in each.

one program

This is FizzBuzz in gal. Names start with a capital letter, keywords are lowercase, and a statement ends with a semicolon or a block.

module Fizzbuzz
{
    main
    {
        for range I 1 20
        {
            if ((I mod 15) = 0)
            {
                say "FizzBuzz";
            }
            else if ((I mod 3) = 0)
            {
                say "Fizz";
            }
            else if ((I mod 5) = 0)
            {
                say "Buzz";
            }
            else
            {
                say I;
            }
        }
    }
}

six languages

This is what the gal 3.3 compiler generates from that program, unedited.

python

# module: Fizzbuzz
if __name__ == '__main__':
    for I in range(1,20+1):
        if I % 15 == 0:
            print('FizzBuzz')
        elif I % 3 == 0:
            print('Fizz')
        elif I % 5 == 0:
            print('Buzz')
        else:
            print(str(I))

javascript

// module: Fizzbuzz
// main program
for (var I = 1; I <= 20; I++)
{
    if (I % 15 == 0)
    {
        console.log('FizzBuzz');
    }
    else if (I % 3 == 0)
    {
        console.log('Fizz');
    }
    else if (I % 5 == 0)
    {
        console.log('Buzz');
    }
    else
    {
        console.log(globalThis.String(I));
    }
}

go

package main

import "fmt"

// module: Fizzbuzz
func main() {
    for I := 1; I <= 20; I++ {
        if ((I % 15) == 0) {
            fmt.Println("FizzBuzz")
        } else if ((I % 3) == 0) {
            fmt.Println("Fizz")
        } else if ((I % 5) == 0) {
            fmt.Println("Buzz")
        } else {
            fmt.Printf("%d\n", I)
        }
    }
}

java

@SuppressWarnings({"unchecked", "cast", "serial", "rawtypes", "this-escape", "deprecation", "removal"})
public class Fizzbuzz {
    public static void main(String[] args) {
        for (int I = 1; I <= 20; I++) {
            if (((I % 15) == 0)) {
                System.out.println("FizzBuzz");
            } else if (((I % 3) == 0)) {
                System.out.println("Fizz");
            } else if (((I % 5) == 0)) {
                System.out.println("Buzz");
            } else {
                System.out.println(I);
            }
        }
    }
}

c++

#include <iostream>

// module: Fizzbuzz
int main() {
    for (int I = 1; I <= 20; I++) {
        if ((I % 15) == 0) {
            std::cout << "FizzBuzz\n";
        } else if ((I % 3) == 0) {
            std::cout << "Fizz\n";
        } else if ((I % 5) == 0) {
            std::cout << "Buzz\n";
        } else {
            std::cout << I << "\n";
        }
    }
    return 0;
}

mumps

Fizzbuzz ; gal ; Fizzbuzz module.
    do init^galrt
    do main()
    quit
main() ; main program
    new %etin set %etin=$etrap
    new $etrap,$estack set $etrap=%etin
    set I=1
    goto:$select(1<0:I<20,1:I>20) L41K
    goto L41B
L41C ; for range continue
    goto:$select(1<0:I+1<20,1:I+1>20) L41K
    set I=I+1
L41B ; for I range begin
    if ((I#15)=0)
    else  goto L80X
    use $principal write "FizzBuzz",!
    goto L80E
L80X ; if-else
    if ((I#3)=0)
    else  goto L173X
    use $principal write "Fizz",!
    goto L80E
L173X ; else-if-else
    if ((I#5)=0)
    else  goto L266X
    use $principal write "Buzz",!
    goto L80E
L266X ; else-if-else
    use $principal write I,!
L80E ; end if
    goto L41C
L41K ; for I range break
    quit

Each of them prints the same 20 lines:

1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz

The repository's five-languages oracle runs five programs through every target and fails if any two outputs differ by a byte.

a compiler written in gal

The gal compiler is a gal program. It compiles its own source, the result compiles the source again, and the two generations come out byte-identical across all fourteen of its parts. Because the compiler is ordinary gal, it also runs wherever gal runs: on CPython, node, the JVM and YottaDB — and in your browser.

try it

what comes next

gal3 goes one way: from gal down to a target language. gal4 is the next release, and it adds the other directions — reading programs written in other languages into gal, and lifting low-level code back up into more abstract code.