"Addonless" is only partially true, but the point is: Object-Oriented Programming is 100% possible in Skript without an addon dedicated for it. All that's required is tedious manual scripting or a Skript compiler, which is what I'm currently working on.
My plan is to have this code:
compile into:
The "compiled" version (it was written manually ) currently works as expected, but I still have to complete the compiler.
Now, the "compiled" results look a bit funky, but let me explain.
My plan is to have this code:
code_language.skript:
class Test:
method constructor():
set [this]->count to 6
method hello(to):
send "Hello!!!" to [to]
method count():
add 1 to [this]->count
return [this]->count
command /test:
trigger:
debug "Creating a new Test object and calling a method."
set [object] to new Test()
[object]->hello(sender)
loop 3 times:
set [number] to [object]->count()
set [number-variable] to [object]->count
send "The counter has counted: %[number]% and stored it as: %[number-variable]%"
compile into:
code_language.skript:
on script load:
registerNewClass("Test")
registerClassMethod("Test", "constructor", 0)
registerClassMethod("Test", "hello", 1)
registerClassMethod("Test", "count", 0)
sub "Test:constructor":
set {_this} to parameter 1
set {->%{_this}%::count} to 6
sub "Test:hello":
set {_this} to parameter 1
set {_return} to parameter 2
set {_args} to parameter 3
set {_to} to {->%{_args}%::1}
send "Hello!!!" to {_to}
sub "Test:count":
set {_this} to parameter 1
set {_return} to parameter 2
add 1 to {->%{_this}%::count}
set {->%{_return}%} to {->%{_this}%::count}
command /test:
trigger:
invoke "debug" from script and "Creating a new Test object and calling several methods."
set {_object} to newInstance("Test")
invoke "Skim:Framework:construct" from {_object}
set {_return$1} to newTemporaryAddress()
invoke "Skim:Framework:call-method" from {_object} and "hello" and {_return$1} and sender
delete({_return$1})
loop 3 times:
set {_return$2} to newTemporaryAddress()
invoke "Skim:Framework:call-method" from {_object} and "count" and {_return$2}
set {_number} to {->%{_return$2}%}
delete({_return$2})
set {_number-variable} to {->%{_object}%::count}
send "The counter has counted: %{_number}% and stored it as: %{_number-variable}%"
The "compiled" version (it was written manually ) currently works as expected, but I still have to complete the compiler.
Now, the "compiled" results look a bit funky, but let me explain.
I've implemented a way to pass by reference (like Java) instead of pass by value (how Skript normally behaves) using global-yet-effectively-temporary variables that get deleted often. I'm abusing the fact that all Skript variables names are keys in a giant map, so I pass around variable names instead of values.
In order to create dynamic functions, I use SkQuery subroutines. Subroutines don't offer a way to return a value, but that's quite easy to achieve: I simply pass a variable name that the subroutine should set and immediately delete it after use.
In order to create dynamic functions, I use SkQuery subroutines. Subroutines don't offer a way to return a value, but that's quite easy to achieve: I simply pass a variable name that the subroutine should set and immediately delete it after use.
Last edited: