-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Class Syntax
Here is the proposal to add a new syntax for defining custom classes in scripts. They may eventually become a replacement for static classes in the classes.db.
Let's take a look at an example:
class Actor
putInCar(car)
036A: put_actor self in_car car
end
end
var
0@: Actor
end
0@.putInCar($car)
Here we defined a class named Actor that has one method putInCar in. putInCar method has one parameter car. Then we declared a variable 0@ of the type Actor and finally called method putInCar on that class instance.
Important Notes
- class declaration is lazy. it means no code is produced until it gets actually used in the code. if we were to remove
0@.putInCar($car)no code was produced in this script. - each method receives an implicit variable
selfthat represents the class instance the method is called on. in this case it is the variable0@ - in this example
0@.putInCar($car)gets compiled into036A: put_actor 0@ in_car $car
Design Choices
-
when there is a method call statement the compiler takes the method body and replaces the statement with the entire body. it means the method could have many instructions and possibly even labels and they will be put in place of the call statement. in this sense class method are more templates than functions as in the other languages.
-
this however does not prevent local variables from being altered inside the method body. it means there is no separate scope created when the class method is called and if you, for example, change the variable 0@ in the class method it will be a side-effect for the caller:
class Actor
putInCar(car)
036A: put_actor self in_car car
0@ = 2
end
end
0@ = 1
0@.putInCar($car)
// 0@ is now equal to 2
There are a few possible choices to this dilemma:
- leave it as is, considering this a liberate language design decision (when you invoke subroutines with
gosubthey could alter local scope as well) - forbid using local variables syntax inside methods. only use arguments passed into the method. this could be inconvenient if you need to keep a local state.
- add extra prologue and epilogue before and after each method call that will store and restore all local variables. this adds extra overhead in runtime
- use CLEO's scm_function that basically does # 3. this adds unnecessary dependency on CLEO.
- however if preserving a local scope is important, one could consider using a scm function inside a method body:
class Actor
putInCar(car)
0AB1: call_scm_func @local 0
:local
036A: put_actor self in_car car
0@ = 2
0AB2: ret 0
end
end
0@ = 1
0@.putInCar($car)
// 0@ is still 1