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

Added types to iterator variables #1054

Closed

Conversation

siddharthvader
Copy link

- What I did

Added types to iterator variables, to close #1039

Example:
for x in range(N, type=bytes32):

- How I did it

Parsed the for loop object for keyword "type", and if it exists, uses that as the type for the iterator. If not, type defaults to int128 for backwards compatibility
Checks to make sure that the type is valid as well

- How to verify it

Added two extra blocks to tests/parser/syntax/test_for_range.py and they compile. Also tested by modifying examples/crowdfund.vy loop to have types and it compiles (did not commit those tests)

- Description for the changelog

Added types to iterator objects

- Cute Animal Picture

giraffe

Copy link
Member

@fubuloubu fubuloubu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Looking good!

Need to see some more tests of it in action though. pass isn't good enough. Validate that types work as intended.

@siddharthvader
Copy link
Author

siddharthvader commented Oct 21, 2018

I added tests to check that the iterator variables were actually adhering to the types, and had to fix an issue regarding handling decimal types.

Not yet done with this, but did have some questions regarding some of the changes I made so far:

  • For decimal type iterators, it still just iterates through integer steps, but converts each value to a decimal along the way (ex: 1.0, 2.0, 3.0, ...). Is there extra functionality that is wanted here besides just a conversion? Like adding steps between integer values (ex: 1.0, 1.5, 2.0, 2.5, ...)?

  • canonicalize_type returns 'fixed168x10' when decimal is inputted, but I had to change the type back to 'decimal' for functions like floor(x) to work. If this is the case, should canonicalize_type be used here?

  • I also copied the values for valency and gas that was there for integers, but not sure if this makes sense for decimals (valency=1, gas=5)

  • I wasn't sure of the exact behavior that is expected for iterating on a bytes32 object, so I didn't add a test for that yet. Is there an example of what would be expected?

Copy link
Contributor

@jacqueswww jacqueswww left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs some fixes ;) fix 'em and we can merge this.

@@ -117,6 +118,8 @@ def ann_assign(self):
pos = self.context.new_variable(varname, typ)
o = LLLnode.from_list('pass', typ=None, pos=pos)
if self.stmt.value is not None:
print('ann_assign does it get this far')
print(self.stmt.value, self.context)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the print statements ;)

# should canonicalize_type be used if this is the case?
# or another mapping?
if typ == 'fixed168x10':
typ = 'decimal'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm not sure canonicalize_type is really intended for this, I would suggest one just creates a simple list of supported types for this functionality with a if type not in (): raise TypeMismatch....

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also have a base_types in utils.py that you could use for that list ;)

@@ -70,6 +70,10 @@ def __init__(self, value, args=None, typ=None, location=None, pos=None, annotati
if isinstance(self.value, int):
self.valency = 1
self.gas = 5
elif isinstance(self.value, float):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you sure this gets handled correctly? As far as I know the LLL compiler has no concept of float. So you will have to remove this. And the multiply the value by the decimal multiplier (in stmt code below) to get an int for consumption by LLL compiler.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I double checked this, and you're right; it isn't needed, which means that it isn't being handled properly. To handle this for the decimal type we do need to use the DECIMAL_DIVISOR to convert it. Would it make sense to use the function to convert base types in parser_utils.py? Or to handle it in a different manner?


@pytest.mark.parametrize('good_code', valid_list)
def test_type_success(good_code):
assert compiler.compile(good_code) is not None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need additional tests that confirm each of these types actually produce the output that one thinks it does. I have suspicion decimal might not as it needs num * DECIMAL_DIVISOR // den to work as intended.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think taking some of the tests from the types testing and combining those with the for loops will work? Or are some different tests needed?

Copy link
Contributor

@jacqueswww jacqueswww Oct 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a look at the tests for the in list() functionality (test_for_in_list.py) for a guide on what type of tests we need here. I think creating a new test file "test_for_range." (outside /syntax/) should do just fine.

@jacqueswww jacqueswww changed the title added types to iterator variables, and appended to the for loop test Added types to iterator variables, and appended to the for loop test Oct 25, 2018
@jacqueswww jacqueswww changed the title Added types to iterator variables, and appended to the for loop test Added types to iterator variables Oct 25, 2018
@jacqueswww jacqueswww closed this Dec 10, 2018
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.

VIP: Give iterator variables a type
3 participants