예제 #1
0
def full(code, symlist = None):
	return complete(proton_parser.parse(lexer.tokenize(code)), symlist = symlist)
예제 #2
0
def evaluate(tree, symlist = None, comma_mode = tuple, looped = False, func = False):
	if not isinstance(tree, proton_parser.ASTNode):
		return tree
	setevalp(lambda k: complete(proton_parser.parse(lexer.tokenize(k)), symlist = symlist or default)[0])
	symlist = symlist or default
	treetype = tree.type.split('/')
	tokentype = tree.token.type.replace(':', '/').split('/')
	if 'literal' in tokentype:
		return h(tree.token.content)
	elif 'identifier' in tokentype:
		def getter():
			return None if tree.token.content not in symlist else symlist[tree.token.content]
		def setter(*args):
			if 'const' in symlist and tree.token.content in symlist['const']:
				raise RuntimeError('Cannot set constant value ' + tree.token.content)
			symlist[tree.token.content] = args[0]
		return Identifier(tree.token.content, getter, setter)
	elif 'const' in treetype:
		left  = evaluate(tree.children[0], symlist, looped = looped, func = func)
		right = evaluate(tree.children[1], symlist, looped = looped, func = func)
		if not all(isinstance(node, Identifier) for node in walk(left)):
			left, right = right, left
		assign(left, right)
		if 'const' not in symlist: symlist['const'] = []
		for node in walk(left):
			symlist['const'] += node.name
	elif 'comp' in treetype:
		result = []
		for val in hardeval(tree.children[2], symlist, looped = looped, func = func):
			assign(evaluate(tree.children[1], symlist, looped = looped, func = func), val)
			if len(tree.children) < 4 or hardeval(tree.children[3], symlist, looped = looped, func = func):
				result.append(_hardeval(tree.children[0], symlist, looped = looped, func = func))
		return result
	elif tree.token.content == 'unless':
		if hardeval(tree.children[1], symlist, looped = looped, func = func):
			return _evaluate(tree.children[2], symlist, looped = looped, func = func)
		else:
			return _evaluate(tree.children[0], symlist, looped = looped, func = func)
	elif tree.token.content == 'if':
		if hardeval(tree.children[0], symlist, looped = looped, func = func):
			return _evaluate(tree.children[1], symlist, looped = looped, func = func)
		elif len(tree.children) > 2:
			return _evaluate(tree.children[2], symlist, looped = looped, func = func)
	elif tree.token.content == 'while':
		if 'whileas' in treetype:
			sidelist = clone_scope(symlist)
			value = hardeval(tree.children[0], sidelist, looped = looped, func = func)
			result = None
			while value:
				assign(evaluate(tree.children[1], sidelist, looped = looped, func = func), value)
				result = evaluate(tree.children[2], sidelist, looped = True, func = func)
				if isinstance(result, Statement):
					if result.name == 'break': break
					if result.name == 'continue': continue
					if result.name == 'return': return result
				value = hardeval(tree.children[0], sidelist, looped = looped, func = func)
			else:
				if len(tree.children) > 3:
					evaluate(tree.children[3])
			del sidelist[evaluate(tree.children[1], looped = looped, func = func).name]
			merge(sidelist, symlist)
			return result
		else:
			result = None
			while hardeval(tree.children[0], symlist, looped = looped, func = func):
				result = _evaluate(tree.children[1], symlist, looped = True, func = func)
				if isinstance(result, Statement):
					if result.name == 'break': break
					if result.name == 'continue': continue
					if result.name == 'return': return result
			else:
				if len(tree.children) > 2:
					evaluate(tree.children[2])
			return result
	elif tree.token.content == 'repeat':
		if 'repeatinto' in treetype:
			sidelist = clone_scope(symlist)
			value = f(hardeval(tree.children[0], sidelist, looped = looped, func = func))
			index = 0
			result = None
			while index < value:
				assign(evaluate(tree.children[1], sidelist, looped = looped, func = func), index)
				result = evaluate(tree.children[2], sidelist, looped = True, func = func)
				if isinstance(result, Statement):
					if result.name == 'break': break
					if result.name == 'continue': continue
					if result.name == 'return': return result
				index += 1
			del sidelist[evaluate(tree.children[1], looped = looped, func = func).name]
			merge(sidelist, symlist)
			return result
		else:
			result = None
			value = f(hardeval(tree.children[0], symlist, looped = looped, func = func))
			while value:
				result = _evaluate(tree.children[1], symlist, looped = True, func = func)
				if isinstance(result, Statement):
					if result.name == 'break': break
					if result.name == 'continue': continue
					if result.name == 'return': return result
				value -= 1
			return result
	elif tree.token.content == 'for':
		if 'foreach' in treetype:
			sidelist = clone_scope(symlist)
			result = None
			for val in hardeval(tree.children[1], sidelist, looped = looped, func = func):
				assign(evaluate(tree.children[0], sidelist, looped = looped, func = func), val)
				result = evaluate(tree.children[2], sidelist, looped = True, func = func)
				if isinstance(result, Statement):
					if result.name == 'break': break
					if result.name == 'continue': continue
					if result.name == 'return':
						try:
							del sidelist[evaluate(tree.children[0], looped = looped, func = func).name]
						except: pass
						merge(sidelist, symlist)
						return result
			else:
				if len(tree.children) > 3:
					evaluate(tree.children[3])
			try:
				del sidelist[evaluate(tree.children[0], looped = looped, func = func).name]
			except: pass
			merge(sidelist, symlist)
			return result
		else:
			sidelist = clone_scope(symlist)
			evaluate(tree.children[0], sidelist, looped = looped, func = func)
			result = None
			broken = False
			while not tree.children[1].children or hardeval(tree.children[1], sidelist, looped = looped, func = func):
				result = evaluate(tree.children[-1], sidelist, looped = True, func = func)
				if isinstance(result, Statement):
					if result.name == 'break': broken = True; break
					if result.name == 'continue': continue
					if result.name == 'return':
						try:
							del sidelist[evaluate(tree.children[0], looped = looped, func = func).name]
						except: pass
						merge(sidelist, symlist)
						return result
				if len(tree.children) >= 4: evaluate(tree.children[2], sidelist, looped = looped, func = func)
			if not broken:
				if len(tree.children) > 3:
					evaluate(tree.children[3])
			merge(sidelist, symlist)
			return result
	elif tree.token.content == 'try':
		try:
			return _hardeval(tree.children[0], symlist, looped = looped, func = func)
		except Exception as e:
			sidelist = clone_scope(symlist)
			assign(evaluate(tree.children[1], sidelist), e, looped = looped, func = func)
			return evaluate(tree.children[2], sidelist, looped = looped, func = func)
	elif 'prebinopfunc' in treetype:
		def inner(*args, **kwargs):
			arguments = args[:1] + (evaluate(tree.children[0], symlist, looped = looped, func = func), symlist)
			value = infix_operators[tree.token.content](*arguments)
			return args[1:] and (value,) + args[1:] or value
		return inner
	elif 'postbinopfunc' in treetype:
		def inner(*args, **kwargs):
			arguments = (evaluate(tree.children[0], symlist, looped = looped, func = func),) + args[:1] + (symlist,)
			value = infix_operators[tree.token.content](*arguments)
			return args[1:] and (value,) + args[1:] or value
		return inner
	elif 'binary_operator' in tokentype or 'binary_RTL' in tokentype:
		if tree.token.content in infix_operators:
			return infix_operators[tree.token.content](tree.children[0], tree.children[1], symlist)
		else:
			raise NotImplementedError(tree.token.content + ' not yet implemented')
	elif 'prefix' in treetype:
		if tree.token.content in prefix_operators:
			return prefix_operators[tree.token.content](tree.children[0], symlist)
		else:
			raise NotImplementedError(tree.token.content + ' not yet implemented')
	elif 'postfix' in treetype:
		if tree.token.content in postfix_operators:
			return postfix_operators[tree.token.content](tree.children[0], symlist)
		else:
			raise NotImplementedError(tree.token.content + ' not yet implemented')
	elif tree.token.content == 'import':
		_import(tree.children[0], symlist)
	elif tree.token.content == 'include':
		__include__(tree.children[0], symlist, include)
	elif tree.token.content in ['exist', 'exists']:
		return exists(tree.children[0], symlist)
	elif tree.token.content in ['exist not', 'exists not']:
		return not exists(tree.children[0], symlist)
	elif 'break_statement' in treetype:
		if looped:
			return Statement('break')
		else:
			raise SyntaxError('break outside of loop')
	elif 'continue_statement' in treetype:
		if looped:
			return Statement('continue')
		else:
			raise SyntaxError('continue outside of loop')
	elif 'return_statement' in treetype:
		if func:
			return Statement('return', f(evaluate(tree.children[0], symlist)))
		else:
			raise SyntaxError('return outside of function')
	elif 'comma_expr' in treetype:
		result = comma_mode(evaluate(child, symlist, looped = looped, func = func) for child in tree.children)
		def flatten(array):
			result = comma_mode()
			if isinstance(array, (list, tuple, set)):
				for element in array: result += flatten(element)
			else:
				result = comma_mode([array])
			return result
		if all(isinstance(f(element), Function) for element in flatten(result)):
			return getfunction(lambda *args, **kwargs: call(f(result), *args, **kwargs))
		return result
	elif 'mapping' in treetype:
		return MapExpr(*[evaluate(child, symlist, looped = looped, func = func) for child in tree.children])
	elif 'binopfunc' in treetype:
		def inner(*args, **kwargs):
			arguments = args[:2] + (symlist,)
			value = infix_operators[tree.token.content](*arguments)
			return args[2:] and (value,) + args[2:] or value
		return getfunction(inner, False)
	elif 'unopfunc' in treetype:
		def inner(*args, **kwargs):
			arguments = args[:2] + (symlist,)
			value = prefix_operators[tree.token.content](*arguments)
			return args[1:] and (value,) + args[1:] or value
		return getfunction(inner, False)
	elif 'bracket_expr' in treetype:
		if 'bracket' in treetype:
				return evaluate(tree.children[0], symlist, tuple, looped = looped, func = func)
		elif 'list' in treetype:
			if tree.children:
				result = evaluate(tree.children[0], symlist, list, looped = looped, func = func)
				innertype = tree.children[0].type.split('/')
				if 'comma_expr' not in innertype and 'comp' not in innertype: result = [result]
				maps = [isinstance(element, MapExpr) for element in result]
				if any(maps):
					if not all(maps):
						raise SyntaxError('Mixed mappings and non-mappings in list expression')
					return dict([(element.key, element.value) for element in result])
				return result
			return []
		elif 'codeblock' in treetype:
			sidelist = clone_scope(symlist)
			result = None
			for statement in tree.children:
				result = evaluate(statement, sidelist, looped = looped, func = True)
				if isinstance(result, Statement):
					merge(sidelist, symlist)
					if result.name == 'return': return result
					return result
			merge(sidelist, symlist)
			return result
	elif tree.token.type == 'ternary':
		return evaluate(tree.children[1], symlist, looped = looped, func = func) if hardeval(tree.children[0], symlist, looped = looped, func = func) else evaluate(tree.children[2], symlist, looped = looped, func = func)
	elif 'call' in treetype:
		if tree.children[0].token.content in ['eval']:
			return symlist['eval'](*([symlist] + [evaluate(child, symlist, looped = looped, func = func) for child in tree.children[1:]]))[0]
		else:
			args = []
			for argument in tree.children[1:]:
				if argument.token.type == 'unifix_operator' and argument.token.content == '*':
					for arg in f(hardeval(argument.children[0], symlist, looped = looped, func = func)):
						args.append(arg)
				else:
					args.append(evaluate(argument, symlist, looped = looped, func = func))
			func = f(evaluate(tree.children[0], symlist, looped = looped, func = func))
			return call(func, *args)
	elif 'getitem' in treetype:
		if 'comma_expr' in tree.children[1].type.split('/') or 'slice' in tree.children[1].type.split('/'):
			ref = evaluate(tree.children[0], symlist, looped = looped, func = func)
			array = f(ref)
			index_list = indices(array, tree.children[1], symlist)
			def getter():
				return get_indices(array, index_list)
			def setter(*args):
				set_indices(ref, array, index_list, args[0])
			return Identifier('.getitem', getter, setter)
		else:
			ref = evaluate(tree.children[0], symlist, looped = looped, func = func)
			array = f(ref)
			index = f(hardeval(tree.children[1], symlist))
			def getter():
				return get_index(array, index)
			def setter(*args):
				set_index(ref, array, index, args[0])
			return Identifier('.getitem', getter, setter)
	elif 'anonfunc' in treetype:
		def inner(*values):
			scope = clone_scope(symlist)
			try:
				assign_method_parameters(values, tree.children[0], scope)
				value = f(hardeval(tree.children[1], scope, func = True))
				merge(scope, symlist)
				if isinstance(value, Statement):
					if value.name == 'return': return value.value
					raise SystemExit('huh?')
				return value
			except IndexError:
				if getfunction(inner).partial:
					def _inner(*args):
						return inner(*(values + args))
					return _inner
				else:
					raise
		return getfunction(inner)
	elif 'del' in treetype:
		delete(evaluate(tree.children[0]), symlist)
	elif 'expression' in treetype:
		return evaluate(tree.children[0], symlist, looped = looped, func = func)
