Merge changes Icaf1ef7f,I979c222a,I9e05ee0b,I798a4707,I7732f3ec
* changes:
Add options to PrologMain to emulate usage in Gerrit
Cleanup formatting of PrologMain
Correct usage for cafeteria java_binary()
Remove version from PrologMain header
Add missing fake_pom_deploy.xml required by buck build deploy
diff --git a/fake_pom_deploy.xml b/fake_pom_deploy.xml
new file mode 100644
index 0000000..dec372e
--- /dev/null
+++ b/fake_pom_deploy.xml
@@ -0,0 +1,21 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>com.googlecode.prolog-cafe</groupId>
+ <artifactId>prolog-cafe</artifactId>
+ <version>1</version> <!-- Do not edit; see BUCK. -->
+ <build>
+ <extensions>
+ <extension>
+ <groupId>com.googlesource.gerrit</groupId>
+ <artifactId>gs-maven-wagon</artifactId>
+ <version>3.3</version>
+ </extension>
+ </extensions>
+ </build>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>gerrit-maven-repository</id>
+ <url>https://gerrit-maven.storage.googleapis.com/</url>
+ </pluginRepository>
+ </pluginRepositories>
+</project>
diff --git a/src/repl/PrologMain.java b/src/repl/PrologMain.java
index 95952b6..6e4b004 100644
--- a/src/repl/PrologMain.java
+++ b/src/repl/PrologMain.java
@@ -1,106 +1,154 @@
package com.googlecode.prolog_cafe.repl;
+
import com.googlecode.prolog_cafe.exceptions.HaltException;
+import com.googlecode.prolog_cafe.lang.JavaObjectTerm;
import com.googlecode.prolog_cafe.lang.ListTerm;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.StructureTerm;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
-import java.util.EnumSet;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.PrintStream;
+import java.io.PushbackReader;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
import java.util.StringTokenizer;
-/**
- * Prolog Cafe launcher.
- * The <code>PrologMain</code> class launchs the Prolog Cafe system.<br>
- * The usage is as follows, where
- * <code>package</code> is a package name, and
- * <code>predicate</code> is a predicate name (only atom).
- * <pre>
- * % java -cp $PLCAFEDIR/plcafe.jar com.googlecode.prolog_cafe.lang.PrologMain package:predicate
- * % java -cp $PLCAFEDIR/plcafe.jar com.googlecode.prolog_cafe.lang.PrologMain predicate
- * </pre>
- * Let us show a sample session for launching a small Prolog interpreter:
- * <code>com.googlecode.prolog_cafe.builtin:cafeteria/0</code>.<br>
- * <pre>
- * % java -cp $PLCAFEDIR/plcafe.jar:$CLASSPATH com.googlecode.prolog_cafe.lang.PrologMain com.googlecode.prolog_cafe.builtin:cafeteria
- * Prolog Cafe X.X.X (YYY)
- * Copyright(C) 1997-200X M.Banbara and N.Tamura
- * | ?-
- * </pre>
- *
- * @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
- * @author Naoyuki Tamura (tamura@kobe-u.ac.jp)
- * @version 1.0
- */
+
+/** Launches the meta-interpreter from the command line. */
public class PrologMain {
- /** Version information */
- public static final String VERSION = "Prolog Cafe 1.2.5 (mantis)";
- /** Copyright information */
- public static final String COPYRIGHT = "Copyright(C) 1997-2009 M.Banbara and N.Tamura";
+ private static final String COPYRIGHT = "Copyright(C) 1997-2009 M.Banbara and N.Tamura";
+ private static final String HEADER = "Prolog Cafe (" + COPYRIGHT + ")";
- public static void main(String argv[]) {
- BlockingPrologControl p;
- try {
- System.err.println("\n" + VERSION);
- System.err.println(COPYRIGHT);
- if (argv.length != 1) {
- usage();
- System.exit(999);
- }
- Term arg1 = Prolog.Nil;
- arg1 = new ListTerm(SymbolTerm.intern("user"), arg1);
- arg1 = new ListTerm(SymbolTerm.intern(Prolog.BUILTIN), arg1);
- Term arg2 = parseAtomicGoal(argv[0]);
- if (arg2 == null) {
- usage();
- System.exit(1);
- }
+ public static void main(String argv[]) {
+ try {
+ System.err.println(HEADER);
- p = new BlockingPrologControl();
- p.setEnabled(EnumSet.allOf(Prolog.Feature.class), true);
- p.configureUserIO(System.in, System.out, System.err);
- p.setPredicate(Prolog.BUILTIN, "initialization", arg1, arg2);
- for (boolean r = p.call(); r; r = p.redo()) {}
- System.exit(0);
- } catch (HaltException e) {
- System.exit(e.getStatus());
- } catch (Exception e){
- e.printStackTrace();
- System.exit(1);
- }
+ BlockingPrologControl p = new BlockingPrologControl();
+ p.configureUserIO(System.in, System.out, System.err);
+ p.setMaxDatabaseSize(256);
+
+ List<File> toLoad = new ArrayList<>(4);
+ long reductionLimit = Long.MAX_VALUE;
+ Term goal = null;
+ for (int i = 0; i < argv.length; i++) {
+ String arg = argv[i];
+ if (arg.equals("--enable-io")) {
+ p.setEnabled(Prolog.Feature.IO, true);
+ } else if (arg.equals("--enable-statistics")) {
+ p.setEnabled(Prolog.Feature.STATISTICS, true);
+ } else if (arg.startsWith("--max-database-size=")) {
+ String v = arg.substring(arg.indexOf('=') + 1);
+ p.setMaxDatabaseSize(Integer.parseInt(v, 10));
+ } else if (arg.startsWith("--reduction-limit=")) {
+ String v = arg.substring(arg.indexOf('=') + 1);
+ reductionLimit = Long.parseLong(v, 10);
+ } else if (arg.equals("-f") && i + 1 < argv.length) {
+ toLoad.add(new File(argv[++i]));
+ } else if (arg.startsWith("-")) {
+ usage();
+ System.exit(1);
+ } else if (i == argv.length - 1) {
+ goal = parseAtomicGoal(arg);
+ } else {
+ usage();
+ System.exit(1);
+ }
+ }
+
+ initializePackages(p, goal);
+ for (File file : toLoad) {
+ try (FileReader src = new FileReader(file);
+ BufferedReader buf = new BufferedReader(src);
+ PushbackReader in = new PushbackReader(buf, Prolog.PUSHBACK_SIZE)) {
+ Term path = SymbolTerm.create(file.getPath());
+ if (!p.execute(Prolog.BUILTIN, "consult_stream",
+ path, new JavaObjectTerm(in))) {
+ System.err.println();
+ System.err.flush();
+ System.exit(1);
+ }
+ }
+ System.err.println();
+ System.err.flush();
+ }
+
+ if (goal == null) {
+ System.err.println();
+ System.err.flush();
+ goal = new StructureTerm(SymbolTerm.intern(":", 2), new Term[]{
+ SymbolTerm.intern(Prolog.BUILTIN),
+ SymbolTerm.create("cafeteria")});
+ }
+
+ p.setReductionLimit(reductionLimit);
+ p.execute(Prolog.BUILTIN, "call", goal);
+ } catch (HaltException e) {
+ System.exit(e.getStatus());
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ /**
+ * Returns a term for given string representation of atom goal, or
+ * <code>null</code> if parsing fails.
+ *
+ * @param s a string representation of initial goal (ex. foge:main).
+ * @return a term which corresponds to a given string, or <code>null</code> if
+ * parsing fails.
+ */
+ private static Term parseAtomicGoal(String s) {
+ StringTokenizer st = new StringTokenizer(s, ":");
+ int i = st.countTokens();
+ if (i == 1) {
+ Term[] args = {
+ SymbolTerm.intern("user"),
+ SymbolTerm.create(st.nextToken())};
+ return new StructureTerm(SymbolTerm.intern(":", 2), args);
+ } else if (i == 2) {
+ Term[] args = {
+ SymbolTerm.create(st.nextToken()),
+ SymbolTerm.create(st.nextToken())};
+ return new StructureTerm(SymbolTerm.intern(":", 2), args);
+ } else {
+ return null;
+ }
+ }
+
+ private static void initializePackages(BlockingPrologControl p, Term goal) {
+ LinkedHashSet<String> set = new LinkedHashSet<>(3);
+ set.add(Prolog.BUILTIN);
+ set.add("user");
+ if (goal != null) {
+ set.add(goal.arg(1).name());
}
- /** Returns a term for given string representation of atom goal, or
- * <code>null</code> if parsing fails.
- * @param s a string representation of initial goal (ex. foge:main).
- * @return a term which corresponds to a given string,
- * or <code>null</code> if parsing fails.
- */
- protected static Term parseAtomicGoal(String s) {
- StringTokenizer st = new StringTokenizer(s, ":");
- int i = st.countTokens();
- if (i == 1) {
- Term[] args = {SymbolTerm.intern("user"),
- SymbolTerm.create(st.nextToken())};
- return new StructureTerm(SymbolTerm.intern(":", 2), args);
- } else if (i == 2) {
- Term[] args = {SymbolTerm.create(st.nextToken()),
- SymbolTerm.create(st.nextToken())};
- return new StructureTerm(SymbolTerm.intern(":", 2), args);
- } else {
- return null;
- }
+ List<String> list = new ArrayList<>(set);
+ Term done = SymbolTerm.intern("true");
+ Term head = Prolog.Nil;
+ for (int i = list.size() - 1; 0 <= i; i--) {
+ head = new ListTerm(SymbolTerm.intern(list.get(i)), head);
}
+ p.execute(Prolog.BUILTIN, "initialization", head, done);
+ }
- /** Shows usage */
- protected static void usage() {
- String s = "Usage:\n";
- s += "java -cp $PLCAFEDIR/plcafe.jar";
- s += " com.googlecode.prolog_cafe.lang.PrologMain package:predicate\n";
- s += "java -cp $PLCAFEDIR/plcafe.jar";
- s += " com.googlecode.prolog_cafe.lang.PrologMain predicate\n";
- s += " package: package name\n";
- s += " predicate: predicate name (only atom)";
- System.out.println(s);
- }
+ private static void usage() {
+ PrintStream e = System.err;
+ e.println("usage: java -jar cafeteria.jar [options] [goal]");
+ e.println();
+ e.println(" --enable-io : enable file system access");
+ e.println(" --enable-statistics : enable statistics/2");
+ e.println(" --max-database-size=N : maximum entries in dynamic database");
+ e.println(" --reduction-limit=N : max reductions during execution");
+ e.println();
+ e.println(" -f source.pl : load file.pl (may be repeated)");
+ e.println();
+ e.println(" goal : predicate or package:predicate");
+ e.println(" (if not specified, runs interactive loop)");
+ }
}
-