pawn-lang / compiler

Pawn compiler for SA-MP with bug fixes and new features - runs on Windows, Linux, macOS
Other
298 stars 68 forks source link

[] operator overloading #251

Open YashasSamaga opened 6 years ago

YashasSamaga commented 6 years ago

It would be really useful if [] could be overloaded.

TagValue:operator[](Tag:myobj, idx) {
       return list[myobjj][idx];
}

Usage:

new Tag:vec;
vec_init(vec);
printf("%d", vec[123]);

It would be even more useful if the [] operator could return references.

vec[55] = 123;

Real life example:

new arr[100][100];
new raw_ptr:ptr = addressOf(arr[5]);

new x = ptr[10]; //x will have the value of arr[5][10]

ptr[15] = 123; //arr[5][15] will be set to 123

As of now, I use a really ugly syntax @ptr[15].

I am not sure how it should work for multi-dimensional arrays.

YashasSamaga commented 6 years ago

We could have a different overload for assignments.

operator[]=(Tag:abc, idx, {Tag1, Tag2, Tag3}:value) {
       mystuff[abc][idx] = value;
}

This might simplify the compiler code as we won't have to deal with references.

Thanks to https://github.com/alliedmodders/sourcepawn/issues/130 for the idea.

Southclaws commented 6 years ago

Coincidence you mention this! Just recently I was experimenting with the operator keyword and attempted this - I had a poke around at the code and it should be kind of simple to add support for this.

Southclaws commented 6 years ago

I'm not too sure about uses outside of scalar values though - I was wondering how easy it would be to allow string literals or array variables as arguments:

a["key"] = 10;

But then again, this might be a bit out of scope for this project...

YashasSamaga commented 6 years ago

I managed to implement this:

ReturnValueTag:operator[](ObjectTag:obj, IndexTag:idx) { }
new FloatVector:x;
new Float:t = x[Index:10];

would invoke Float:operator[](FloatVector:obj, Index:idx);

This requires changing how arrays are handled literally everywhere. Apart from that, there are unexplained errors and weird crashes that happen at the slightest change — for example, operator[(Tag:asd, Index:asd); — and doesn't work properly as function arguments and other unknown things. Other changes include how the operator function name is stored (the compiler encodes the tags and operator name in a specific format), how user defined operators are checked and what not.

Implementing this is awfully complicated (if done my way) and this could also break a lot of other things. Not to mention that this would require a lot of rigorous testing.