123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504 |
- package me.hammerle.scriptsystem;
- import java.io.File;
- import java.io.IOException;
- import java.nio.file.Files;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.HashMap;
- import java.util.HashSet;
- import me.hammerle.exceptions.CodeTooLongException;
- import me.hammerle.exceptions.GoHigherAtRootTreeException;
- import me.hammerle.exceptions.GotoLabelNotFoundException;
- import me.hammerle.exceptions.NoChildTreeException;
- public class ScriptData
- {
- private final int id;
- private final Tree<String> code;
- private String currentCode;
- private int position;
- private final HashMap<String, Object> variables;
- private final HashMap<String, Integer[]> gotos;
- private final HashSet<String> events;
-
- private final String scriptName;
-
- private boolean isWaiting;
- //private boolean isValid;
- private int overflowProtection;
-
- public ScriptData(int id, String filename)
- {
- this.id = id;
-
- code = new Tree<>();
- position = 0;
-
- variables = new HashMap<>();
- gotos = new HashMap<>();
- events = new HashSet<>();
-
- scriptName = filename;
-
- readCode(filename);
- isWaiting = false;
- //isValid = true;
- overflowProtection = 0;
- }
-
- public void goDeeper() throws NoChildTreeException
- {
- code.goDeeper();
- }
-
- private void readCode(String filename)
- {
- File script = new File(filename + ".txt");
- List<String> lines;
- if(script.exists())
- {
- try
- {
- lines = Files.readAllLines(script.toPath());
- }
- catch (IOException ex)
- {
- ScriptUtils.printError("Datei '" + filename + "' kann nicht gelesen werden.");
- return;
- }
- }
- else
- {
- ScriptUtils.printError("Datei '" + filename + "' wurde nicht gefunden.");
- return;
- }
-
- int line = 0;
- int i = 0;
- int old = 0;
- int bracket = 0;
- boolean bracketEnd = false;
- int bracketEndPos = 0;
- boolean oneLineChild = false;
- boolean comment = false;
- int commentPos = 0;
- StringBuilder codeLine = new StringBuilder();
- while(line < lines.size())
- {
- if(old == codeLine.length() && !comment)
- {
- codeLine = new StringBuilder(lines.get(line).trim());
- i = 0;
- old = 0;
- }
- else
- {
- codeLine.append(lines.get(line).trim());
- }
-
- //System.out.println(codeLine);
-
- while(i < codeLine.length())
- {
- switch(codeLine.charAt(i))
- {
- case '@':
- if(comment)
- {
- break;
- }
- old = i;
- while(i < codeLine.length() && codeLine.charAt(i) != ' ')
- {
- i++;
- }
- try
- {
- code.selectLastChild(); // Nur für richtige Position
- }
- catch(NoChildTreeException ex)
- {
- }
- gotos.put(codeLine.substring(old + 1, i), code.getCurrentPosition());
- codeLine.delete(old, i + 1);
- i = old - 1;
- break;
- case '/':
- if(!comment && i + 1 < codeLine.length() && codeLine.charAt(i + 1) == '*')
- {
- comment = true;
- commentPos = i;
- }
- if(!comment && i + 1 < codeLine.length() && codeLine.charAt(i + 1) == '/')
- {
- codeLine.delete(commentPos, codeLine.length());
- }
- break;
- case '*':
- if(comment && i + 1 < codeLine.length() && codeLine.charAt(i + 1) == '/')
- {
- comment = false;
- codeLine.delete(commentPos, i + 2);
- i = commentPos;
- }
- break;
- case ';':
- if(comment)
- {
- break;
- }
- bracketEnd = false;
- code.addChild(codeLine.substring(old, i));
- old = i + 1;
- if(oneLineChild)
- {
- oneLineChild = false;
- try
- {
- code.goHigher();
- }
- catch(GoHigherAtRootTreeException ex)
- {
- System.out.println("Das sollte nicht passieren");
- return;
- }
- }
- break;
- case '(':
- if(!comment && !oneLineChild)
- {
- bracket++;
- if(bracketEnd)
- {
- bracketEnd = false;
- oneLineChild = true;
- code.addChild(codeLine.substring(old, bracketEndPos));
- old = bracketEndPos;
- try
- {
- code.selectLastChild();
- code.goDeeper();
- }
- catch(NoChildTreeException ex)
- {
- System.out.println("Das sollte nicht passieren");
- }
- }
- }
- break;
- case ')':
- if(comment || oneLineChild)
- {
- break;
- }
- bracket--;
- if(bracket < 0)
- {
- ScriptUtils.printError(") ohne ( in Zeile " + (line + 1));
- return;
- }
- if(bracket == 0)
- {
- bracketEnd = true;
- bracketEndPos = i + 1;
- }
- break;
- case '{':
- if(comment)
- {
- break;
- }
- bracketEnd = false;
- code.addChild(codeLine.substring(old, i));
- old = i + 1;
- try
- {
- code.selectLastChild();
- code.goDeeper();
- }
- catch(NoChildTreeException ex)
- {
- System.out.println("Das sollte nicht passieren");
- }
- break;
- case '}':
- if(comment)
- {
- break;
- }
- old = i + 1;
- try
- {
- code.goHigher();
- }
- catch(GoHigherAtRootTreeException ex)
- {
- ScriptUtils.printError("} ohne { in Zeile " + (line + 1));
- return;
- }
- break;
- }
- i++;
- }
- line++;
- }
- code.goToRoot();
- }
-
- public void runCode()
- {
- try
- {
- while(!isWaiting)
- {
- try
- {
- code.selectNextChild();
- }
- catch(NoChildTreeException ex)
- {
- //System.out.println("NACH OBEN!");
- code.goHigher();
- continue;
- }
- currentCode = code.getCurrentChildData();
- findFunction(0, currentCode.length() - 1);
- }
- }
- catch(NoChildTreeException | GoHigherAtRootTreeException ex)
- {
- System.out.println("END PROGRAM");
- }
- }
-
- private Object findFunction(int from, int to)
- {
- if(to <= from) // Springt in { } ohne Kopf
- {
- try
- {
- code.goDeeper();
- }
- catch(NoChildTreeException ex)
- {
- System.out.println("SOLLTE NICHT SEIN");
- }
- return null;
- }
- int old = from;
- int bracket;
- ArrayList<Object> list = new ArrayList<>();
- while(currentCode.charAt(from) != '(')
- {
- from++;
- }
- bracket = from;
- from++;
-
- int last = from;
- int counter = 0;
- boolean string = false;
- while(from <= to)
- {
- if(string)
- {
- if(currentCode.charAt(from) == '"')
- {
- string = !string;
- }
- from++;
- continue;
- }
- switch(currentCode.charAt(from))
- {
- case '"':
- string = !string;
- break;
- case ',':
- if(last != from)
- {
- list.add(currentCode.substring(last, from).trim());
- }
- last = from + 1;
- break;
- case ')':
- if(counter > 0)
- {
- last = from + 1;
- counter--;
- break;
- }
- position = from;
- if(last != from)
- {
- list.add(currentCode.substring(last, from).trim());
- }
- return doFunction(currentCode.substring(old, bracket).trim(), list);
- case '(':
- list.add(findFunction(last, to));
- from = position - 1;
- last = from;
- counter++;
- break;
- }
- from++;
- }
- return null;
- }
-
- private Object doFunction(String function, List<Object> args)
- {
- for(int i = 0; i < args.size(); i++)
- {
- args.set(i, readParameter(args.get(i)));
- }
- Object o = CodeParser.parseFunction(this, function, args);
- if(o == null)
- {
- isWaiting = true;
- }
- return o;
- }
-
- private Object readParameter(Object o)
- {
- if(!(o instanceof String))
- {
- return o;
- }
- String s = o.toString();
- if(s.startsWith("\"") && s.endsWith("\""))
- {
- return s.substring(1, s.length() - 1);
- }
- else if(s.startsWith("$"))
- {
- return getVar(s);
- }
- try
- {
- return ScriptUtils.getNumber(s);
- }
- catch(NumberFormatException ex)
- {
- return s;
- }
- }
-
- public int getId()
- {
- return id;
- }
- public String getName()
- {
- return scriptName;
- }
-
- /*public boolean isWaiting()
- {
- return isWaiting;
- }
-
- public void setWaiting(Boolean bool)
- {
- isWaiting = bool;
- }
-
- public boolean isValid()
- {
- return isValid;
- }
-
- public void setValid(Boolean bool)
- {
- isValid = bool;
- }*/
-
- public Object getVar(String var)
- {
- if(var.startsWith("$"))
- {
- return variables.get(var);
- }
- return variables.get("$" + var);
- }
-
- public Object getVar(Object var)
- {
- return getVar(var.toString());
- }
-
- public HashMap<String, Object> getVars()
- {
- return variables;
- }
-
- public void removeVar(String var)
- {
- if(var.startsWith("$"))
- {
- variables.remove(var);
- }
- variables.remove("$" + var);
- }
-
- public void removeVar(Object var)
- {
- removeVar(var.toString());
- }
-
- public void setVar(String var, Object value)
- {
- if(!var.startsWith("$"))
- {
- var = "$" + var;
- }
- variables.put(var, value);
- }
-
- public void setVar(Object var, Object value)
- {
- setVar(var.toString(), value);
- }
-
- public void gotoLabel(String label) throws NoChildTreeException, CodeTooLongException
- {
- Integer[] i = gotos.get(label);
- if(i == null)
- {
- throw new GotoLabelNotFoundException(label);
- }
- overflowProtection++;
- if(overflowProtection > 50)
- {
- overflowProtection = 0;
- throw new CodeTooLongException();
- }
- code.goToPosition(i);
- }
-
- public void resetOverflowProtection()
- {
- overflowProtection = 0;
- }
-
- public void loadEvent(Object event)
- {
- events.add(event.toString());
- }
-
- public void unloadEvent(Object event)
- {
- events.remove(event.toString());
- }
-
- public boolean isEventLoaded(Object event)
- {
- return events.contains(event.toString());
- }
- }
|