123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 |
- package me.hammerle.code;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Stack;
- import me.hammerle.exceptions.CodeTooLongException;
- import me.hammerle.exceptions.GotoLabelNotFoundException;
- import me.hammerle.exceptions.HoldCodeException;
- import me.hammerle.exceptions.SnuviException;
- public class Script
- {
- private final SnuviParser parser;
- protected final boolean receiveEventBroadcast;
- protected final ArrayList<String> eventVars;
-
- private final int id;
- private final String name;
- private final HashMap<String, Object> variables;
- private final HashMap<String, Integer> gotos;
- private final HashSet<String> events;
- private final Stack<Object> valueStack;
- private final Stack<Integer> returnStack;
-
- private Code[] code;
- private int position;
- private int loopCounter;
-
- private boolean halt;
- private boolean valid;
-
- private int tryJumpLine;
-
- public Script(SnuviParser parser, int id, String name, String code, boolean receiveEventBroadcast)
- {
- this.eventVars = new ArrayList<>();
- this.receiveEventBroadcast = receiveEventBroadcast;
- this.parser = parser;
- this.id = id;
- this.name = name;
-
- variables = new HashMap<>();
- gotos = new HashMap<>();
- events = new HashSet<>();
- valueStack = new Stack<>();
- returnStack = new Stack<>();
-
- this.code = Code.generate(parser, name, code, gotos);
- /*for(Code c : this.code)
- {
- System.out.println(c);
- }*/
-
- position = 0;
- loopCounter = 0;
-
- halt = false;
- valid = true;
-
- tryJumpLine = -1;
- }
-
- public Script(SnuviParser parser, int id, String name, String code)
- {
- this(parser, id, name, code, true);
- }
-
- protected void initExpansion(Object... o)
- {
-
- }
-
- public void overload(String code)
- {
- gotos.clear();
- valueStack.clear();
- returnStack.clear();
- this.code = Code.generate(parser, name, code, gotos);
- position = 0;
- halt = false;
- valid = true;
- tryJumpLine = -1;
- }
-
- public Code[] getCode(int line)
- {
- int start = 0;
- int end = code.length;
- int helper;
- while(end - start > 1)
- {
- helper = (start + end) >> 1;
- if(code[helper].line > line)
- {
- end = helper;
- }
- else if(code[helper].line <= line)
- {
- start = helper;
- }
- }
- int realEnd = start;
- start = 0;
- end = code.length;
- while(end - start > 1)
- {
- helper = (start + end) >> 1;
- if(code[helper].line >= line)
- {
- end = helper;
- }
- else if(code[helper].line < line)
- {
- start = helper;
- }
- }
- return Arrays.copyOfRange(code, end, realEnd + 1);
- }
-
- // -----------------------------------------------------------------------------------
- // Script-Daten
- // -----------------------------------------------------------------------------------
-
- public int getId()
- {
- return id;
- }
- public String getName()
- {
- return name;
- }
-
- public boolean isHalt()
- {
- return halt;
- }
-
- public void setHalt(boolean b)
- {
- halt = b;
- }
-
- public boolean isValid()
- {
- return valid;
- }
-
- public void setInvalid()
- {
- valid = false;
- }
-
- public int getActiveCodeLine()
- {
- return code[position].line;
- }
-
- // -----------------------------------------------------------------------------------
- // Event-Handling
- // -----------------------------------------------------------------------------------
-
- public void loadEvent(String s)
- {
- events.add(s);
- }
-
- public boolean isLoadedEvent(String s)
- {
- return events.contains(s);
- }
-
- public void unloadEvent(String s)
- {
- events.remove(s);
- }
-
- // -----------------------------------------------------------------------------------
- // Script-Flow
- // -----------------------------------------------------------------------------------
-
- public void onTerm()
- {
- }
-
- public void runCode()
- {
- if(this.isValid())
- {
- try
- {
- while(position < code.length)
- {
- code[position].executeFunction(parser, this, valueStack);
- position++;
- if(isHalt())
- {
- return;
- }
- }
- parser.termSafe(this);
- }
- catch(Exception ex)
- {
- if(ex.getClass() != HoldCodeException.class)
- {
- parser.logger.printException(new SnuviException(ex, this));
- }
- position++;
- }
- }
- }
-
- // -----------------------------------------------------------------------------------
- // Variablen
- // -----------------------------------------------------------------------------------
-
- public void setEventVar(String var, Object value)
- {
- variables.put(var, value);
- eventVars.add(var);
- }
-
- public void setVar(String var, Object value)
- {
- variables.put(var, value);
- }
-
- public Object getVar(String var)
- {
- return variables.get(var);
- }
-
- public HashMap<String, Object> getVars()
- {
- return variables;
- }
-
- public boolean getBooleanVar(String var)
- {
- try
- {
- return (boolean) getVar(var);
- }
- catch(ClassCastException | NullPointerException ex)
- {
- return false;
- }
- }
-
- public void removeVar(String var)
- {
- variables.remove(var);
- }
-
- // -----------------------------------------------------------------------------------
- // Goto, Return
- // -----------------------------------------------------------------------------------
-
- public void incLoopCounter()
- {
- loopCounter++;
- if(loopCounter > 50)
- {
- resetLoopCounter();
- throw new CodeTooLongException(this);
- }
- }
-
- public void gotoLabel(String label)
- {
- try
- {
- int i = gotos.get(label);
- incLoopCounter();
- position = i - 1;
- }
- catch(NullPointerException ex)
- {
- throw new GotoLabelNotFoundException(this, label);
- }
- }
-
- public void resetLoopCounter()
- {
- loopCounter = 0;
- }
-
- public void gotoLabelWithReturn(String label)
- {
- returnStack.push(position);
- gotoLabel(label);
- }
-
- public void doReturn()
- {
- position = returnStack.pop();
- }
-
- public void gotoSpecialJumpLine(int i)
- {
- position += code[position].getJumpLine() + i;
- }
-
- public void gotoSpecialJumpLine()
- {
- gotoSpecialJumpLine(-1);
- }
-
- public void jumpNextIfElse()
- {
- if(code.length <= position + 1)
- {
- return;
- }
- String s = code[position + 1].getFunction();
- if(s == null || !s.equals("else"))
- {
- return;
- }
- position++;
- }
-
- // -----------------------------------------------------------------------------------
- // try
- // -----------------------------------------------------------------------------------
-
- public void gotoTryJumpLine()
- {
- position = tryJumpLine;
- }
-
- public void saveTryJumpLine()
- {
- tryJumpLine = position + code[position].getJumpLine();
- }
-
- public void resetTryJumpLine()
- {
- tryJumpLine = -1;
- }
-
- public int getTryJumpLine()
- {
- return tryJumpLine;
- }
- }
|