This token processor allows you to use classes and other syntax additions.
Features:
Table of contents:
The syntax for constructors is just a syntax sugar for static methods that create the object and return it. In case you need more flexibility when creating an object (eg. using a different underlying type) you can use static methods directly.
Interfaces provide common type for otherwise different classes. This is achieved by creating a wrapper class that contains reference to the original class and a set of function references specific to that class so it can be called in a common way.
The original class contains some method, called as_interface
(when
the interface class is called Interface
) that returns a new instance
of this wrapper class. It can also cache it when desirable (using weak references
if the same existing interface instance should be always used).
Here is an example:
class Class1 { var @field1; var @field2; var @field3; function as_some_interface(): SomeInterface { return SomeInterface::create(this, Class1::common_method#1); } function common_method() { log("Class1"); } } class Class2 { function as_some_interface(): SomeInterface { return SomeInterface::create(this, Class2::common_method#1); } function common_method() { log("Class2"); } } class SomeInterface { var @data; var @common_method_func; constructor create(data, common_method_func) { this.data = data; this.common_method_func = common_method_func; } function common_method() { common_method_func(data); } }
The API allows other token processors to integrate with classes processing. To
get access to the API, just import classes
script and obtain the
context. Then you can register various hooks. The hooks are added based on actual
needs.
You can also use the API without classes, just use the prefixes class_context_
and class_type_
for the methods and pass the objects as a first parameter.
const { TYPE_DYNAMIC, TYPE_VOID, TYPE_INTEGER, TYPE_FLOAT, TYPE_BOOLEAN, TYPE_STRING }; const { EXT_TYPE_CLASS, EXT_TYPE_ARRAY, EXT_TYPE_HASH }; class ClassContext { static function get(fname: String): ClassContext; function register_function_call(name: String, get_types_func, adjust_call_func, data); function register_postprocess(func, data); function get_class(name: String): ClassType; } class ClassType { static function create_array(base: ClassType): ClassType; static function create_hash(base: ClassType, index: ClassType): ClassType; function get_class_name(): String; function get_parent_class(): ClassType; function get_base(): ClassType; function get_index(): ClassType; function to_string(): String; static function dump_list(list: ClassType[]); }
The types are divided into two enumerations. The simple types are just integers
and you can directly use them (cast from/to ClassType
). The extended
types are contained in an array and the first entry is the type.
function get(fname: String): ClassContext
function register_function_call(name: String, get_types_func, adjust_call_func, data)
null
to match all names) and the callbacks
with these signatures:function get_types(data, name: String, num_params: Integer, line: Integer): ClassType[]
null
if there is no function
for given number of parameters.
function adjust_call(data, name: String, param_types: ClassType[], tokens, src: String, start: Integer, end: Integer): Integer
function register_postprocess(func, data)
function postprocess(data, fname: String, tokens, src: String)
function get_class(name: String): ClassType
function create_array(base_type: ClassType): ClassType
function create_hash(base_type: ClassType, index_type: ClassType): ClassType
function get_class_name(): String
function get_parent_class(): ClassType
function get_base(): ClassType
function get_index(): ClassType
function to_string(): String
static function dump_list(list: ClassType[])