From 66374859a5fd51882a3bdac2345f3e8804e02f12 Mon Sep 17 00:00:00 2001 From: Tzur Soffer <103438808+TzurSoffer@users.noreply.github.com> Date: Sun, 2 Mar 2025 19:16:28 -0800 Subject: [PATCH 1/5] Fix evaluating with Booleans --- duckyinpython.py | 1 + 1 file changed, 1 insertion(+) diff --git a/duckyinpython.py b/duckyinpython.py index d43a620..11529f3 100644 --- a/duckyinpython.py +++ b/duckyinpython.py @@ -175,6 +175,7 @@ def _getCodeBlock(linesIter): def evaluateExpression(expression): """Evaluates an expression with variables and returns the result.""" # Replace variables (e.g., $FOO) in the expression with their values + expression = re.sub(r'\b(true|false)\b', lambda m: m.group(0).capitalize(), expression, flags=re.IGNORECASE) #< fix capitalization mistakes in true and false (for evaluating with booleans) expression = re.sub(r"\$(\w+)", lambda m: str(variables.get(f"${m.group(1)}", 0)), expression) expression = expression.replace("^", "**") #< Replace ^ with ** for exponentiation From d5ee133b84c32d926a9eadaa9d77059472c6ab52 Mon Sep 17 00:00:00 2001 From: Tzur Soffer <103438808+TzurSoffer@users.noreply.github.com> Date: Sun, 2 Mar 2025 19:43:59 -0800 Subject: [PATCH 2/5] replaced re with a function (this feature of re is not supported on circutpython) --- duckyinpython.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/duckyinpython.py b/duckyinpython.py index 11529f3..546fc56 100644 --- a/duckyinpython.py +++ b/duckyinpython.py @@ -172,10 +172,23 @@ def _getCodeBlock(linesIter): code.append(line) return code +def replaceBooleans(text): #< fix capitalization mistakes in true and false (for evaluating with booleans) + lower = text.lower() + if "true" not in lower and "false" not in lower: + return text + words = text.split() + for i, word in enumerate(words): + if word.lower() == "true": + words[i] = "True" + elif word.lower() == "false": + words[i] = "False" + return " ".join(words) + def evaluateExpression(expression): """Evaluates an expression with variables and returns the result.""" # Replace variables (e.g., $FOO) in the expression with their values - expression = re.sub(r'\b(true|false)\b', lambda m: m.group(0).capitalize(), expression, flags=re.IGNORECASE) #< fix capitalization mistakes in true and false (for evaluating with booleans) + print(expression) + expression = replaceBooleans(expression) #< Cant use re due its limitation in circutpython expression = re.sub(r"\$(\w+)", lambda m: str(variables.get(f"${m.group(1)}", 0)), expression) expression = expression.replace("^", "**") #< Replace ^ with ** for exponentiation From 727455aa37c2db8691b62f9c9f2a75da19dff096 Mon Sep 17 00:00:00 2001 From: Tzur Soffer <103438808+TzurSoffer@users.noreply.github.com> Date: Sun, 2 Mar 2025 20:47:45 -0800 Subject: [PATCH 3/5] Fixed internalVar in expression + allows for +=, *=, etc in variable math --- duckyinpython.py | 51 +++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/duckyinpython.py b/duckyinpython.py index 546fc56..dc46d41 100644 --- a/duckyinpython.py +++ b/duckyinpython.py @@ -173,23 +173,17 @@ def _getCodeBlock(linesIter): return code def replaceBooleans(text): #< fix capitalization mistakes in true and false (for evaluating with booleans) - lower = text.lower() - if "true" not in lower and "false" not in lower: - return text - words = text.split() - for i, word in enumerate(words): - if word.lower() == "true": - words[i] = "True" - elif word.lower() == "false": - words[i] = "False" - return " ".join(words) + # Replace any letter-by-letter match for "true" with the proper "True" + text = re.sub(r'[Tt][Rr][Uu][Ee]', 'True', text) + # Replace any letter-by-letter match for "false" with the proper "False" + text = re.sub(r'[Ff][Aa][Ll][Ss][Ee]', 'False', text) + return text def evaluateExpression(expression): """Evaluates an expression with variables and returns the result.""" - # Replace variables (e.g., $FOO) in the expression with their values - print(expression) + expression = replaceVariables(expression) expression = replaceBooleans(expression) #< Cant use re due its limitation in circutpython - expression = re.sub(r"\$(\w+)", lambda m: str(variables.get(f"${m.group(1)}", 0)), expression) + print(expression) expression = expression.replace("^", "**") #< Replace ^ with ** for exponentiation expression = expression.replace("&&", "and") @@ -355,12 +349,30 @@ def parseLine(line, script_lines): else: raise SyntaxError(f"Invalid variable declaration: {line}") elif line.startswith("$"): - match = re.match(r"\$(\w+)\s*=\s*(.+)", line) + match = re.match(r"\$(\w+)\s*([\+\-\*/]?)=\s*(.+)", line) if match: - varName = f"${match.group(1)}" - expression = match.group(2) - value = evaluateExpression(expression) - variables[varName] = value + varName = f"${match.group(1)}" # Extract variable name + operator = match.group(2) # Extract the operator (if any) + expression = match.group(3) # Extract the right-hand side + + # Ensure the variable exists before updating + if operator and varName not in variables: + raise SyntaxError(f"Invalid variable update, declare variable first: {line}") + + value = evaluateExpression(expression) # Evaluate the expression + + if operator: # Handling updates like +=, -=, etc. + if operator == "+": + variables[varName] += value + elif operator == "-": + variables[varName] -= value + elif operator == "*": + variables[varName] *= value + elif operator == "/": + variables[varName] /= value + else: + variables[varName] = value # Simple assignment + else: raise SyntaxError(f"Invalid variable update, declare variable first: {line}") elif line.startswith("DEFINE"): @@ -383,13 +395,12 @@ def parseLine(line, script_lines): loopCode = list(_getCodeBlock(script_lines)) while evaluateExpression(condition) == True: currentIterCode = deepcopy(loopCode) - print(loopCode) + # print(loopCode) while currentIterCode: loopLine = currentIterCode.pop(0) currentIterCode = list(parseLine(loopLine, iter(currentIterCode))) #< very inefficient, should be replaced later. elif line.upper().startswith("IF"): - # print("ENTER IF") script_lines, ret = IF(_getIfCondition(line), script_lines).runIf() print(f"IF returned {ret} code") elif line.upper().startswith("END_IF"): From 89d460c3ee295869253221e003000e2933573f71 Mon Sep 17 00:00:00 2001 From: Tzur Soffer <103438808+TzurSoffer@users.noreply.github.com> Date: Mon, 3 Mar 2025 20:10:09 -0800 Subject: [PATCH 4/5] Removed added +=, *=, etc operations as they are not in the official language Removed added +=, *=, etc operations as they are not in the official language. I added them in a previous commit and removed them in this one. --- duckyinpython.py | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/duckyinpython.py b/duckyinpython.py index dc46d41..0d40c03 100644 --- a/duckyinpython.py +++ b/duckyinpython.py @@ -349,29 +349,15 @@ def parseLine(line, script_lines): else: raise SyntaxError(f"Invalid variable declaration: {line}") elif line.startswith("$"): - match = re.match(r"\$(\w+)\s*([\+\-\*/]?)=\s*(.+)", line) + match = re.match(r"\$(\w+)\s*=\s*(.+)", line) if match: - varName = f"${match.group(1)}" # Extract variable name - operator = match.group(2) # Extract the operator (if any) - expression = match.group(3) # Extract the right-hand side - - # Ensure the variable exists before updating - if operator and varName not in variables: - raise SyntaxError(f"Invalid variable update, declare variable first: {line}") - - value = evaluateExpression(expression) # Evaluate the expression - - if operator: # Handling updates like +=, -=, etc. - if operator == "+": - variables[varName] += value - elif operator == "-": - variables[varName] -= value - elif operator == "*": - variables[varName] *= value - elif operator == "/": - variables[varName] /= value - else: - variables[varName] = value # Simple assignment + varName = f"${match.group(1)}" + expression = match.group(2) + value = evaluateExpression(expression) + variables[varName] = value + + value = evaluateExpression(expression) + variables[varName] = value else: raise SyntaxError(f"Invalid variable update, declare variable first: {line}") From 4fa327adc7a94a3c4efeedd2e09ad9cb3d4531a1 Mon Sep 17 00:00:00 2001 From: Tzur Soffer <103438808+TzurSoffer@users.noreply.github.com> Date: Mon, 3 Mar 2025 20:11:23 -0800 Subject: [PATCH 5/5] Fix duplicate lines --- duckyinpython.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/duckyinpython.py b/duckyinpython.py index 0d40c03..4509d3c 100644 --- a/duckyinpython.py +++ b/duckyinpython.py @@ -356,9 +356,6 @@ def parseLine(line, script_lines): value = evaluateExpression(expression) variables[varName] = value - value = evaluateExpression(expression) - variables[varName] = value - else: raise SyntaxError(f"Invalid variable update, declare variable first: {line}") elif line.startswith("DEFINE"):