예제 #1
0
파일: cast.py 프로젝트: Zippersk/VYPa
    def get_instructions(self, parent):
        self.parent = parent
        self.stack_offset += parent.stack_offset
        self.instruction_tape.merge(self.expression.get_instructions(self))
        self.check_types()

        if self.expression.type == VYPaInt(
        ) and self.casting_type == VYPaString():
            self.type = VYPaString()
            self.add_instruction(INT2STRING(self.expression))
            self.stack.push(AST_value(self.type,
                                      str(VYPaRegister.Accumulator)))
        else:
            this_offset = 0
            class_name = self.expression.type.name
            self.add_instruction(
                SET(VYPaRegister.ClassCallReg, VYPaRegister.Accumulator))
            while self.casting_type.name != class_name:
                this_offset -= len(AST.root.get_class(class_name).variables)
                class_name = AST.root.get_class(class_name).predecessor_name
            self.type = self.casting_type
            self.stack.push(
                AST_value(
                    self.type,
                    self.stack.get(this_offset, VYPaRegister.ClassCallReg)))

        self.add_expression_stack_offset()
        return self.instruction_tape
예제 #2
0
 def __init__(self):
     super().__init__(VYPaString(), "subStr", [
         AST_variable(VYPaString(), "s"),
         AST_variable(VYPaInt(), "i"),
         AST_variable(VYPaInt(), "n")
     ])
     self.add_block(
         AST_ifelse(
             AST_expression(
                 AST_OR(
                     AST_LT(AST_variable_call("n"), AST_value(VYPaInt(),
                                                              0)),
                     AST_OR(
                         AST_LT(AST_variable_call("i"),
                                AST_value(VYPaInt(), 0)),
                         AST_OR(
                             AST_GT(
                                 AST_variable_call("i"),
                                 AST_function_call(
                                     "length", [AST_variable_call("s")])),
                             AST_EQ(
                                 AST_variable_call("i"),
                                 AST_function_call(
                                     "length",
                                     [AST_variable_call("s")])))))),
             [AST_return(AST_expression(AST_value(VYPaString(), '""')))], [
                 AST_declaration(VYPaString(), ["new_substr"]),
                 AST_declaration(VYPaInt(), ["j"]),
                 AST_RESIZE(AST_variable_call("new_substr"),
                            AST_variable_call("n")),
                 AST_while(
                     AST_expression(
                         AST_AND(
                             AST_LT(AST_variable_call("j"),
                                    AST_variable_call("n")),
                             AST_LT(
                                 AST_variable_call("j"),
                                 AST_function_call(
                                     "length", [AST_variable_call("s")])))),
                     [
                         AST_GETWORD(
                             VYPaRegister.DestinationReg,
                             AST_variable_call("s"),
                             AST_expression(
                                 AST_ADD(AST_variable_call("i"),
                                         AST_variable_call("j")))),
                         AST_SETWORD(AST_variable_call("new_substr"),
                                     AST_variable_call("j"),
                                     VYPaRegister.DestinationReg),
                         AST_assigment(
                             AST_variable_call("j"),
                             AST_expression(
                                 AST_ADD(AST_variable_call("j"),
                                         AST_value(VYPaInt(), 1))))
                     ]),
                 AST_return(AST_expression(AST_variable_call("new_substr")))
             ]))
예제 #3
0
 def __init__(self):
     super().__init__(VYPaString(), "stringConcat", [
         AST_variable(VYPaString(), "s1"),
         AST_variable(VYPaString(), "s2")
     ])
     self.add_block(
         AST_condition_body([
             AST_declaration(VYPaString(), ["new_string"]),
             AST_COPY(AST_value(VYPaString(), VYPaRegister.DestinationReg),
                      AST_variable_call("s1")),
             AST_assigment(
                 AST_variable_call("new_string"),
                 AST_value(VYPaString(), VYPaRegister.DestinationReg)),
             AST_RESIZE(
                 AST_variable_call("new_string"),
                 AST_expression(
                     AST_ADD(
                         AST_function_call("length",
                                           [AST_variable_call("s1")]),
                         AST_function_call("length",
                                           [AST_variable_call("s2")])))),
             AST_declaration(VYPaInt(), ["i"]),
             AST_while(
                 AST_expression(
                     AST_LT(
                         AST_variable_call("i"),
                         AST_function_call("length",
                                           [AST_variable_call("s2")]))),
                 [
                     AST_GETWORD(AST_value(VYPaInt(), str("$3")),
                                 AST_variable_call("s2"),
                                 AST_variable_call("i")),
                     AST_SETWORD(
                         AST_variable_call("new_string"),
                         AST_expression(
                             AST_ADD(
                                 AST_variable_call("i"),
                                 AST_function_call(
                                     "length",
                                     [AST_variable_call("s1")])), ),
                         AST_value(VYPaInt(), str("$3"))),
                     AST_assigment(
                         AST_variable_call("i"),
                         AST_expression(
                             AST_ADD(AST_variable_call("i"),
                                     AST_value(VYPaInt(), 1))))
                 ]),
             AST_return(AST_variable_call("new_string"))
         ]))
