You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It is sometimes useful to define a built-in class, i.e. an object that will keep reference of its state and that will contain some functions to deal with the data it contains.
When designing your language you will probably need for example a FILE object to keep track of opened files.
The best way to represent this concept is to create a built-in class.
Since the basic key-value container of the engine is a TokenMap we should start by declaring one to represent our base class, it will keep all the functions and attributes necessary for the class:
// The base class for the file objects.
TokenMap BASE_file;
Then we will need to define a constructor function,
to make instances of this map available for the user:
// Arguments: "addr" and "mode"
packToken default_open(TokenMap scope) {
std::string addr = scope["addr"].asString();
packToken p_mode = scope["mode"];
std::string mode;
// Set "r" as the default value for mode:if (p_mode->type == NONE) {
mode = "r";
} else {
mode = p_mode.asString();
}
FILE* file = fopen(addr.c_str(), mode.c_str());
// Create a child of the BASE class:
TokenMap obj_file = BASE_file.getChild();
// Add the file pointer as an integer attribute:// (A crude but effective way to store the file as an attribute)
obj_file["fp"] = reinterpret_cast<int64_t>(file);
return obj_file;
}
The object returned by this function will contain a single attribute "fp", however it will also be related to the base class, making it possible to access any functions defined as members of the base class.
Lets then define 2 functions that will be useful read() and close() functions.
Since we want them to work as a class, we expect to call them like this:
To define these 2 functions we will first have to write them as C++ functions as explained in Defining New Functions page:
packToken file_read(TokenMap scope) {
TokenMap _this = scope["this"].asMap();
FILE* file = reinterpret_cast<FILE*>(_this["fp"].asInt());
// Read the file:char c = fgetc(file);
std::stringstream ss;
while (c && c != EOF) {
ss << c;
c = fgetc(file);
}
// Return it as a single string:return ss.str();
}
// Close the file:
packToken file_close(TokenMap scope) {
TokenMap _this = scope["this"].asMap();
FILE* file = reinterpret_cast<FILE*>(_this["fp"].asInt());
fclose(file);
_this["fp"] = 0;
returnpackToken::None();
}
Now it will be required to register each of these 3 functions, the constructor and the 2 class functions.
To do this we should declare a Startup struct like this: