1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package io.github.prolobjectlink.prolog.tuprolog;
23
24 import static io.github.prolobjectlink.prolog.PrologTermType.ATOM_TYPE;
25 import static io.github.prolobjectlink.prolog.PrologTermType.CLASS_TYPE;
26 import static io.github.prolobjectlink.prolog.PrologTermType.CUT_TYPE;
27 import static io.github.prolobjectlink.prolog.PrologTermType.DOUBLE_TYPE;
28 import static io.github.prolobjectlink.prolog.PrologTermType.FAIL_TYPE;
29 import static io.github.prolobjectlink.prolog.PrologTermType.FALSE_TYPE;
30 import static io.github.prolobjectlink.prolog.PrologTermType.FIELD_TYPE;
31 import static io.github.prolobjectlink.prolog.PrologTermType.FLOAT_TYPE;
32 import static io.github.prolobjectlink.prolog.PrologTermType.INTEGER_TYPE;
33 import static io.github.prolobjectlink.prolog.PrologTermType.LIST_TYPE;
34 import static io.github.prolobjectlink.prolog.PrologTermType.LONG_TYPE;
35 import static io.github.prolobjectlink.prolog.PrologTermType.MAP_ENTRY_TYPE;
36 import static io.github.prolobjectlink.prolog.PrologTermType.MAP_TYPE;
37 import static io.github.prolobjectlink.prolog.PrologTermType.MIXIN_TYPE;
38 import static io.github.prolobjectlink.prolog.PrologTermType.NIL_TYPE;
39 import static io.github.prolobjectlink.prolog.PrologTermType.OBJECT_TYPE;
40 import static io.github.prolobjectlink.prolog.PrologTermType.PARAMETER_TYPE;
41 import static io.github.prolobjectlink.prolog.PrologTermType.RESULT_TYPE;
42 import static io.github.prolobjectlink.prolog.PrologTermType.STRUCTURE_TYPE;
43 import static io.github.prolobjectlink.prolog.PrologTermType.TRUE_TYPE;
44 import static io.github.prolobjectlink.prolog.PrologTermType.VARIABLE_TYPE;
45
46 import java.util.Iterator;
47
48 import alice.tuprolog.Double;
49 import alice.tuprolog.Float;
50 import alice.tuprolog.Int;
51 import alice.tuprolog.Long;
52 import alice.tuprolog.Struct;
53 import alice.tuprolog.Term;
54 import alice.tuprolog.Var;
55 import io.github.prolobjectlink.prolog.AbstractConverter;
56 import io.github.prolobjectlink.prolog.PrologAtom;
57 import io.github.prolobjectlink.prolog.PrologConverter;
58 import io.github.prolobjectlink.prolog.PrologDouble;
59 import io.github.prolobjectlink.prolog.PrologFloat;
60 import io.github.prolobjectlink.prolog.PrologInteger;
61 import io.github.prolobjectlink.prolog.PrologLong;
62 import io.github.prolobjectlink.prolog.PrologProvider;
63 import io.github.prolobjectlink.prolog.PrologTerm;
64 import io.github.prolobjectlink.prolog.PrologVariable;
65 import io.github.prolobjectlink.prolog.UnknownTermError;
66
67
68
69
70
71
72 final class TuPrologConverter extends AbstractConverter<Term> implements PrologConverter<Term> {
73
74 private static final TuPrologOperatorSet OPERATORS = new TuPrologOperatorSet();
75
76 public PrologTerm toTerm(Term prologTerm) {
77 if (prologTerm.equals(Term.TRUE)) {
78 return new TuPrologTrue(provider);
79 } else if (prologTerm.equals(Term.FALSE)) {
80 return new TuPrologFalse(provider);
81 } else if (prologTerm instanceof Float) {
82 return new TuPrologFloat(provider, ((Float) prologTerm).floatValue());
83 } else if (prologTerm instanceof Int) {
84 return new TuPrologInteger(provider, ((Int) prologTerm).intValue());
85 } else if (prologTerm instanceof Double) {
86 return new TuPrologDouble(provider, ((Double) prologTerm).doubleValue());
87 } else if (prologTerm instanceof Long) {
88 return new TuPrologLong(provider, ((Long) prologTerm).longValue());
89 } else if (prologTerm instanceof Var) {
90 String name = ((Var) prologTerm).getName();
91 PrologVariable variable = sharedVariables.get(name);
92 if (variable == null) {
93 variable = new TuPrologVariable(provider, name);
94 sharedVariables.put(variable.getName(), variable);
95 }
96 return variable;
97 } else if (prologTerm instanceof Struct) {
98
99 Struct struct = (Struct) prologTerm;
100 int arity = struct.getArity();
101 String functor = struct.getName();
102 Term[] arguments = new Term[arity];
103
104 if (struct.isEmptyList()) {
105 return new TuPrologEmpty(provider);
106 }
107
108
109 else if (prologTerm.isAtom()) {
110 if (functor.equals("nil")) {
111 return new TuPrologNil(provider);
112 } else if (functor.equals("!")) {
113 return new TuPrologCut(provider);
114 } else if (functor.equals("fail")) {
115 return new TuPrologFail(provider);
116 } else {
117 return new TuPrologAtom(provider, functor);
118 }
119 }
120
121
122 else if (struct.isList()) {
123 int index = 0;
124 arguments = new Term[struct.listSize()];
125 Iterator<? extends Term> i = struct.listIterator();
126 while (i.hasNext()) {
127 Term term = i.next();
128 arguments[index++] = term;
129 }
130 return new TuPrologList(provider, arguments);
131 }
132
133
134 else if (arity == 2 && OPERATORS.currentOp(functor)) {
135 Term left = struct.getArg(0);
136 Term right = struct.getArg(1);
137 return new TuPrologStructure(provider, left, functor, right);
138 }
139
140
141 else {
142 for (int i = 0; i < arity; i++) {
143 arguments[i] = struct.getArg(i);
144 }
145 return new TuPrologStructure(provider, functor, arguments);
146 }
147
148 } else {
149 throw new UnknownTermError(prologTerm);
150 }
151 }
152
153 public Term fromTerm(PrologTerm term) {
154 switch (term.getType()) {
155 case NIL_TYPE:
156 return new Struct("nil");
157 case CUT_TYPE:
158 return new Struct("!");
159 case FAIL_TYPE:
160 return new Struct("fail");
161 case TRUE_TYPE:
162 return Term.TRUE;
163 case FALSE_TYPE:
164 return Term.FALSE;
165 case ATOM_TYPE:
166 return new Struct(removeQuoted(((PrologAtom) term).getStringValue()));
167 case FLOAT_TYPE:
168 return new Float(((PrologFloat) term).getFloatValue());
169 case INTEGER_TYPE:
170 return new Int(((PrologInteger) term).getIntegerValue());
171 case DOUBLE_TYPE:
172 return new Double(((PrologDouble) term).getDoubleValue());
173 case LONG_TYPE:
174 return new Long(((PrologLong) term).getLongValue());
175 case VARIABLE_TYPE:
176 String name = ((PrologVariable) term).getName();
177 Term variable = sharedPrologVariables.get(name);
178 if (variable == null) {
179 variable = new Var(name);
180 sharedPrologVariables.put(name, variable);
181 }
182 return variable;
183 case MAP_TYPE:
184 case LIST_TYPE:
185 return new Struct(fromTermArray(term.getArguments()));
186 case STRUCTURE_TYPE:
187 case MAP_ENTRY_TYPE:
188 String functor = term.getFunctor();
189 Term[] arguments = fromTermArray(term.getArguments());
190 return new Struct(functor, arguments);
191 case OBJECT_TYPE:
192 return TuPrologReference.set(term.getObject());
193 case PARAMETER_TYPE:
194 case RESULT_TYPE:
195 case FIELD_TYPE:
196 name = ((PrologVariable) term).getName();
197 return new Var(name);
198 case MIXIN_TYPE:
199 case CLASS_TYPE:
200 functor = removeQuoted(term.getFunctor());
201 arguments = fromTermArray(term.getArguments());
202 return new Struct(functor, arguments);
203 default:
204 throw new UnknownTermError(term);
205 }
206 }
207
208 public Term[] fromTermArray(PrologTerm[] terms) {
209 Term[] prologTerms = new Term[terms.length];
210 for (int i = 0; i < terms.length; i++) {
211 prologTerms[i] = fromTerm(terms[i]);
212 }
213 return prologTerms;
214 }
215
216 public Term fromTerm(PrologTerm head, PrologTerm[] body) {
217 Term clauseHead = fromTerm(head);
218 if (body != null && body.length > 0) {
219 Term clauseBody = fromTerm(body[body.length - 1]);
220 for (int i = body.length - 2; i >= 0; --i) {
221 clauseBody = new Struct(",", new Term[] { fromTerm(body[i]), clauseBody });
222 }
223 return new Struct(":-", clauseHead, clauseBody);
224 }
225 return clauseHead;
226 }
227
228 public PrologProvider createProvider() {
229 return new TuProlog(this);
230 }
231
232 @Override
233 public String toString() {
234 return "TuPrologConverter";
235 }
236
237 }