コード例 #1
0
    def make_offset(self, var_type):
        self.push_operator(Operation.PLUS)
        self.make_expression()
        res = self._operand_stack.pop()
        res.type = GreaseType(GreaseTypeClass.Pointer, res.type)

        res_ref = GreaseVar(GreaseType(GreaseTypeClass.Pointer, var_type),
                            res._address, AddressingMethod.Indirect)
        self._operand_stack.push(res_ref)
コード例 #2
0
    def find_type(self, name):
        struct = self._structs.find_struct(name)

        if struct is not None:
            return GreaseType(GreaseTypeClass.Struct, struct, size=struct.size)

        interface = self._interfaces.find_interface(name)

        if interface is not None:
            return GreaseType(GreaseTypeClass.Intererface, interface)

        raise UndefinedType(name)
コード例 #3
0
    def resolve_main(self):
        main = self.find_function('main')
        if main is None:
            raise UndefinedFunction(
                'Main is not defined. No entry point for this program.')

        address = GreaseVar(GreaseType(GreaseTypeClass.Int), main.start,
                            AddressingMethod.Literal)
        size = GreaseVar(GreaseType(GreaseTypeClass.Int), main.size,
                         AddressingMethod.Literal)
        self._quads._quads[self._jump_stack.pop()].left_operand = address
        self._quads._quads[self._jump_stack.pop()].left_operand = size
コード例 #4
0
 def push_fn_size(self):
     self._active_fn.size = self._next_local_address
     while self._era_stack.peek() is not None:
         quad = self._quads._quads[self._era_stack.pop()]
         quad.left_operand = GreaseVar(GreaseType(GreaseTypeClass.Int),
                                       self._next_local_address,
                                       AddressingMethod.Literal)
コード例 #5
0
 def make_addr(self):
     aux = self._operand_stack.pop()
     temp = GreaseVar(GreaseType(GreaseTypeClass.Int),
                      self._next_local_address, AddressingMethod.Relative)
     quad = Quadruple(Operation.ADDR, aux, result=temp)
     self._quads.push_quad(quad)
     self.push_operand(temp)
     self._next_local_address += 1
コード例 #6
0
ファイル: parser.py プロジェクト: JorgeRubio96/grease-lang
def p_optional_struct_interfaces(p):
  '''optional_struct_interfaces : COLON more_interfaces interface_id
                                | empty'''
  if len(p) > 2:
    vtable_t = greaser.find_struct('vtable')
    var_builder.add_type(GreaseType(GreaseTypeClass.Pointer, vtable_t))
    vtable = var_builder.build()
    struct_builder.add_member('vtable', vtable)
コード例 #7
0
ファイル: parser.py プロジェクト: JorgeRubio96/grease-lang
def p_const_int(p):
  '''const_int : CONST_INT'''
  val = p[1]

  # Store as 32bit unsigned 2's complement
  if val < 0:
    val += 1 << 32

  greaser.push_constant(val, GreaseType(GreaseTypeClass.Int))
コード例 #8
0
    def fill_jump(self, offset=0):
        quad_no = self._jump_stack.pop()

        if quad_no is not None:
            next_quad = self._quads.next_free_quad
            address = GreaseVar(GreaseType(GreaseTypeClass.Int),
                                next_quad + offset, AddressingMethod.Literal)
            self._quads.fill_quad(quad_no, address)
        else:
            raise GreaseError('No jumps pending to be resolved')
コード例 #9
0
    def make_expression(self):
        """Exp quad helper:
    Pops 2 operands from typestack and operand stack, checks type and calls build_and_push_quad"""
        op = self._operator_stack.pop()

        rhs = self._operand_stack.pop()

        if op is Operation.ADDR:
            self.make_addr()
        elif op is Operation.DEREF:
            self.make_deref()
        elif op in [Operation.U_MINUS, Operation.NOT]:
            return_type_class = cube.check(rhs, op, None)

            if return_type_class is None:
                raise TypeMismatch('{} {}'.format(op, rhs))

            tmp_var = GreaseVar(GreaseType(return_type_class),
                                self._next_local_address,
                                AddressingMethod.Relative)
            self._next_local_address += tmp_var.type.size
            self._quads.push_quad(Quadruple(op, rhs, result=tmp_var))
            self.push_operand(tmp_var)
        else:
            lhs = self._operand_stack.pop()

            return_type_class = cube.check(lhs, op, lhs)

            if return_type_class is None:
                raise TypeMismatch('{} {} {}'.format(lhs, op, rhs))

            tmp_type = GreaseType(return_type_class)
            tmp_var = GreaseVar(tmp_type, self._next_local_address,
                                AddressingMethod.Relative)

            self._next_local_address += tmp_var.type.size

            # Generate Quadruple and push it to the list
            quad = Quadruple(op, lhs, rhs, tmp_var)
            self._quads.push_quad(quad)

            # push the tmp_var to stack
            self._operand_stack.push(tmp_var)
