|
|
- # `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`
-
- These functions need to be wrapped, the wrapper allows to make them stateful to keep individual heaps per context,
- allowing to clean the context by cleaning up its allocations.
-
- 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
-
- ```asm
- # 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.
-
- ```asm
- # 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
- ```
-
- ```asm
- [ 72 101 108 108 111 32 87 111 114 108 100 10 ]
- dup
- 32 128 encrypt
- string.dump
- ```
|