Search in sources :

Example 11 with Node

use of io.github.wysohn.triggerreactor.core.script.parser.Node in project TriggerReactor by wysohn.

the class ParserTest method testPlaceholder.

@Test
public void testPlaceholder() throws Exception {
    Charset charset = Charset.forName("UTF-8");
    String text = "" + "x = 10;" + "#MESSAGE $placeholdertest:0:x:5:true;";
    Lexer lexer = new Lexer(text, charset);
    Parser parser = new Parser(lexer);
    Node root = parser.parse();
    Queue<Node> queue = new LinkedList<Node>();
    serializeNode(queue, root);
    assertEquals(new Node(new Token(Type.THIS, "<This>")), queue.poll());
    assertEquals(new Node(new Token(Type.ID, "x")), queue.poll());
    assertEquals(new Node(new Token(Type.OPERATOR, ".")), queue.poll());
    assertEquals(new Node(new Token(Type.INTEGER, "10")), queue.poll());
    assertEquals(new Node(new Token(Type.OPERATOR, "=")), queue.poll());
    assertEquals(new Node(new Token(Type.INTEGER, "0")), queue.poll());
    assertEquals(new Node(new Token(Type.THIS, "<This>")), queue.poll());
    assertEquals(new Node(new Token(Type.ID, "x")), queue.poll());
    assertEquals(new Node(new Token(Type.OPERATOR, ".")), queue.poll());
    assertEquals(new Node(new Token(Type.INTEGER, "5")), queue.poll());
    assertEquals(new Node(new Token(Type.BOOLEAN, "true")), queue.poll());
    assertEquals(new Node(new Token(Type.PLACEHOLDER, "placeholdertest")), queue.poll());
    assertEquals(new Node(new Token(Type.EXECUTOR, "MESSAGE")), queue.poll());
    assertEquals(new Node(new Token(Type.ROOT, "<ROOT>")), queue.poll());
    assertEquals(0, queue.size());
}
Also used : Lexer(io.github.wysohn.triggerreactor.core.script.lexer.Lexer) Node(io.github.wysohn.triggerreactor.core.script.parser.Node) Charset(java.nio.charset.Charset) Token(io.github.wysohn.triggerreactor.core.script.Token) LinkedList(java.util.LinkedList) Parser(io.github.wysohn.triggerreactor.core.script.parser.Parser) Test(org.junit.Test)

Example 12 with Node

use of io.github.wysohn.triggerreactor.core.script.parser.Node in project TriggerReactor by wysohn.

the class ParserTest method testParam.

@Test
public void testParam() throws IOException, LexerException, ParserException {
    Charset charset = Charset.forName("UTF-8");
    String text = "#SOUND player.getLocation() \"LEVEL_UP\" 1.0 1.0";
    Lexer lexer = new Lexer(text, charset);
    Parser parser = new Parser(lexer);
    Node root = parser.parse();
    Queue<Node> queue = new LinkedList<Node>();
    serializeNode(queue, root);
    assertEquals(new Node(new Token(Type.THIS, "<This>")), queue.poll());
    assertEquals(new Node(new Token(Type.ID, "player")), queue.poll());
    assertEquals(new Node(new Token(Type.OPERATOR, ".")), queue.poll());
    assertEquals(new Node(new Token(Type.CALL, "getLocation")), queue.poll());
    assertEquals(new Node(new Token(Type.OPERATOR, ".")), queue.poll());
    assertEquals(new Node(new Token(Type.STRING, "LEVEL_UP")), queue.poll());
    assertEquals(new Node(new Token(Type.DECIMAL, "1.0")), queue.poll());
    assertEquals(new Node(new Token(Type.DECIMAL, "1.0")), queue.poll());
    assertEquals(new Node(new Token(Type.EXECUTOR, "SOUND")), queue.poll());
    assertEquals(new Node(new Token(Type.ROOT, "<ROOT>")), queue.poll());
    assertEquals(0, queue.size());
}
Also used : Lexer(io.github.wysohn.triggerreactor.core.script.lexer.Lexer) Node(io.github.wysohn.triggerreactor.core.script.parser.Node) Charset(java.nio.charset.Charset) Token(io.github.wysohn.triggerreactor.core.script.Token) LinkedList(java.util.LinkedList) Parser(io.github.wysohn.triggerreactor.core.script.parser.Parser) Test(org.junit.Test)

