Ludovic 'Archivist' Lagouardette e9ea189cf9 | 19 小時之前 | |
---|---|---|
include | 1 周之前 | |
test | 19 小時之前 | |
.gitignore | 5 月之前 | |
CMakeLists.txt | 19 小時之前 | |
LICENSE | 6 月之前 | |
README.md | 2 月之前 | |
bench.c | 5 月之前 | |
lib.c | 1 周之前 | |
main.c | 1 周之前 |
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.
ink_lex
)int
ink_compile
)ink_parse
)ink_parse
)[ 72 101 108 108 111 32 87 111 114 108 100 10 ]
array.print_utf8
# 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
+%
encryptionEncrypts 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