package be.jeffcheasey88.peeratcode.parser.java; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.function.BiFunction; import java.util.regex.Matcher; import java.util.regex.Pattern; import be.jeffcheasey88.peeratcode.parser.java.CleanerPool.Cleaner; public class Variable extends JavaElement{ private static Pattern PATTERN = Pattern.compile("^(\\s*)(.*)$"); private int modifier; private String name; private String type; private Variable value; //Change into operation or JavaElement public Variable(){} public Variable(int modifier, String type){ this.modifier = modifier; this.type = type; } public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{ CleanerPool generic = new CleanerPool( new Cleaner("GENERIC_TYPE",'<','>'), new Cleaner("GENERIC_ARRAY",'[',']'), new Cleaner("GENERIC_FUNCTION", '{','}'), new Cleaner("GENERIC_PARENTHESIS",'(',')')); if(local == null) local = generic; else local = local.group(generic); content = local.clean(content); Matcher matcher = PATTERN.matcher(content); matcher.matches(); int offset = matcher.group(1).length(); String body = matcher.group(2); int equals = indexOf(body, "="); int quote = indexOf(body,","); int quotes = indexOf(body, ";"); int min = Math.min(quote, quotes); body = body.substring(0, min); if(equals < quote && equals < quotes){ assigment(body, local); }else{ onlyDefine(body, local); } return offset+local.unzipOne(body, (s,p) -> (p.equals("^GENERIC_TYPE") || p.equals("^GENERIC_ARRAY")) ? s : null).length(); } private void assigment(String content, CleanerPool cleaner){ Iterator values = onlyDefine(content, cleaner); if(!values.hasNext()) return; values.next(); if(!values.hasNext()) return; String spacesValue = values.next(); while(values.hasNext()) spacesValue+=" "+values.next(); this.value = new Value(spacesValue); } private Iterator onlyDefine(String content, CleanerPool cleaner){ content = generiqueTypes(content, cleaner); Iterator values = new ArrayIterator<>(content.split("\\s+")); String value = null; int modifier; while(values.hasNext() && (modifier = JavaParser.getModifier(value = values.next())) > 0){ this.modifier+=modifier; } if(this.type == null){ this.type = value; if(values.hasNext()) value = values.next(); } if(this.name == null){ this.name = value; } return values; } private static Pattern UNZIP_STICK = Pattern.compile("\\s+(?[<|(|\\[|\"|'])"); private static Pattern UNZIP_MAJ = Pattern.compile(">(?[^>\\d,;(])"); private static Pattern UNZIP_ARRAY = Pattern.compile("](?[^\\[\\d,;])"); private static Pattern UNZIP_EQUALS_LEFT = Pattern.compile("(?[^=\\s])="); private static Pattern UNZIP_EQUALS_RIGHT = Pattern.compile("=(?[^=\\s])"); private String generiqueTypes(String content, CleanerPool cleaner){ String unzip = cleaner.unzip(content, (value, pattern) -> { if(pattern.equals("^GENERIC_FUNCTION")) return null; if(pattern.equals("^GENERIC_PARENTHESIS")) return value.replace("\\s+", " "); return value.replaceAll("\\s+", ""); }); unzip = UNZIP_STICK.matcher(unzip).replaceAll("${e}"); unzip = UNZIP_MAJ.matcher(unzip).replaceAll("> ${e}"); unzip = UNZIP_ARRAY.matcher(unzip).replaceAll("] ${e}"); unzip = UNZIP_EQUALS_LEFT.matcher(unzip).replaceAll("${e} ="); unzip = UNZIP_EQUALS_RIGHT.matcher(unzip).replaceAll("= ${e}"); return unzip; } private int indexOf(String value, String target){ return value.split(target)[0].length(); } public int getModifier(){ return this.modifier; } public String getName(){ return this.name; } public String getType(){ return this.type; } public Variable getValue(){ return this.value; } @Override public void build(ArrayBuffer buffer, int tab) throws Exception{ super.build(buffer, tab); buffer.append((s) -> s+=Modifier.toString(modifier)+(modifier > 0 ? " ":"")+type+" "+name+(value == null ? ";":" = "+value+";")); buffer.add(""); } @Override public E find(java.util.function.Function search, java.util.function.Function, Boolean> deep, List trace){ if(search.apply(this)) return (E)this; trace.add(this); int index = trace.size()-1; if(!deep.apply(trace)) return null; //Value of the variable trace.remove(index); return null; } @Override public E find(BiFunction, Boolean> search, List trace){ trace.add(this); int index = trace.size()-1; if(search.apply(this, trace)) return (E)this; //value trace.remove(index); return null; } public static class Value extends Variable{ private String value; public Value(String value){ this.value = value; } public String value(){ return this.value; } @Override public String toString(){ return this.value; } } public static class MultipleDeclaratedVariable extends Variable{ private List names; private List values; public MultipleDeclaratedVariable(int modifier, String type){ super(modifier, type); this.names = new ArrayList<>(); this.values = new ArrayList<>(); } public void addVariable(String name, Variable value){ this.names.add(name); this.values.add(value); } @Override public void build(ArrayBuffer buffer, int tab) throws Exception { String spacement = ""; for(int i = 0; i < tab; i++) spacement+="\t"; final String sMod = spacement; String vars = ""; for(int i = 0; i < this.names.size(); i++){ Variable value = this.values.get(i); vars+=","+this.names.get(i)+((value == null) ? "" : " = "+value); } vars = vars.substring(1); String varMod = vars; buffer.append((s) -> s+=sMod+Modifier.toString(getModifier())+" "+getType()+" "+varMod+";"); buffer.add(""); } } }