Advertisement

Implementing new feature (Template functions)

Started by May 22, 2024 09:59 AM
12 comments, last by Miss 6 months ago

I've been learning quite a lot of language design lately, so i decided to try my hand by implementing template functions for angel script, thing is I don't know much about the project structure. I was hoping to get some pointers on where to look and how angelscript manages some things, my rough idea is any function is any function with templates would have the corresponding template types passed as void* and type id's passed at the end of the function. say T@ DoSomething<class T,class K>(K@ param)would be called as void* DoSomething(void* param,int tid_t,int tid_k) But there's some considerations i have:

  • built-in types cannot be handles, iirc, so how would the engine manage something like this(probably only use handles when you're sure its a ref type and throw an error otherwise)
  • For templated script functions, would we need to make a new function for each instantiation? if yes I don't know how exactly script functions work and may not be able to do that.

It would be great if you manage to implement this feature. It would be a excellent contribution.

I haven't put too much thought into this yet, but here's s few initial ideas:

  • Template functions must not rely on hidden parameters added by the compiler, because that would make them incompatible with funcdefs and delegates.
  • My suggestion is to only allow the generic calling convention with the template functions. The C++ function can get the script function representing the template instance from the generic interface and determine the types for the arguments from there.
  • Generating template instances of the functions should follow pretty much the same pattern as that use for template class methods in asCScriptEngine::GenerateNewTemplateFunction

There has been some previous forum threads on this topic in the past. It might be worth going through them. Although, old ideas may not necessarily hold true today. Anyway, you can find the links in my To-Do document: https://docs.google.com/document/d/1st0NAN_zQkiigxWCTEbLvpwNyYE1Q91LeGchFq8mWAw/edit#heading=h.c4mgma48zk46

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Advertisement

I've been poking around the codebase a bit, while looking at the template type implementation. I cant find where the actual script parsing is done but as of now im backtracking the “RegisterGlobalFunction” function.
Here's an update:

I have the parsing working with the syntax being BNF: TEMPLATE_DECL ::= '<' 'class'? TYPE [',' 'class'? TYPE] '>' this is adds a bunch of snIdentifier nodes right before the snParameter list, do i store these, how would i store it, do i just store them as strings in the asCScriptFunction Structure. for example
void get<class T, K, U>() i store a string array containing ['T','K','U']. Another issue i sense I'm going to have is the actual calling, using only generic sounds like a good idea, but i have no idea how or where both script and native functions are called.

I also have a question, should I add a flag in the asCDataTypes to check if they're templates, like a uint32, 0 meaning they're not template types and the value -1 being the index into the template identifier array

Update: I have been able to get template functions to succesfully parse, i have decided to go generic call conv only, the only issue im having now is with the symbol table thing and the compiler. I made it so that for application functions you have to specify whether each template type is REF or VALUE. so that its possible to enforce rules about pointer and value in the function signature.

MindOfTony said:
I have the parsing working with the syntax being BNF: TEMPLATE_DECL ::= '<' 'class'? TYPE [',' 'class'? TYPE] '>' this is adds a bunch of snIdentifier nodes right before the snParameter list, do i store these, how would i store it, do i just store them as strings in the asCScriptFunction Structure. for example void get() i store a string array containing ['T','K','U']. Another issue i sense I'm going to have is the actual calling, using only generic sounds like a good idea, but i have no idea how or where both script and native functions are called.

I suggest you store them as an array of asCDataType, similar to how the template subtypes are stored in asCObjectType for template classes. You can see how to convert the snIdentifiers into asCDataType in RegisterObjectType for condition if( flags & asOBJ_TEMPLATE ), on line 1826 in as_scriptengine.cpp.

MindOfTony said:
I also have a question, should I add a flag in the asCDataTypes to check if they're templates, like a uint32, 0 meaning they're not template types and the value -1 being the index into the template identifier array

There is no need for that. The template types in the template functions should be identified in the same way the template subtypes are for class templates, i.e. the asCTypeInfo within asCDataType should have the flag = asOBJ_TEMPLATE_SUBTYPE. The asCTypeInfo should also be stored in asCScriptEngine::templateSubTypes. See the same code in RegisterObjectType referenced above for how this should be implemented.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

I've actually edited the code a bit since i made that comment, I created a asCDataType but i also stored it in a list, but I'm going to move that list into the engine. just to clarify in function<class T>(). im going to add ‘T’ into the engine's subtype list? is this purpose of this is validation wouldn't it make more sense to store it in the actual asCScrptFunction as template types are local to the function.

Again still on the actual asCCompiler, i dont understand the stuff one bit. I'm trying to hack the CompileFunctoin to support template types, but in my examplet function i used get<int>() and i get “int” as an unknown symbol.

MindOfTony said:
I've actually edited the code a bit since i made that comment, I created a asCDataType but i also stored it in a list, but I'm going to move that list into the engine. just to clarify in function(). im going to add ‘T’ into the engine's subtype list? is this purpose of this is validation wouldn't it make more sense to store it in the actual asCScrptFunction as template types are local to the function.

The purpose of the asCScriptEngine::templateSubTypes array is to keep track of all the non-real types used only in template declarations so they can be matched for replacement with the real type when generating the actual instance of the template. The second purpose is to allow sharing of these template subtypes between templates.

Yes, you will also need to store the template types in the script function for the template function so you know which are actually used in the function.

MindOfTony said:
Again still on the actual asCCompiler, i dont understand the stuff one bit. I'm trying to hack the CompileFunctoin to support template types, but in my examplet function i used get() and i get “int” as an unknown symbol.

Yes, the compiler is definitely the most complex piece of code in the library.

I should think that you'll need to do most of the changes in asCCompiler::CompileFunctionCall. This is where I imagine you would get the script nodes indicating that the script is trying to call a template function, and you'll need to find the correct template instance for that based on the data types informed, and then proceed with the actual code to invoke the function call as usual.

Perhaps you might change SymbolLookup called by CompileFunctionCall to return a new symbol type for template functions instead of SL_GLOBALFUNC.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Advertisement

alright will check it out tommorrow, ill just edit the parser logic, then I'll think of the magic I'll use to handle script side templates. and hopefully crack the compiler

Oh, I didn't realize you wanted to allow declaring function templates within the script as well. I actually think that is going a bit too far for a script language, but if you really want to do this, I believe it would be best done so that the function template would be compiled each time a new instance is generated. The compiled function instance should then be dynamically added to the script module similarly to how it is done in asCModule::CompileFunction.

The compiler itself will have to be able to identify when a data type is declared using one of the template subtypes and automatically replace them with the corresponding real type from the instantiated function template. This logic can probably be put inside of asCBuilder::CreateDataTypeFromNode, which is called from the compiler anytime it needs to convert the script nodes into a datatype (e.g. variable declartions, type casts, etc).

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Update: i thought i had to do script templates, because i thought scripts supported template types. anyway i've scrapped the idea. I have successfully gotten the function to call, and they type id is correct

Whats left is for object methods, it shouldn't be too different, but I'm having issues with finding the parser path to a method call. Once im done Ill get a fresh copy and create a git repo so I can see all my changes and remove those that came in as part of prototyping then i'll send it to you how?

Nicely done. I look forward to seeing the changes so I can incorporate them into the library.

When you're done you can send me the modified source code to my e-mail andreas@angelcode.com. I'll review the code, merge it into my WIP branch with WinMerge, add regression tests, as well as documentation.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement