def impl_functor(engine, heap, t, functor, arity): if helper.is_atomic(t): functor.unify(t, heap) arity.unify(term.Number(0), heap) elif helper.is_term(t): assert isinstance(t, term.Callable) sig = t.signature() atom = term.Callable.build(t.name(), signature=sig.atom_signature) functor.unify(atom, heap) arity.unify(term.Number(t.argument_count()), heap) elif isinstance(t, term.Var): if isinstance(functor, term.Var): error.throw_instantiation_error() a = helper.unwrap_int(arity) jit.promote(a) if a < 0: error.throw_domain_error("not_less_than_zero", arity) else: functor = helper.ensure_atomic(functor) if a == 0: t.unify(functor, heap) else: jit.promote(functor) name = helper.unwrap_atom(functor) t.unify( term.Callable.build(name, [heap.newvar() for i in range(a)]), heap)
def unpack_modname_and_predicate(rule): if helper.is_numeric(rule.argument_at(0)): error.throw_domain_error("atom", rule.argument_at(0)) assert 0, "unreachable" mod = rule.argument_at(0) indicator = rule.argument_at(1) if not isinstance(mod, term.Atom): raise error.UnificationFailed() assert 0, "unreachable" return mod.name(), indicator
def impl_seek(engine, heap, stream, offset, mode, obj): try: mode = seek_mode[mode] except KeyError: error.throw_domain_error("seek_method", term.Callable.build(mode)) try: stream.seek(offset, mode) except OSError: error.throw_domain_error("position", term.Number(offset)) pos = int(stream.tell()) obj.unify(term.Number(pos), heap)
def unwrap_stream(engine, obj): if isinstance(obj, term.Var): error.throw_instantiation_error() if isinstance(obj, term.Atom): try: stream = engine.streamwrapper.aliases[obj.name()] except KeyError: pass else: assert isinstance(stream, PrologStream) return stream error.throw_domain_error("stream", obj)
def make_option_dict(options): opts = {} for option in options: if isinstance(option, term.Var): error.throw_instantiation_error() if isinstance(option, term.Numeric): error.throw_domain_error("stream_option", option) if isinstance(option, term.Callable) and option.argument_count() == 1: arg0 = option.argument_at(0) if isinstance(arg0, term.Atom): opts[option.name()] = arg0.name() return opts
def unwrap_outstream(engine, obj): if isinstance(obj, term.Var): error.throw_instantiation_error() if isinstance(obj, term.Atom): try: stream = engine.streamwrapper.aliases[obj.name()] except KeyError: pass else: if not isinstance(stream, PrologOutputStream): error.throw_permission_error("output", "stream", term.Atom(stream.alias)) assert isinstance(stream, PrologOutputStream) return stream error.throw_domain_error("stream", obj)
def impl_abolish(engine, heap, module, predicate): modname = None if predicate.signature().eq(prefixsig): modname, predicate = unpack_modname_and_predicate(predicate) name, arity = helper.unwrap_predicate_indicator(predicate) if arity < 0: error.throw_domain_error("not_less_than_zero", term.Number(arity)) signature = Signature.getsignature(name, arity) if signature.get_extra("builtin"): error.throw_permission_error("modify", "static_procedure", predicate) if modname is not None: module = engine.modulewrapper.get_module(modname, predicate) try: del module.functions[signature] except KeyError: pass
def unwrap_meta_arguments(predicate): assert isinstance(predicate, Callable) args = predicate.arguments() arglist = [] for arg in args: if isinstance(arg, Var): error.throw_instantiation_error() assert 0 elif isinstance(arg, Atom) and arg.name() in meta_args: val = arg.name() elif isinstance(arg, Number) and 0 <= arg.num <= 9: val = str(arg.num) else: error.throw_domain_error("expected one of 0..9, :, ?, +, -", arg) assert 0 arglist.append(val[0]) return "".join(arglist)
def impl_open_options(engine, heap, srcpath, mode, stream, options): if not isinstance(stream, term.Var): error.throw_type_error("variable", stream) opts = make_option_dict(options) mode = rwa.get(mode, None) if mode is None: error.throw_domain_error("io_mode", term.Callable.build("mode not supported")) else: buffering = opts.get("buffer", "full") if buffering == "full": bufmode = -1 elif buffering == "line": bufmode = 1 elif buffering == "false": bufmode = 0 else: error.throw_domain_error("buffering", term.Callable.build(buffering)) assert 0, "unreachable" try: if mode == "r": prolog_stream = PrologInputStream( open_file_as_stream(srcpath, mode, bufmode)) else: prolog_stream = PrologOutputStream( open_file_as_stream(srcpath, mode, bufmode)) except OSError: error.throw_existence_error("source_sink", term.Callable.build(srcpath)) assert 0, "unreachable" engine.streamwrapper.streams[prolog_stream.fd()] = prolog_stream try: alias = opts["alias"] prolog_stream.alias = alias except KeyError: alias = "$stream_%d" % prolog_stream.fd() engine.streamwrapper.aliases[alias] = prolog_stream stream.unify(term.Callable.build(alias), heap)
def from_option_list(engine, options): # XXX add numbervars support quoted = False max_depth = 0 ignore_ops = False number_vars = False for option in options: if (not helper.is_term(option) or (isinstance(option, Callable) and option.argument_count() != 1)): error.throw_domain_error('write_option', option) assert isinstance(option, Callable) arg = option.argument_at(0) if option.name()== "max_depth": try: max_depth = helper.unwrap_int(arg) except error.CatchableError: error.throw_domain_error('write_option', option) elif (not isinstance(arg, Atom) or (arg.name()!= "true" and arg.name()!= "false")): error.throw_domain_error('write_option', option) assert 0, "unreachable" elif option.name()== "quoted": quoted = arg.name()== "true" elif option.name()== "ignore_ops": ignore_ops = arg.name()== "true" return TermFormatter(engine, quoted, max_depth, ignore_ops)
def impl_open_options(engine, heap, srcpath, mode, stream, options): if not isinstance(stream, term.Var): error.throw_type_error("variable", stream) opts = make_option_dict(options) mode = rwa.get(mode, None) if mode is None: error.throw_domain_error("io_mode", term.Callable.build( "mode not supported")) else: buffering = opts.get("buffer", "full") if buffering == "full": bufmode = -1 elif buffering == "line": bufmode = 1 elif buffering == "false": bufmode = 0 else: error.throw_domain_error("buffering", term.Callable.build(buffering)) assert 0, "unreachable" try: if mode == "r": prolog_stream = PrologInputStream(open_file_as_stream( srcpath, mode, bufmode)) else: prolog_stream = PrologOutputStream(open_file_as_stream( srcpath, mode, bufmode)) except OSError: error.throw_existence_error("source_sink", term.Callable.build(srcpath)) assert 0, "unreachable" engine.streamwrapper.streams[prolog_stream.fd()] = prolog_stream try: alias = opts["alias"] prolog_stream.alias = alias except KeyError: alias = "$stream_%d" % prolog_stream.fd() engine.streamwrapper.aliases[alias] = prolog_stream stream.unify(term.Callable.build(alias), heap)
def impl_arg(engine, heap, rule, first, second, third, scont, fcont): if isinstance(second, term.Var): error.throw_instantiation_error() if isinstance(second, term.Atom): raise error.UnificationFailed() error.throw_type_error('compound', second) if not helper.is_term(second): error.throw_type_error("compound", second) assert isinstance(second, term.Callable) if isinstance(first, term.Var): return continue_arg(engine, scont, fcont, heap, first, 0, second, third, rule) elif isinstance(first, term.Number): num = first.num if num == 0: raise error.UnificationFailed if num < 0: error.throw_domain_error("not_less_than_zero", first) if num > second.argument_count(): raise error.UnificationFailed() arg = second.argument_at(num - 1) third.unify(arg, heap) else: error.throw_type_error("integer", first) return scont, fcont, heap
def impl_current_output(engine, heap, obj): if not isinstance(obj, term.Var) and not isinstance(obj, term.Atom): error.throw_domain_error("stream", obj) obj.unify(term.Atom(engine.streamwrapper.current_outstream.alias), heap)