def run(self):
        from visualize.plot import resetFlagInStack
        from utils.recursive import recursive
        from utils.executor import containVariableInGlbStack, getVariableFromGlbStack, evaluate

        glb.variable_stack.append(self)
        resetFlagInStack()

        # judge the condition
        self._judge = evaluate(self.condition)

        # TODO: we may also print out the condition result

        # navigates to the next line -- start of the content
        self.line = glb.current_line + 1

        while self._judge:
            # check end_recursive flag
            if self.end_recursive:
                break

            recursive(self.content, 0, self)

            # clear flags after one loop
            resetFlagInStack()

            # re-evaluate the judge condition
            self._judge = evaluate(self.condition)

            if self.continue_flag:
                self.resetEnd()
                self.resetContinue()

        self._end_module()
Exemple #2
0
    def run(self):
        from visualize.plot import resetFlagInStack
        from utils.recursive import recursive
        from utils.executor import containVariableInGlbStack, getVariableFromGlbStack, evaluate

        glb.variable_stack.append(self)
        resetFlagInStack()

        #judge the condition
        self._judge = evaluate(self.condition)

        #TODO: we may also print out the condition result

        #navigates to the next line -- start of the content
        self.line = glb.current_line + 1

        while self._judge:
            #check end_recursive flag
            if self.end_recursive:
                break

            recursive(self.content, 0, self)

            #clear flags after one loop
            resetFlagInStack()

            #re-evaluate the judge condition
            self._judge = evaluate(self.condition)

            if self.continue_flag:
                self.resetEnd()
                self.resetContinue()

        self._end_module()
    def run(self):
        from visualize.plot import resetFlagInStack
        from itertools import zip_longest
        from utils.executor import evaluate
        from utils.recursive import recursive

        glb.variable_stack.append(self)
        resetFlagInStack()

        for condition, content in zip_longest(self.conditionList, self.contentList):
            # print("\tcompile if else condition: {}".format(condition))

            self._judge = evaluate(condition)

            #TODO add return value of the condition to stack

            if self._judge:
                self.line = glb.current_line + 1

                recursive(content, 0, self)
                break
            #update glb.current_line, jump to next if else condition
            else:
                glb.current_line += len(content) + 1

        self._end_module()
Exemple #4
0
    def run(self):
        from visualize.plot import resetFlagInStack
        from itertools import zip_longest
        from utils.executor import evaluate
        from utils.recursive import recursive

        glb.variable_stack.append(self)
        resetFlagInStack()

        for condition, content in zip_longest(self.conditionList,
                                              self.contentList):
            # print("\tcompile if else condition: {}".format(condition))

            self._judge = evaluate(condition)

            #TODO add return value of the condition to stack

            if self._judge:
                self.line = glb.current_line + 1

                recursive(content, 0, self)
                break
            #update glb.current_line, jump to next if else condition
            else:
                glb.current_line += len(content) + 1

        self._end_module()
