Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixes tagof behaviour on default values #274

Merged
merged 1 commit into from
Apr 22, 2018

Conversation

YashasSamaga
Copy link
Member

@YashasSamaga YashasSamaga commented Jan 28, 2018

Previously, if the tagof operator was used on an argument with default value, the tag identifier recorded would be 0 in case the default value was used.

f({Tag1, Tag2}:a = Tag2:123, b = tagof(a)) { }
main () { f(); }

In the above code, the argument a would have the value 123 but b would have 0.

This commit patches the bug. The value of b will be the tag identifier of the default argument.

This commit patches for two cases: default argument is a reference and default argument is a variable.

The case of reference arrays is not handled correctly as the tag of the default reference array is not well defined.

Implementation details:
The compiler first processes arguments which are not taking default values (including tagof and sizeof parameters). The compiler does a second pass on the list of all formal parameters and processes the default values. The compiler then does a final pass on the list of formal parameters and processes sizeof and tagof parameters.

The compiler maintains a list of tags of all the arguments in a constvalue list called taglst as it processes the arguments.

The name field of the members of the tag list is the argument name and the tag field stores the tag identifier of that argument (tag identifier of the actual parameter).

In the first pass where the expclit arguments are being processed, the compiler checks the argument's tag and adds the tag along with the formal parameter name (can be thought of as ) to the tag list if the tag identifier is NOT zero.

In the second pass where the default values are being handled, the compiler does not modify the tag list (source of the bug).

After all the arguments other than sizeof and tagof have been handled othe, the compiler iterates through the list of arguments and takes care of sizeof and tagof arguments.

Here it checks to which formal parameter (say F) the tagof parameter (say T) points to. It then checks the tag list for that symbol F, if an entry is found, it uses the tag identifier associated with that argument. If not found, it defaults to 0.

Since the tags of default arguments along with it's formal name is not added to the tag list, the third pass won't be aware of any tag associated with the default values and assumes 0.

This commit adds code to add the tags of the default values to the tag list so that the compiler is aware of the tag of the default values in the final pass.

Fixes #268

Basic tests:

#include <a_samp>
f1({Tag1, Tag2}:a = Tag2:123, b = tagof(a)) {
	printf("[VARIABLE] Expected Tag: %d, Found Tag: %d", tagof(Tag2:), _:b);
}
f2(&{Tag3, Tag4}:a = Tag4:123, b = tagof(a)) {
	printf("[REFERENCE] Expected Tag: %d, Found Tag: %d", tagof(Tag4:), _:b);
}
f3({Tag5, Tag6}:a[] = {Tag6:1, Tag6:2}, b = tagof(a)) {
	printf("[REFARRAY] Expected Tag: %d, Found Tag: %d", tagof(Tag6:), _:b);
}
main () {
	f1();
	f2();
	f3();
}

Output:

[VARIABLE] Expected Tag: -1073741808, Found Tag: -1073741808
[REFERENCE] Expected Tag: -1073741806, Found Tag: -1073741806
[REFARRAY] Expected Tag: -1073741804, Found Tag: 0

Previously, if the tagof operator was used on an argument with default value, the tag identifier recorded would be 0 in case the default value was used.

```
f({Tag1, Tag2}:a = Tag2:123, b = tagof(a)) { }
main () { f(); }
```

In the above code, the argument `a` would have the value `123` but `b` would have `0`.

This commit patches the bug. The value of `b` will be the tag identifier of the default argument.

This commit patches for two cases: default argument is a reference and default argument is a variable.

The case of reference arrays is not handled correctly as the tag of the default reference array is not well defined.

**Implementation details:**
The compiler first processes arguments which are not taking default values (including `tagof` and `sizeof` parameters). The compiler does a second pass on the list of all formal parameters and processes the default values. The compiler then does a final pass on the list of formal parameters and processes `sizeof` and `tagof` parameters.

The compiler maintains a list of tags of all the arguments in a `constvalue` list called `taglst` as it processes the arguments.

The name field of the members of the tag list is the argument name and the tag field stores the tag identifier of that argument (tag identifier of the actual parameter).

In the first pass where the expclit arguments are being processed, the compiler checks the argument's tag and adds the tag along with the formal parameter name (can be thought of as <formal-paramter-name : tag pair>) to the tag list if the tag identifier is NOT zero.

In the second pass where the default values are being handled, the compiler does not modify the tag list (**source of the bug**).

After all the arguments other than `sizeof` and `tagof` have been handled othe, the compiler iterates through the list of arguments and takes care of `sizeof` and `tagof` arguments.

Here it checks to which formal parameter (say F) the `tagof` parameter (say T) points to. It then checks the tag list for that symbol F, if an entry is found, it uses the tag identifier associated with that argument. If not found, it defaults to 0.

Since the tags of default arguments along with it's formal name is not added to the tag list, the third pass won't be aware of any tag associated with the default values and assumes 0.

This commit adds code to add the tags of the default values to the tag list so that the compiler is aware of the tag of the default values in the final pass.
@Zeex Zeex merged commit 06382a9 into pawn-lang:master Apr 22, 2018
@YashasSamaga YashasSamaga deleted the fix-i268 branch October 11, 2020 11:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants