tuple support without braces

This commit is contained in:
David Halter
2012-04-24 15:40:12 +02:00
parent b06b4e2dd8
commit 7de81ca4a5
8 changed files with 120 additions and 50 deletions

View File

@@ -161,17 +161,13 @@ class Array(object):
self._array = array self._array = array
def get_index_types(self, index=None): def get_index_types(self, index=None):
#print self._array.values, index.values
values = self._array.values values = self._array.values
#print 'ui', index.values, index.values[0][0].type
if index is not None: if index is not None:
# This is indexing only one element, with a fixed index number # This is indexing only one element, with a fixed index number,
iv = index.values # otherwise it just ignores the index (e.g. [1+1])
if len(iv) == 1 and len(iv[0]) == 1 \
and iv[0][0].type == parsing.Call.NUMBER \
and self._array.type != parsing.Array.DICT:
try: try:
values = [self._array[int(iv[0][0].name)]] index_nr = int(index.get_only_subelement().name)
values = [self._array[index_nr]]
except: except:
pass pass
scope = self._array.parent_stmt.parent scope = self._array.parent_stmt.parent
@@ -317,7 +313,7 @@ def strip_imports(scopes):
result.append(s) result.append(s)
return result return result
def assign_tuples(scope, tuples, results, seek_name): def assign_tuples(tup, results, seek_name):
""" """
This is a normal assignment checker. In python functions and other things This is a normal assignment checker. In python functions and other things
can return tuples: can return tuples:
@@ -326,6 +322,8 @@ def assign_tuples(scope, tuples, results, seek_name):
Here, if seek_name is "a", the number type will be returned. Here, if seek_name is "a", the number type will be returned.
The first part (before `=`) is the param tuples, the second one result. The first part (before `=`) is the param tuples, the second one result.
:type tup: parsing.Array
""" """
def eval_results(index): def eval_results(index):
types = [] types = []
@@ -334,23 +332,31 @@ def assign_tuples(scope, tuples, results, seek_name):
return types return types
result = [] result = []
for i, t in enumerate(tuples): if tup.type == parsing.Array.NOARRAY:
# used in an assignment, there is just one call and no other things, # here we have unnessecary braces, which we just remove
arr = tup.get_only_subelement()
result = assign_tuples(arr, results, seek_name)
else:
for i, t in enumerate(tup):
# used in assignments. there is just one call and no other things,
# therefor we can just assume, that the first part is important. # therefor we can just assume, that the first part is important.
if len(t) != 1:
raise AttributeError('Array length should be 1')
t = t[0] t = t[0]
# check the left part, if it's still tuples in it or a Call # check the left part, if it's still tuples in it or a Call
if isinstance(t, parsing.Array): if isinstance(t, parsing.Array):
# these are "sub" tuples # these are "sub" tuples
print 'arr', t print 'arr', t
result += assign_tuples(scope, t, eval_results(i), seek_name) result += assign_tuples(t, eval_results(i), seek_name)
print 'arr2', result
else: else:
if t.name.names[-1] == seek_name: if t.name.names[-1] == seek_name:
result += eval_results(i) result += eval_results(i)
print 't', t, result print 't', t, result
else: else:
print 'name not found' print 'name not found', t.name
#print follow_call_list(scope, result[i]) print seek_name, tup, results
print seek_name, tuples, results
return result return result
@memoize(default=[]) @memoize(default=[])
@@ -373,7 +379,7 @@ def follow_statement(stmt, scope=None, seek_name=None):
new_result = [] new_result = []
for op, set_vars in stmt.assignment_details: for op, set_vars in stmt.assignment_details:
print '\ntup' print '\ntup'
new_result += assign_tuples(scope, set_vars, result, seek_name) new_result += assign_tuples(set_vars, result, seek_name)
print new_result print new_result
print '\n\nlala', op, set_vars.values, call_list.values print '\n\nlala', op, set_vars.values, call_list.values
print stmt, scope print stmt, scope
@@ -382,12 +388,21 @@ def follow_statement(stmt, scope=None, seek_name=None):
def follow_call_list(scope, call_list): def follow_call_list(scope, call_list):
""" The call list has a special structure """ """
The call list has a special structure.
This can be either `parsing.Array` or `list`.
"""
if isinstance(call_list, parsing.Array) \
and call_list.type != parsing.Array.NOARRAY:
# Especially tuples can stand just alone without any braces. These
# would be recognized as separate calls, but actually are a tuple.
result = follow_call(scope, call_list)
else:
result = [] result = []
for calls in call_list: for calls in call_list:
for call in calls: for call in calls:
if not isinstance(call, str): if not isinstance(call, str):
# the string tokens are just operations (+, -, etc.) # The string tokens are just operations (+, -, etc.)
result += follow_call(scope, call) result += follow_call(scope, call)
return result return result

View File

@@ -2,7 +2,7 @@
import functions import functions
functions.debug.debug_function = functions.debug.print_to_stdout #functions.debug.debug_function = functions.debug.print_to_stdout
functions.debug.ignored_modules = ['parsing', 'builtin'] functions.debug.ignored_modules = ['parsing', 'builtin']
#functions.debug.ignored_modules = ['parsing', 'builtin', 'evaluate', 'modules'] #functions.debug.ignored_modules = ['parsing', 'builtin', 'evaluate', 'modules']
functions.modules.module_find_path.insert(0, '.') functions.modules.module_find_path.insert(0, '.')

View File

@@ -147,4 +147,4 @@ c = b().c3(); abc = datetime; return [abc][0]. ;pylab.; add(1+2,2).; for fi in [
1.0.fromhex(); import flask ; flsk = flask.Flask + flask.Request; 1.0.fromhex(); import flask ; flsk = flask.Flask + flask.Request;
abc = [1,2+3]; abc[0]. abc = [1,2+3]; abc[0].
import pylab; def add(a1,b1): nana = 1; return a1+b1 import pylab; def add(a1,b1): nana = 1; return a1+b1
flow_test.; a12, (b12, c12) = (1,("", "")); a12. flow_test.; a12, (b12, c12) = (1,(list, "")); b12.

View File

@@ -799,6 +799,16 @@ class Array(Call):
self.keys[c] = self.values[c] self.keys[c] = self.values[c]
self.values[c] = [] self.values[c] = []
def get_only_subelement(self):
"""
Returns the only element that an array contains. If it contains
more than one element, raise an exception.
"""
if len(self.values) != 1 or len(self.values[0]) != 1:
raise AttributeError("More than one value found")
return self.values[0][0]
def __len__(self): def __len__(self):
return len(self.values) return len(self.values)
@@ -814,14 +824,8 @@ class Array(Call):
def __repr__(self): def __repr__(self):
if self.type == self.NOARRAY: if self.type == self.NOARRAY:
temp = 'noarray' temp = 'noarray'
elif self.type == self.TUPLE: else:
temp = 'tuple' temp = self.type
elif self.type == self.LIST:
temp = 'list'
elif self.type == self.DICT:
temp = 'dict'
elif self.type == self.SET:
temp = 'set'
parent_str = " of %s" % self.parent if self.parent else "" parent_str = " of %s" % self.parent if self.parent else ""
return "<%s: %s%s>" % (self.__class__.__name__, temp, parent_str) return "<%s: %s%s>" % (self.__class__.__name__, temp, parent_str)

View File

@@ -1,6 +1,11 @@
# -----------------
# basic array lookups
# -----------------
#? ['imag'] #? ['imag']
[1,2][0].imag [1,""][0].imag
#? []
[1,""][1].imag
a = list() a = list()
#? ['append'] #? ['append']
@@ -10,14 +15,52 @@ a = list()
[[a]][0][100].append [[a]][0][100].append
# -----------------
# tuple assignments
# -----------------
a1, b1 = (1, "") a1, b1 = (1, "")
#? ['real'] #? ['real']
a1.real a1.real
#? ['lower'] #? ['lower']
b1.lower b1.lower
#? []
b1.real
(a2, b2) = (1, "") (a2, b2) = (1, "")
#? ['imag'] #? ['imag']
a2.imag a2.imag
#? ['upper'] #? ['upper']
b2.upper b2.upper
# -----------------
# subtuple assignment
# -----------------
(a3, (b3, c3)) = (1, ("", list))
##? ['append']
c3.append
#? []
c3.upper
#? []
c3.real
a4, (b4, c4) = (1, ("", list))
#? ['append']
c4.append
#? []
c4.upper
#? []
c4.real
#? ['real']
a4.real
#? ['upper']
b4.upper
# -----------------
# unnessecary braces
# -----------------
u, v = 1, ""
#? ['real']
u.real
#? []
u.upper

View File

@@ -14,7 +14,7 @@ with open('') as f1, open('') as f2:
def global_define(): def global_define():
#global glob global glob
glob = 3 glob = 3
#? ['real'] #? ['real']

View File

@@ -68,3 +68,11 @@ tup2 = tuple()
tup2.i tup2.i
##? ['index'] TODO enable ##? ['index'] TODO enable
().i ().i
tup3 = 1,""
#? ['index']
tup3.index
tup4 = 1,""
#? ['index']
tup4.index

View File

@@ -43,8 +43,8 @@ def completion_test(source):
# TODO remove set! duplicates should not be normal # TODO remove set! duplicates should not be normal
comp_str = str(sorted(set([str(c) for c in completions]))) comp_str = str(sorted(set([str(c) for c in completions])))
if comp_str != correct: if comp_str != correct:
print 'Solution not correct, received %s, wanted %s' % \ print 'Solution on %s not correct, received %s, wanted %s'\
(comp_str, correct) % (line_nr, comp_str, correct)
#print [(c.name, c.name.parent) for c in completions] #print [(c.name, c.name.parent) for c in completions]
fails += 1 fails += 1
correct = None correct = None