예제 #4
0
파일: function.py 프로젝트: Zippersk/VYPa
    def get_instructions(self, parent):
        self.parent = parent
        self.add_instruction(COMMENT(""))
        self.add_instruction(COMMENT(f"Start of function {self.name}"))
        self.add_instruction(LABEL(self.label))
        self.stack.allocate(2 + len(self.params))
        for variable in self.variables.values():
            self.merge_instructions(variable.get_instructions(self))

        for statement in self.AST_blocks:
            self.merge_instructions(statement.get_instructions(self))

        if isinstance(self.get_parent(), AST_program
                      ) and self.name == "main" and self.type == VYPaVoid():
            self.add_instruction(JUMP("END"))
        else:
            from src.VYPcode.AST.blocks.function_return import AST_return
            if self.type == VYPaVoid():
                default_return = AST_return(None)
            else:
                default_return = AST_return(
                    AST_value(self.type, self.type.get_default()))
            default_return.set_parent(self)
            self.merge_instructions(default_return.get_instructions(self))

        self.add_instruction(COMMENT(f"End of function {self.name}"))
        self.add_instruction(COMMENT(""))

        return self.instruction_tape
예제 #5
0
    def __init__(self):
        super().__init__("Object", None)

        self.add_declaration(
            AST_declaration(VYPaString(), ["**runtime_name**"]))

        to_string_function = AST_function(
            VYPaString(), "Object_toString",
            [AST_variable(VYPaClass("Object"), "this")])
        to_string_function.add_block(AST_block().add_instruction(
            SET(VYPaRegister.ClassCallReg, self.stack.top())))
        to_string_function.add_block(
            AST_return(
                AST_expression(
                    AST_cast(
                        VYPaString(),
                        AST_value(
                            VYPaInt(),
                            self.stack.get(-1, VYPaRegister.ClassCallReg))))))
        to_string_function.set_label(f"class_Object_func_toString")
        AST.get_root().add_function(to_string_function)

        get_class_function = AST_function(
            VYPaString(), "Object_getClass",
            [AST_variable(VYPaClass("Object"), "this")])
        get_class_function.add_block(
            AST_return(
                AST_expression(
                    AST_class_variable_call("this", "**runtime_name**"))))
        get_class_function.set_label(f"class_Object_func_getClass")
        AST.get_root().add_function(get_class_function)

        AST.root.add_class(self)
예제 #6
0
 def get_instructions(self, parent):
     self.parent = parent
     self.variable = self.get_variable(self.name)
     self.type = self.variable.type
     self.instruction_tape.add(
         SET(AST_value(self.type, str(VYPaRegister.Accumulator)),
             str(self)))
     return self.instruction_tape
예제 #7
0
    def get_instructions(self, parent):
        self.parent = parent
        self.class_block = AST.root.get_class(self.name)

        if self.name != "Object":
            self.predecessor = AST_class_instance(
                self.class_block.predecessor_name)
            self.merge_instructions(self.predecessor.get_instructions(self))

        self.add_instruction(COMMENT(f"Constructor of class {self.name}"))
        for declaration in self.class_block.declarations:
            self.merge_instructions(declaration.get_instructions(self))

        if self.name == "Object":
            top_most_children = self
            while isinstance(top_most_children.parent, AST_class_instance):
                top_most_children = top_most_children.parent
            self.merge_instructions(
                AST_assigment(
                    AST_variable_call("**runtime_name**"),
                    AST_value(
                        VYPaString(),
                        f'"{top_most_children.name}"')).get_instructions(self))

        self.merge_instructions(
            AST_declaration(VYPaClass(self.name),
                            ["this"]).get_instructions(self))
        self.merge_instructions(
            AST_assigment(
                AST_variable_call("this"),
                AST_value(VYPaInt(),
                          VYPaRegister.StackPointer)).get_instructions(self))

        constructor = AST.root.functions.get(f"{self.name}_{self.name}", None)
        if constructor and constructor.type == VYPaVoid() and len(
                constructor.params) == 1:
            self.merge_instructions(
                AST_expression(
                    AST_function_call(
                        f"{self.name}_{self.name}",
                        [AST_variable_call("this")])).get_instructions(self))

        self.add_instruction(SET(VYPaRegister.Accumulator, self.stack.top()))
        self.add_instruction(COMMENT(f"End of {self.name} constructor"))

        return self.instruction_tape
