Class: Upl::Term
Overview
This thing’s job is interacting with term_t, whereas Tree’s job is being a ruby copy of a term-tree.
Instance Attribute Summary collapse
-
#term_t ⇒ Object
(also: #to_term_t)
readonly
Returns the value of attribute term_t.
Class Method Summary collapse
- .of_atom(atom) ⇒ Object
-
.predicate(name, *args) ⇒ Object
returns a term.
Instance Method Summary collapse
- #<=>(rhs) ⇒ Object
- #==(rhs) ⇒ Object
- #[](idx) ⇒ Object
-
#[]=(idx, val_term_t) ⇒ Object
set term_t = val_term_t idx is zero-based, unlike the prolog calls.
- #arity ⇒ Object
- #atom ⇒ Object
- #deconstruct ⇒ Object
- #each ⇒ Object
- #first ⇒ Object
-
#initialize(term_or_string) ⇒ Term
constructor
A new instance of Term.
- #last ⇒ Object
- #populate ⇒ Object
- #pretty_print(pp) ⇒ Object
- #to_functor ⇒ Object
- #to_predicate ⇒ Object
- #tree ⇒ Object (also: #to_ruby)
Constructor Details
#initialize(term_or_string) ⇒ Term
Returns a new instance of Term.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/upl/term.rb', line 5 def initialize term_or_string case term_or_string when String # sadly, this doesn't keep variable names rv = Extern.PL_put_term_from_chars \ (@term_t = Extern.PL_new_term_ref), Extern::Convert::REP_UTF8, term_or_string.bytesize, Fiddle::Pointer[term_or_string] case rv when 1; true # all ok when 0 raise "failure parsing term #{term_or_string}, #{Tree.of_term(@term_t).inspect}" else raise "unknown api return value #{rv}" end when Fiddle::Pointer # assume this is a pointer to a term. Unsafe, but there's no choice really @term_t = term_or_string else raise "can't handle #{term_or_string}" end end |
Instance Attribute Details
#term_t ⇒ Object (readonly) Also known as: to_term_t
Returns the value of attribute term_t.
32 33 34 |
# File 'lib/upl/term.rb', line 32 def term_t @term_t end |
Class Method Details
.of_atom(atom) ⇒ Object
35 36 37 38 39 40 |
# File 'lib/upl/term.rb', line 35 def self.of_atom atom term_t = Extern.PL_new_term_ref rv = Extern.PL_put_atom term_t, atom.to_atom rv == 1 or raise "can't set term to atom #{atom}" term_t end |
.predicate(name, *args) ⇒ Object
returns a term
args are things that can be converted to term_t pointers using to_term_t method TODO misnamed. functor means pred_name/n and this is actually :pred_name, arg1, arg2…
47 48 49 50 51 52 53 54 55 56 |
# File 'lib/upl/term.rb', line 47 def self.predicate name, *args # TODO maybe use a frame or something because this allocates quite a few sub-terms rv = Extern.PL_cons_functor_v \ (term_t = Extern.PL_new_term_ref), Extern.PL_new_functor(name.to_sym.to_atom, args.size), TermVector[*args].terms rv == 1 or raise "can't populate functor #{name}" new term_t end |
Instance Method Details
#<=>(rhs) ⇒ Object
77 78 79 |
# File 'lib/upl/term.rb', line 77 def <=> rhs [@atom, @arity] <=> [rhs.atom, rhs.arity] end |
#==(rhs) ⇒ Object
73 74 75 |
# File 'lib/upl/term.rb', line 73 def == rhs @atom == rhs.atom && @arity == rhs.arity && args == rhs.args end |
#[](idx) ⇒ Object
125 126 127 128 129 130 |
# File 'lib/upl/term.rb', line 125 def [](idx) # remember args for terms are 1-based rv = Extern::PL_get_arg idx+1, term_t, (arg = Extern.PL_new_term_ref) rv == 1 or raise "can't access term at #{idx}" Term.new arg end |
#[]=(idx, val_term_t) ⇒ Object
set term_t = val_term_t idx is zero-based, unlike the prolog calls
134 135 136 137 138 |
# File 'lib/upl/term.rb', line 134 def []=( idx, val_term_t) raise IndexError, "max index is #{arity-1}" if idx >= arity rv = Extern.PL_unify_arg idx+1, term_t, val_term_t rv == 1 or raise "can't set index #{idx}" end |
#arity ⇒ Object
88 89 90 91 92 93 |
# File 'lib/upl/term.rb', line 88 def arity @arity or begin populate @arity end end |
#atom ⇒ Object
81 82 83 84 85 86 |
# File 'lib/upl/term.rb', line 81 def atom @atom or begin populate @atom end end |
#deconstruct ⇒ Object
121 122 123 |
# File 'lib/upl/term.rb', line 121 def deconstruct map{|t| Term.new t} end |
#each ⇒ Object
106 107 108 109 110 111 112 113 114 |
# File 'lib/upl/term.rb', line 106 def each return enum_for :args unless block_given? (1..arity).each do |idx| rv = Extern::PL_get_arg idx, term_t, (subterm = Extern.PL_new_term_ref) rv == 1 or raise "#{rv}: can't convert #{i} arg of #{atom}" yield subterm end end |
#first ⇒ Object
118 |
# File 'lib/upl/term.rb', line 118 def first; self[0] end |
#last ⇒ Object
119 |
# File 'lib/upl/term.rb', line 119 def last; self[arity-1] end |
#populate ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/upl/term.rb', line 58 def populate rv = Extern::PL_get_name_arity \ term_t, (atom_ptr = Fiddle::Pointer[0].ref), (int_ptr = Fiddle::Pointer[0].ref) # This happens when the term_t is not a PL_TERM (ie a compound) rv == 1 or raise "can't populate term" @arity = int_ptr.ptr.to_i @atom = Atom.new atom_ptr.ptr self end |
#pretty_print(pp) ⇒ Object
140 141 142 143 144 145 |
# File 'lib/upl/term.rb', line 140 def pretty_print(pp) # to_ruby.pretty_print pp pp.text atom.to_s pp.text ?/ pp.text arity.to_s end |
#to_functor ⇒ Object
95 96 97 |
# File 'lib/upl/term.rb', line 95 def to_functor Extern::PL_new_functor atom.atom_t, arity end |
#to_predicate ⇒ Object
99 100 101 |
# File 'lib/upl/term.rb', line 99 def to_predicate Extern::PL_pred to_functor, Fiddle::NULL end |
#tree ⇒ Object Also known as: to_ruby
103 |
# File 'lib/upl/term.rb', line 103 def tree; @tree || (Tree.of_term term_t) end |