コード例 #10
0
    def set_arr_add(self):
        arr = self._agregate_stack.pop()

        arr_addr = GreaseVar(
            GreaseType(GreaseTypeClass.Pointer, arr.type.type_data),
            arr._address, arr.method)

        self._operand_stack.push(arr_addr)
        self.make_offset(arr.type.type_data)
        self.pop_fake_bottom()
コード例 #11
0
    def push_substruct(self, name):
        if self._operator_stack.peek() is Operation.ACCESS:
            self._operator_stack.pop(
            )  # This operation can not be executed by VM
            parent = self._operand_stack.pop()

            if parent is None:
                raise UndefinedVariable('Struct does not exist')

            if self._operator_stack.peek() is Operation.DEREF:
                self._operand_stack.pop(
                )  # This operation can not be executed by VM
                if parent.type.type_class is not GreaseTypeClass.Pointer:
                    raise GreaseError('Expected pointer')

                parent_addr = GreaseVar(parent.type, parent._address,
                                        parent.method)
                parent_type = parent.type.type_data
            else:
                parent_addr = GreaseVar(
                    GreaseType(GreaseTypeClass.Pointer, parent.type),
                    parent._address, parent.method)
                parent_type = parent.type

            if parent_type.type_class is not GreaseTypeClass.Struct:
                raise TypeMismatch('Expression must be struct')

            var_table = parent_type.type_data.variables
            var = var_table.find_variable(name)

            if var is None:
                raise UndefinedMember(name)

            offset = GreaseVar(GreaseType(GreaseTypeClass.Int), var._address,
                               AddressingMethod.Literal)
            parent_addr.type.type_data = var.type

            self.push_operand(offset)
            self.push_operand(parent_addr)
            self.make_offset(var.type)
        else:
            var = self.find_variable(name)
            self.push_operand(var)
コード例 #12
0
 def push_dim_stack(self):
     arr = self._agregate_stack.peek()
     if len(arr.type.dimens
            ) > self._dim:  #if the next pointer is different from null then
         t = self._operand_stack.peek()
         size = GreaseVar(GreaseType(GreaseTypeClass.Int),
                          arr.type.dimens[self._dim].size,
                          AddressingMethod.Literal)
         offset = GreaseVar(GreaseType(GreaseTypeClass.Int),
                            arr.type.dimens[self._dim].offset,
                            AddressingMethod.Literal)
         ver = Quadruple(Operation.VER, t, size)
         self._quads.push_quad(ver)
         self.push_operator(Operation.TIMES)
         self.push_operand(offset)
         self.make_expression()
     if self._dim > 0:
         self._operator_stack.push(Operation.PLUS)
         self.make_expression()
コード例 #13
0
ファイル: parser.py プロジェクト: JorgeRubio96/grease-lang
def p_array(p):
  '''array : OPEN_BRACK basic_type SEMICOLON CONST_INT array_more_dimens CLOSE_BRACK'''
  dimens = [GreaseDimension(p[4])] + p[5]
  r = 1
  for dimen in dimens:
    r = r * dimen.size
  
  total_size = r

  for dimen in dimens:
    dimen.offset = int(r / dimen.size)
    r = dimen.offset
  
  p[0] = GreaseType(GreaseTypeClass.Array, p[2], dimens, total_size)
コード例 #14
0
    def make_gosub(self):
        self.pop_fake_bottom()

        if self._next_param < len(self._called_fn.param_types):
            raise UndefinedFunction(
                'Invalid function signature. Check argument count.')

        # Recursive functions dont have their size
        # calculated yet. Add them to era stack.
        if self._called_fn is self._active_fn:
            self._era_stack.push(self._quads.next_free_quad)
        size = GreaseVar(GreaseType(GreaseTypeClass.Int), self._called_fn.size,
                         AddressingMethod.Literal)

        # Make ERA
        era = Quadruple(Operation.ERA, size)
        self._quads.push_quad(era)

        for param_quad in self._param_quads:
            self._quads.push_quad(param_quad)

        self._param_quads = []

        start = GreaseVar(GreaseType(GreaseTypeClass.Int),
                          self._called_fn.start, AddressingMethod.Literal)
        gosub = Quadruple(Operation.GOSUB, start)
        self._quads.push_quad(gosub)

        if self._called_fn.return_type is not None:
            return_var = GreaseVar(self._called_fn.return_type,
                                   self._next_global_address)
            temp = GreaseVar(return_var.type, self._next_local_address,
                             AddressingMethod.Relative)
            self._next_local_address += temp.type.size
            self._quads.push_quad(
                Quadruple(Operation.ASSIGN, return_var, result=temp))
            self.push_operand(temp)
コード例 #15
0
    def make_jump(self, to_stack=False):
        if to_stack:
            to = self._jump_stack.pop()

            if to is None:
                raise GreaseError('Empty jump stack!')

            address = GreaseVar(GreaseType(GreaseTypeClass.Int), to,
                                AddressingMethod.Literal)
            quad = Quadruple(Operation.JMP, result=address)
        else:
            self._jump_stack.push(self._quads.next_free_quad)
            quad = Quadruple(Operation.JMP)

        self._quads.push_quad(quad)
コード例 #16
0
ファイル: parser.py プロジェクト: JorgeRubio96/grease-lang
def p_optional_method_declaration(p):
  '''optional_method_declaration : OPEN_PAREN ID COLON ID CLOSE_PAREN
                                 | empty'''
  if len(p) > 2:
    try:
      struct = greaser.find_struct(p[4])
      t = GreaseType(GreaseTypeClass.Struct, struct)
      var_builder.add_type(t)
      var = var_builder.build()
      var_builder.reset()
      
      fn_builder.add_param(p[2], var)
      fn_builder.add_struct(struct)
    except GreaseError as e:
      e.print(p.lineno(2))
      raise
コード例 #17
0
ファイル: parser.py プロジェクト: JorgeRubio96/grease-lang
def p_const_real(p):
  '''const_real : CONST_REAL'''
  num = struct.pack('>f', p[1])
  rep = struct.unpack('>l', num)[0]
  greaser.push_constant(rep, GreaseType(GreaseTypeClass.Float))
コード例 #18
0
ファイル: parser.py プロジェクト: JorgeRubio96/grease-lang
def p_const_str(p):
  '''const_str : CONST_STR'''
  str_t = GreaseType(GreaseTypeClass.Array, GreaseType(GreaseTypeClass.Char))
  str_t.size = len(p[1]) + 1 # Don't forget null terminator!
  greaser.push_constant(p[1], str_t)
コード例 #19
0
ファイル: parser.py プロジェクト: JorgeRubio96/grease-lang
def p_const_char(p):
  '''const_char : CONST_CHAR'''
  val = bytes(p[1], 'utf-8').decode('unicode_escape')
  greaser.push_constant(ord(val), GreaseType(GreaseTypeClass.Char))
コード例 #20
0
ファイル: parser.py プロジェクト: JorgeRubio96/grease-lang
def p_pointer(p):
  '''pointer : compound_type TIMES'''
  p[0] = GreaseType(GreaseTypeClass.Pointer, p[1])
コード例 #21
0
ファイル: parser.py プロジェクト: JorgeRubio96/grease-lang
def p_true(p):
  '''true : TRUE'''
  greaser.push_constant(True, GreaseType(GreaseTypeClass.Bool))
コード例 #22
0
ファイル: parser.py プロジェクト: JorgeRubio96/grease-lang
def p_false(p):
  '''false : FALSE'''
  greaser.push_constant(False, GreaseType(GreaseTypeClass.Bool))
コード例 #23
0
 def basic_type_from_text(name):
     return GreaseType(type_class_dict.get(name))