def recursive(content, index, module):
    """
    recursively execute sentences

    Grammar structure:
    definition: Define variables or functions. Assignment statements are also considered as definition

    Expression: Operations

    Statement: Including if, while, for and repeat/until, break, continue, return.
    """
    if module.end_recursive:
        return
    else:
        # code compilation in progress
        if index < len(content):
            glb.current_line = module.line + index

            # empty line or comment line
            if not content[index].split("#")[0] or content[index].split("#")[0].isspace():
                index += 1
            else:
                # console output on server side
                # print("compile content: {}".format(content[index]))

                # lexicial analyze the statement
                grammar_type, tokenList, exeToken, param_list = parser.parse(content[index])

                # Case1: function definition
                if grammar_type == "function_def":
                    lineCount = get_block_count(content, index)
                    module_content = content[index + 1 : index + lineCount + 1]
                    func_name = param_list[0]
                    func_param_list = param_list[1]
                    glb.current_line += 1  # navigate to the next line
                    funcModule = functionmodule(func_name, func_param_list, module_content, glb.current_line)
                    module._func_inc(func_name, funcModule)
                    index += lineCount + 1
                # Case2: expression
                elif grammar_type == "expression":
                    from utils.consoleManager import stdoutIO

                    with stdoutIO() as s:
                        execute(exeToken)
                    consoleOutput = s.getvalue()
                    if consoleOutput:
                        glb.console_output.append(consoleOutput)

                    plot.plot()

                    index += 1
                # Case3: statement
                elif grammar_type == "statement":
                    # continue, break, return

                    # 3.1 return statement
                    if tokenList[0][1] == "return":
                        try:
                            for item in reversed(glb.variable_stack):
                                if isinstance(item, functionmodule):
                                    item.return_list = evaluate(exeToken)
                                    break
                        except AttributeError:
                            raise Exception("SyntaxError: return statement must be used inside function.")

                        # set end_recursive to true
                        for item in reversed(glb.variable_stack):
                            if isinstance(item, functionmodule):
                                break
                            elif isinstance(item, basemodule):
                                item.setEnd()

                        # TODO plot.printVar() #print variable status before return

                        return  # terminate the function

                    # 3.2 break/continue statement
                    elif tokenList[0][1] == "break" or tokenList[0][1] == "continue":
                        for item in reversed(glb.variable_stack):
                            if isinstance(item, functionmodule):
                                raise Exception("Break/continue can only be used in while and for loops")

                            # terminate the modules inside loops
                            if isinstance(item, basemodule):
                                if not isinstance(item, loopType):
                                    item.setEnd()
                                else:
                                    item.setEnd()
                                    if tokenList[0][1] == "continue":
                                        item.setContinue()
                                    break
                        # TODO plot.printVar() #print variable status
                        return

                    # 3.3 if, while, for statement
                    else:
                        lineCount = get_block_count(content, index)
                        module_content = content[index + 1 : index + lineCount + 1]

                        if tokenList[0][1] == "if":
                            conditionList = [param_list[0]]
                            contentList = [module_content]

                            index += lineCount + 1

                            if index < len(content):
                                grammar_type, tokenList, exeToken, param_list = parser.parse(content[index])

                                while len(tokenList) > 0 and tokenList[0][1] == "else":
                                    lineCount = get_block_count(content, index)
                                    contentList.append(content[index + 1 : index + lineCount + 1])
                                    index += lineCount + 1
                                    conditionList.append(param_list[0])

                                    # continue looping
                                    if index >= len(content):
                                        break
                                    grammar_type, tokenList, exeToken, param_list = parser.parse(content[index])

                            ifModule = ifelsemodule(conditionList, contentList, glb.current_line)

                            ifModule.run()

                        elif tokenList[0][1] == "for":
                            forModule = formodule(param_list, module_content, glb.current_line)
                            forModule.run()
                            index += lineCount + 1

                        elif tokenList[0][1] == "while":
                            whileModule = whilemodule(param_list[0], module_content, glb.current_line)
                            whileModule.run()
                            index += lineCount + 1

                        else:
                            raise Exception(
                                'Unsupported keyword: {} in statement "{}"'.format(tokenList[0][1], content[index])
                            )

            # recursively compile the content
            recursive(content, index, module)
