Access Control is now enabled for Gitlab Pages so you can now restrict Pages to authorized users only. If needed, make your website publicly available : Navigate to your project's Settings > General > Visibility and select Everyone in pages section.

Commit d30c339a authored by Tony Licata's avatar Tony Licata

Added polyglot_eval/3 builtin, evaluating foreign language code and unifying...

Added polyglot_eval/3 builtin, evaluating foreign language code and unifying with the first term ( polyglot_eval(prologTerm, languageID, foreignCode) ).
Tried to fix no args is operators (like tau/0) but currently not working.
parent 541c7b80
......@@ -34,7 +34,7 @@ public abstract class ProloGraalIsBuiltin extends ProloGraalBuiltinClause {
// create the head of this clause
// since we do not need custom unification, a simple structure is enough
ProloGraalStructure head = new ProloGraalStructure(getVariables());
head.setFunctor(new ProloGraalAtom(getVariables(), "testos"));
head.setFunctor(new ProloGraalAtom(getVariables(), "is"));
// we create and store the variables to access them more easily later in the execute method
arg = new ProloGraalVariable(getVariables(), "_");
......@@ -46,12 +46,6 @@ public abstract class ProloGraalIsBuiltin extends ProloGraalBuiltinClause {
setHead(head);
}
protected ProloGraalBoolean executeFastPath(VirtualFrame frame) {
if(arg.unify(arg2))
return new ProloGraalSuccess(getVariables());
return new ProloGraalFailure();
}
@Specialization
public ProloGraalBoolean returnHead(VirtualFrame frame, ProloGraalBoolean head){
......
package ch.heiafr.prolograal.builtins.predicates;
import ch.heiafr.prolograal.nodes.*;
import ch.heiafr.prolograal.runtime.*;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeInfo;
import com.oracle.truffle.api.nodes.NodeUtil;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Class representing the polyglot_bind/3(term,languageID,code) predicate.
* Evaluate the foreign language code and try to unify the given term with the result.
* @author Licata Tony
* @see ProloGraalBuiltinClause
*/
@NodeInfo(shortName = "ProloGraalPolyglotBindBuiltin")
public abstract class ProloGraalPolyglotEvalBuiltin extends ProloGraalBuiltinClause {
ProloGraalVariable arg; // the variable A in is(A,B). We keep it to use it in the execute method
ProloGraalVariable arg2; // the variable B in is(A,B). We keep it to use it in the execute method
ProloGraalVariable arg3; // the variable B in is(A,B). We keep it to use it in the execute method
public ProloGraalPolyglotEvalBuiltin(Map<ProloGraalVariable,ProloGraalVariable> variables) {
super(variables);
// create the head of this clause
// since we do not need custom unification, a simple structure is enough
ProloGraalStructure head = new ProloGraalStructure(getVariables());
head.setFunctor(new ProloGraalAtom(getVariables(), "polyglot_eval"));
// we create and store the variables to access them more easily later in the execute method
arg = new ProloGraalVariable(getVariables(), "term");
head.addSubterm(arg);
arg2 = new ProloGraalVariable(getVariables(), "languageID");
head.addSubterm(arg2);
arg3 = new ProloGraalVariable(getVariables(), "code");
head.addSubterm(arg3);
setHead(head);
}
@Specialization
public ProloGraalBoolean returnHead(VirtualFrame frame, ProloGraalBoolean head){
return head;
}
// override the default copy so we do not lose the built-in status
@Override
public ProloGraalClause copy() {
List<Node> childrens = NodeUtil.findNodeChildren(this);
ProloGraalTerm head = ((ProloGraalBuiltinHeadNode)childrens.get(0)).getValue();
Map<ProloGraalVariable, ProloGraalVariable> newVars = new HashMap<>();
ProloGraalTerm copiedHead = head.copy(newVars);
List<ProloGraalTerm<?>> headArgs = copiedHead.asStructure().getArguments();
return ProloGraalPolyglotEvalBuiltinNodeGen.create(newVars, ProloGraalPolyglotEvalHeadNodeGen.create(copiedHead,new ProloGraalSimpleTermNode(headArgs.get(0)),new ProloGraalSimpleTermNode(headArgs.get(1)),new ProloGraalSimpleTermNode(headArgs.get(2))));
}
// override getHead method to handle AST node head
@Override
public ProloGraalTerm<?> getHead(){
return ((ProloGraalPolyglotEvalHeadNode)NodeUtil.findNodeChildren(this).get(0)).getValue();
}
}
......@@ -19,15 +19,28 @@ public abstract class ProloGraalIsOpTermNode extends ProloGraalTermNode {
public ProloGraalIsOpTermNode(ProloGraalTerm<?> value) {
super(value);
operation = ProloGraalIsBuiltin.getOperations().get(value.asStructure().getFunctor());
ProloGraalAtom functor;
if(value.isStructure() || value.isAtom()){
if(value.isAtom()){
functor = value.asAtom();
String atomName = functor.getName();
if(atomName.equals("pi") || atomName.equals("e") || atomName.equals("tau")){
operation = ProloGraalIsBuiltin.getOperations().get(functor);
}else{
operation = null;
}
}else{ // since surrounding if check if it's an atom or a struct, we are sure the value is a struct
functor = value.asStructure().getFunctor();
operation = ProloGraalIsBuiltin.getOperations().get(functor);
}
}else{
operation = null;
}
}
/*
@Override
public ProloGraalNumber executeTerm(VirtualFrame frame) {
return null;
}*/
public Function<List<ProloGraalNumber>,ProloGraalNumber> getOperation(){
return operation;
}
@Specialization
public ProloGraalNumber computeNoArgs(VirtualFrame frame, ProloGraalAtom left, ProloGraalAtom right){
......
package ch.heiafr.prolograal.nodes;
import ch.heiafr.prolograal.builtins.predicates.ProloGraalIsBuiltin;
import ch.heiafr.prolograal.runtime.*;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeInfo;
import com.oracle.truffle.api.nodes.NodeUtil;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@NodeInfo(shortName = "ProloGraalPolyglotEvalHeadNode")
public abstract class ProloGraalPolyglotEvalHeadNode extends ProloGraalTernaryHeadNode {
public ProloGraalPolyglotEvalHeadNode(ProloGraalTerm<?> value) {
super(value);
}
@Specialization(guards = {"center.isAtom()","right.isAtom()"})
@CompilerDirectives.TruffleBoundary
public ProloGraalBoolean returnValue(ProloGraalTerm left, ProloGraalTerm center, ProloGraalTerm right) {
Context context;
context = Context.newBuilder(center.asAtom().getName()).build();
Value res = context.eval(center.asAtom().getName(),right.asAtom().getName());
ProloGraalTerm resAsTerm = genericValueToProloGraalTerm(res);
if(resAsTerm != null && left.unify(resAsTerm)){
return new ProloGraalSuccess();
}
System.out.println(res+" can not be casted into ProloGraalTerm (from ProloGraalPolyglotEvalHeadNode)");
System.out.println("or "+res+" and "+left+" can not be unified");
return new ProloGraalFailure();
}
@Specialization
public ProloGraalBoolean wrongParams(ProloGraalTerm left, ProloGraalTerm center, ProloGraalTerm right) {
System.out.println(center+" and "+right+" have to be atoms (2nd = languageID, 3rd = codeToEval)");
return new ProloGraalFailure();
}
private ProloGraalTerm genericValueToProloGraalTerm(Value value){
ProloGraalTerm res = null;
if(value.isBoolean()){
res = value.asBoolean()?new ProloGraalAtom(new HashMap<>(),"true"):new ProloGraalAtom(new HashMap<>(),"false");
}else if(value.isNumber()){
if(value.asDouble() % 1 == 0 && value.fitsInInt()){
res = new ProloGraalIntegerNumber(new HashMap<>(), value.asInt());
}else{
res = new ProloGraalDoubleNumber(new HashMap<>(), value.asDouble());
}
}else if(value.isString()){
res = new ProloGraalAtom(new HashMap<>(), value.asString());
}
return res;
}
@Override
public ProloGraalBuiltinHeadNode copyBuiltin(Map<ProloGraalVariable, ProloGraalVariable> variables){
List<Node> childrens = NodeUtil.findNodeChildren(this);
ProloGraalTermNode left = (ProloGraalTermNode) childrens.get(0);
ProloGraalTermNode center = (ProloGraalTermNode) childrens.get(1);
ProloGraalTermNode right = (ProloGraalTermNode) childrens.get(2);
return ProloGraalPolyglotEvalHeadNodeGen.create(value.copy(variables), left.copyTermNode(variables), center.copyTermNode(variables), right.copyTermNode(variables));
}
}
package ch.heiafr.prolograal.nodes;
import ch.heiafr.prolograal.runtime.ProloGraalTerm;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.nodes.NodeInfo;
@NodeInfo(shortName = "ProloGraalBinaryHeadNode")
@NodeChild(value = "left", type = ProloGraalTermNode.class)
@NodeChild(value = "center", type = ProloGraalTermNode.class)
@NodeChild(value = "right", type = ProloGraalTermNode.class)
public abstract class ProloGraalTernaryHeadNode extends ProloGraalBuiltinHeadNode {
public ProloGraalTernaryHeadNode(ProloGraalTerm<?> value) {
super(value);
}
}
......@@ -178,6 +178,13 @@ public class ProloGraalListenerImpl extends ProloGraalBaseListener {
elements.push(atom);
}
@Override
public void exitAtom(ProloGraalParser.AtomContext ctx) {
// if the atom represent a builtin clause, it will be built as it, else, the atom won't change.
//System.out.println(elements.peek());
//buildBuiltin(elements.peek());
}
@Override
public void enterNumber(ProloGraalParser.NumberContext ctx) {
// create a number according to its type (Integer or Double) and push it to the element stack
......@@ -240,19 +247,25 @@ public class ProloGraalListenerImpl extends ProloGraalBaseListener {
for (int i = subterms.size() - 1; i >= 0; i--) {
struct.addSubterm(subterms.get(i));
}
// if the struct is a builtin, it will be built by buildBuiltin, else, the structure won't be changed.
buildBuiltin(struct);
// no need to do anything else since it was already in the element stack (we do not remove it here)
}
private boolean buildBuiltin(ProloGraalTerm term){
// check if the current structure is a builtin, and initialize it as a builtin if it is one
ProloGraalAtom functor = term instanceof ProloGraalStructure?((ProloGraalStructure)term).getFunctor():(ProloGraalAtom)term;
ProloGraalStructure builtinStructure = null;
if(ProloGraalBuiltinStructure.getBuiltinsInitializers().containsKey(struct.getFunctor().getName())){
builtinStructure = ProloGraalBuiltinStructure.getBuiltinsInitializers().get(struct.getFunctor().getName()).apply(struct);
}else if(ProloGraalIsBuiltin.getOperations().containsKey(struct.getFunctor())){ //if the structure is an is/2 operator (by functor name), build it
builtinStructure = ProloGraalBuiltinStructure.getBuiltinsInitializers().get("isOp").apply(struct);
if(ProloGraalBuiltinStructure.getBuiltinsInitializers().containsKey(functor.getName())){
builtinStructure = ProloGraalBuiltinStructure.getBuiltinsInitializers().get(functor.getName()).apply(term);
}else if(ProloGraalIsBuiltin.getOperations().containsKey(functor)){ //if the structure is an is/2 operator (by functor name), build it
builtinStructure = ProloGraalBuiltinStructure.getBuiltinsInitializers().get("isOp").apply(term);
}
if(builtinStructure != null){
elements.pop();
elements.push(builtinStructure);
}
// no need to do anything else since it was already in the element stack (we do not remove it here)
return builtinStructure != null;
}
@Override
......
package ch.heiafr.prolograal.runtime;
import ch.heiafr.prolograal.builtins.predicates.ProloGraalBuiltinClause;
import ch.heiafr.prolograal.nodes.*;
import java.util.HashMap;
......@@ -45,6 +44,7 @@ public class ProloGraalBuiltinStructure extends ProloGraalStructure{
private static Map<String, Function<ProloGraalTerm, ProloGraalStructure>> fillBuiltinsInitializers(){
Map<String, Function<ProloGraalTerm, ProloGraalStructure>> initializers = new HashMap<>();
initializers.put("is", ProloGraalBuiltinStructure::initializeIs);
initializers.put("polyglot_eval", ProloGraalBuiltinStructure::initializePolyglotEval);
initializers.put("isOp", ProloGraalBuiltinStructure::initializeIsOp);
return initializers;
}
......@@ -57,14 +57,28 @@ public class ProloGraalBuiltinStructure extends ProloGraalStructure{
return new ProloGraalBuiltinStructure(isTerm.asStructure(),isBuiltinHead);
}
public static ProloGraalBuiltinStructure initializePolyglotEval(ProloGraalTerm polyglotEvalTerm){
if( !(polyglotEvalTerm.isStructure() && polyglotEvalTerm.asStructure().getArity() == 3) )
return null;
List<ProloGraalTerm<?>> polyglotEvalArgs = polyglotEvalTerm.asStructure().getArguments();
ProloGraalPolyglotEvalHeadNode polyglotEvalBuiltinHead = ProloGraalPolyglotEvalHeadNodeGen.create(polyglotEvalTerm,
new ProloGraalSimpleTermNode(polyglotEvalArgs.get(0)),
new ProloGraalSimpleTermNode(polyglotEvalArgs.get(1)),
new ProloGraalSimpleTermNode(polyglotEvalArgs.get(2)));
return new ProloGraalBuiltinStructure(polyglotEvalTerm.asStructure(),polyglotEvalBuiltinHead);
}
public static ProloGraalIsOpStructure initializeIsOp(ProloGraalTerm isOpTerm){
if( !(isOpTerm.isStructure() || isOpTerm.isAtom()) )
return null;
ProloGraalTermNode emptyNode = new ProloGraalIsOpTermNode.ProloGraalEmptyTermNode();
if(isOpTerm.isAtom()){
ProloGraalIsOpTermNode isOpTermNode = ProloGraalIsOpTermNodeGen.create(isOpTerm,emptyNode,emptyNode);
if(isOpTermNode.getOperation() == null)
return null;
ProloGraalStructure isOpStruct = new ProloGraalStructure(isOpTerm.getVariables());
isOpStruct.setFunctor(isOpStruct.asAtom());
return new ProloGraalIsOpStructure(isOpStruct, ProloGraalIsOpTermNodeGen.create(isOpStruct,emptyNode,emptyNode));
isOpStruct.setFunctor(isOpTerm.asAtom());
return new ProloGraalIsOpStructure(isOpStruct, isOpTermNode);
}
ProloGraalTermNode left = emptyNode;
ProloGraalTermNode right = emptyNode;
......@@ -77,6 +91,11 @@ public class ProloGraalBuiltinStructure extends ProloGraalStructure{
return new ProloGraalIsOpStructure(isOpTerm.asStructure(),isOpBuiltinHead);
}
/**
* Build a term node specifically to the given opArg term.
* @param opArg the term to build as a ProloGraalTermNode
* @return the built ProloGraalTermNode
*/
private static ProloGraalTermNode buildTermNodeForIsOp(ProloGraalTerm opArg){
if(opArg instanceof ProloGraalIsOpStructure)
return ((ProloGraalIsOpStructure)opArg).getIsOpTermNode();
......
package ch.heiafr.prolograal.runtime;
import ch.heiafr.prolograal.builtins.predicates.*;
import ch.heiafr.prolograal.nodes.ProloGraalIsHeadNode;
import ch.heiafr.prolograal.nodes.ProloGraalIsHeadNodeGen;
import ch.heiafr.prolograal.nodes.ProloGraalSimpleTermNode;
import ch.heiafr.prolograal.nodes.*;
import java.util.*;
......@@ -57,17 +55,37 @@ public final class ProloGraalRuntime {
isHead.setFunctor(new ProloGraalAtom(isVars, "is"));
ProloGraalVariable arg = new ProloGraalVariable(isVars, "Left");
isHead.addSubterm(arg);
ProloGraalVariable isArg = new ProloGraalVariable(isVars, "Left");
isHead.addSubterm(isArg);
ProloGraalVariable arg2 = new ProloGraalVariable(isVars, "Right");
isHead.addSubterm(arg2);
ProloGraalVariable isArg2 = new ProloGraalVariable(isVars, "Right");
isHead.addSubterm(isArg2);
ProloGraalIsHeadNode isHeadNode = ProloGraalIsHeadNodeGen.create(isHead, new ProloGraalSimpleTermNode(arg), new ProloGraalSimpleTermNode(arg2));
ProloGraalIsHeadNode isHeadNode = ProloGraalIsHeadNodeGen.create(isHead, new ProloGraalSimpleTermNode(isArg), new ProloGraalSimpleTermNode(isArg2));
ProloGraalClause isBuiltin = ProloGraalIsBuiltinNodeGen.create(new HashMap<>(), isHeadNode);
ProloGraalClause isBuiltin = ProloGraalIsBuiltinNodeGen.create(isVars, isHeadNode);
clauses.put(isBuiltin.getHead(), Collections.singletonList(isBuiltin));
HashMap<ProloGraalVariable,ProloGraalVariable> polyglotEvalVars = new HashMap<>();
ProloGraalStructure polyglotEvalHead = new ProloGraalStructure(polyglotEvalVars);
polyglotEvalHead.setFunctor(new ProloGraalAtom(polyglotEvalVars, "polyglot_eval"));
ProloGraalVariable pEarg1 = new ProloGraalVariable(polyglotEvalVars, "Left");
polyglotEvalHead.addSubterm(pEarg1);
ProloGraalVariable pEarg2 = new ProloGraalVariable(polyglotEvalVars, "Center");
polyglotEvalHead.addSubterm(pEarg2);
ProloGraalVariable pEarg3 = new ProloGraalVariable(polyglotEvalVars, "Right");
polyglotEvalHead.addSubterm(pEarg3);
ProloGraalPolyglotEvalHeadNode polyglotEvalHeadNode = ProloGraalPolyglotEvalHeadNodeGen.create(polyglotEvalHead, new ProloGraalSimpleTermNode(pEarg1), new ProloGraalSimpleTermNode(pEarg2), new ProloGraalSimpleTermNode(pEarg3));
ProloGraalClause polyglotEvalBuiltin = ProloGraalPolyglotEvalBuiltinNodeGen.create(polyglotEvalVars, polyglotEvalHeadNode);
clauses.put(polyglotEvalBuiltin.getHead(), Collections.singletonList(polyglotEvalBuiltin));
ProloGraalClause useinterpreterBuiltin = new ProloGraalUseInterpreterBuiltin(context);
clauses.put(useinterpreterBuiltin.getHead(), Collections.singletonList(useinterpreterBuiltin));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment