From eb351f4c4e5aec3386cf04eae38a59c43e6830df Mon Sep 17 00:00:00 2001 From: Gal Sasson Date: Mon, 27 Apr 2015 22:52:18 -0400 Subject: [PATCH 1/2] tweak mode: move tweakmode functions to the end of setup and ignore all values in setup --- java/src/processing/mode/java/JavaEditor.java | 9 +- .../mode/java/tweak/SketchParser.java | 90 ++++++++++++++----- 2 files changed, 73 insertions(+), 26 deletions(-) diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index e7d01835f..3da31ad88 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -2739,7 +2739,6 @@ public class JavaEditor extends Editor { * Replace all numbers with variables and add code to initialize * these variables and handle update messages. */ - //public boolean automateSketch(Sketch sketch, ArrayList handles[]) protected boolean automateSketch(Sketch sketch, List> handles) { SketchCode[] code = sketch.getCode(); @@ -2751,8 +2750,8 @@ public class JavaEditor extends Editor { return false; } - int setupStartPos = SketchParser.getSetupStart(baseCode[0]); - if (setupStartPos < 0) { + int setupEndPos = SketchParser.getSetupEnd(baseCode[0]); + if (setupEndPos < 0) { return false; } @@ -2849,8 +2848,8 @@ public class JavaEditor extends Editor { " tweakmode_initAllVars();\n"+ " tweakmode_initCommunication();\n\n"; - setupStartPos = SketchParser.getSetupStart(c); - c = replaceString(c, setupStartPos, setupStartPos, addToSetup); + setupEndPos = SketchParser.getSetupEnd(c); + c = replaceString(c, setupEndPos, setupEndPos, addToSetup); code[0].setProgram(header + c); diff --git a/java/src/processing/mode/java/tweak/SketchParser.java b/java/src/processing/mode/java/tweak/SketchParser.java index 4f6eca38f..876d4840d 100644 --- a/java/src/processing/mode/java/tweak/SketchParser.java +++ b/java/src/processing/mode/java/tweak/SketchParser.java @@ -38,17 +38,22 @@ public class SketchParser { ArrayList colorModes; List> scientificNotations; - - + + Range setupFunction; + public SketchParser(String[] codeTabs, boolean requiresComment) { this.codeTabs = codeTabs; this.requiresComment = requiresComment; intVarCount=0; floatVarCount=0; - + + // get setup function range (to ignore all numbers there) + setupFunction = new Range(getSetupStart(codeTabs[0]), getSetupEnd(codeTabs[0])); + + // get all scientific notation (to ignore them) scientificNotations = getAllScientificNotations(); - // find, add, and sort all tweakable numbers in the sketch + // find, add, and sort all tweak-able numbers in the sketch addAllNumbers(); // handle colors @@ -65,11 +70,11 @@ public class SketchParser { public void addAllNumbers() { - //allHandles = new ArrayList[codeTabs.length]; // moved inside addAllDecimalNumbers + allHandles = new ArrayList<>(); + addAllDecimalNumbers(); addAllHexNumbers(); addAllWebColorNumbers(); - //for (int i=0; i handle : allHandles) { //Collections.sort(allHandles[i], new HandleComparator()); Collections.sort(handle, new HandleComparator()); @@ -83,14 +88,11 @@ public class SketchParser { * list of all numbers in the sketch (excluding hexadecimals) */ private void addAllDecimalNumbers() { - allHandles = new ArrayList<>(); - // for every number found: // save its type (int/float), name, value and position in code. Pattern p = Pattern.compile("[\\[\\{<>(),\\t\\s\\+\\-\\/\\*^%!|&=?:~]\\d+\\.?\\d*"); for (int i = 0; i < codeTabs.length; i++) { - //allHandles[i] = new ArrayList(); List handles = new ArrayList(); allHandles.add(handles); @@ -106,6 +108,11 @@ public class SketchParser { // ignore comments continue; } + + if (setupFunction.contains(start)) { + // ignore numbers in setup + continue; + } if (requiresComment) { // only add numbers that have the "// tweak" comment in their line @@ -193,6 +200,11 @@ public class SketchParser { // ignore comments continue; } + + if (setupFunction.contains(start)) { + // ignore number in setup + continue; + } if (requiresComment) { // only add numbers that have the "// tweak" comment in their line @@ -249,6 +261,11 @@ public class SketchParser { // ignore comments continue; } + + if (setupFunction.contains(start)) { + // ignore number in setup + continue; + } if (requiresComment) { // only add numbers that have the "// tweak" comment in their line @@ -326,7 +343,6 @@ public class SketchParser { Pattern p = Pattern.compile("color\\(|color\\s\\(|fill[\\(\\s]|stroke[\\(\\s]|background[\\(\\s]|tint[\\(\\s]"); for (int i = 0; i < codeTabs.length; i++) { - //colorBoxes[i] = new ArrayList(); List colorBox = new ArrayList(); colorBoxes.add(colorBox); @@ -348,6 +364,11 @@ public class SketchParser { // ignore colors in a comment continue; } + + if (setupFunction.contains(m.start())) { + // ignore number in setup + continue; + } // look for handles inside the parenthesis for (Handle handle : allHandles.get(i)) { @@ -360,7 +381,7 @@ public class SketchParser { if (colorHandles.size() > 0) { /* make sure there is no other stuff between '()' like variables. - * substract all handle values from string inside parenthesis and + * subtract all handle values from string inside parenthesis and * check there is no garbage left */ String insidePar = tab.substring(openPar+1, closePar); @@ -427,6 +448,11 @@ public class SketchParser { // ignore colors in a comment continue; } + + if (setupFunction.contains(m.start())) { + // ignore number in setup + continue; + } // put 'colorParamsEnd' after three parameters inside the parenthesis or at the close int colorParamsEnd = openPar; @@ -450,7 +476,7 @@ public class SketchParser { if (colorHandles.size() > 0) { /* make sure there is no other stuff between '()' like variables. - * substract all handle values from string inside parenthesis and + * subtract all handle values from string inside parenthesis and * check there is no garbage left */ String insidePar = tab.substring(openPar+1, colorParamsEnd); @@ -546,14 +572,10 @@ public class SketchParser { List> notations = new ArrayList<>(); Pattern p = Pattern.compile("[+\\-]?(?:0|[1-9]\\d*)(?:\\.\\d*)?[eE][+\\-]?\\d+"); - //for (int i = 0; i < codeTabs.length; i++) { for (String code : codeTabs) { List notation = new ArrayList(); - //notations[i] = new ArrayList(); - //Matcher m = p.matcher(codeTabs[i]); Matcher m = p.matcher(code); while (m.find()) { - //notations[i].add(new Range(m.start(), m.end())); notation.add(new Range(m.start(), m.end())); } notations.add(notation); @@ -772,11 +794,37 @@ public class SketchParser { return -1; } - - -// private String replaceString(String str, int start, int end, String put) { -// return str.substring(0, start) + put + str.substring(end, str.length()); -// } + + static public int getSetupEnd(String code) { + int setupStart = getSetupStart(code); + if (setupStart == -1) { + return -1; + } + + // count brackets to look for setup end + int bracketCount=1; + int pos = setupStart; + while (bracketCount>0 && pos Date: Tue, 28 Apr 2015 09:42:52 -0400 Subject: [PATCH 2/2] tweakmode: handle comment blocks, ignore global assignments --- java/src/processing/mode/java/JavaEditor.java | 6 +- java/src/processing/mode/java/JavaMode.java | 9 +- .../mode/java/tweak/SketchParser.java | 234 +++++++++++------- 3 files changed, 155 insertions(+), 94 deletions(-) diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index 3da31ad88..a988bef88 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -2739,9 +2739,11 @@ public class JavaEditor extends Editor { * Replace all numbers with variables and add code to initialize * these variables and handle update messages. */ - protected boolean automateSketch(Sketch sketch, List> handles) { + protected boolean automateSketch(Sketch sketch, SketchParser parser) { SketchCode[] code = sketch.getCode(); + List> handles = parser.allHandles; + if (code.length < 1) { return false; } @@ -2793,7 +2795,7 @@ public class JavaEditor extends Editor { } code[tab].setProgram(c); } - + // add the main header to the code in the first tab String c = code[0].getProgram(); diff --git a/java/src/processing/mode/java/JavaMode.java b/java/src/processing/mode/java/JavaMode.java index 50a6a083e..9933cfcba 100644 --- a/java/src/processing/mode/java/JavaMode.java +++ b/java/src/processing/mode/java/JavaMode.java @@ -167,7 +167,6 @@ public class JavaMode extends Mode { RunnerListener listener, final boolean present) throws SketchException { final JavaEditor editor = (JavaEditor)listener; - boolean launchInteractive = false; if (isSketchModified(sketch)) { editor.deactivateRun(); @@ -193,7 +192,7 @@ public class JavaMode extends Mode { final SketchParser parser = new SketchParser(editor.baseCode, requiresTweak); // add our code to the sketch - launchInteractive = editor.automateSketch(sketch, parser.allHandles); + final boolean launchInteractive = editor.automateSketch(sketch, parser); build = new JavaBuild(sketch); appletClassName = build.build(false); @@ -204,8 +203,10 @@ public class JavaMode extends Mode { public void run() { runtime.launch(present); // this blocks until finished // next lines are executed when the sketch quits - editor.initEditorCode(parser.allHandles, false); - editor.stopInteractiveMode(parser.allHandles); + if (launchInteractive) { + editor.initEditorCode(parser.allHandles, false); + editor.stopInteractiveMode(parser.allHandles); + } } }).start(); diff --git a/java/src/processing/mode/java/tweak/SketchParser.java b/java/src/processing/mode/java/tweak/SketchParser.java index 876d4840d..56130b33e 100644 --- a/java/src/processing/mode/java/tweak/SketchParser.java +++ b/java/src/processing/mode/java/tweak/SketchParser.java @@ -41,15 +41,30 @@ public class SketchParser { Range setupFunction; + List> commentBlocks; + List curlyScopes; + public SketchParser(String[] codeTabs, boolean requiresComment) { this.codeTabs = codeTabs; this.requiresComment = requiresComment; intVarCount=0; floatVarCount=0; + // get all comment blocks + commentBlocks = new ArrayList<>(); + for (String code : codeTabs) { + commentBlocks.add(getCommentBlocks(code)); + } + // get setup function range (to ignore all numbers there) setupFunction = new Range(getSetupStart(codeTabs[0]), getSetupEnd(codeTabs[0])); + // build curly scope for every character in the code + curlyScopes = new ArrayList<>(); + for (String code : codeTabs) { + curlyScopes.add(getCurlyScopes(code)); + } + // get all scientific notation (to ignore them) scientificNotations = getAllScientificNotations(); @@ -104,7 +119,7 @@ public class SketchParser { int start = m.start()+1; int end = m.end(); - if (isInComment(start, codeTabs[i])) { + if (isInRangeList(start, commentBlocks.get(i))) { // ignore comments continue; } @@ -157,7 +172,7 @@ public class SketchParser { continue; // beware of the global assignment (bug from 26.07.2013) - if (isGlobal(m.start(), c)) + if (isGlobal(m.start(), i)) continue; int line = countLines(c.substring(0, start)) - 1; // zero based @@ -196,7 +211,7 @@ public class SketchParser { int start = m.start()+1; int end = m.end(); - if (isInComment(start, codeTabs[i])) { + if (isInRangeList(start, commentBlocks.get(i))) { // ignore comments continue; } @@ -219,7 +234,7 @@ public class SketchParser { } // beware of the global assignment (bug from 26.07.2013) - if (isGlobal(m.start(), c)) { + if (isGlobal(m.start(), i)) { continue; } @@ -257,7 +272,7 @@ public class SketchParser { int start = m.start(); int end = m.end(); - if (isInComment(start, codeTabs[i])) { + if (isInRangeList(start, commentBlocks.get(i))) { // ignore comments continue; } @@ -280,7 +295,7 @@ public class SketchParser { } // beware of the global assignment (bug from 26.07.2013) - if (isGlobal(m.start(), c)) { + if (isGlobal(m.start(), i)) { continue; } @@ -305,13 +320,14 @@ public class SketchParser { private ArrayList findAllColorModes() { ArrayList modes = new ArrayList(); - for (String tab : codeTabs) { + for (int i=0; i -1) { // found colorMode at index - if (isInComment(index, tab)) { + if (isInRangeList(index, commentBlocks.get(i))) { // ignore comments continue; } @@ -360,7 +376,7 @@ public class SketchParser { continue; } - if (isInComment(m.start(), tab)) { + if (isInRangeList(m.start(), commentBlocks.get(i))) { // ignore colors in a comment continue; } @@ -444,7 +460,7 @@ public class SketchParser { continue; } - if (isInComment(m.start(), tab)) { + if (isInRangeList(m.start(), commentBlocks.get(i))) { // ignore colors in a comment continue; } @@ -568,7 +584,6 @@ public class SketchParser { private List> getAllScientificNotations() { - //ArrayList notations[] = new ArrayList[codeTabs.length]; List> notations = new ArrayList<>(); Pattern p = Pattern.compile("[+\\-]?(?:0|[1-9]\\d*)(?:\\.\\d*)?[eE][+\\-]?\\d+"); @@ -668,92 +683,128 @@ public class SketchParser { return false; } + + /** + * Builds an int array for every tab that represents the scope depth at each character + * + * @return + */ + static private int[] getCurlyScopes(String code) + { + List comments = getCommentBlocks(code); + + int[] scopes = new int[code.length()]; + int curlyScope = 0; + boolean arrayAssignmentMaybeCommingFlag = false; + int arrayAssignmentCurlyScope = 0; + for (int pos=0; pos0) { + // this is an array assignment + arrayAssignmentCurlyScope++; + arrayAssignmentMaybeCommingFlag = false; + } + else { + curlyScope++; + } + } + else if (code.charAt(pos) == '}') { + if (arrayAssignmentCurlyScope>0) { + arrayAssignmentCurlyScope--; + } + else { + curlyScope--; + } + } + else if (code.charAt(pos) == '=') { + arrayAssignmentMaybeCommingFlag = true; + } + else if (!isWhiteSpace(code.charAt(pos))) { + arrayAssignmentMaybeCommingFlag = false; + } + } + + return scopes; + } + + static private boolean isWhiteSpace(char c) { + if (c == ' ' || + c == '\t' || + c == '\n' || + c == '\r') { + return true; + } + + int[][] a = {{1,2},{3,4}}; + + return false; + } /** * Is this a global position? * @param pos position - * @param code code + * @param codeTabIndex index of the code in codeTabs * @return - * true if the position 'pos' is in global scope in the code 'code' + * true if the position 'pos' is in global scope in the code 'codeTabs[codeTabIndex]' + * */ - static private boolean isGlobal(int pos, String code) { - int curlyScope = 0; // count '{-}' - - for (int c=pos; c>=0; c--) - { - if (code.charAt(c) == '{') { - // check if a function or an array assignment - for (int cc=c; cc>=0; cc--) { - if (code.charAt(cc)==')') { - curlyScope++; - break; - } - else if (code.charAt(cc)==']') { - break; - } - else if (code.charAt(cc)==';') { - break; - } - } - } - else if (code.charAt(c) == '}') { - // check if a function or an array assignment - for (int cc=c; cc>=0; cc--) { - if (code.charAt(cc)==')') { - curlyScope--; - break; - } - else if (code.charAt(cc)==']') { - break; - } - else if (code.charAt(cc)==';') { - break; - } - } - } - } - - if (curlyScope == 0) { - // it is a global position - return true; - } - - return false; + private boolean isGlobal(int pos, int codeTabIndex) { + return (curlyScopes.get(codeTabIndex)[pos]==0); }; - static private boolean isInComment(int pos, String code) { - // look for one line comment - int lineStart = getStartOfLine(pos, code); - if (lineStart < 0) { - return false; + public static List getCommentBlocks(String code) { + List commentBlocks = new ArrayList(); + + int lastBlockStart=0; + boolean lookForEnd = false; + for (int pos=0; pos rangeList) { + for (Range r : rangeList) { + if (r.contains(pos)) { + return true; + } } - - // TODO: look for block comments + return false; } - static private int getEndOfLine(int pos, String code) { return code.indexOf("\n", pos); } - - static private int getStartOfLine(int pos, String code) { - while (pos >= 0) { - if (code.charAt(pos) == '\n') { - return pos+1; - } - pos--; - } - - return 0; - } - - - /** returns the object of the function starting at 'pos' + /** returns the object name (what comes before the '.') of the function starting at 'pos' * * @param pos * @param code @@ -784,7 +835,7 @@ public class SketchParser { } - static public int getSetupStart(String code) { + public static int getSetupStart(String code) { Pattern p = Pattern.compile("void[\\s\\t\\r\\n]*setup[\\s\\t]*\\(\\)[\\s\\t\\r\\n]*\\{"); Matcher m = p.matcher(code); @@ -795,25 +846,32 @@ public class SketchParser { return -1; } - static public int getSetupEnd(String code) { + public static int getSetupEnd(String code) { + List comments = getCommentBlocks(code); + int setupStart = getSetupStart(code); if (setupStart == -1) { return -1; } + System.out.println("setup start = " + setupStart); + // count brackets to look for setup end int bracketCount=1; int pos = setupStart; while (bracketCount>0 && pos