예제 #8
0
    def __init__(self):
        super().__init__(VYPaString(), "readString", [])
        self.add_block(AST_declaration(VYPaString(), ["string"]))

        reads_block = AST_block()
        reads_block.add_instruction(READS(VYPaRegister.DestinationReg))
        reads_block.stack.set(VYPaRegister.DestinationReg)
        self.add_block(reads_block)

        self.add_block(AST_return(AST_value(VYPaString(), self.stack.top())))
예제 #9
0
파일: NOT.py 프로젝트: Zippersk/VYPa
 def get_instructions(self, parent):
     self.parent = parent
     self.stack_offset += parent.stack_offset
     self.instruction_tape.merge(self.expression.get_instructions(self))
     self.type = VYPaInt()
     self.check_types()
     self.add_instruction(NOT(self.expression))
     self.stack.push(AST_value(self.type, str(VYPaRegister.Accumulator)))
     self.add_expression_stack_offset()
     return self.instruction_tape
예제 #10
0
    def __init__(self):
        super().__init__(VYPaInt(), "readInt", [])
        self.add_block(AST_declaration(VYPaInt(), ["number"]))

        readi_block = AST_block()
        readi_block.add_instruction(READI(VYPaRegister.DestinationReg))
        readi_block.stack.set(VYPaRegister.DestinationReg)
        self.add_block(readi_block)

        self.add_block(AST_return(AST_value(VYPaInt(), self.stack.top())))
예제 #11
0
파일: EQ.py 프로젝트: Zippersk/VYPa
    def get_instructions(self, parent):
        self.parent = parent
        self.stack_offset += parent.stack_offset
        self.instruction_tape.merge(self.left.get_instructions(self))
        self.instruction_tape.merge(self.right.get_instructions(self))

        if self.left.type == VYPaInt() and self.right.type == VYPaInt():
            self.instruction = EQI
            self.type = VYPaInt()
            self.add_instruction(self.instruction(self.left, self.right))
        elif self.left.type == VYPaString() and self.right.type == VYPaString(
        ):
            self.instruction = EQS
            self.type = VYPaInt()
            self.add_instruction(self.instruction(self.left, self.right))
        elif isinstance(self.left.type, VYPaClass) and isinstance(
                self.right.type, VYPaClass):
            self.instruction = EQI
            self.type = VYPaInt()

            left_class = AST_expression(
                AST_class_variable_call(self.left.name, "**runtime_name**"))
            self.merge_instructions(left_class.get_instructions(self))
            self.add_instruction(SET("$6", VYPaRegister.Accumulator))

            right_class = AST_expression(
                AST_class_variable_call(self.right.name, "**runtime_name**"))
            self.merge_instructions(right_class.get_instructions(self))
            self.add_instruction(SET("$7", VYPaRegister.Accumulator))
            self.add_instruction(DUMPREGS())
            self.add_instruction(DUMPSTACK())
            self.add_instruction(DUMPHEAP())

            self.add_instruction(
                self.instruction(AST_value(VYPaInt(), "$6"),
                                 AST_value(VYPaInt(), "$7")))
        else:
            Exit(Error.SemanticError, "Types mismatch")
            pass
        self.stack.push(AST_value(self.type, str(VYPaRegister.Accumulator)))
        self.add_expression_stack_offset()
        return self.instruction_tape
예제 #12
0
    def __init__(self):
        super().__init__(VYPaInt(), "length",
                         [AST_variable(VYPaString(), "string")])

        getsize_block = AST_block()
        getsize_block.add_instruction(
            GETSIZE(VYPaRegister.DestinationReg, self.function.stack.top()))
        getsize_block.stack.set(VYPaRegister.DestinationReg)
        self.add_block(getsize_block)

        self.add_block(AST_return(AST_value(VYPaInt(), self.stack.top())))
예제 #13
0
    def get_instructions(self, parent):
        self.parent = parent
        self.class_variable = AST_variable_call(self.class_variable_name)
        self.instruction_tape.merge(self.class_variable.get_instructions(self))
        self.add_instruction(
            SET(VYPaRegister.ClassCallReg, self.class_variable))

        self.variable = AST.root.get_class(
            self.class_variable.type.name).get_variable(self.name)
        self.type = self.variable.type
        self.instruction_tape.add(
            SET(AST_value(self.type, str(VYPaRegister.Accumulator)),
                str(self)))
        return self.instruction_tape
