MultiScript
MultiScript is designed by PSTF inspired from ↑→↓.
Inspired by a problem from the 'Algorithm Training Camp,' I created this language.
Intro
As the name shown, MultiScript is multi-threaded.
Each program has at least one and at most five threads. For each thread, the thread at the head of the ready queue is executed first; after executing q commands (including no-ops), it is placed at the end of the ready queue, and this process repeats. If a thread has completed execution, it is directly pushed onto the stack of completed threads and is no longer used.
| Command | Meaning |
|---|---|
| print x | Output the value of x. |
| input x | Input a value to x. |
| let x = p | Assign p to x. |
| let x -> t | Convert x to the type of t. |
| getline x | Limited to the case where x is a string. Read a string until a newline character is encountered. |
| if(x){y}else{z} | If x is true, execute y; otherwise, execute z. An expression is considered true if and only if it returns a true or non-zero value. |
| while(x){y} | As long as x is true, y will keep executing. Evaluating whether the expression is true takes one unit of time. |
| lock x | Set an open variable for exclusive access by a specific thread. A variable is considered open if and only if its value is not NULL. |
| unlock x | Unlock a locked variable. The unlocked variable will be accessible by all threads. |
| pass | Literally an N.O.P. |
| break | Jump out from current loop. |
| halt | Stop the current thread and place it at the end of the ready queue. |
| end | Terminate the current thread and push it onto the completed stack. |
| for(x,y){t} | For every x in y, perform t once. |
If a variable that is exclusively accessed by one thread is attempted to be accessed by another thread, that thread will be blocked and placed at the end of the blocked queue until the variable becomes a shared variable again. At that point, the head of the blocked queue is moved to the end of the ready queue.
Predefined Functions and Libraries
Predefined functions are defined before the main program. They share the same commands with each thread, but they have some extended commands.
| Command | Meaning |
|---|---|
| return x | Make the function terminate and return the value of x. |
A library (or header file) is a program that is introduced at the beginning of a program in the format import XXX.lib. These library programs usually do not have threads, but they contain many predefined variables and functions.
If a thread finishes executing its code, it will be terminated immediately regardless of any remaining time.
Initializing
All initialization code will be executed before any threads. In the initialization code, there are two reserved variables: __THREAD__ and __QUANTUM__, which represent the number of threads and the time unit, respectively. Threads 1 to 5 are represented by A, B, C, D, and E.
Cleaning up
All cleanup code will be executed after the thread. It usually removes some unnecessary results, outputs the final results, restores the state, and so on.
Program Format
@PROGRAM_NAME
__QUANTUM__: q
__THREAD__: t
@predefined functions
$function_name argument_list:
# Code of predefined functions
@initialize
# Initializing code
@main
->A: {
# Code of thread A
}
->B: {
# Code of thread B
}
->C: {
# Code of thread C
}
->D: {
# Code of thread D
}
->E: {
# Code of thread E
}
@cleanup
# Cleanup code
Examples
Hello, world!
@PROGRAM_NAME
__QUANTUM__: 100
__THREAD__: 1
@predefined functions
@initialize
@main
->A: {
print "Hello, world!"
end
}
@cleanup
Fibonacci
@PROGRAM_NAME
__QUANTUM__: 1145141919810
__THREAD__: 1
@predefined functions
$Fibonacci x:
return (x == 0)?(1):((Fibonacci (x-1)) + (Fibonacci (x-2)))
@initialize
let x = 0
input x
@main
->A: {
print Fibonacci x
end
}
@cleanup