Example #1
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)
Example #2
0
    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
Example #3
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")))
             ]))
Example #4
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())))
Example #5
0
File: EQ.py Project: 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
Example #6
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())))
Example #7
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
Example #8
0
    def get_instructions(self, parent):
        self.parent = parent
        self.instruction_tape.clear()
        for name in self.variable_names:
            if self.type == VYPaInt():
                parent.add_variable(self.declare_integer(name))
            elif self.type == VYPaString():
                parent.add_variable(self.declare_string(name))
            elif self.type == VYPaVoid():
                Exit(Error.SemanticError, "Can not create void variable")
            else:
                parent.add_variable(self.declare_class_instance(name))

        return self.instruction_tape
Example #9
0
File: ADD.py Project: 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
Example #10
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
Example #11
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"))
         ]))
Example #12
0
    def get_instructions(self, parent):
        self.parent = parent
        self.stack_offset += parent.stack_offset

        # print is a special function which can be called with multiple parameters
        # so internally we call PrintInt or PrintString for each parameter...
        if self.name == "print":
            self.type = VYPaVoid()
            if len(self.calling_params) == 0:
                Exit(Error.SemanticError, "Print called with zero params")

            for idx, param in enumerate(self.calling_params, 1):
                self.instruction_tape.merge(param.get_instructions(self))
                if param.type == VYPaInt():
                    function = AST.root.get_function("printInt")

                elif param.type == VYPaString():
                    function = AST.root.get_function("printString")
                else:
                    Exit(Error.SemanticError,
                         "argument of print can be only int or str")

                self.stack.set(param, 3)
                self.add_instruction(CALL(self.stack.get(2), function))
                if idx != len(self.calling_params):
                    self.stack.pop()

        else:
            function = AST.root.get_function(self.name)
            self.type = function.type

            for offset, param in enumerate(self.calling_params, 3):
                if self.name != "stringConcat":  # string concat has already merged instructions
                    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
Example #13
0
 def __init__(self):
     super().__init__(VYPaVoid(), "printString",
                      [AST_variable(VYPaString(), "string")])
     block = AST_block()
     block.add_instruction(WRITES(self.function.stack.top()))
     self.add_block(block)
Example #14
0
def p_expression_string(t):
    'expression : WORD'
    t[0] = AST_value(VYPaString(), t[1])
Example #15
0
 def declare_string(self, name):
     self.instruction_tape.add(CREATE(VYPaRegister.DestinationReg, 1))
     self.instruction_tape.add(SETWORD(VYPaRegister.DestinationReg, 0,
                                       '""'))
     self.stack.push(VYPaRegister.DestinationReg)
     return AST_variable(VYPaString(), name)
Example #16
0
 def check_types(self):
     if not ((self.expression.type == VYPaInt()
              and self.casting_type == VYPaString()) or
             (isinstance(self.expression.type, VYPaClass)
              and AST.root.classes.get(self.casting_type.name, False))):
         Exit(Error.TypesIncompatibility, "Type check error!")