View Javadoc

1   /*
2    * #%L
3    * prolobjectlink-jpi-jpl
4    * %%
5    * Copyright (C) 2019 Prolobjectlink Project
6    * %%
7    * This program is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU Lesser General Public License as
9    * published by the Free Software Foundation, either version 2.1 of the
10   * License, or (at your option) any later version.
11   * 
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Lesser Public License for more details.
16   * 
17   * You should have received a copy of the GNU General Lesser Public
18   * License along with this program.  If not, see
19   * <http://www.gnu.org/licenses/lgpl-2.1.html>.
20   * #L%
21   */
22  package io.github.prolobjectlink.prolog.jpl;
23  
24  import static io.github.prolobjectlink.prolog.PrologTermType.LIST_TYPE;
25  
26  import java.util.Iterator;
27  import java.util.NoSuchElementException;
28  
29  import io.github.prolobjectlink.prolog.AbstractIterator;
30  import io.github.prolobjectlink.prolog.PrologList;
31  import io.github.prolobjectlink.prolog.PrologProvider;
32  import io.github.prolobjectlink.prolog.PrologTerm;
33  import jpl.Atom;
34  import jpl.Compound;
35  import jpl.Term;
36  
37  /**
38   * 
39   * @author Jose Zalacain
40   * @since 1.0
41   */
42  public class JplList extends JplTerm implements PrologList {
43  
44  	public static final Term EMPTY = new Atom("[]");
45  
46  	protected JplList(PrologProvider provider) {
47  		super(LIST_TYPE, provider, EMPTY);
48  	}
49  
50  	protected JplList(PrologProvider provider, Term[] arguments) {
51  		super(LIST_TYPE, provider);
52  		value = EMPTY;
53  		for (int i = arguments.length - 1; i >= 0; --i) {
54  			value = new Compound(".", new Term[] { arguments[i], value });
55  		}
56  	}
57  
58  	protected JplList(PrologProvider provider, PrologTerm[] arguments) {
59  		super(LIST_TYPE, provider);
60  		value = EMPTY;
61  		for (int i = arguments.length - 1; i >= 0; --i) {
62  			value = new Compound(".", new Term[] { ((JplTerm) arguments[i]).value, value });
63  		}
64  	}
65  
66  	protected JplList(PrologProvider provider, PrologTerm head, PrologTerm tail) {
67  		super(LIST_TYPE, provider);
68  		Term h = ((JplTerm) head).value;
69  		Term t = ((JplTerm) tail).value;
70  		value = new Compound(".", new Term[] { h, t });
71  	}
72  
73  	protected JplList(PrologProvider provider, PrologTerm[] arguments, PrologTerm tail) {
74  		super(LIST_TYPE, provider);
75  		value = fromTerm(tail, Term.class);
76  		for (int i = arguments.length - 1; i >= 0; --i) {
77  			Term[] args = { fromTerm(arguments[i], Term.class), value };
78  			value = new Compound(".", args);
79  		}
80  	}
81  
82  	public int size() {
83  		return ((Compound) value).listLength();
84  	}
85  
86  	public void clear() {
87  		value = EMPTY;
88  	}
89  
90  	public boolean isEmpty() {
91  		return value.equals(EMPTY);
92  	}
93  
94  	public Iterator<PrologTerm> iterator() {
95  		return new SwiPrologListIter(value);
96  	}
97  
98  	public PrologTerm getHead() {
99  		Compound list = (Compound) value;
100 		return provider.toTerm(list.arg(1), PrologTerm.class);
101 	}
102 
103 	public PrologTerm getTail() {
104 		Compound list = (Compound) value;
105 		return provider.toTerm(list.arg(2), PrologTerm.class);
106 	}
107 
108 	public int getArity() {
109 		return value.arity();
110 	}
111 
112 	public String getFunctor() {
113 		return ".";
114 	}
115 
116 	public PrologTerm[] getArguments() {
117 		return toTermArray(value.toTermArray(), PrologTerm[].class);
118 	}
119 
120 	public String toString() {
121 		StringBuilder string = new StringBuilder("[");
122 		Iterator<PrologTerm> i = iterator();
123 		if (i.hasNext()) {
124 			string.append(i.next());
125 		}
126 		while (i.hasNext()) {
127 			string.append(", ");
128 			string.append(i.next());
129 		}
130 		return string.append("]").toString();
131 	}
132 
133 	private class SwiPrologListIter extends AbstractIterator<PrologTerm> implements Iterator<PrologTerm> {
134 
135 		private Term ptr;
136 		private int index;
137 		private int length;
138 
139 		private SwiPrologListIter(Term l) {
140 			ptr = l;
141 			if (l.hasFunctor(".", 2)) {
142 				length = l.listLength();
143 			}
144 		}
145 
146 		public boolean hasNext() {
147 			return index < length;
148 		}
149 
150 		public PrologTerm next() {
151 
152 			if (!hasNext()) {
153 				throw new NoSuchElementException();
154 			}
155 
156 			PrologTerm term = toTerm(ptr.arg(1), PrologTerm.class);
157 			ptr = ptr.arg(2);
158 			index++;
159 			return term;
160 		}
161 
162 	}
163 
164 }