def parse(sentence):
    '''
    :param sentence: one line of the input source code
    :return:
    1. grammar_type: 'function_def', 'expression', 'statement'.  'variable_def' is regarded as expression
    2. tokenList
    3. exeToken: executable tokens for execute function use
    4. param_list: Due to grammar_type.
        If block is var definition,         param_list = [var_name]
        If block is function definition,    param_list = [func_name, function_parameter_tuple]
        if block is if or while statement,  param_list = [condition_expression]
        if block is for statement,          param_list = [iterator_variable_name, iterator_list, range_var]
                                                e.g 'for i = 1 to 10, step 1'
                                                param_list = ['i', (1, 2, 3, ..., 10), None]
                                                'for i in X'
                                                param_list = ['i', X, 'X']
    '''

    grammar_type = ''
    exeToken = ''
    param_list = []

    #lexical analyze the input statement
    tokens = lexical_analyze(sentence)

    if tokens:
        #case 1: function definition. E.g. function insert(param)
        if tokens[0][1] == 'function':
            grammar_type = 'function_def'
            #leave exeToken empty

            function_name, function_param = function_analyze(tokens[1:])
            param_list = [function_name, function_param]

        elif tokens[0][0] == 1:
            #case 2: variable definition. E.g. Stack s = [1,2]
            if tokens[1][0] == 0:
                grammar_type = 'expression'
                var_type = tokens[0][1]
                var_name = tokens[1][1]
                param_list = [var_name]
                exeToken = var_name + ' = ' + var_type

                if len(tokens) == 2:
                    exeToken += "()"
                else:
                    if tokens[2][1] == '=':
                        exeToken += '('
                        for indx in range(3, len(tokens)):
                            exeToken += tokens[indx][1] + ' '
                        exeToken += ')'
            #case 3: expression
            else:
                grammar_type = 'expression'
                #leave param_list empty
                for token in tokens:
                    exeToken += token[1] + ' ' #to remove unnecessary spaces, we do not use exeToken = sentence

        #case 4: statements
        elif tokens[0][0] in STATEMENTRANGE:
            grammar_type = 'statement'

            try:
                #case 4.1: for loop
                #for statement have two types:
                # 1. for [var_name] in [iter_list]
                # 2. for [var_name] = [startpos] to [endpos] step [step]
                if tokens[0][1] == 'for':
                    var_name = tokens[1][1]
                    loop_range = None #[iter_list]
                    range_var_name = ""

                    from utils.executor import evaluate
                    #first type
                    if tokens[2][1] == 'in':
                        range_exp = ''.join([token[1] for token in tokens[3:]]) #string expression of the range. In other words, [iter_list] string
                        loop_range = evaluate(range_exp)
                        range_var_name = range_exp
                    #second type
                    elif tokens[2][1] == '=':
                        exp_index = 3

                        #get start position
                        start_exp = ''
                        while exp_index < len(tokens) and tokens[exp_index][1] != 'to':
                            start_exp += tokens[exp_index][1] + ' '
                            exp_index += 1
                        startPos = evaluate(start_exp)

                        #skip 'to'
                        exp_index += 1

                        #get end position
                        end_exp = ''
                        while exp_index < len(tokens) and tokens[exp_index][1] != 'step':
                            end_exp += tokens[exp_index][1] + ' '
                            exp_index += 1
                        endPos = evaluate(end_exp)

                        #get step
                        exp_index += 1 #skip 'step'
                        step = 1 #default value
                        if exp_index < len(tokens):
                            step_exp = ''
                            while exp_index < len(tokens):
                                step_exp += tokens[exp_index][1] + ' '
                                exp_index += 1
                            step = evaluate(step_exp)

                        loop_range = range(startPos, endPos, step)
                    else:
                        raise Exception("Invalid for loop syntax: " + sentence)
                    param_list = [var_name, loop_range, range_var_name]

                # besides for statement
                else:
                    #get judge condition
                    if tokens[0][0] in STATEMENTRANGE:
                        for token in tokens[1:]:
                            #deal with cases like: else if
                            if token[0] in STATEMENTRANGE:
                                continue
                            #     raise Exception("Unacceptable: More than one condition statement in one line. E.g if XX else XX")
                            exeToken += token[1] + ' '

                        #cases like return, and so on
                        if exeToken == '':
                            exeToken = 'True'
                        param_list = [exeToken]
                    else:
                        raise Exception("Invalid syntax find in parser step: " + sentence)

            except Exception:
                raise

        #all other situations?!
        else:
            grammar_type = 'expression'
            #leave param_list empty
            for token in tokens:
                exeToken += token[1] + ' ' #to remove unnecessary spaces, we do not use exeToken = sentence

    return grammar_type, tokens, exeToken, param_list
