def parse_first_assignment(cls, assignment): c_index, c = lineparse.find_first( lambda current_char: current_char in (',', '='), assignment) if c_index == -1: # If assignment / next variable not found c_index = len(assignment) variable_name = assignment[:c_index].strip() if not variable_name.startswith('$'): raise SyntaxError( "Variable name must start in '$'! Variable: {variable}".format( variable=variable_name)) # Initialized with an expression if c == '=': # Parse the expression if len(assignment) == c_index: raise SyntaxError("Empty Assignment Value") exp_str = assignment[c_index + 1:] exp_tree, exp_end = expressions.parse_expression( exp_str, end_options=(',', ), allow_more=True) variable_value = exp_tree else: variable_value = expnodes.ValueNode(value='') exp_end = len(assignment) return variable_name, variable_value, c_index + 1 + exp_end + 1
def test_insert_sub_node_and_add(): exp = '10+20*30*40+40' node, node_end = expressions.parse_expression(exp) expected = \ expnodes.BinaryOperatorNode( operator='+', a=expnodes.BinaryOperatorNode( operator='+', a=expnodes.ValueNode(10), b=expnodes.BinaryOperatorNode( operator='*', a=expnodes.BinaryOperatorNode( operator='*', a=expnodes.ValueNode(20), b=expnodes.ValueNode(30) ), b=expnodes.ValueNode(40) ) ), b=expnodes.ValueNode(40) ) assert node == expected assert node_end == len(exp)
def test_nested_parenthesis(): exp = '10+((1+2)*(3+4))+30' node, node_end = expressions.parse_expression(exp) expected = \ expnodes.BinaryOperatorNode( operator='+', a=expnodes.BinaryOperatorNode( operator='+', a=expnodes.ValueNode(10), b=expnodes.BinaryOperatorNode( operator='*', a=expnodes.BinaryOperatorNode( operator='+', a=expnodes.ValueNode(1), b=expnodes.ValueNode(2) ), b=expnodes.BinaryOperatorNode( operator='+', a=expnodes.ValueNode(3), b=expnodes.ValueNode(4) ) ) ), b=expnodes.ValueNode(30) ) assert node == expected assert node_end == len(exp)
def test_string_node(): s = "Hello World!" ts = '"{0}"'.format(s) node, node_end = expressions.parse_expression(ts) assert s == ts[1:-1] assert node_end == len(ts)
def evaluate_loop(): while True: val = raw_input(">> ") try: root, root_end = expressions.parse_expression(val) except Exception as e: traceback.print_exc() else: print str(root)
def test_basic_addition(): exp = '10 + 20' node, node_end = expressions.parse_expression(exp) expected = expnodes.BinaryOperatorNode( operator='+', a=expnodes.ValueNode(10), b=expnodes.ValueNode(20) ) assert node == expected assert node_end == len(exp)
def test_multi_char_operators(): exp = 'True <> False' node, node_end = expressions.parse_expression(exp) assert node == expnodes.BinaryOperatorNode( operator='<>', a=expnodes.ValueNode(True), b=expnodes.ValueNode(False) ) assert node_end == len(exp)
def test_string_nodes(): exp = '"Bye" & "\'Hello\'"' node, node_end = expressions.parse_expression(exp) expected = \ expnodes.BinaryOperatorNode( operator='&', a=expnodes.ValueNode("Bye"), b=expnodes.ValueNode("\'Hello\'") ) assert node == expected assert node_end == len(exp)
def test_boolean_node(): exp = 'False And True' node, node_end = expressions.parse_expression(exp) expected = \ expnodes.BinaryOperatorNode( operator='And', a=expnodes.ValueNode(False), b=expnodes.ValueNode(True) ) assert node == expected assert node_end == len(exp)
def test_var_function_call(): var = '$var' call = '$var(1, 2)' node, node_end = expressions.parse_expression(call) assert expnodes.FunctionCallNode( function_name=var, arguments=[ expnodes.ValueNode(1), expnodes.ValueNode(2) ] ) == node assert node_end == len(call)
def test_function_call(): exp = 'MyFunc(10, 20)' node, node_end = expressions.parse_expression(exp) expected = \ expnodes.FunctionCallNode( function_name='MyFunc', arguments=[ expnodes.ValueNode(10), expnodes.ValueNode(20) ] ) assert node == expected assert node_end == len(exp)
def test_additions_without_spacing(): exp = '10+20+30' node, node_end = expressions.parse_expression(exp) expected = expnodes.BinaryOperatorNode( operator='+', a=expnodes.BinaryOperatorNode( operator='+', a=expnodes.ValueNode(10), b=expnodes.ValueNode(20) ), b=expnodes.ValueNode(30) ) assert node == expected assert node_end == len(exp)
def test_not_call(): exp = 'Not (10 = 12)' node, node_end = expressions.parse_expression(exp) expected = \ expnodes.NotNode( value=expnodes.BinaryOperatorNode( operator='=', a=expnodes.ValueNode(10), b=expnodes.ValueNode(12) ) ) assert node == expected assert node_end == len(exp)
def test_variable_exp(): exp = '10+$value*12' node, node_end = expressions.parse_expression(exp) expected = \ expnodes.BinaryOperatorNode( operator='+', b=expnodes.BinaryOperatorNode( operator='*', a=expnodes.VariableNode("$value"), b=expnodes.ValueNode(12) ), a=expnodes.ValueNode(10) ) assert node == expected assert node_end == len(exp)
def test_basic_parenthesis(): exp = '10+(200+300)' node, node_end = expressions.parse_expression(exp) expected = \ expnodes.BinaryOperatorNode( operator='+', b=expnodes.BinaryOperatorNode( operator='+', a=expnodes.ValueNode(200), b=expnodes.ValueNode(300) ), a=expnodes.ValueNode(10) ) assert node == expected assert node_end == len(exp)
def try_parse(cls, raw_lines, current_line): while_line = raw_lines[current_line].content if not while_line.startswith('While'): return NO_MATCH while_condition = while_line[5:] if not (while_condition[0] == '(' or while_condition[0] == ' '): return NO_MATCH while_condition, _ = expressions.parse_expression(while_condition) block, end_line = blocks.parse_lines( raw_lines, current_line + 1, end_condition=lambda line: line == 'WEnd') return WhileStatement(while_condition, block), end_line + 1
def test_array_node(): exp = '[1, 2, 4, 5, 20+30]' node, node_end = expressions.parse_expression(exp) expected = \ expnodes.ArrayNode( [ expnodes.ValueNode(1), expnodes.ValueNode(2), expnodes.ValueNode(4), expnodes.ValueNode(5), expnodes.BinaryOperatorNode(operator='+', a=expnodes.ValueNode(20), b=expnodes.ValueNode(30) ) ] ) assert node == expected assert node_end == len(exp)
def debug_step(linum): """ Execute traces and watches on a program step. """ if not debug_mode: return outstr = '' if debug_tron: outstr += ('['+('%i' % linum) +']') for (expr, outs) in watch_list: outstr += (' ' + expr +' = ') outs.seek(2) try: val = expressions.parse_expression(outs) if val[0] == '$': outstr += '"' + var.copy_str(val) + '"' else: outstr += representation.number_to_str(val, screen=False) except Exception as e: debug_handle_exc(e) if outstr: logging.debug(outstr)
def debug_step(linum): """ Execute traces and watches on a program step. """ if not debug_mode: return outstr = '' if debug_tron: outstr += ('['+('%i' % linum) +']') for (expr, outs) in watch_list: outstr += (' ' + expr +' = ') outs.seek(2) try: val = expressions.parse_expression(outs) if val[0] == '$': outstr += '"' + var.copy_str(val) + '"' else: outstr += representation.number_to_str(val, screen=False) except Exception as e: debug_handle_exc(e) if outstr: logging.debug(outstr)
def debug_step(linum): """ Execute traces and watches on a program step. """ if not debug_mode: return outstr = '' if debug_tron: outstr += ('['+('%i' % linum) +']') for (expr, outs) in watch_list: outstr += (' ' + expr +' = ') outs.seek(2) try: val = expressions.parse_expression(outs) st = vartypes.unpack_string(representation.value_to_str_keep(val, screen=False)) if val[0] == '$': outstr += ('"'+st+'"') else: outstr += (st) except Exception as e: debug_handle_exc(e) if outstr: logging.debug(outstr)
def debug_step(linum): """ Execute traces and watches on a program step. """ if not debug_mode: return outstr = '' if debug_tron: outstr += ('[' + ('%i' % linum) + ']') for (expr, outs) in watch_list: outstr += (' ' + expr + ' = ') outs.seek(2) try: val = expressions.parse_expression(outs) st = vartypes.unpack_string( representation.value_to_str_keep(val, screen=False)) if val[0] == '$': outstr += ('"' + st + '"') else: outstr += (st) except Exception as e: debug_handle_exc(e) if outstr: logging.debug(outstr)
def try_parse(cls, raw_lines, current_line): line = raw_lines[current_line].content if not line.startswith('If '): return NO_MATCH exp_result = IfStatement.if_exp.parse(line) if exp_result is None: raise SyntaxError("Cannot parse If line: {}".format(line)) if_expression = exp_result['exp'] condition_blocks = [] if_expression_node, _ = expressions.parse_expression(if_expression) block, current_line = blocks.parse_lines( raw_lines, current_line + 1, end_condition=cls.__end_condition) condition_blocks.append( ConditionBlock(exp=if_expression_node, block=block)) else_if_blocks, current_line = cls.__parse_else_if_blocks( raw_lines, current_line) condition_blocks += else_if_blocks if raw_lines[current_line].content == 'Else': else_block, current_line = blocks.parse_lines( raw_lines, current_line + 1, end_condition=lambda x: x == 'EndIf') else: else_block = None return IfStatement(condition_blocks=condition_blocks, else_block=else_block), current_line + 1
def __parse_else_if_blocks(cls, raw_lines, current_line): condition_blocks = [] while current_line < len(raw_lines) and \ raw_lines[current_line].content.startswith('ElseIf '): else_if_expression = IfStatement.elseif_exp.parse( raw_lines[current_line].content) if else_if_expression is None: raise SyntaxError("Could not parse ElseIf Expression: " + str(raw_lines[current_line])) else_if_expression_node, _ = expressions.parse_expression( else_if_expression['exp']) else_if_block, current_line = blocks.parse_lines( raw_lines, current_line + 1, end_condition=cls.__end_condition) condition_blocks.append( ConditionBlock(exp=else_if_expression_node, block=else_if_block)) return condition_blocks, current_line
def test_number_node(): node, node_end = expressions.parse_expression("10") assert 10 == node.value assert node_end == 2
def test_string_enclosing_error(): with pytest.raises(SyntaxError) as e_info: expressions.parse_expression('"hello world')
def test_get_var(): var = '$val' node, node_end = expressions.parse_expression(var) assert node == expnodes.VariableNode(var) assert node_end == len(var)
def test_end_with_spaces(): expressions.parse_expression('10 ')
def test_unexpected_end(): exp = '10 +' with pytest.raises(SyntaxError) as e_info: expressions.parse_expression(exp)