1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package io.github.prolobjectlink.prolog;
27
28 import java.io.BufferedReader;
29 import java.io.IOException;
30 import java.io.Reader;
31 import java.io.StringReader;
32 import java.util.Map;
33 import java.util.Map.Entry;
34
35 import javax.script.AbstractScriptEngine;
36 import javax.script.Bindings;
37 import javax.script.ScriptContext;
38 import javax.script.ScriptEngine;
39 import javax.script.ScriptEngineFactory;
40 import javax.script.ScriptException;
41 import javax.script.SimpleBindings;
42
43
44
45
46
47
48
49 public final class PrologScriptEngine extends AbstractScriptEngine implements ScriptEngine {
50
51 private final PrologEngine prolog;
52 private final ScriptEngineFactory factory;
53
54 PrologScriptEngine(ScriptEngineFactory factory, PrologEngine prolog) {
55 this.factory = factory;
56 this.prolog = prolog;
57 }
58
59 public Bindings createBindings() {
60 return new SimpleBindings();
61 }
62
63 public ScriptEngineFactory getFactory() {
64 return factory;
65 }
66
67 public Object eval(String script, ScriptContext context) throws ScriptException {
68 return eval(script, context.getBindings(ScriptContext.ENGINE_SCOPE));
69 }
70
71 public Object eval(Reader reader, ScriptContext context) throws ScriptException {
72 return eval(reader, context.getBindings(ScriptContext.ENGINE_SCOPE));
73 }
74
75 @Override
76 public Object eval(Reader reader, Bindings bindings) throws ScriptException {
77 BufferedReader bfr = new BufferedReader(reader);
78 StringBuilder script = new StringBuilder();
79 try {
80 String line = bfr.readLine();
81 while (line != null) {
82 script.append(line);
83 script.append("\n");
84 line = bfr.readLine();
85 }
86 } catch (IOException ex) {
87 throw new ScriptException(ex);
88 }
89 return eval("" + script + "", bindings);
90 }
91
92 @Override
93 public Object eval(String script, Bindings bindings) throws ScriptException {
94
95 String code = script;
96
97
98 if (code.startsWith("?-")) {
99
100
101 for (Entry<String, Object> entry : bindings.entrySet()) {
102 code = code.replace(entry.getKey(), "" + entry.getValue() + "");
103 }
104
105 code = code.substring(2).trim();
106
107
108 if (code.endsWith(".")) {
109 code = code.substring(0, code.length() - 1);
110 }
111
112 PrologQuery query = prolog.query(code);
113 if (!query.hasSolution()) {
114 return false;
115 }
116
117
118 Map<String, Object> map = query.oneVariablesResult();
119 for (Entry<String, Object> entry : map.entrySet()) {
120 put(entry.getKey(), entry.getValue());
121 }
122
123 }
124
125
126
127 else {
128 prolog.include(new StringReader(code));
129 }
130
131 return true;
132
133 }
134
135 @Override
136 public Object eval(String string) throws ScriptException {
137 return eval(string, getContext());
138 }
139
140 @Override
141 public Object eval(Reader reader) throws ScriptException {
142 return eval(reader, getContext());
143 }
144
145 public PrologProvider getProvider() {
146 return prolog.getProvider();
147 }
148
149 }