Example 13 with Node

use of io.github.wysohn.triggerreactor.core.script.parser.Node in project TriggerReactor by wysohn.

the class JavaPluginBridge method createInterrupter.

@Override
public ProcessInterrupter createInterrupter(Object e, Interpreter interpreter, Map<UUID, Long> cooldowns) {
    return new ProcessInterrupter() {

        @Override
        public boolean onNodeProcess(Node node) {
            if (interpreter.isCooldown() && e instanceof PlayerEvent) {
                Player player = ((PlayerEvent) e).getPlayer();
                UUID uuid = player.getUniqueId();
                cooldowns.put(uuid, interpreter.getCooldownEnd());
            }
            return false;
        }

        @Override
        public boolean onCommand(Object context, String command, Object[] args) {
            if ("CALL".equals(command)) {
                if (args.length < 1)
                    throw new RuntimeException("Need parameter [String] or [String, boolean]");
                if (args[0] instanceof String) {
                    Trigger trigger = getNamedTriggerManager().getTriggerForName((String) args[0]);
                    if (trigger == null)
                        throw new RuntimeException("No trigger found for Named Trigger " + args[0]);
                    if (args.length > 1 && args[1] instanceof Boolean) {
                        trigger.setSync((boolean) args[1]);
                    } else {
                        trigger.setSync(true);
                    }
                    if (trigger.isSync()) {
                        trigger.activate(e, interpreter.getVars());
                    } else {
                        // use snapshot to avoid concurrent modification
                        trigger.activate(e, new HashMap<>(interpreter.getVars()));
                    }
                    return true;
                } else {
                    throw new RuntimeException("Parameter type not match; it should be a String." + " Make sure to put double quotes, if you provided String literal.");
                }
            } else if ("CANCELEVENT".equals(command)) {
                if (!interpreter.isSync())
                    throw new RuntimeException("CANCELEVENT is illegal in async mode!");
                if (context instanceof Cancellable) {
                    ((Cancellable) context).setCancelled(true);
                    return true;
                } else {
                    throw new RuntimeException(context + " is not a Cancellable event!");
                }
            }
            return false;
        }
    };
}
Also used : ProcessInterrupter(io.github.wysohn.triggerreactor.core.script.interpreter.Interpreter.ProcessInterrupter) DelegatedPlayer(io.github.wysohn.triggerreactor.bukkit.tools.DelegatedPlayer) IPlayer(io.github.wysohn.triggerreactor.core.bridge.player.IPlayer) Player(org.bukkit.entity.Player) BukkitPlayer(io.github.wysohn.triggerreactor.bukkit.bridge.player.BukkitPlayer) Trigger(io.github.wysohn.triggerreactor.core.manager.trigger.AbstractTriggerManager.Trigger) InventoryTrigger(io.github.wysohn.triggerreactor.core.manager.trigger.AbstractInventoryTriggerManager.InventoryTrigger) Cancellable(org.bukkit.event.Cancellable) Node(io.github.wysohn.triggerreactor.core.script.parser.Node) PlayerEvent(org.bukkit.event.player.PlayerEvent) UUID(java.util.UUID)

Example 14 with Node

use of io.github.wysohn.triggerreactor.core.script.parser.Node in project TriggerReactor by wysohn.

the class Interpreter method start.

