def apply(self, f, x, xstart, xstop, y, ystart, ystop, evaluation, options): 'DensityPlot[f_, {x_Symbol, xstart_, xstop_}, {y_Symbol, ystart_, ystop_}, OptionsPattern[DensityPlot]]' x = x.get_name() y = y.get_name() color_function = self.get_option(options, 'ColorFunction', evaluation, pop=True) color_function_scaling = self.get_option(options, 'ColorFunctionScaling', evaluation, pop=True) color_function_min = color_function_max = None if color_function.get_name() == 'Automatic': color_function = String('LakeColors') if color_function.get_string_value(): func = Expression('ColorData', color_function.get_string_value()).evaluate(evaluation) if func.has_form('ColorDataFunction', 4): color_function_min = func.leaves[2].leaves[0].get_real_value() color_function_max = func.leaves[2].leaves[1].get_real_value() color_function = Expression('Function', Expression(func.leaves[3], Expression('Slot', 1))) else: evaluation.message('DensityPlot', 'color', func) return if color_function.has_form('ColorDataFunction', 4): color_function_min = color_function.leaves[2].leaves[0].get_real_value() color_function_max = color_function.leaves[2].leaves[1].get_real_value() color_function_scaling = color_function_scaling.is_true() try: xstart, xstop, ystart, ystop = [value.to_number(n_evaluation=evaluation) for value in (xstart, xstop, ystart, ystop)] except NumberError, exc: expr = Expression('DensityPlot', f, Expression('List', x, xstart, xstop), Expression('List', y, ystart, ystop), *options_to_rules(options)) evaluation.message('DensityPlot', 'plln', exc.value, expr) return
def apply(self, z, evaluation): '%(name)s[z__]' args = z.get_sequence() if len(args) != self.nargs: return # if no arguments are inexact attempt to use sympy if all(not x.is_inexact() for x in args): result = Expression(self.get_name(), *args).to_sympy() result = self.prepare_mathics(result) result = from_sympy(result) # evaluate leaves to convert e.g. Plus[2, I] -> Complex[2, 1] result = result.evaluate_leaves(evaluation) else: prec = min_prec(*args) with mpmath.workprec(prec): mpmath_args = [sympy2mpmath(x.to_sympy()) for x in args] if None in mpmath_args: return try: result = self.eval(*mpmath_args) result = from_sympy(mpmath2sympy(result, prec)) except ValueError, exc: text = str(exc) if text == 'gamma function pole': return Symbol('ComplexInfinity') else: raise except ZeroDivisionError: return except SpecialValueError, exc: return Symbol(exc.name)
def importer(self, filename, evaluation): path = filename.to_python() if not (isinstance(path, basestring) and path[0] == path[-1] == '"'): evaluation.message('Import', 'chtype', filename) return Symbol('$Failed') path = path.strip('"') if path.startswith("ExampleData"): path = ROOT_DIR + 'data/' + path if not os.path.exists(path): evaluation.message('Import', 'nffil') return None filetype = Expression('FileFormat', path).evaluate(evaluation=evaluation) assert isinstance(filetype, String) filetype = filetype.to_python().strip('"') assert filetype in IMPORTFORMATS result = {} if filetype == 'Text': with open(path, 'r') as f: plaintext = f.read() textlines = filter(lambda x: x != '', plaintext.split('\n')) textwords = filter(lambda x: x != '', plaintext.split()) result['Plaintext'] = plaintext result['Lines'] = textlines result['Words'] = textwords result['String'] = plaintext result['Data'] = textlines return result
def apply(self, expr, evaluation): 'Variables[expr_]' variables = set() def find_vars(e): if e.to_sympy().is_constant(): return elif e.is_symbol(): variables.add(e) elif (e.has_form('Plus', None) or e.has_form('Times', None)): for l in e.leaves: find_vars(l) elif e.has_form('Power', 2): (a, b) = e.leaves # a^b if not(a.to_sympy().is_constant()) and b.to_sympy().is_rational: find_vars(a) elif not(e.is_atom()): variables.add(e) exprs = expr.leaves if expr.has_form('List', None) else [expr] for e in exprs: find_vars(from_sympy(e.to_sympy().expand())) variables = Expression('List', *variables) variables.sort() # MMA doesn't do this return variables
def apply(self, items, evaluation): 'Times[items___]' items = items.numerify(evaluation).get_sequence() number = mpz(1) leaves = [] for item in items: if isinstance(item, Number): if get_type(item.value) == 'z' and item.value == 0: return Integer('0') number = mul(number, item.value) elif leaves and item == leaves[-1]: leaves[-1] = Expression('Power', leaves[-1], Integer(2)) elif leaves and item.has_form('Power', 2) and leaves[-1].has_form('Power', 2) and item.leaves[0].same(leaves[-1].leaves[0]): leaves[-1].leaves[1] = Expression('Plus', item.leaves[1], leaves[-1].leaves[1]) elif leaves and item.has_form('Power', 2) and item.leaves[0].same(leaves[-1]): leaves[-1] = Expression('Power', leaves[-1], Expression('Plus', item.leaves[1], Integer(1))) elif leaves and leaves[-1].has_form('Power', 2) and leaves[-1].leaves[0].same(item): leaves[-1] = Expression('Power', item, Expression('Plus', Integer(1), leaves[-1].leaves[1])) else: leaves.append(item) if get_type(number) == 'z': if number == 1: number = None elif number == -1 and leaves and leaves[0].has_form('Plus', None): leaves[0].leaves = [Expression('Times', Integer(-1), leaf) for leaf in leaves[0].leaves] number = None if number is not None: leaves.insert(0, Number.from_mp(number)) if not leaves: return Integer(1) elif len(leaves) == 1: return leaves[0] else: return Expression('Times', *leaves)
def apply(self, items, evaluation): '%(name)s[items__]' items_sequence = items.get_sequence() all_numeric = all(item.is_numeric() and item.get_precision() is None for item in items_sequence) if all_numeric and any(not isinstance(item, Number) for item in items_sequence): # All expressions are numeric but exact and they are not all numbers, # so apply N and compare them. items = items_sequence n_items = [] for item in items: if not isinstance(item, Number): # TODO: use $MaxExtraPrecision insterad of hard-coded 50 n_expr = Expression('N', item, Real(50)) item = n_expr.evaluate(evaluation) n_items.append(item) items = n_items else: items = items.numerify(evaluation).get_sequence() wanted = operators[self.get_name()] prev = None for item in items: if item.get_real_value() is None and not item.has_form('DirectedInfinity', None): return if prev is not None and do_cmp(prev, item) not in wanted: return Symbol('False') prev = item return Symbol('True')
def apply(self, f, args, h, evaluation): 'Thread[f_[args___], h_]' args = args.get_sequence() expr = Expression(f, *args) threaded, result = expr.thread(evaluation, head=h) return result
def format_output(self, expr, format=None): if format is None: format = self.format if isinstance(format, dict): return dict((k, self.format_output(expr, f)) for k, f in format.items()) from mathics.core.expression import Expression, BoxError if format == 'text': result = expr.format(self, 'System`OutputForm') elif format == 'xml': result = Expression( 'StandardForm', expr).format(self, 'System`MathMLForm') elif format == 'tex': result = Expression('StandardForm', expr).format( self, 'System`TeXForm') else: raise ValueError try: boxes = result.boxes_to_text(evaluation=self) except BoxError: self.message('General', 'notboxes', Expression('FullForm', result).evaluate(self)) boxes = None return boxes
def yield_match(vars, rest): if rest is None: rest = ([], []) if 0 < len(rest[0]) + len(rest[1]) == len(expression.get_leaves()): # continue return options = {} for name, value in list(vars.items()): if name.startswith('_option_'): options[name[len('_option_'):]] = value del vars[name] new_expression = self.do_replace(expression, vars, options, evaluation) if new_expression is None: new_expression = expression if rest[0] or rest[1]: result = Expression(expression.get_head(), *( rest[0] + [new_expression] + rest[1])) else: result = new_expression # Flatten out sequences (important for Rule itself!) result = result.flatten_pattern_sequence() if return_list: result_list.append(result) # count += 1 if max_list is not None and len(result_list) >= max_list: # return result_list raise StopGenerator_BaseRule(result_list) else: raise StopGenerator_BaseRule(result)
def get_msg_list(expr): if expr.has_form('MessageName', 2): expr = Expression('List', expr) if expr.get_name() == 'All': all = True messages = [] elif expr.get_name() == 'None': all = False messages = [] elif expr.has_form('List', None): all = False messages = [] for item in expr.leaves: if item.has_form('MessageName', 2): symbol = item.leaves[0].get_name() tag = item.leaves[1].get_string_value() if symbol and tag: messages.append((symbol, tag)) else: raise ValueError else: raise ValueError else: raise ValueError return all, messages
def apply(self, expr, evaluation): 'Variables[expr_]' variables = find_all_vars(expr) variables = Expression('List', *variables) variables.sort() # MMA doesn't do this return variables
def apply(self, items, evaluation): 'Times[items___]' #TODO: Clean this up and optimise it items = items.numerify(evaluation).get_sequence() number = (sympy.Integer(1), sympy.Integer(0)) leaves = [] prec = min_prec(*items) is_real = all([not isinstance(i, Complex) for i in items]) for item in items: if isinstance(item, Number): if isinstance(item, Complex): sym_real, sym_imag = item.real.to_sympy(), item.imag.to_sympy() else: sym_real, sym_imag = item.to_sympy(), sympy.Integer(0) if prec is not None: sym_real = sym_real.n(dps(prec)) sym_imag = sym_imag.n(dps(prec)) if sym_real.is_zero and sym_imag.is_zero and prec is None: return Integer('0') number = (number[0]*sym_real - number[1]*sym_imag, number[0]*sym_imag + number[1]*sym_real) elif leaves and item == leaves[-1]: leaves[-1] = Expression('Power', leaves[-1], Integer(2)) elif leaves and item.has_form('Power', 2) and leaves[-1].has_form('Power', 2) and item.leaves[0].same(leaves[-1].leaves[0]): leaves[-1].leaves[1] = Expression('Plus', item.leaves[1], leaves[-1].leaves[1]) elif leaves and item.has_form('Power', 2) and item.leaves[0].same(leaves[-1]): leaves[-1] = Expression('Power', leaves[-1], Expression('Plus', item.leaves[1], Integer(1))) elif leaves and leaves[-1].has_form('Power', 2) and leaves[-1].leaves[0].same(item): leaves[-1] = Expression('Power', item, Expression('Plus', Integer(1), leaves[-1].leaves[1])) else: leaves.append(item) if number == (1, 0): number = None elif number == (-1, 0) and leaves and leaves[0].has_form('Plus', None): leaves[0].leaves = [Expression('Times', Integer(-1), leaf) for leaf in leaves[0].leaves] number = None if number is not None: if number[1].is_zero and is_real: leaves.insert(0, Number.from_mp(number[0], prec)) elif number[1].is_zero and number[1].is_Integer and prec is None: leaves.insert(0, Number.from_mp(number[0], prec)) else: leaves.insert(0, Complex(from_sympy(number[0]), from_sympy(number[1]), prec)) if not leaves: return Integer(1) elif len(leaves) == 1: return leaves[0] else: return Expression('Times', *leaves)
def compare(e1, e2): result = Expression(p, e1, e2).evaluate(evaluation) if result.is_true(): result = Expression(p, e2, e1).evaluate(evaluation) if result.is_true(): return 0 else: return -1 else: return 1
def apply_elements(self, filename, expr, elems, evaluation, options={}): "Export[filename_, expr_, elems_List?(AllTrue[#, NotOptionQ]&), OptionsPattern[]]" # Check filename if not self._check_filename(filename, evaluation): return Symbol('$Failed') # Process elems {comp* format?, elem1*} leaves = elems.get_leaves() format_spec, elems_spec = [], [] found_form = False for leaf in leaves[::-1]: leaf_str = leaf.get_string_value() if not found_form and leaf_str in EXPORTERS: found_form = True if found_form: format_spec.append(leaf_str) else: elems_spec.append(leaf) # Infer format if not present if not found_form: assert format_spec == [] format_spec = self._infer_form(filename, evaluation) if format_spec is None: evaluation.message('Export', 'infer', filename) return Symbol('$Failed') format_spec = [format_spec] else: assert format_spec != [] # First item in format_spec is the explicit format. # The other elements (if present) are compression formats if elems_spec != []: # FIXME: support elems evaluation.message( 'Export', 'noelem', elems, String(format_spec[0])) return Symbol('$Failed') # Load the exporter exporter_symbol, exporter_options = EXPORTERS[format_spec[0]] stream_options, custom_options = _importer_exporter_options( exporter_options.get("System`Options"), options, evaluation) exporter_function = Expression( exporter_symbol, filename, expr, *list(chain(stream_options, custom_options))) if exporter_function.evaluate(evaluation) == Symbol('Null'): return filename return Symbol('$Failed')
def post_parse(self, expression): leaves = [leaf.post_parse() for leaf in expression.leaves] expression = Expression(expression.head.post_parse(), *leaves) if expression.has_form('Optional', 2) and expression.leaves[0].get_name(): sub = expression.leaves[1] if sub.has_form(('Pattern', 'Optional'), 2): return Expression('Optional', Expression('Pattern', expression.leaves[0], sub.leaves[0]), sub.leaves[1]) else: return Expression('Pattern', *[leaf.post_parse() for leaf in expression.leaves]) else: return expression
def apply(self, list, expr, evaluation): 'Select[list_, expr_]' if list.is_atom(): evaluation.message('Select', 'normal') return new_leaves = [] for leaf in list.leaves: test = Expression(expr, leaf) if test.evaluate(evaluation) == Symbol('True'): new_leaves.append(leaf) return Expression(list.head, *new_leaves)
def _norm_calc(head, u, v, evaluation): expr = Expression(head, u, v) old_quiet_all = evaluation.quiet_all try: evaluation.quiet_all = True expr_eval = expr.evaluate(evaluation) finally: evaluation.quiet_all = old_quiet_all if expr_eval.same(expr): evaluation.message('Norm', 'nvm') return None else: return expr_eval
def eval_color(x, y, v): v_scaled = (v - v_min) / v_range if color_function_scaling and color_function_min is not None and color_function_max is not None: v_color_scaled = color_function_min + v_scaled * color_function_range else: v_color_scaled = v v_lookup = int(v_scaled * 100 + 0.5) # calculate and store 100 different shades max. value = colors.get(v_lookup) if value is None: value = Expression(color_func, Real(v_color_scaled)) value = value.evaluate(evaluation) colors[v_lookup] = value return value
def apply(self, filename, expr, elems, evaluation): "Export[filename_, expr_, elems_List]" # Check filename if not self._check_filename(filename, evaluation): return Symbol('$Failed') ## Process elems {comp* format?, elem1*} leaves = elems.get_leaves() format_spec, elems_spec = [], [] found_form = False for leaf in leaves[::-1]: leaf_str = leaf.get_string_value() if not found_form and leaf_str in EXPORTERS: found_form = True if found_form: format_spec.append(leaf_str) else: elems_spec.append(leaf) # Infer format if not present if not found_form: assert format_spec == [] format_spec = self._infer_form(filename, evaluation) if format_spec is None: evaluation.message('Export', 'infer', filename) return Symbol('$Failed') format_spec = [format_spec] else: assert format_spec != [] # First item in format_spec is the explicit format. # The other elements (if present) are compression formats if elems_spec != []: # FIXME: support elems evaluation.message( 'Export', 'noelem', elems, String(format_spec[0])) return Symbol('$Failed') # Load the exporter exporter_symbol = EXPORTERS[format_spec[0]] exporter_function = Expression(exporter_symbol, filename, expr) if exporter_function.evaluate(evaluation) == Symbol('Null'): return filename return Symbol('$Failed')
def add(self, expression, evaluation): expr = Expression('System`Private`ManipulateParameter', expression).evaluate(evaluation) if expr.get_head_name() != 'System`List': # if everything was parsed ok, we get a List return False # convert the rules given us by ManipulateParameter[] into a dict. note: duplicate keys # will be overwritten, the latest one wins. kwargs = {'evaluation': evaluation} for rule in expr.leaves: if rule.get_head_name() != 'System`Rule' or len(rule.leaves) != 2: return False kwargs[strip_context(rule.leaves[0].to_python()).lower()] = rule.leaves[1] widget = kwargs['type'].get_string_value() del kwargs['type'] getattr(self, '_add_%s_widget' % widget.lower())(**kwargs) # create the widget return True
def yield_match(vars_2, rest): items = expression.get_sequence() for item in items: quick_test = self.quick_pattern_test(item, self.test_name) if quick_test is not None: if not quick_test: break #raise StopGenerator else: test_expr = Expression(self.test, item) test_value = test_expr.evaluate(evaluation) if not test_value.is_true(): break #raise StopGenerator else: yield_func(vars_2, None)
def get_wrappings(self, yield_func, items, max_count, expression, attributes, include_flattened=True): if len(items) == 1: yield_func(items[0]) else: if max_count is None or len(items) <= max_count: if 'Orderless' in attributes: for perm in permutations(items): sequence = Expression('Sequence', *perm) sequence.pattern_sequence = True yield_func(sequence) else: sequence = Expression('Sequence', *items) sequence.pattern_sequence = True yield_func(sequence) if 'Flat' in attributes and include_flattened: yield_func(Expression(expression.get_head(), *items))
def format_output(self, expr): from mathics.core.expression import Expression, String, BoxError if self.format == 'text': result = expr.format(self, 'OutputForm') elif self.format == 'xml': result = Expression('StandardForm', expr).format(self, 'MathMLForm') elif self.format == 'tex': result = Expression('StandardForm', expr).format(self, 'TeXForm') else: raise ValueError try: boxes = result.boxes_to_text(evaluation=self) except BoxError: self.message('General', 'notboxes', String('%s' % result)) boxes = None return boxes
def apply(self, f, expr, test, m, evaluation): 'NestWhile[f_, expr_, test_, Pattern[m,_Integer|All]]' results = [expr] while True: if m.get_name() == 'All': test_leaves = results else: test_leaves = results[-m.value:] test_expr = Expression(test, *test_leaves) test_result = test_expr.evaluate(evaluation) if test_result.is_true(): next = Expression(f, results[-1]) results.append(next.evaluate(evaluation)) else: break return results[-1]
def apply_iter(self, expr, i, imin, imax, di, evaluation): '%(name)s[expr_, {i_Symbol, imin_, imax_, di_}]' if isinstance(self, SympyFunction) and di.get_int_value() == 1: whole_expr = Expression(self.get_name(), expr, Expression('List', i, imin, imax)) sympy_expr = whole_expr.to_sympy() # apply Together to produce results similar to Mathematica result = sympy.together(sympy_expr) result = from_sympy(result) result = cancel(result) if not result.same(whole_expr): return result index = imin.evaluate(evaluation) imax = imax.evaluate(evaluation) di = di.evaluate(evaluation) result = [] while True: cont = Expression('LessEqual', index, imax).evaluate(evaluation) if cont == Symbol('False'): break if cont != Symbol('True'): if self.throw_iterb: evaluation.message(self.get_name(), 'iterb') return evaluation.check_stopped() try: item = dynamic_scoping(expr.evaluate, {i.name: index}, evaluation) result.append(item) except ContinueInterrupt: if self.allow_loopcontrol: pass else: raise except BreakInterrupt: if self.allow_loopcontrol: break else: raise index = Expression('Plus', index, di).evaluate(evaluation) return self.get_result(result)
def apply(self, mlist, test, evaluation): 'Split[mlist_, test_]' expr = Expression('Split', mlist, test) if mlist.is_atom(): evaluation.message('Select', 'normal', 1, expr) return result = [[mlist.leaves[0]]] for leaf in mlist.leaves[1:]: applytest = Expression(test, result[-1][-1], leaf) if applytest.evaluate(evaluation) == Symbol('True'): result[-1].append(leaf) else: result.append([leaf]) return Expression(mlist.head, *[Expression('List', *l) for l in result])
def apply(self, filename, evaluation): 'FileFormat[filename_String]' findfile = Expression('FindFile', filename).evaluate(evaluation) if findfile == Symbol('$Failed'): evaluation.message( 'FileFormat', 'nffil', Expression('FileFormat', filename)) return findfile path = findfile.get_string_value() if not FileFormat.detector: loader = magic.MagicLoader() loader.load() FileFormat.detector = magic.MagicDetector(loader.mimetypes) mime = set(FileFormat.detector.match(path)) # If match fails match on extension only if mime == set([]): mime, encoding = mimetypes.guess_type(path) if mime is None: mime = set([]) else: mime = set([mime]) result = [] for key in mimetype_dict.keys(): if key in mime: result.append(mimetype_dict[key]) # the following fixes an extremely annoying behaviour on some (not all) # installations of Windows, where we end up classifying .csv files als XLS. if len(result) == 1 and result[0] == 'XLS' and path.lower().endswith('.csv'): return String('CSV') if len(result) == 0: result = 'Binary' elif len(result) == 1: result = result[0] else: return None return from_python(result)
def get_results(tmp_function): if function_channels == Expression('List', String('FileNames')): tmp = Expression(tmp_function, findfile).evaluate(evaluation) elif function_channels == Expression('List', String('Streams')): stream = Expression('OpenRead', findfile).evaluate(evaluation) if stream.get_head_name() != 'InputStream': evaluation.message('Import', 'nffil') return None tmp = Expression(tmp_function, stream).evaluate(evaluation) Expression('Close', stream).evaluate(evaluation) else: #TODO print appropriate error message raise NotImplementedError tmp = tmp.get_leaves() if not all(expr.has_form('Rule', None) for expr in tmp): return None # return {a.get_string_value() : b for (a,b) in map(lambda x: x.get_leaves(), tmp)} return dict((a.get_string_value(), b) for (a,b) in map(lambda x: x.get_leaves(), tmp))
def check(level, expr): if not expr.has_form('List', None): test_expr = Expression(test, expr) if test_expr.evaluate(evaluation) != Symbol('True'): return False level_dim = None else: level_dim = len(expr.leaves) if len(dims) > level: if dims[level] != level_dim: return False else: dims.append(level_dim) if level_dim is not None: for leaf in expr.leaves: if not check(level + 1, leaf): return False return True
def apply_iter(self, expr, i, imin, imax, di, evaluation): '%(name)s[expr_, {i_Symbol, imin_, imax_, di_}]' if di.get_int_value() == 1 and isinstance(self, SageFunction): whole_expr = Expression(self.get_name(), expr, Expression('List', i, imin, imax)) sympy_expr = whole_expr.to_sympy() # apply Together to produce results similar to Mathematica result = sympy.together(sympy_expr) result = from_sympy(result) result = cancel(result) if not result.same(whole_expr): return result index = imin.evaluate(evaluation).get_real_value() imax = imax.evaluate(evaluation).get_real_value() di = di.evaluate(evaluation).get_real_value() if index is None or imax is None or di is None: if self.throw_iterb: evaluation.message(self.get_name(), 'iterb') return result = [] while index <= imax: evaluation.check_stopped() try: item = dynamic_scoping(expr.evaluate, {i.name: Number.from_mp(index)}, evaluation) result.append(item) except ContinueInterrupt: if self.allow_loopcontrol: pass else: raise except BreakInterrupt: if self.allow_loopcontrol: break else: raise index = add(index, di) return self.get_result(result)
def determine_filetype(): return Expression( 'FileFormat', findfile).evaluate(evaluation=evaluation).get_string_value()
def to_sympy(self, expr): if len(expr.leaves) == 1: return Expression('ArcSinh', Expression('Power', expr.leaves[0], Integer(-1))).to_sympy()
def p_slotseq(self, args): ' expr ::= slotseq ' return Expression('SlotSequence', Integer(args[0].value))
def apply_element(self, expr, element, evaluation, options={}): 'ExportString[expr_, element_String, OptionsPattern[]]' return self.apply_elements(expr, Expression('List', element), evaluation, options)
def op_670_part(self, args): ' expr ::= expr position' return Expression('Part', args[0], *args[1].items)
def p_list(self, args): ' expr ::= { sequence } ' return Expression('List', *args[1].items)
def op_305_2(self, args): ' expr ::= span_start ;; span_stop ' return Expression('Span', args[0], args[2], Integer(1))
def _infer_form(self, filename, evaluation): ext = Expression('FileExtension', filename).evaluate(evaluation) ext = ext.get_string_value().lower() return self._extdict.get(ext)
def get_results(tmp_function, findfile): if function_channels == Expression('List', String('FileNames')): joined_options = list(chain(stream_options, custom_options)) tmpfile = False if findfile is None: tmpfile = True stream = Expression('OpenWrite').evaluate(evaluation) findfile = stream.leaves[0] if not data is None: Expression('WriteString', data).evaluate(evaluation) else: Expression('WriteString', String("")).evaluate(evaluation) Expression('Close', stream).evaluate(evaluation) stream = None tmp = Expression(tmp_function, findfile, *joined_options).evaluate(evaluation) if tmpfile: Expression("DeleteFile", findfile).evaluate(evaluation) elif function_channels == Expression('List', String('Streams')): if findfile is None: stream = Expression('StringToStream', data).evaluate(evaluation) else: stream = Expression('OpenRead', findfile, *stream_options).evaluate(evaluation) if stream.get_head_name() != 'System`InputStream': evaluation.message('Import', 'nffil') evaluation.predetermined_out = current_predetermined_out return None tmp = Expression(tmp_function, stream, *custom_options).evaluate(evaluation) Expression('Close', stream).evaluate(evaluation) else: # TODO message evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') tmp = tmp.get_leaves() if not all(expr.has_form('Rule', None) for expr in tmp): evaluation.predetermined_out = current_predetermined_out return None # return {a.get_string_value() : b for (a,b) in map(lambda x: # x.get_leaves(), tmp)} evaluation.predetermined_out = current_predetermined_out return dict((a.get_string_value(), b) for (a, b) in [x.get_leaves() for x in tmp])
class OptionsPattern(PatternObject): """ <dl> <dt>'OptionsPattern[$f$]' <dd>is a pattern that stands for a sequence of options given to a function, with default values taken from 'Options[$f$]'. The options can be of the form '$opt$->$value$' or '$opt$:>$value$', and might be in arbitrarily nested lists. <dt>'OptionsPattern[{$opt1$->$value1$, ...}]' <dd>takes explicit default values from the given list. The list may also contain symbols $f$, for which 'Options[$f$]' is taken into account; it may be arbitrarily nested. 'OptionsPattern[{}]' does not use any default values. </dl> The option values can be accessed using 'OptionValue'. >> f[x_, OptionsPattern[{n->2}]] := x ^ OptionValue[n] >> f[x] = x ^ 2 >> f[x, n->3] = x ^ 3 Delayed rules as options: >> e = f[x, n:>a] = x ^ a >> a = 5; >> e = x ^ 5 Options might be given in nested lists: >> f[x, {{{n->4}}}] = x ^ 4 #> {opt -> b} /. OptionsPattern[{}] -> t = t #> Clear[f] #> Options[f] = {Power -> 2}; #> f[x_, OptionsPattern[f]] := x ^ OptionValue[Power] #> f[10] = 100 #> f[10, Power -> 3] = 1000 #> Clear[f] #> Options[f] = {Power -> 2}; #> f[x_, OptionsPattern[]] := x ^ OptionValue[Power] #> f[10] = 100 #> f[10, Power -> 3] = 1000 #> Clear[f] """ arg_counts = [0, 1] def init(self, expr): super(OptionsPattern, self).init(expr) try: self.defaults = expr.leaves[0] except IndexError: # OptionsPattern[] takes default options of the nearest enclosing # function. Set to not None in self.match self.defaults = None def match(self, yield_func, expression, vars, evaluation, **kwargs): if self.defaults is None: self.defaults = kwargs.get("head") if self.defaults is None: # we end up here with OptionsPattern that do not have any # default options defined, e.g. with this code: # f[x:OptionsPattern[]] := x; f["Test" -> 1] # set self.defaults to an empty List, so we don't crash. self.defaults = Expression(SymbolList) values = self.defaults.get_option_values(evaluation, allow_symbols=True, stop_on_error=False) sequence = expression.get_sequence() for options in sequence: option_values = options.get_option_values(evaluation) if option_values is None: return values.update(option_values) new_vars = vars.copy() for name, value in values.items(): new_vars["_option_" + name] = value yield_func(new_vars, None) def get_match_count(self, vars={}): return (0, None) def get_match_candidates(self, leaves, expression, attributes, evaluation, vars={}): def _match(leaf): return leaf.has_form( ("Rule", "RuleDelayed"), 2) or leaf.has_form("List", None) return [leaf for leaf in leaves if _match(leaf)]
def apply_element(self, data, element, evaluation, options={}): 'ImportString[data_, element_String, OptionsPattern[]]' return self.apply_elements(data, Expression('List', element), evaluation, options)
def rhs(expr): if expr.has_form('Infix', None): expr = Expression(Expression( 'HoldForm', expr.head), *expr.leaves) return Expression('InputForm', expr)
def get_result(self, items): return Expression('Times', *items)
def from_sympy(self, sympy_name, args): # Hack to get around weird sympy.Piecewise 'otherwise' behaviour if str(args[-1].leaves[1]).startswith('System`_True__Dummy_'): args[-1].leaves[1] = Symbol('True') return Expression(self.get_name(), args)
def apply_element(self, filename, element, evaluation, options={}): 'Import[filename_, element_String, OptionsPattern[]]' return self.apply_elements(filename, Expression('List', element), evaluation, options)
def format_definition(self, symbol, evaluation, grid=True): 'StandardForm,TraditionalForm,OutputForm: Definition[symbol_]' lines = [] def print_rule(rule, up=False, lhs=lambda l: l, rhs=lambda r: r): evaluation.check_stopped() if isinstance(rule, Rule): r = rhs(rule.replace.replace_vars( {'System`Definition': Expression('HoldForm', Symbol('Definition'))})) lines.append(Expression('HoldForm', Expression( up and 'UpSet' or 'Set', lhs(rule.pattern.expr), r))) name = symbol.get_name() if not name: evaluation.message('Definition', 'sym', symbol, 1) return attributes = evaluation.definitions.get_attributes(name) definition = evaluation.definitions.get_user_definition( name, create=False) all = evaluation.definitions.get_definition(name) if attributes: attributes = list(attributes) attributes.sort() lines.append(Expression( 'HoldForm', Expression( 'Set', Expression('Attributes', symbol), Expression( 'List', *(Symbol(attribute) for attribute in attributes))))) if definition is not None and 'System`ReadProtected' not in attributes: for rule in definition.ownvalues: print_rule(rule) for rule in definition.downvalues: print_rule(rule) for rule in definition.subvalues: print_rule(rule) for rule in definition.upvalues: print_rule(rule, up=True) for rule in definition.nvalues: print_rule(rule) formats = sorted(definition.formatvalues.items()) for format, rules in formats: for rule in rules: def lhs(expr): return Expression('Format', expr, Symbol(format)) def rhs(expr): if expr.has_form('Infix', None): expr = Expression(Expression( 'HoldForm', expr.head), *expr.leaves) return Expression('InputForm', expr) print_rule(rule, lhs=lhs, rhs=rhs) for rule in all.defaultvalues: print_rule(rule) if all.options: options = sorted(all.options.items()) lines.append( Expression('HoldForm', Expression( 'Set', Expression('Options', symbol), Expression('List', *( Expression('Rule', Symbol(name), value) for name, value in options))))) if grid: if lines: return Expression( 'Grid', Expression( 'List', *(Expression('List', line) for line in lines)), Expression( 'Rule', Symbol('ColumnAlignments'), Symbol('Left'))) else: return Symbol('Null') else: for line in lines: evaluation.print_out(Expression('InputForm', line)) return Symbol('Null')
def p_slot(self, args): ' expr ::= slot ' return Expression('Slot', Integer(args[0].value))
def assign_elementary(self, lhs, rhs, evaluation, tags=None, upset=False): name = lhs.get_head_name() if name in system_symbols('OwnValues', 'DownValues', 'SubValues', 'UpValues', 'NValues', 'Options', 'DefaultValues', 'Attributes', 'Messages'): if len(lhs.leaves) != 1: evaluation.message_args(name, len(lhs.leaves), 1) return False tag = lhs.leaves[0].get_name() if not tag: evaluation.message(name, 'sym', lhs.leaves[0], 1) return False if tags is not None and tags != [tag]: evaluation.message(name, 'tag', Symbol(name), Symbol(tag)) return False if (name != 'System`Attributes' and 'System`Protected' # noqa in evaluation.definitions.get_attributes(tag)): evaluation.message(name, 'wrsym', Symbol(tag)) return False if name == 'System`Options': option_values = rhs.get_option_values(evaluation) if option_values is None: evaluation.message(name, 'options', rhs) return False evaluation.definitions.set_options(tag, option_values) elif name == 'System`Attributes': attributes = get_symbol_list( rhs, lambda item: evaluation.message(name, 'sym', item, 1)) if attributes is None: return False if 'System`Locked' in evaluation.definitions.get_attributes(tag): evaluation.message(name, 'locked', Symbol(tag)) return False evaluation.definitions.set_attributes(tag, attributes) else: rules = rhs.get_rules_list() if rules is None: evaluation.message(name, 'vrule', lhs, rhs) return False evaluation.definitions.set_values(tag, name, rules) return True form = '' nprec = None default = False message = False allow_custom_tag = False focus = lhs if name == 'System`N': if len(lhs.leaves) not in (1, 2): evaluation.message_args('N', len(lhs.leaves), 1, 2) return False if len(lhs.leaves) == 1: nprec = Symbol('MachinePrecision') else: nprec = lhs.leaves[1] focus = lhs.leaves[0] lhs = Expression('N', focus, nprec) elif name == 'System`MessageName': if len(lhs.leaves) != 2: evaluation.message_args('MessageName', len(lhs.leaves), 2) return False focus = lhs.leaves[0] message = True elif name == 'System`Default': if len(lhs.leaves) not in (1, 2, 3): evaluation.message_args('Default', len(lhs.leaves), 1, 2, 3) return False focus = lhs.leaves[0] default = True elif name == 'System`Format': if len(lhs.leaves) not in (1, 2): evaluation.message_args('Format', len(lhs.leaves), 1, 2) return False if len(lhs.leaves) == 2: form = lhs.leaves[1].get_name() if not form: evaluation.message('Format', 'fttp', lhs.leaves[1]) return False else: form = system_symbols( 'StandardForm', 'TraditionalForm', 'OutputForm', 'TeXForm', 'MathMLForm') lhs = focus = lhs.leaves[0] else: allow_custom_tag = True focus = focus.evaluate_leaves(evaluation) if tags is None and not upset: name = focus.get_lookup_name() if not name: evaluation.message(self.get_name(), 'setraw', focus) return False tags = [name] elif upset: if allow_custom_tag: tags = [] if focus.is_atom(): evaluation.message(self.get_name(), 'normal') return False for leaf in focus.leaves: name = leaf.get_lookup_name() tags.append(name) else: tags = [focus.get_lookup_name()] else: allowed_names = [focus.get_lookup_name()] if allow_custom_tag: for leaf in focus.get_leaves(): allowed_names.append(leaf.get_lookup_name()) for name in tags: if name not in allowed_names: evaluation.message(self.get_name(), 'tagnfd', Symbol(name)) return False ignore_protection = False rhs_int_value = rhs.get_int_value() lhs_name = lhs.get_name() if lhs_name == 'System`$RecursionLimit': # if (not rhs_int_value or rhs_int_value < 20) and not # rhs.get_name() == 'System`Infinity': if (not rhs_int_value or rhs_int_value < 20 or rhs_int_value > MAX_RECURSION_DEPTH): # nopep8 evaluation.message('$RecursionLimit', 'limset', rhs) return False try: set_python_recursion_limit(rhs_int_value) except OverflowError: # TODO: Message return False ignore_protection = True if lhs_name == 'System`$IterationLimit': if (not rhs_int_value or rhs_int_value < 20) and not rhs.get_name() == 'System`Infinity': evaluation.message('$IterationLimit', 'limset', rhs) return False ignore_protection = True elif lhs_name == 'System`$ModuleNumber': if not rhs_int_value or rhs_int_value <= 0: evaluation.message('$ModuleNumber', 'set', rhs) return False ignore_protection = True elif lhs_name in ('System`$Line', 'System`$HistoryLength'): if rhs_int_value is None or rhs_int_value < 0: evaluation.message(lhs_name, 'intnn', rhs) return False ignore_protection = True elif lhs_name == 'System`$RandomState': # TODO: allow setting of legal random states! # (but consider pickle's insecurity!) evaluation.message('$RandomState', 'rndst', rhs) return False elif lhs_name == 'System`$Context': new_context = rhs.get_string_value() if new_context is None or not valid_context_name( new_context, allow_initial_backquote=True): evaluation.message(lhs_name, 'cxset', rhs) return False # With $Context in Mathematica you can do some strange # things: e.g. with $Context set to Global`, something # like: # $Context = "`test`"; newsym # is accepted and creates Global`test`newsym. # Implement this behaviour by interpreting # $Context = "`test`" # as # $Context = $Context <> "test`" # if new_context.startswith('`'): new_context = (evaluation.definitions.get_current_context() + new_context.lstrip('`')) evaluation.definitions.set_current_context(new_context) ignore_protection = True return True elif lhs_name == 'System`$ContextPath': context_path = [s.get_string_value() for s in rhs.get_leaves()] if rhs.has_form('List', None) and all(valid_context_name(s) for s in context_path): evaluation.definitions.set_context_path(context_path) ignore_protection = True return True else: evaluation.message(lhs_name, 'cxlist', rhs) return False elif lhs_name == 'System`$MinPrecision': # $MinPrecision = Infinity is not allowed if rhs_int_value is not None and rhs_int_value >= 0: ignore_protection = True max_prec = evaluation.definitions.get_config_value('$MaxPrecision') if max_prec is not None and max_prec < rhs_int_value: evaluation.message('$MinPrecision', 'preccon', Symbol('$MinPrecision')) return True else: evaluation.message(lhs_name, 'precset', lhs, rhs) return False elif lhs_name == 'System`$MaxPrecision': if rhs.has_form('DirectedInfinity', 1) and rhs.leaves[0].get_int_value() == 1: ignore_protection = True elif rhs_int_value is not None and rhs_int_value > 0: ignore_protection = True min_prec = evaluation.definitions.get_config_value('$MinPrecision') if min_prec is not None and rhs_int_value < min_prec: evaluation.message('$MaxPrecision', 'preccon', Symbol('$MaxPrecision')) ignore_protection = True return True else: evaluation.message(lhs_name, 'precset', lhs, rhs) return False rhs_name = rhs.get_head_name() if rhs_name == 'System`Condition': if len(rhs.leaves) != 2: evaluation.message_args('Condition', len(rhs.leaves), 2) return False else: lhs = Expression('Condition', lhs, rhs.leaves[1]) rhs = rhs.leaves[0] rule = Rule(lhs, rhs) count = 0 defs = evaluation.definitions for tag in tags: if (not ignore_protection and 'System`Protected' # noqa in evaluation.definitions.get_attributes(tag)): if lhs.get_name() == tag: evaluation.message(self.get_name(), 'wrsym', Symbol(tag)) else: evaluation.message(self.get_name(), 'write', Symbol(tag), lhs) continue count += 1 if form: defs.add_format(tag, rule, form) elif nprec: defs.add_nvalue(tag, rule) elif default: defs.add_default(tag, rule) elif message: defs.add_message(tag, rule) else: if upset: defs.add_rule(tag, rule, position='up') else: defs.add_rule(tag, rule) if count == 0: return False return True
def evaluate(self, evaluation): return Expression('List', *sorted(EXPORTERS.keys()))
def assign_elementary(self, lhs, rhs, evaluation, tags=None, upset=False): name = lhs.get_head_name() if name in ('OwnValues', 'DownValues', 'SubValues', 'UpValues', 'NValues', 'Options', 'DefaultValues', 'Attributes', 'Messages'): if len(lhs.leaves) != 1: evaluation.message_args(name, len(lhs.leaves), 1) return False tag = lhs.leaves[0].get_name() if not tag: evaluation.message(name, 'sym', lhs.leaves[0], 1) return False if tags is not None and tags != [tag]: evaluation.message(name, 'tag', name, tag) return False if name != 'Attributes' and 'Protected' in evaluation.definitions.get_attributes( tag): evaluation.message(name, 'wrsym', tag) return False if name == 'Options': option_values = rhs.get_option_values(evaluation) if option_values is None: evaluation.message(name, 'options', rhs) return False evaluation.definitions.set_options(tag, option_values) elif name == 'Attributes': attributes = get_symbol_list( rhs, lambda item: evaluation.message(name, 'sym', item, 1)) if attributes is None: return False if 'Locked' in evaluation.definitions.get_attributes(tag): evaluation.message(name, 'locked', tag) return False evaluation.definitions.set_attributes(tag, attributes) else: rules = rhs.get_rules_list() if rules is None: evaluation.message(name, 'vrule', lhs, rhs) return False evaluation.definitions.set_values(tag, name, rules) return True form = '' nprec = None default = False message = False allow_custom_tag = False focus = lhs if name == 'N': if len(lhs.leaves) not in (1, 2): evaluation.message_args('N', len(lhs.leaves), 1, 2) return False if len(lhs.leaves) == 1: nprec = Symbol('MachinePrecision') else: nprec = lhs.leaves[1] focus = lhs.leaves[0] lhs = Expression('N', focus, nprec) elif name == 'MessageName': if len(lhs.leaves) != 2: evaluation.message_args('MessageName', len(lhs.leaves), 2) return False focus = lhs.leaves[0] message = True elif name == 'Default': if len(lhs.leaves) not in (1, 2, 3): evaluation.message_args('Default', len(lhs.leaves), 1, 2, 3) return False focus = lhs.leaves[0] default = True elif name == 'Format': if len(lhs.leaves) not in (1, 2): evaluation.message_args('Format', len(lhs.leaves), 1, 2) return False if len(lhs.leaves) == 2: form = lhs.leaves[1].get_name() if not form: evaluation.message('Format', 'fttp', lhs.leaves[1]) return False else: form = ( 'StandardForm', 'TraditionalForm', 'OutputForm', 'TeXForm', 'MathMLForm', ) lhs = focus = lhs.leaves[0] else: allow_custom_tag = True focus = focus.evaluate_leaves(evaluation) if tags is None and not upset: name = focus.get_lookup_name() if not name: evaluation.message(self.get_name(), 'setraw', focus) return False tags = [name] elif upset: if allow_custom_tag: tags = [] if focus.is_atom(): evaluation.message(self.get_name(), 'normal') return False for leaf in focus.leaves: name = leaf.get_lookup_name() tags.append(name) else: tags = [focus.get_lookup_name()] else: allowed_names = [focus.get_lookup_name()] if allow_custom_tag: for leaf in focus.get_leaves(): allowed_names.append(leaf.get_lookup_name()) for name in tags: if name not in allowed_names: evaluation.message(self.get_name(), 'tagnfd', name) return False ignore_protection = False rhs_int_value = rhs.get_int_value() lhs_name = lhs.get_name() if lhs_name == '$RecursionLimit': #if (not rhs_int_value or rhs_int_value < 20) and not rhs.get_name() == 'Infinity': if not rhs_int_value or rhs_int_value < 20 or rhs_int_value > settings.MAX_RECURSION_DEPTH: evaluation.message('$RecursionLimit', 'limset', rhs) return False try: set_recursionlimit(rhs_int_value) except OverflowError: #TODO: Message return False ignore_protection = True elif lhs_name == '$ModuleNumber': if not rhs_int_value or rhs_int_value <= 0: evaluation.message('$ModuleNumber', 'set', rhs) return False ignore_protection = True elif lhs_name in ('$Line', '$HistoryLength'): if rhs_int_value is None or rhs_int_value < 0: evaluation.message(lhs_name, 'intnn', rhs) return False ignore_protection = True elif lhs_name == '$RandomState': # TODO: allow setting of legal random states! # (but consider pickle's insecurity!) evaluation.message('$RandomState', 'rndst', rhs) return False rhs_name = rhs.get_head_name() if rhs_name == 'Condition': if len(rhs.leaves) != 2: evaluation.message_args('Condition', len(rhs.leaves), 2) return False else: lhs = Expression('Condition', lhs, rhs.leaves[1]) rhs = rhs.leaves[0] rule = Rule(lhs, rhs) count = 0 defs = evaluation.definitions for tag in tags: if not ignore_protection and 'Protected' in evaluation.definitions.get_attributes( tag): if lhs.get_name() == tag: evaluation.message(self.get_name(), 'wrsym', tag) else: evaluation.message(self.get_name(), 'write', tag, lhs) continue count += 1 if form: defs.add_format(tag, rule, form) elif nprec: defs.add_nvalue(tag, rule) elif default: defs.add_default(tag, rule) elif message: defs.add_message(tag, rule) else: if upset: defs.add_rule(tag, rule, position='up') else: defs.add_rule(tag, rule) if count == 0: return False return True
def apply_elements(self, expr, elems, evaluation, options={}): "ExportString[expr_, elems_List?(AllTrue[#, NotOptionQ]&), OptionsPattern[]]" # Process elems {comp* format?, elem1*} leaves = elems.get_leaves() format_spec, elems_spec = [], [] found_form = False for leaf in leaves[::-1]: leaf_str = leaf.get_string_value() if not found_form and leaf_str in EXPORTERS: found_form = True if found_form: format_spec.append(leaf_str) else: elems_spec.append(leaf) # Just to be sure that the following evaluations do not change the value of this property current_predetermined_out = evaluation.predetermined_out # Infer format if not present if format_spec is None: evaluation.message('ExportString', 'infer', filename) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') # First item in format_spec is the explicit format. # The other elements (if present) are compression formats if elems_spec != []: # FIXME: support elems if format_spec != []: evaluation.message('ExportString', 'noelem', elems, String(format_spec[0])) else: evaluation.message('ExportString', 'noelem', elems, String("Unknown")) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') # Load the exporter exporter_symbol, exporter_options = EXPORTERS[format_spec[0]] function_channels = exporter_options.get("System`FunctionChannels") stream_options, custom_options = _importer_exporter_options( exporter_options.get("System`Options"), options, "System Options", evaluation) if function_channels is None: evaluation.message('ExportString', 'emptyfch') evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') elif function_channels == Expression('List', String('FileNames')): # Generates a temporary file import tempfile tmpfile = tempfile.NamedTemporaryFile(dir=tempfile.gettempdir()) filename = String(tmpfile.name) tmpfile.close() exporter_function = Expression( exporter_symbol, filename, expr, *list(chain(stream_options, custom_options))) if exporter_function.evaluate(evaluation) != Symbol('Null'): evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') else: try: tmpstream = open(filename.value, 'rb') res = tmpstream.read().decode('utf-8') tmpstream.close() except Exception as e: print("something went wrong") print(e) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') res = String(str(res)) elif function_channels == Expression('List', String('Streams')): from io import StringIO from mathics.builtin.files import STREAMS, NSTREAMS pystream = StringIO() n = next(NSTREAMS) STREAMS.append(pystream) stream = Expression('OutputStream', String('String'), Integer(n)) exporter_function = Expression( exporter_symbol, stream, expr, *list(chain(stream_options, custom_options))) res = exporter_function.evaluate(evaluation) if res == Symbol('Null'): res = String(str(pystream.getvalue())) else: res = Symbol("$Failed") Expression('Close', stream).evaluate(evaluation) else: evaluation.message('ExportString', 'emptyfch') evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') evaluation.predetermined_out = current_predetermined_out return res
def _import(findfile, determine_filetype, elements, evaluation, options, data=None): current_predetermined_out = evaluation.predetermined_out # Check elements if elements.has_form('List', None): elements = elements.get_leaves() else: elements = [elements] for el in elements: if not isinstance(el, String): evaluation.message('Import', 'noelem', el) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') elements = [el.get_string_value() for el in elements] # Determine file type for el in elements: if el in IMPORTERS.keys(): filetype = el elements.remove(el) break else: filetype = determine_filetype() if filetype not in IMPORTERS.keys(): evaluation.message('Import', 'fmtnosup', filetype) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') # Load the importer (conditionals, default_function, posts, importer_options) = IMPORTERS[filetype] stream_options, custom_options = _importer_exporter_options( importer_options.get("System`Options"), options, "System`Import", evaluation) function_channels = importer_options.get("System`FunctionChannels") if function_channels is None: # TODO message if data is None: evaluation.message('Import', 'emptyfch') else: evaluation.message('ImportString', 'emptyfch') evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') default_element = importer_options.get("System`DefaultElement") if default_element is None: # TODO message evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') def get_results(tmp_function, findfile): if function_channels == Expression('List', String('FileNames')): joined_options = list(chain(stream_options, custom_options)) tmpfile = False if findfile is None: tmpfile = True stream = Expression('OpenWrite').evaluate(evaluation) findfile = stream.leaves[0] if not data is None: Expression('WriteString', data).evaluate(evaluation) else: Expression('WriteString', String("")).evaluate(evaluation) Expression('Close', stream).evaluate(evaluation) stream = None tmp = Expression(tmp_function, findfile, *joined_options).evaluate(evaluation) if tmpfile: Expression("DeleteFile", findfile).evaluate(evaluation) elif function_channels == Expression('List', String('Streams')): if findfile is None: stream = Expression('StringToStream', data).evaluate(evaluation) else: stream = Expression('OpenRead', findfile, *stream_options).evaluate(evaluation) if stream.get_head_name() != 'System`InputStream': evaluation.message('Import', 'nffil') evaluation.predetermined_out = current_predetermined_out return None tmp = Expression(tmp_function, stream, *custom_options).evaluate(evaluation) Expression('Close', stream).evaluate(evaluation) else: # TODO message evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') tmp = tmp.get_leaves() if not all(expr.has_form('Rule', None) for expr in tmp): evaluation.predetermined_out = current_predetermined_out return None # return {a.get_string_value() : b for (a,b) in map(lambda x: # x.get_leaves(), tmp)} evaluation.predetermined_out = current_predetermined_out return dict((a.get_string_value(), b) for (a, b) in [x.get_leaves() for x in tmp]) # Perform the import defaults = None if not elements: defaults = get_results(default_function, findfile) if defaults is None: evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') if default_element == Symbol("Automatic"): evaluation.predetermined_out = current_predetermined_out return Expression( 'List', *(Expression('Rule', String(key), defaults[key]) for key in defaults.keys())) else: result = defaults.get(default_element.get_string_value()) if result is None: evaluation.message('Import', 'noelem', default_element, from_python(filetype)) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') evaluation.predetermined_out = current_predetermined_out return result else: assert len(elements) == 1 el = elements[0] if el == "Elements": defaults = get_results(default_function, findfile) if defaults is None: evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') # Use set() to remove duplicates evaluation.predetermined_out = current_predetermined_out return from_python( sorted( set( list(conditionals.keys()) + list(defaults.keys()) + list(posts.keys())))) else: if el in conditionals.keys(): result = get_results(conditionals[el], findfile) if result is None: evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') if len(list(result.keys())) == 1 and list( result.keys())[0] == el: evaluation.predetermined_out = current_predetermined_out return list(result.values())[0] elif el in posts.keys(): # TODO: allow use of conditionals result = get_results(posts[el]) if result is None: evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') else: if defaults is None: defaults = get_results(default_function, findfile) if defaults is None: evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') if el in defaults.keys(): evaluation.predetermined_out = current_predetermined_out return defaults[el] else: evaluation.message('Import', 'noelem', from_python(el), from_python(filetype)) evaluation.predetermined_out = current_predetermined_otu return Symbol('$Failed')
def op_305_1(self, args): ' expr ::= span_start ;; span_stop ;; span_step ' return Expression('Span', args[0], args[2], args[4])
def p_out(self, args): ' expr ::= out ' return Expression('Out', Integer(args[0].value))
def lhs(expr): return Expression('Format', expr, Symbol(format))
def op_670_call(self, args): ' expr ::= expr args' expr = Expression(args[0], *args[1].items) expr.parenthesized = True # to handle e.g. Power[a,b]^c correctly return expr
def apply(self, items, evaluation): 'Plus[items___]' items = items.numerify(evaluation).get_sequence() leaves = [] last_item = last_count = None prec = min_prec(*items) is_machine_precision = any(item.is_machine_precision() for item in items) numbers = [] def append_last(): if last_item is not None: if last_count == 1: leaves.append(last_item) else: if last_item.has_form('Times', None): last_item.leaves.insert(0, from_sympy(last_count)) leaves.append(last_item) else: leaves.append( Expression('Times', from_sympy(last_count), last_item)) for item in items: if isinstance(item, Number): numbers.append(item) else: count = rest = None if item.has_form('Times', None): for leaf in item.leaves: if isinstance(leaf, Number): count = leaf.to_sympy() rest = item.leaves[:] rest.remove(leaf) if len(rest) == 1: rest = rest[0] else: rest.sort() rest = Expression('Times', *rest) break if count is None: count = sympy.Integer(1) rest = item if last_item is not None and last_item == rest: last_count = last_count + count else: append_last() last_item = rest last_count = count append_last() if numbers: if prec is not None: if is_machine_precision: numbers = [item.to_mpmath() for item in numbers] number = mpmath.fsum(numbers) number = Number.from_mpmath(number) else: with mpmath.workprec(prec): numbers = [item.to_mpmath() for item in numbers] number = mpmath.fsum(numbers) number = Number.from_mpmath(number, dps(prec)) else: number = from_sympy(sum(item.to_sympy() for item in numbers)) else: number = Integer(0) if not number.same(Integer(0)): leaves.insert(0, number) if not leaves: return Integer(0) elif len(leaves) == 1: return leaves[0] else: leaves.sort() return Expression('Plus', *leaves)
def apply_elements(self, filename, expr, elems, evaluation, options={}): "Export[filename_, expr_, elems_List?(AllTrue[#, NotOptionQ]&), OptionsPattern[]]" # Check filename if not self._check_filename(filename, evaluation): return Symbol('$Failed') # Process elems {comp* format?, elem1*} leaves = elems.get_leaves() format_spec, elems_spec = [], [] found_form = False for leaf in leaves[::-1]: leaf_str = leaf.get_string_value() if not found_form and leaf_str in EXPORTERS: found_form = True if found_form: format_spec.append(leaf_str) else: elems_spec.append(leaf) # Just to be sure that the following calls do not change the state of this property current_predetermined_out = evaluation.predetermined_out # Infer format if not present if not found_form: assert format_spec == [] format_spec = self._infer_form(filename, evaluation) if format_spec is None: evaluation.message('Export', 'infer', filename) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') format_spec = [format_spec] else: assert format_spec != [] # First item in format_spec is the explicit format. # The other elements (if present) are compression formats if elems_spec != []: # FIXME: support elems evaluation.message('Export', 'noelem', elems, String(format_spec[0])) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') # Load the exporter exporter_symbol, exporter_options = EXPORTERS[format_spec[0]] function_channels = exporter_options.get("System`FunctionChannels") stream_options, custom_options = _importer_exporter_options( exporter_options.get("System`Options"), options, 'System`Export', evaluation) if function_channels is None: evaluation.message('Export', 'emptyfch') evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') elif function_channels == Expression('List', String('FileNames')): exporter_function = Expression( exporter_symbol, filename, expr, *list(chain(stream_options, custom_options))) res = exporter_function.evaluate(evaluation) elif function_channels == Expression('List', String('Streams')): stream = Expression('OpenWrite', filename, *stream_options).evaluate(evaluation) if stream.get_head_name() != 'System`OutputStream': evaluation.message('Export', 'nffil') evaluation.predetermined_out = current_predetermined_out return Symbol("$Failed") exporter_function = Expression( exporter_symbol, stream, expr, *list(chain(stream_options, custom_options))) res = exporter_function.evaluate(evaluation) Expression('Close', stream).evaluate(evaluation) if res == Symbol('Null'): evaluation.predetermined_out = current_predetermined_out return filename evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed')
def create_infix(items, operator, prec, grouping): if len(items) == 1: return items[0] else: return Expression('Infix', Expression('List', *items), String(operator), prec, Symbol(grouping))
def op_010(self, args): ' expr ::= expr ; ' return Expression('CompoundExpression', args[0], Symbol('Null'))