예제 #3
0
		pass

default["int"] = getfunction(sympy.Integer)
default["float"] = getfunction(sympy.Rational)
# TODO default["complex"]

class proton_str(str):
	def __init__(self, obj):
		if isinstance(obj, dict):
			self = '[%s]' % ', '.join(sorted([ascii(key) + ' :> ' + ascii(obj[key]) for key in obj]))
		elif isinstance(obj, Function):
			self = proton_str(obj.function)
		else:
			self = str(obj)

default['eval'] = getfunction(lambda s, x: complete(proton_parser.parse(lexer.tokenize(x)), s))
default['Function'] = Function
default['str'] = proton_str
default['type'] = lambda x: x['__type__'] if isinstance(x, dict) and '__type__' in x else type(x)
default['class'] = make_type

def merge(d1, d2):
	for x in d1:
		if x in d2 or x.startswith('!'):
			if d1[x] != d2[x]:
				d2[x] = d1[x]

def indices(array, ref, symlist):
	reftype = ref.type.split('/')
	tokentype = ref.token.type.replace(':', '/').split('/')
	if 'comma_expr' in reftype:
예제 #4
0
def include(name):
	filename = ((path) and (path + '/')) + name + '.proton'
	with open(filename, 'r') as f:
		return complete(proton_parser.parse(lexer.tokenize(f.read())))[1]
예제 #5
0
# TODO default["complex"]


class proton_str(str):
    def __init__(self, obj):
        if isinstance(obj, dict):
            self = '[%s]' % ', '.join(
                sorted([ascii(key) + ' :> ' + ascii(obj[key]) for key in obj]))
        elif isinstance(obj, Function):
            self = proton_str(obj.function)
        else:
            self = str(obj)


default['eval'] = getfunction(
    lambda s, x: complete(proton_parser.parse(lexer.tokenize(x)), s))
default['Function'] = Function
default['str'] = proton_str
default['type'] = lambda x: x['__type__'] if isinstance(
    x, dict) and '__type__' in x else type(x)


def merge(d1, d2):
    for x in d1:
        if x in d2 or x.startswith('!'):
            if d1[x] != d2[x]:
                d2[x] = d1[x]


def indices(array, ref, symlist):
    reftype = ref.type.split('/')