Exemple #7
0
def recursive(content, index, module):
    """
    recursively execute sentences

    Grammar structure:
    definition: Define variables or functions. Assignment statements are also considered as definition

    Expression: Operations

    Statement: Including if, while, for and repeat/until, break, continue, return.
    """
    if module.end_recursive:
        return
    else:
        #code compilation in progress
        if index < len(content):
            glb.current_line = module.line + index

            #empty line or comment line
            if not content[index].split("#")[0] or content[index].split(
                    "#")[0].isspace():
                index += 1
            else:
                #console output on server side
                # print("compile content: {}".format(content[index]))

                #lexicial analyze the statement
                grammar_type, tokenList, exeToken, param_list = parser.parse(
                    content[index])

                #Case1: function definition
                if grammar_type == 'function_def':
                    lineCount = get_block_count(content, index)
                    module_content = content[index + 1:index + lineCount + 1]
                    func_name = param_list[0]
                    func_param_list = param_list[1]
                    glb.current_line += 1  #navigate to the next line
                    funcModule = functionmodule(func_name, func_param_list,
                                                module_content,
                                                glb.current_line)
                    module._func_inc(func_name, funcModule)
                    index += (lineCount + 1)
                #Case2: expression
                elif grammar_type == 'expression':
                    from utils.consoleManager import stdoutIO

                    with stdoutIO() as s:
                        execute(exeToken)
                    consoleOutput = s.getvalue()
                    if consoleOutput:
                        glb.console_output.append(consoleOutput)

                    plot.plot()

                    index += 1
                #Case3: statement
                elif grammar_type == 'statement':
                    #continue, break, return

                    #3.1 return statement
                    if tokenList[0][1] == 'return':
                        try:
                            for item in reversed(glb.variable_stack):
                                if isinstance(item, functionmodule):
                                    item.return_list = evaluate(exeToken)
                                    break
                        except AttributeError:
                            raise Exception(
                                "SyntaxError: return statement must be used inside function."
                            )

                        #set end_recursive to true
                        for item in reversed(glb.variable_stack):
                            if isinstance(item, functionmodule):
                                break
                            elif isinstance(item, basemodule):
                                item.setEnd()

                        # TODO plot.printVar() #print variable status before return

                        return  #terminate the function

                    #3.2 break/continue statement
                    elif tokenList[0][1] == 'break' or tokenList[0][
                            1] == 'continue':
                        for item in reversed(glb.variable_stack):
                            if isinstance(item, functionmodule):
                                raise Exception(
                                    "Break/continue can only be used in while and for loops"
                                )

                            #terminate the modules inside loops
                            if isinstance(item, basemodule):
                                if not isinstance(item, loopType):
                                    item.setEnd()
                                else:
                                    item.setEnd()
                                    if tokenList[0][1] == 'continue':
                                        item.setContinue()
                                    break
                        #TODO plot.printVar() #print variable status
                        return

                    #3.3 if, while, for statement
                    else:
                        lineCount = get_block_count(content, index)
                        module_content = content[index + 1:index + lineCount +
                                                 1]

                        if tokenList[0][1] == 'if':
                            conditionList = [param_list[0]]
                            contentList = [module_content]

                            index += (lineCount + 1)

                            if index < len(content):
                                grammar_type, tokenList, exeToken, param_list = parser.parse(
                                    content[index])

                                while len(tokenList
                                          ) > 0 and tokenList[0][1] == 'else':
                                    lineCount = get_block_count(content, index)
                                    contentList.append(
                                        content[index + 1:index + lineCount +
                                                1])
                                    index += (lineCount + 1)
                                    conditionList.append(param_list[0])

                                    #continue looping
                                    if index >= len(content):
                                        break
                                    grammar_type, tokenList, exeToken, param_list = parser.parse(
                                        content[index])

                            ifModule = ifelsemodule(conditionList, contentList,
                                                    glb.current_line)

                            ifModule.run()

                        elif tokenList[0][1] == 'for':
                            forModule = formodule(param_list, module_content,
                                                  glb.current_line)
                            forModule.run()
                            index += (lineCount + 1)

                        elif tokenList[0][1] == 'while':
                            whileModule = whilemodule(param_list[0],
                                                      module_content,
                                                      glb.current_line)
                            whileModule.run()
                            index += (lineCount + 1)

                        else:
                            raise Exception(
                                "Unsupported keyword: {} in statement \"{}\"".
                                format(tokenList[0][1], content[index]))

            #recursively compile the content
            recursive(content, index, module)
