示例#1
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())))
示例#2
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())))
示例#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
    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)
示例#5
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
示例#6
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
示例#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
示例#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
示例#9
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
示例#10
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")))
             ]))
示例#11
0
    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
示例#12
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
示例#13
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
示例#14
0
    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
示例#15
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
示例#16
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
示例#17
0
def p_expression_number(t):
    'expression : NUMBER'
    t[0] = AST_value(VYPaInt(), t[1])
示例#18
0
 def check_types(self):
     if self.left.type != VYPaInt() or self.right.type != VYPaInt():
         Exit(Error.TypesIncompatibility, "Type check error!")
示例#19
0
 def __init__(self):
     super().__init__(VYPaVoid(), "printInt",
                      [AST_variable(VYPaInt(), "number")])
     block = AST_block()
     block.add_instruction(WRITEI(self.function.stack.top()))
     self.add_block(block)
示例#20
0
 def declare_integer(self, name):
     self.stack.push(str(0))
     return AST_variable(VYPaInt(), name)
示例#21
0
文件: NOT.py 项目: Zippersk/VYPa
 def check_types(self):
     if self.expression.type != VYPaInt():
         Exit(Error.TypesIncompatibility, "Type check error!")
示例#22
0
文件: cast.py 项目: Zippersk/VYPa
 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!")
示例#23
0
def p_expr_uminus(t):
    'expression : MINUS expression %prec UMINUS'
    t[0] = AST_SUBI(AST_value(VYPaInt(), 0), t[2])
示例#24
0
def p_expr_uplus(t):
    'expression : PLUS expression %prec UMINUS'
    t[0] = AST_ADD(AST_value(VYPaInt(), 0), t[2])