예제 #14
0
파일: while_loop.py 프로젝트: Zippersk/VYPa
    def get_instructions(self, parent):
        self.parent = parent
        global WHILE_BLOCK_COUNTS
        self.instruction_tape.add(LABEL(f"loop_{WHILE_BLOCK_COUNTS}"))
        self.instruction_tape.merge(self.condition.get_instructions(self))
        self.instruction_tape.add(
            JUMPZ(f"end_loop_{WHILE_BLOCK_COUNTS}",
                  AST_value(VYPaInt(), str(VYPaRegister.Accumulator))))

        self.instruction_tape.merge(self.body.get_instructions(self))

        self.stack.deallocate(len(self.variables))
        self.instruction_tape.add(JUMP(f"loop_{WHILE_BLOCK_COUNTS}"))
        self.instruction_tape.add(LABEL(f"end_loop_{WHILE_BLOCK_COUNTS}"))

        WHILE_BLOCK_COUNTS += 1
        return self.instruction_tape
예제 #15
0
파일: ifelse.py 프로젝트: Zippersk/VYPa
    def get_instructions(self, parent):
        self.parent = parent
        global IF_BLOCK_COUNTS
        self.instruction_tape.merge(self.condition.get_instructions(self))
        self.instruction_tape.add(
            JUMPZ(f"else_{IF_BLOCK_COUNTS}",
                  AST_value(VYPaInt(), str(VYPaRegister.Accumulator))))

        self.instruction_tape.merge(self.if_body.get_instructions(self))

        self.instruction_tape.add(JUMP(f"end_else_if_{IF_BLOCK_COUNTS}"))
        self.instruction_tape.add(LABEL(f"else_{IF_BLOCK_COUNTS}"))

        self.instruction_tape.merge(self.else_body.get_instructions(self))

        self.instruction_tape.add(LABEL(f"end_else_if_{IF_BLOCK_COUNTS}"))
        IF_BLOCK_COUNTS += 1
        return self.instruction_tape
예제 #16
0
파일: assigment.py 프로젝트: Zippersk/VYPa
    def get_instructions(self, parent):
        self.parent = parent
        global CLASS_INSTANCE_COUNTS
        self.instruction_tape.merge(self.expression.get_instructions(self))
        self.variables["_"] = AST_variable(VYPaInt(), "_")
        self.stack.push(
            AST_value(self.expression.type, VYPaRegister.Accumulator))
        self.instruction_tape.merge(self.variable.get_instructions(self))

        from src.VYPcode.AST.blocks.class_instance import AST_class_instance
        if hasattr(self.expression, "expression_root") and isinstance(
                self.expression.expression_root, AST_class_instance):
            class_instance_variable = AST_variable(
                VYPaClass(self.expression.type.name),
                f"instance of {self.expression.type.name} {CLASS_INSTANCE_COUNTS}"
            )
            class_instance_variable.set_size(
                AST.root.get_class(self.expression.type.name).get_size())
            self.variable.variable.parent.add_variable(class_instance_variable)
            CLASS_INSTANCE_COUNTS += 1

        if self.variable.type != self.expression.type:
            if self.variable.name != "this":
                Exit(Error.TypesIncompatibility, "Type check error!")

        if isinstance(self.variable.type,
                      VYPaClass) and self.variable.name != "this":
            this_offset = 0
            class_name = self.expression.type.name
            self.add_instruction(
                SET(VYPaRegister.ClassCallReg, self.stack.top()))
            while self.variable.type.name != class_name:
                this_offset -= len(AST.root.get_class(class_name).variables)
                class_name = AST.root.get_class(class_name).predecessor_name

            self.instruction_tape.add(
                SET(self.variable,
                    self.stack.get(this_offset, VYPaRegister.ClassCallReg)))
        else:
            self.instruction_tape.add(SET(self.variable, self.stack.top()))
        self.stack.pop()
        return self.instruction_tape
예제 #17
0
    def get_instructions(self, parent):
        self.parent = parent
        self.stack_offset += parent.stack_offset
        self.instruction_tape.merge(self.left.get_instructions(self))
        self.instruction_tape.merge(self.right.get_instructions(self))

        if self.left.type == VYPaInt() and self.right.type == VYPaInt():
            self.instruction = GTI
            self.type = VYPaInt()
            self.add_instruction(self.instruction(self.left, self.right))
        elif self.left.type == VYPaString() and self.right.type == VYPaString(
        ):
            self.instruction = GTS
            self.type = VYPaString()
            self.add_instruction(self.instruction(self.left, self.right))
        else:
            Exit(Error.SemanticError, "Types mismatch")
            pass
        self.stack.push(AST_value(self.type, str(VYPaRegister.Accumulator)))
        self.add_expression_stack_offset()
        return self.instruction_tape
