prolog-shell: Simple command line Prolog interpreter

Since Prolog isn't the most popular language, define a small
interactive interpreter that users or site administartors can play
around with by downloading the Gerrit WAR file and executing:

  java -jar gerrit.war prolog-shell

Change-Id: I0474b59e6ace24e6e6bfda58f574add3b2bf79e0
This commit is contained in:
Shawn O. Pearce 2011-06-21 14:14:34 -07:00
parent c1806f2a2e
commit 5e0071169a
4 changed files with 164 additions and 1 deletions

View File

@ -18,6 +18,9 @@ link:pgm-daemon.html[daemon]::
link:pgm-gsql.html[gsql]::
Administrative interface to idle database.
link:pgm-prolog-shell.html[prolog-shell]::
Simple interactive Prolog interpreter.
link:pgm-rulec.html[rulec]::
Compile project-specific Prolog rules to JARs.

View File

@ -0,0 +1,57 @@
prolog-shell
============
NAME
----
prolog-shell - Simple interactive Prolog interpreter
SYNOPSIS
--------
[verse]
'java' -jar gerrit.war 'prolog-shell' [-s FILE.pl ...]
DESCRIPTION
-----------
Provides a simple interactive Prolog interpreter for development
and testing.
OPTIONS
-------
-s::
Dynamically load the Prolog source code at startup,
as though the user had entered `['FILE.pl'].` into
the interepter once it was running. This option may
be supplied more than once to load multiple files.
EXAMPLES
--------
Define a simple predicate and test it:
====
$ cat >simple.pl
food(apple).
food(orange).
^D
$ java -jar gerrit.war prolog-shell -s simple.pl
Gerrit Code Review 2.2.1-84-ge9c3992 - Interactive Prolog Shell
based on Prolog Cafe 1.2.5 (mantis)
Copyright(C) 1997-2009 M.Banbara and N.Tamura
(type Ctrl-D or "halt." to exit, "['path/to/file.pl']." to load a file)
{consulting /usr/local/google/users/sop/gerrit2/gerrit/simple.pl ...}
{/usr/local/google/users/sop/gerrit2/gerrit/simple.pl consulted 99 msec}
| ?- food(Type).
Type = apple ? ;
Type = orange ? ;
no
| ?-
====
GERRIT
------
Part of link:index.html[Gerrit Code Review]

View File

@ -120,7 +120,17 @@ public final class GerritLauncher {
try {
String cn = name;
if (cn.equals(cn.toLowerCase())) {
cn = cn.substring(0, 1).toUpperCase() + cn.substring(1);
StringBuilder buf = new StringBuilder();
buf.append(Character.toUpperCase(cn.charAt(0)));
for (int i = 1; i < cn.length(); i++) {
if (cn.charAt(i) == '-' && i + 1 < cn.length()) {
i++;
buf.append(Character.toUpperCase(cn.charAt(i)));
} else {
buf.append(cn.charAt(i));
}
}
cn = buf.toString();
}
clazz = Class.forName(pkg + "." + cn, true, loader);
} catch (ClassNotFoundException cnfe) {

View File

@ -0,0 +1,93 @@
// Copyright (C) 2011 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.pgm;
import com.google.gerrit.pgm.util.AbstractProgram;
import com.googlecode.prolog_cafe.lang.BufferingPrologControl;
import com.googlecode.prolog_cafe.lang.HaltException;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.PrologClassLoader;
import com.googlecode.prolog_cafe.lang.PrologMain;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import org.kohsuke.args4j.Option;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
public class PrologShell extends AbstractProgram {
@Option(name = "-s", multiValued = true, metaVar = "FILE.pl", usage = "file to load")
private List<String> fileName = new ArrayList<String>();
@Override
public int run() {
banner();
BufferingPrologControl pcl = new BufferingPrologControl();
pcl.setPrologClassLoader(new PrologClassLoader(getClass().getClassLoader()));
pcl.setEnabled(EnumSet.allOf(Prolog.Feature.class), false);
pcl.setEnabled(Prolog.Feature.IO, true);
pcl.setEnabled(Prolog.Feature.STATISTICS_RUNTIME, true);
pcl.initialize(Prolog.BUILTIN);
pcl.execute(Prolog.BUILTIN, "set_prolog_flag",
SymbolTerm.intern("print_stack_trace"),
SymbolTerm.intern("on"));
for (String file : fileName) {
String path;
try {
path = new File(file).getCanonicalPath();
} catch (IOException e) {
path = new File(file).getAbsolutePath();
}
pcl.execute(Prolog.BUILTIN, "consult", SymbolTerm.create(path));
System.err.println();
System.err.flush();
}
try {
pcl.execute(Prolog.BUILTIN, "cafeteria");
write("% halt\n");
return 0;
} catch (HaltException halt) {
write("% halt(" + halt.getStatus() + ")\n");
return halt.getStatus();
}
}
private void banner() {
System.err.format("Gerrit Code Review %s - Interactive Prolog Shell",
com.google.gerrit.common.Version.getVersion());
System.err.println();
System.err.println("based on " + PrologMain.VERSION);
System.err.println(" " + PrologMain.COPYRIGHT);
System.err.println("(type Ctrl-D or \"halt.\" to exit,"
+ " \"['path/to/file.pl'].\" to load a file)");
System.err.println();
System.err.flush();
}
private void write(String msg) {
System.out.flush();
System.err.flush();
System.out.println(msg);
System.out.flush();
}
}