def parse(sentence):
    '''
    :param sentence: one line of the input source code
    :return:
    1. grammar_type: 'function_def', 'expression', 'statement'.  'variable_def' is regarded as expression
    2. tokenList
    3. exeToken: executable tokens for execute function use
    4. param_list: Due to grammar_type.
        If block is var definition,         param_list = [var_name]
        If block is function definition,    param_list = [func_name, function_parameter_tuple]
        if block is if or while statement,  param_list = [condition_expression]
        if block is for statement,          param_list = [iterator_variable_name, iterator_list, range_var]
                                                e.g 'for i = 1 to 10, step 1'
                                                param_list = ['i', (1, 2, 3, ..., 10), None]
                                                'for i in X'
                                                param_list = ['i', X, 'X']
    '''

    grammar_type = ''
    exeToken = ''
    param_list = []

    #lexical analyze the input statement
    tokens = lexical_analyze(sentence)

    if tokens:
        #case 1: function definition. E.g. function insert(param)
        if tokens[0][1] == 'function':
            grammar_type = 'function_def'
            #leave exeToken empty

            function_name, function_param = function_analyze(tokens[1:])
            param_list = [function_name, function_param]

        elif tokens[0][0] == 1:
            #case 2: variable definition. E.g. Stack s = [1,2]
            if tokens[1][0] == 0:
                grammar_type = 'expression'
                var_type = tokens[0][1]
                var_name = tokens[1][1]
                param_list = [var_name]
                exeToken = var_name + ' = ' + var_type

                if len(tokens) == 2:
                    exeToken += "()"
                else:
                    if tokens[2][1] == '=':
                        exeToken += '('
                        for indx in range(3, len(tokens)):
                            exeToken += tokens[indx][1] + ' '
                        exeToken += ')'
            #case 3: expression
            else:
                grammar_type = 'expression'
                #leave param_list empty
                for token in tokens:
                    exeToken += token[
                        1] + ' '  #to remove unnecessary spaces, we do not use exeToken = sentence

        #case 4: statements
        elif tokens[0][0] in STATEMENTRANGE:
            grammar_type = 'statement'

            try:
                #case 4.1: for loop
                #for statement have two types:
                # 1. for [var_name] in [iter_list]
                # 2. for [var_name] = [startpos] to [endpos] step [step]
                if tokens[0][1] == 'for':
                    var_name = tokens[1][1]
                    loop_range = None  #[iter_list]
                    range_var_name = ""

                    from utils.executor import evaluate
                    #first type
                    if tokens[2][1] == 'in':
                        range_exp = ''.join(
                            [token[1] for token in tokens[3:]]
                        )  #string expression of the range. In other words, [iter_list] string
                        loop_range = evaluate(range_exp)
                        range_var_name = range_exp
                    #second type
                    elif tokens[2][1] == '=':
                        exp_index = 3

                        #get start position
                        start_exp = ''
                        while exp_index < len(
                                tokens) and tokens[exp_index][1] != 'to':
                            start_exp += tokens[exp_index][1] + ' '
                            exp_index += 1
                        startPos = evaluate(start_exp)

                        #skip 'to'
                        exp_index += 1

                        #get end position
                        end_exp = ''
                        while exp_index < len(
                                tokens) and tokens[exp_index][1] != 'step':
                            end_exp += tokens[exp_index][1] + ' '
                            exp_index += 1
                        endPos = evaluate(end_exp)

                        #get step
                        exp_index += 1  #skip 'step'
                        step = 1  #default value
                        if exp_index < len(tokens):
                            step_exp = ''
                            while exp_index < len(tokens):
                                step_exp += tokens[exp_index][1] + ' '
                                exp_index += 1
                            step = evaluate(step_exp)

                        loop_range = range(startPos, endPos, step)
                    else:
                        raise Exception("Invalid for loop syntax: " + sentence)
                    param_list = [var_name, loop_range, range_var_name]

                # besides for statement
                else:
                    #get judge condition
                    if tokens[0][0] in STATEMENTRANGE:
                        for token in tokens[1:]:
                            #deal with cases like: else if
                            if token[0] in STATEMENTRANGE:
                                continue
                            #     raise Exception("Unacceptable: More than one condition statement in one line. E.g if XX else XX")
                            exeToken += token[1] + ' '

                        #cases like return, and so on
                        if exeToken == '':
                            exeToken = 'True'
                        param_list = [exeToken]
                    else:
                        raise Exception(
                            "Invalid syntax find in parser step: " + sentence)

            except Exception:
                raise

        #all other situations?!
        else:
            grammar_type = 'expression'
            #leave param_list empty
            for token in tokens:
                exeToken += token[
                    1] + ' '  #to remove unnecessary spaces, we do not use exeToken = sentence

    return grammar_type, tokens, exeToken, param_list