Commit 4c93d2ec authored by Martin Spoto's avatar Martin Spoto
Browse files

Update branch 'ci-test' to latest work

parents de1e8c82 9263c785
Pipeline #10589 passed with stage
in 33 seconds
.vscode/
\ No newline at end of file
.vscode/
# copied from https://github.com/github/gitignore/blob/master/Global/JetBrains.gitignore
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
\ No newline at end of file
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="launcher" />
<module name="language" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
<module name="language" target="1.8" />
<module name="launcher" target="1.8" />
<module name="prolograal" target="1.8" />
<module name="prolograal-parent" target="1.5" />
</bytecodeTargetLevel>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/code" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/code/language" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/code/launcher" charset="UTF-8" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/code/pom.xml" />
</list>
</option>
<option name="ignoredFiles">
<set>
<option value="$PROJECT_DIR$/code/language/pom.xml" />
</set>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" project-jdk-name="GraalVM-19.2.0.1" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/code/language/src/main/language.iml" filepath="$PROJECT_DIR$/code/language/src/main/language.iml" />
<module fileurl="file://$PROJECT_DIR$/code/launcher/launcher.iml" filepath="$PROJECT_DIR$/code/launcher/launcher.iml" />
<module fileurl="file://$PROJECT_DIR$/code/prolograal-parent.iml" filepath="$PROJECT_DIR$/code/prolograal-parent.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="ProloGraalMain" type="Application" factoryName="Application" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="ch.heiafr.prolograal.launcher.ProloGraalMain" />
<module name="launcher" />
<option name="PROGRAM_PARAMETERS" value="&quot;$ProjectFileDir$\code\language\tests\04_clauses.pl&quot;" />
<option name="VM_PARAMETERS" value="-Dtruffle.class.path.append=&quot;$ProjectFileDir$\code\language\target\prolograal-19.2.0.1-SNAPSHOT.jar;$ProjectFileDir$\code\antlr-4.7.1-complete.jar&quot;" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="ch.heiafr.prolograal.launcher.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
<option name="Maven.BeforeRunTask" enabled="true" file="$PROJECT_DIR$/code/language/pom.xml" goal="package" />
</method>
</configuration>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/simplelanguage" vcs="Git" />
</component>
</project>
\ No newline at end of file
......@@ -89,10 +89,5 @@
<artifactId>antlr4-runtime</artifactId>
<version>4.7</version>
</dependency>
<dependency>
<groupId>org.jline</groupId>
<artifactId>jline</artifactId>
<version>3.9.0</version>
</dependency>
</dependencies>
</project>
package ch.heiafr.prolograal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import ch.heiafr.prolograal.builtins.ProloGraalBuiltinNode;
import ch.heiafr.prolograal.nodes.ProloGraalEvalRootNode;
import ch.heiafr.prolograal.parser.ProloGraalParserImpl;
import ch.heiafr.prolograal.runtime.ProloGraalBoolean;
import ch.heiafr.prolograal.runtime.ProloGraalContext;
import ch.heiafr.prolograal.runtime.ProloGraalRuntime;
import ch.heiafr.prolograal.runtime.ProloGraalTerm;
import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.RootCallTarget;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.TruffleLanguage;
import com.oracle.truffle.api.TruffleLanguage.ContextPolicy;
import com.oracle.truffle.api.dsl.NodeFactory;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;
import ch.heiafr.prolograal.builtins.ProloGraalBuiltinNode;
import ch.heiafr.prolograal.nodes.ProloGraalEvalRootNode;
import ch.heiafr.prolograal.parser.ProloGraalParserImpl;
import ch.heiafr.prolograal.runtime.ProloGraalContext;
import ch.heiafr.prolograal.runtime.ProloGraalTerm;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@TruffleLanguage.Registration(id = ProloGraalLanguage.ID, name = "Prolog", defaultMimeType = ProloGraalLanguage.MIME_TYPE, characterMimeTypes = ProloGraalLanguage.MIME_TYPE, contextPolicy = ContextPolicy.SHARED, fileTypeDetectors = ProloGraalFileDetector.class)
public class ProloGraalLanguage extends TruffleLanguage<ProloGraalContext> {
......@@ -31,6 +32,19 @@ public class ProloGraalLanguage extends TruffleLanguage<ProloGraalContext> {
public static final String ID = "pl";
public static final String MIME_TYPE = "application/x-prolog";
public static final boolean DEBUG_MODE = false;
static {
if(DEBUG_MODE) {
System.setOut(new PrintStream(System.out) {
@Override
public void println(String x) {
super.println("(DEBUG) " + x);
}
});
}
}
public ProloGraalLanguage() {
counter++;
}
......@@ -43,13 +57,17 @@ public class ProloGraalLanguage extends TruffleLanguage<ProloGraalContext> {
@Override
protected CallTarget parse(ParsingRequest request) throws Exception {
Source source = request.getSource();
List<ProloGraalTerm> clauses = null;
ProloGraalRuntime result = null;
if (request.getArgumentNames().isEmpty()) {
clauses = ProloGraalParserImpl.parseProloGraal(this, source);
long time = System.currentTimeMillis();
result = ProloGraalParserImpl.parseProloGraal(this, source);
long time2 = System.currentTimeMillis();
if(DEBUG_MODE)
System.out.println("Parsing time : " + (time2-time) + "ms");
}
RootNode eval = new ProloGraalEvalRootNode(this, clauses);
RootNode eval = new ProloGraalEvalRootNode(this, result);
return Truffle.getRuntime().createCallTarget(eval);
}
......@@ -62,18 +80,11 @@ public class ProloGraalLanguage extends TruffleLanguage<ProloGraalContext> {
@Override
protected boolean isObjectOfLanguage(Object object) {
return false;
// FIXME when all types are declared
/*
if (!(object instanceof TruffleObject)) {
return false;
} else if (object instanceof SLBigNumber || object instanceof SLFunction || object instanceof SLNull) {
return true;
} else if (SLContext.isSLObject(object)) {
return true;
} else {
return false;
}*/
}
return object instanceof ProloGraalTerm<?> || object instanceof ProloGraalBoolean;
}
@Override
......@@ -81,11 +92,12 @@ public class ProloGraalLanguage extends TruffleLanguage<ProloGraalContext> {
return toString(value);
}
// FIXME when all types are declared
public static String toString(Object value) {
try {
if (value == null) {
return "ANY";
} else if(value instanceof ProloGraalTerm<?> || value instanceof ProloGraalBoolean) {
return value.toString();
}
InteropLibrary interop = InteropLibrary.getFactory().getUncached(value);
if (interop.isString(value)) {
......
package ch.heiafr.prolograal.builtins;
import ch.heiafr.prolograal.runtime.ProloGraalAtom;
public final class ProloGraalBuiltinAtoms {
public static final ProloGraalAtom EMPTY_LIST = new ProloGraalAtom(null, "[]");
public static final ProloGraalAtom DOT_OPERATOR = new ProloGraalAtom(null, "'.'");
}
\ No newline at end of file
package ch.heiafr.prolograal.exceptions;
import com.oracle.truffle.api.nodes.ControlFlowException;
public class ProloGraalExistenceError extends ControlFlowException {
private static final long serialVersionUID = 0xd4cc78cfb9ef9000L;
}
\ No newline at end of file
package ch.heiafr.prolograal.nodes;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.Frame;
import com.oracle.truffle.api.nodes.Node;
public abstract class ProloGraalClauseNode extends Node {
......
package ch.heiafr.prolograal.nodes;
import java.util.Arrays;
import java.util.List;
import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.TruffleContext;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.TruffleLanguage.ContextReference;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.DirectCallNode;
import com.oracle.truffle.api.nodes.RootNode;
import ch.heiafr.prolograal.ProloGraalLanguage;
import ch.heiafr.prolograal.runtime.ProloGraalContext;
import ch.heiafr.prolograal.runtime.ProloGraalTerm;
import ch.heiafr.prolograal.runtime.ProloGraalRuntime;
public final class ProloGraalEvalRootNode extends RootNode {
private final ProloGraalLanguage language;
private final List<ProloGraalTerm> clauses;
private final ProloGraalRuntime runtime;
@CompilationFinal
private boolean registered;
......@@ -30,13 +24,12 @@ public final class ProloGraalEvalRootNode extends RootNode {
@Child
private DirectCallNode mainCallNode;
public ProloGraalEvalRootNode(ProloGraalLanguage language, List<ProloGraalTerm> clauses) {
public ProloGraalEvalRootNode(ProloGraalLanguage language, ProloGraalRuntime runtime) {
super(null); // internal frame
this.clauses = clauses;
this.runtime = runtime;
this.mainCallNode = null;
this.language = language;
this.reference = language.getContextReference();
System.out.println("ProloGraalEvalRootNode()");
}
@Override
......@@ -56,12 +49,11 @@ public final class ProloGraalEvalRootNode extends RootNode {
@Override
public Object execute(VirtualFrame frame) {
System.out.println("ProloGraalEvalRootNode.execute" + Arrays.toString(frame.getArguments()));
/* Lazy registrations of clauses on first execution. */
if (!registered) {
/* Function registration is a slow-path operation that must not be compiled. */
CompilerDirectives.transferToInterpreterAndInvalidate();
reference.get().registerClauses(clauses);
reference.get().registerRuntime(runtime);
ProloGraalInterpreterNode interpreterNode = new ProloGraalInterpreterNode(language);
ProloGraalResolverNode resolverNode = new ProloGraalResolverNode(language);
......
package ch.heiafr.prolograal.nodes;
import java.io.IOException;
import java.util.List;
import ch.heiafr.prolograal.ProloGraalLanguage;
import ch.heiafr.prolograal.exceptions.ProloGraalExistenceError;
import ch.heiafr.prolograal.parser.ProloGraalParseError;
import ch.heiafr.prolograal.parser.ProloGraalParserImpl;
import ch.heiafr.prolograal.runtime.*;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.source.Source;
import org.jline.reader.LineReader;
import org.jline.reader.LineReaderBuilder;
import org.jline.reader.UserInterruptException;
import org.jline.reader.impl.history.DefaultHistory;
import ch.heiafr.prolograal.ProloGraalLanguage;
import ch.heiafr.prolograal.parser.ProloGraalParseError;
import ch.heiafr.prolograal.parser.ProloGraalParserImpl;
import ch.heiafr.prolograal.runtime.ProloGraalContext;
import ch.heiafr.prolograal.runtime.ProloGraalFailure;
import ch.heiafr.prolograal.runtime.ProloGraalSuccess;
import ch.heiafr.prolograal.runtime.ProloGraalTerm;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;
public class ProloGraalInterpreterNode extends RootNode {
......@@ -34,26 +30,71 @@ public class ProloGraalInterpreterNode extends RootNode {
@Override
public Object execute(VirtualFrame frame) {
LineReader reader = LineReaderBuilder.builder().history(new DefaultHistory()).build();
while(true) {
PrintWriter writer = new PrintWriter(context.getOutput(), true);
BufferedReader reader = new BufferedReader(new InputStreamReader(context.getInput(), StandardCharsets.UTF_8));
while (true) {
try {
String line = reader.readLine("?- ");
writer.print("?- ");
writer.flush();
String line = reader.readLine();
writer.println();
if (line == null) {
break;
}
if (line.equals("exit.")) {
writer.println("Exiting.");
break;
} else if (line.equals("listing.")) {
writer.println(context.getRuntime().getClauses().values());
continue;
} else if (line.startsWith("listing ")) {
String filter = line.split("[ .]")[1];
writer.println(context.getRuntime().getClauses().values().stream().filter(x -> x.get(0).getHead().toString().startsWith(filter)).collect(Collectors.toList()));
continue;
}
Source source = Source.newBuilder("pl", line, null).build();
try {
List<ProloGraalTerm> terms = ProloGraalParserImpl.parseProloGraal(language, source);
if(terms.size() > 0) {
if(terms.get(0).toString().equals("exit")) break;
System.out.println(Truffle.getRuntime().createCallTarget(context.getResolverNode()).call(terms));
ProloGraalRuntime runtime = ProloGraalParserImpl.parseProloGraal(language, source);
if(runtime.getClauses().size() == 1) {
try {
ProloGraalBoolean callResult = (ProloGraalBoolean) Truffle.getRuntime().createCallTarget(context.getResolverNode()).call(runtime);
if(callResult.asBoolean()) {
ProloGraalSuccess success = (ProloGraalSuccess)callResult;
for(ProloGraalVariable variable : success.getVariables().values()) {
if(variable.isBound()) {
ProloGraalTerm<?> root = variable.getRootValue();
String rootStr;
if(root instanceof ProloGraalStructure) {
rootStr = ((ProloGraalStructure) root).toRootString();
} else {
rootStr = root.toString();
}
writer.println(variable.getName() + " = " + rootStr);
}
}
}
writer.println(callResult);
} catch(ProloGraalExistenceError existenceError) {
writer.println("Error : no clause for goal '" + runtime.getFirstClause() + "'");
}
}
} catch(ProloGraalParseError parseError) {
System.err.println(parseError.getMessage());
writer.println(parseError.getMessage());
}
} catch ( IOException ex) {
break;
}
} catch (UserInterruptException ex) {
ex.printStackTrace();
return new ProloGraalFailure();
}
}
try {
reader.close();
} catch(IOException ex) {
// ignored
}
return new ProloGraalSuccess();
......
package ch.heiafr.prolograal.nodes;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeInfo;
......
package ch.heiafr.prolograal.nodes;
import ch.heiafr.prolograal.ProloGraalLanguage;
import ch.heiafr.prolograal.exceptions.ProloGraalExistenceError;
import ch.heiafr.prolograal.runtime.*;
import com.oracle.truffle.api.nodes.Node;
import java.util.*;
public class ProloGraalProofTreeNode extends Node {
private final Map<ProloGraalTerm<?>, List<ProloGraalClause>> clauses;
private final Deque<ProloGraalTerm<?>> goals;
@Children
private ProloGraalProofTreeNode[] branches;
public ProloGraalProofTreeNode(Map<ProloGraalTerm<?>, List<ProloGraalClause>> clauses, Deque<ProloGraalTerm<?>> goals) {
this.clauses = clauses;
this.goals = goals;
}
public ProloGraalBoolean execute() {
if(ProloGraalLanguage.DEBUG_MODE) {
System.out.println("ProofTreeNode : " + goals);
}
if(goals.isEmpty()) { // leaf node
return new ProloGraalSuccess();
}
ProloGraalTerm<?> currentGoal = goals.getFirst();
List<ProloGraalClause> possibleClauses = clauses.get(currentGoal);
if(possibleClauses == null || possibleClauses.isEmpty()) // if no match, throw an error
throw new ProloGraalExistenceError();
List<ProloGraalProofTreeNode> branches = new ArrayList<>();
for(ProloGraalClause possibleClauseOriginal : possibleClauses) {
ProloGraalClause possibleClause = possibleClauseOriginal.copy();
currentGoal.save();
// if the head of the clause is unifiable with the current goal
if(possibleClause.getHead().unify(currentGoal)) {
if (ProloGraalLanguage.DEBUG_MODE) {
System.out.println("Unified " + currentGoal + " with " + possibleClause.getHead());
}
// create a copy of the current goals
Deque<ProloGraalTerm<?>> newGoals = new ArrayDeque<>(goals);
List<ProloGraalTerm<?>> body = possibleClause.getGoals();
// always remove the first goal since it will be replaced
newGoals.pollFirst();
// no need for distinction between facts and regular clauses
for (ProloGraalTerm<?> term : body) {
newGoals.addFirst(term); // add all the new goals
}