Skip to content

Commit

Permalink
Merge pull request #1139 from jacqueswww/fix_unroll_constant_is_literal
Browse files Browse the repository at this point in the history
Fix literal for Constants.
  • Loading branch information
jacqueswww authored Dec 13, 2018
2 parents 50b5701 + 956713f commit c8bd237
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 3 deletions.
17 changes: 17 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,3 +304,20 @@ def get_logs(tx_hash, c, event_name):
logs = c._classic_contract.events[event_name]().processReceipt(tx_receipt)
return logs
return get_logs


@pytest.fixture
def search_for_sublist():

def search_for_sublist(lll, sublist):
_list = lll.to_list() if hasattr(lll, 'to_list') else lll
if _list == sublist:
return True
if isinstance(_list, list):
for i in _list:
ret = search_for_sublist(i, sublist)
if ret is True:
return ret
return False

return search_for_sublist
15 changes: 15 additions & 0 deletions tests/parser/types/numbers/test_constants.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from decimal import Decimal
from vyper.compiler import compile_code


def test_builtin_constants(get_contract_with_gas_estimation):
Expand Down Expand Up @@ -191,3 +192,17 @@ def market_cap() -> uint256(wei):
c = get_contract(code)

assert c.market_cap() == 5000


def test_constant_folds(search_for_sublist):
code = """
SOME_CONSTANT: constant(uint256) = 11 + 1
@public
def test(some_dynamic_var: uint256) -> uint256:
return some_dynamic_var + 2**SOME_CONSTANT
"""

lll = compile_code(code, ['ir'])['ir']
assert search_for_sublist(lll, ['add', ['mload', [320]], [4096]])
12 changes: 9 additions & 3 deletions vyper/parser/global_context.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ast
import copy

from vyper.exceptions import (
EventDeclarationException,
Expand Down Expand Up @@ -229,6 +230,8 @@ def is_valid_varname(self, name, item):

def unroll_constant(self, const):
# const = self.context.constants[self.expr.id]

ann_expr = None
expr = Expr.parse_value_expr(const.value, Context(vars=None, global_ctx=self, origcode=const.source_code))
annotation_type = parse_type(const.annotation.args[0], None, custom_units=self._custom_units, custom_structs=self._structs)

Expand All @@ -254,9 +257,12 @@ def unroll_constant(self, const):

if fail:
raise TypeMismatchException('Invalid value for constant type, expected %r' % annotation_type, const.value)
else:
expr.typ = annotation_type
return expr

ann_expr = copy.deepcopy(expr)
ann_expr.typ = annotation_type
ann_expr.typ.is_literal = expr.typ.is_literal # Annotation type doesn't have literal set.

return ann_expr

def add_constant(self, item):
args = item.annotation.args
Expand Down
6 changes: 6 additions & 0 deletions vyper/parser/lll_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,12 @@ def __init__(self, value, args=None, typ=None, location=None, pos=None, annotati

self.gas += self.add_gas_estimate

def __getitem__(self, i):
return self.to_list()[i]

def __len__(self):
return len(self.to_list())

def to_list(self):
return [self.value] + [a.to_list() for a in self.args]

Expand Down

0 comments on commit c8bd237

Please sign in to comment.