예제 #18
0
    def get_instructions(self, parent):
        self.parent = parent
        self.stack_offset += parent.stack_offset

        this_offset = 0
        if self.class_variable_name == "super":
            this_variable = AST_variable_call("this")
            self.instruction_tape.merge(this_variable.get_instructions(self))
            this_offset += len(
                AST.root.get_class(this_variable.type.name).variables)
            class_name = AST.root.get_class(
                this_variable.type.name).predecessor_name
            self.class_variable_name = "this"
        else:
            this_variable = AST_variable_call(self.class_variable_name)
            self.instruction_tape.merge(this_variable.get_instructions(self))
            class_name = this_variable.type.name

        function = None
        while function is None:
            if AST.root.functions.get(f"{class_name}_{self.name}", None):
                self.stack.set(
                    self.stack.get(-this_offset, VYPaRegister.Accumulator), 3)
                function = AST.root.get_function(f"{class_name}_{self.name}")
            else:
                this_offset += len(AST.root.get_class(class_name).variables)
                class_name = AST.root.get_class(class_name).predecessor_name

        self.type = function.type

        self.calling_params.insert(0, AST_value(VYPaClass(class_name), None))
        for offset, param in enumerate(self.calling_params[1:], 4):
            self.instruction_tape.merge(param.get_instructions(self))
            self.stack.set(param, offset)

        self.check_params(function)
        self.add_instruction(CALL(self.stack.get(2), function))
        self.add_expression_stack_offset()
        return self.instruction_tape
예제 #19
0
파일: ADD.py 프로젝트: Zippersk/VYPa
    def get_instructions(self, parent):
        self.parent = parent
        self.stack_offset += parent.stack_offset
        self.instruction_tape.merge(self.left.get_instructions(self))
        self.instruction_tape.merge(self.right.get_instructions(self))

        if self.left.type == VYPaInt() and self.right.type == VYPaInt():
            self.instruction = ADDI
            self.check_types()
            self.type = VYPaInt()
            self.add_instruction(self.instruction(self.left, self.right))
            self.stack.push(AST_value(self.type, str(VYPaRegister.Accumulator)))
            self.add_expression_stack_offset()
        elif self.left.type == VYPaString() and self.right.type == VYPaString():
            self.check_types()
            self.type = VYPaString()
            self.instruction_tape.merge(
                AST_function_call("stringConcat", [self.left, self.right]).get_instructions(self)
            )
        else:
            Exit(Error.TypesIncompatibility, "Can not add other types as primitives")

        return self.instruction_tape
예제 #20
0
 def deallocate(self, how_much_variables_to_remove=1):
     self.instruction_tape.add(
         SUBI(VYPaRegister.StackPointer,
              AST_value(VYPaInt, how_much_variables_to_remove),
              VYPaRegister.StackPointer))
예제 #21
0
 def __str__(self):
     return str(AST_value(self.type, str(VYPaRegister.Accumulator)))
예제 #22
0
파일: NOT.py 프로젝트: Zippersk/VYPa
 def __str__(self):
     return str(AST_value(self.type, self.stack.get()))
예제 #23
0
 def push(self, value):
     self.instruction_tape.add(SET(self.get(1), value))
     self.instruction_tape.add(
         ADDI(VYPaRegister.StackPointer, AST_value(VYPaInt, 1),
              VYPaRegister.StackPointer))
     return value
예제 #24
0
 def allocate(self, how_much_variables_to_allocate=1):
     self.instruction_tape.add(
         ADDI(VYPaRegister.StackPointer,
              AST_value(VYPaInt, how_much_variables_to_allocate),
              VYPaRegister.StackPointer))
예제 #25
0
 def pop(self):
     self.instruction_tape.add(
         SUBI(VYPaRegister.StackPointer, AST_value(VYPaInt, 1),
              VYPaRegister.StackPointer))
     return self.get(1)
예제 #26
0
def p_expression_string(t):
    'expression : WORD'
    t[0] = AST_value(VYPaString(), t[1])
예제 #27
0
def p_expr_uplus(t):
    'expression : PLUS expression %prec UMINUS'
    t[0] = AST_ADD(AST_value(VYPaInt(), 0), t[2])
예제 #28
0
def p_expr_uminus(t):
    'expression : MINUS expression %prec UMINUS'
    t[0] = AST_SUBI(AST_value(VYPaInt(), 0), t[2])
예제 #29
0
def p_expression_number(t):
    'expression : NUMBER'
    t[0] = AST_value(VYPaInt(), t[1])