// Check if stopFlag is on before pop Token from stack.
private void start(Node node) throws InterpreterException {
    if (stopFlag)
        return;
    // IF children -- [0] : condition , [1] : true body , [2] : false body(may not exist)
    if ("ELSEIF".equals(node.getToken().value) || "IF".equals(node.getToken().value)) {
        // [0] condition
        start(node.getChildren().get(0));
        if (stopFlag)
            return;
        Token resultToken = stack.pop();
        if (isVariable(resultToken)) {
            resultToken = unwrapVariable(resultToken);
        }
        if (resultToken.type == Type.NULLVALUE) {
            // null check failed
            if (node.getChildren().size() > 2) {
                start(node.getChildren().get(2));
            }
        } else {
            // normal IF statement
            if (resultToken.isBoolean()) {
                boolean result = (boolean) resultToken.value;
                if (result) {
                    // [1] true body
                    start(node.getChildren().get(1));
                } else if (node.getChildren().size() > 2) {
                    // [2] false body
                    start(node.getChildren().get(2));
                }
            } else if (resultToken.isInt()) {
                int value = resultToken.toInt();
                if (value != 0) {
                    start(node.getChildren().get(1));
                } else if (node.getChildren().size() > 2) {
                    start(node.getChildren().get(2));
                }
            } else if (resultToken.isDouble()) {
                double value = resultToken.toDouble();
                if (value != 0.0) {
                    start(node.getChildren().get(1));
                } else if (node.getChildren().size() > 2) {
                    start(node.getChildren().get(2));
                }
            } else if (resultToken.value != null) {
                // always true if not null
                start(node.getChildren().get(1));
            } else {
                throw new InterpreterException("Unexpected token for IF statement! -- " + resultToken);
            }
        }
    } else if ("WHILE".equals(node.getToken().value)) {
        Token resultToken = null;
        do {
            start(node.getChildren().get(0));
            resultToken = stack.pop();
            if (resultToken == null)
                throw new InterpreterException("Could not find conditon for WHILE statement!");
            if (isVariable(resultToken)) {
                resultToken = unwrapVariable(resultToken);
            }
            if (!(resultToken.value instanceof Boolean))
                throw new InterpreterException("Unexpected token for WHILE statement! -- " + resultToken);
            if ((boolean) resultToken.value) {
                start(node.getChildren().get(1));
            } else {
                break;
            }
        } while (!stopFlag);
    } else if ("FOR".equals(node.getToken().value)) {
        start(node.getChildren().get(0));
        if (stopFlag)
            return;
        Token idToken = stack.pop();
        if (idToken == null)
            throw new InterpreterException("Iteration variable for FOR statement not found!");
        if (node.getChildren().get(1).getToken().type != Type.ITERATOR)
            throw new InterpreterException("Expected <ITERATOR> but found " + node.getChildren().get(1).getToken());
        Node iterNode = node.getChildren().get(1);
        if (iterNode.getChildren().size() == 1) {
            start(iterNode.getChildren().get(0));
            if (stopFlag)
                return;
            Token valueToken = stack.pop();
            if (isVariable(valueToken)) {
                valueToken = unwrapVariable(valueToken);
            }
            if (!valueToken.isIterable())
                throw new InterpreterException(valueToken + " is not iterable!");
            if (valueToken.isArray()) {
                for (int i = 0; i < Array.getLength(valueToken.value); i++) {
                    Object obj = Array.get(valueToken.value, i);
                    if (stopFlag)
                        break;
                    assignValue(idToken, parseValue(obj));
                    start(node.getChildren().get(2));
                }
            } else {
                for (Object obj : (Iterable<?>) valueToken.value) {
                    if (stopFlag)
                        break;
                    assignValue(idToken, parseValue(obj));
                    start(node.getChildren().get(2));
                }
            }
        } else if (iterNode.getChildren().size() == 2) {
            Node initNode = iterNode.getChildren().get(0);
            if (initNode.getToken().type != Type.INTEGER)
                throw new InterpreterException("Init value must be an Integer value! -- " + initNode);
            start(initNode);
            if (stopFlag)
                return;
            Token initToken = stack.pop();
            Node limitNode = iterNode.getChildren().get(1);
            start(limitNode);
            if (stopFlag)
                return;
            Token limitToken = stack.pop();
            if (isVariable(limitToken)) {
                limitToken = unwrapVariable(limitToken);
            }
            if (limitToken.type != Type.INTEGER)
                throw new InterpreterException("Limit value must be an Integer value! -- " + limitToken);
            for (int i = initToken.toInt(); !stopFlag && i < limitToken.toInt(); i++) {
                assignValue(idToken, new Token(Type.INTEGER, i));
                start(node.getChildren().get(2));
            }
        } else {
            throw new InterpreterException("Number of <ITERATOR> must be 1 or 2!");
        }
    } else {
        for (int i = 0; i < node.getChildren().size(); i++) {
            Node child = node.getChildren().get(i);
            start(child);
            // experimental
            if (i == 0) {
                if ("&&".equals(node.getToken().value)) {
                    Token leftBool = stack.pop();
                    if (isVariable(leftBool)) {
                        leftBool = unwrapVariable(leftBool);
                    }
                    stack.push(leftBool);
                    if (!leftBool.isBoolean())
                        throw new InterpreterException("Left of && operator should be Boolean but was " + leftBool);
                    boolean result = leftBool.toBoolean();
                    if (!result) {
                        // false anyway
                        return;
                    }
                } else if ("||".equals(node.getToken().value)) {
                    Token leftBool = stack.pop();
                    if (isVariable(leftBool)) {
                        leftBool = unwrapVariable(leftBool);
                    }
                    stack.push(leftBool);
                    if (!leftBool.isBoolean())
                        throw new InterpreterException("Left of || operator should be Boolean but was " + leftBool);
                    boolean result = leftBool.toBoolean();
                    if (result) {
                        // true anyway
                        return;
                    }
                }
            }
        }
    }
    Integer result = interpret(node);
    if (result != null) {
        switch(result) {
            case Executor.STOP:
                stopFlag = true;
                return;
            case Executor.WAIT:
                waitFlag = true;
                synchronized (this) {
                    while (waitFlag) {
                        try {
                            this.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
                break;
            default:
                throw new InterpreterException(result + " is not a valid return code!");
        }
    }
}
Also used : Node(io.github.wysohn.triggerreactor.core.script.parser.Node) Token(io.github.wysohn.triggerreactor.core.script.Token) IScriptObject(io.github.wysohn.triggerreactor.core.script.wrapper.IScriptObject)

Example 15 with Node

use of io.github.wysohn.triggerreactor.core.script.parser.Node in project TriggerReactor by wysohn.

the class Interpreter method startWithContextAndInterrupter.

/**
 * Start interpretation.
 * @param context The context that can be used by Executors. This is usually Event object for Bukkit plugin.
 * @param interupter gives the caller to interrupt the execution
 * @throws InterpreterException
 */
public void startWithContextAndInterrupter(Object context, ProcessInterrupter interrupter) throws InterpreterException {
    this.context = context;
    this.interrupter = interrupter;
    Node child = null;
    try {
        for (int i = 0; i < root.getChildren().size(); i++) start(child = root.getChildren().get(i));
    } catch (InterpreterException e) {
        throw new InterpreterException("While interpreting " + child, e);
    }
}
Also used : Node(io.github.wysohn.triggerreactor.core.script.parser.Node)

Aggregations

Node (io.github.wysohn.triggerreactor.core.script.parser.Node)31 Lexer (io.github.wysohn.triggerreactor.core.script.lexer.Lexer)27 Parser (io.github.wysohn.triggerreactor.core.script.parser.Parser)27 Charset (java.nio.charset.Charset)27 Test (org.junit.Test)27 CommonFunctions (io.github.wysohn.triggerreactor.bukkit.manager.trigger.share.CommonFunctions)21 Executor (io.github.wysohn.triggerreactor.core.script.interpreter.Executor)21 Interpreter (io.github.wysohn.triggerreactor.core.script.interpreter.Interpreter)21 HashMap (java.util.HashMap)21 Token (io.github.wysohn.triggerreactor.core.script.Token)7 Placeholder (io.github.wysohn.triggerreactor.core.script.interpreter.Placeholder)7 LinkedList (java.util.LinkedList)6 Player (org.bukkit.entity.Player)6 BukkitPlayer (io.github.wysohn.triggerreactor.bukkit.bridge.player.BukkitPlayer)2 DelegatedPlayer (io.github.wysohn.triggerreactor.bukkit.tools.DelegatedPlayer)2 IPlayer (io.github.wysohn.triggerreactor.core.bridge.player.IPlayer)2 InventoryTrigger (io.github.wysohn.triggerreactor.core.manager.trigger.AbstractInventoryTriggerManager.InventoryTrigger)2 Trigger (io.github.wysohn.triggerreactor.core.manager.trigger.AbstractTriggerManager.Trigger)2 ProcessInterrupter (io.github.wysohn.triggerreactor.core.script.interpreter.Interpreter.ProcessInterrupter)2 ArrayList (java.util.ArrayList)2