A minimalistic programming language written in C89.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

3.6 KiB

ink

ink is a minimalistic interpreted programming language, tentatively implemented exclusively in C89. It features coroutines and can currently only manipulate integers. Part of the code may not be compliant with C89 and I will try to fix that in time.

It is fully self-contained and doesn't rely on a working standard library beyond the following:

  • malloc
  • realloc
  • free
  • putchar

To make the library not use the standard library, build it with NOSTDLIB defined as a preprocessor directive.

All of these functions need to work for ink to work. It is easy to add new functions to the interpreter. I added a garbage collector to handle cleaning dynamically allocated resources.

It is possible to segregate unsafe allocations (allocations that should be hidden from the interpreter) by setting the inner_ versions of the library functions to different allocation functions.

Limits

  • Token size is limited to 127 bytes (see ink_lex)
  • Values and indices are limited to the platform size of int
  • Main function has a size limit of 256 tokens (see ink_compile)
  • Functions have a size limit of 256 tokens (see ink_parse)
  • Functions have a count limit 128 labels (see ink_parse)
  • Only non-main functions can use labels

Examples

Hello World

[ 72 101 108 108 111 32 87 111 114 108 100 10 ] 
    array.print_utf8

Clone array

# Clones an array, creating a new array
# 
# @param array The array to clone into a new array
# @return a new array that contains the same elements as the source array
# 
# array -> new_array
fn array.clone do
    array.new 2 pluck array.size 0
    # array new_array end it
    2 pluck 2 pluck == end_loop jump_if
    # array new_array end it
    loop:
        dup 5 pluck
        # array new_array end it it array
        array.index 4 pluck
        # array new_array end it v new_array
        array.push
        # array new_array end it
        1 +
   2 pluck 2 pluck > loop jump_if
   end_loop: drop drop swap drop
   # new_array
end

+% encryption

Encrypts a string with (v + add_key) % modulo_key. It modifies the array that was passed in.

# Encrypts things by doing `(v + add_key) % modulo_key`
#
# @param array An array of ints representing a string
# @param add_key Should be lower than the add key
# @param modulo_key Should ke higher than all the codepoints of the array
#
# array add_key modulo_key
fn encrypt do
    3 pluck array.size
    # array add_key modulo_key index
    loop:
        1 - dup 5 pluck
        # array add_key modulo_key index index array
        array.index
        # array add_key modulo_key index v
        4 pluck +
        # array add_key modulo_key index (v + add_key)
        3 pluck %
        # array add_key modulo_key index ((v + add_key) % modulo_key)
        2 pluck
        # array add_key modulo_key index ((v + add_key) % modulo_key) index
        6 pluck
        # array add_key modulo_key index ((v + add_key) % modulo_key) index array
        array.set
        # array add_key modulo_key index
    dup 0 != loop jump_if drop drop drop drop
end

# Prints a string as an array of ints
#
# @param array An array of ints representing a string
#
# array
fn string.dump do
    dup array.size 0
    # array end it
    91 print_utf8
    32 print_utf8
    loop:
        dup
        # array end it it
        4 pluck
        # array end it it array
        array.index print_int
        32 print_utf8
        1 +
        # array end it
    2 pluck 2 pluck > loop jump_if
    # array end it
    93 print_utf8
end
[ 72 101 108 108 111 32 87 111 114 108 100 10 ] 
    dup 
    32 128 encrypt 
    string.dump