예제 #1
0
  def c_gen_code(self):
    op_map = {
        '!': '_negate_bool',
        '-': '_negate_int',
    }

    return [
      common.store_param(self.expr),
      'call {0}'.format(op_map[self.operator]),
      'pop ebx ; pop to garbage',
      '; eax contains a pointer to the result',
    ]
예제 #2
0
  def c_gen_code(self):
    class_defn = self.type_node.definition
    param_code = [common.store_param(x) for x in self.arguments]
    pop_params = ['pop ebx ; pop param to garbage' for x in self.arguments]
    sig = (str(class_defn.name), [x.expr_type for x in self.arguments])
    constructor, _ = class_defn.environment.lookup_method(sig, constructor=True)

    if constructor is None:
      raise Exception(
          'Could not match instance creation expression with constructor')

    return [
      'call {0}'.format(class_defn.c_create_object_function_label),
      'push eax ; push instance object',
      param_code,
      'call {0}'.format(constructor.c_defn_label),
      pop_params,
      'pop eax ; restore the instance to eax',
    ]
예제 #3
0
  def c_gen_code(self):
    # Quickly handle string concat to avoid multiple code gens of children.
    if self.operator == '+' and str(self.expr_type) == 'java.lang.String':
      import code_gen.string
      return code_gen.string.string_concat(self)

    # We provide the code to generate the value of each operand separately as
    # some operators (e.g. &&) will not necessarily evaluate both.
    left_operand = common.store_param(self.left_expr)
    right_operand = common.store_param(self.right_expr)

    lazy_ops = {
        '+': '_add_int',
        '-': '_sub_int',
        '*': '_mult_int',
        '/': '_divide_int',
        '%': '_mod_int',
        '&': '_eager_and',
        '|': '_eager_or',
        '>': '_greater_than',
        '>=': '_greater_than_eq',
        '<': '_less_than',
        '<=': '_less_than_eq',
    }

    if self.operator in lazy_ops.keys():
      op_function = lazy_ops[self.operator]
      return [
          left_operand,
          right_operand,
          'call {0}'.format(op_function),
          'pop ebx  ; pop second param',
          'pop ebx  ; pop first param',
          '; eax contains a pointer to the result'
      ]
    elif self.operator == '&&':
      done_eval = manager.CodeGenManager.get_label('done_and_and_operator')
      return [
          '; start &&',
          common.if_false(self.left_expr, done_eval),
          self.right_expr.c_gen_code(),
          '{0}:'.format(done_eval),
          '; eax contains a pointer to the result',
          '; end &&',
      ]
    elif self.operator == '||':
      done_eval = manager.CodeGenManager.get_label('done_or_or_operator')
      return [
          '; start ||',
          common.if_true(self.left_expr, done_eval),
          self.right_expr.c_gen_code(),
          '{0}:'.format(done_eval),
          '; eax contains a pointer to the result',
          '; end ||',
      ]
    elif self.operator == '==' or self.operator == '!=':
      # For == and !=, we have to handle primitive types and references types
      # differently.
      equality_ops = {
        '==': ['_equals_prim', '_equals_ref'],
        '!=': ['_not_equals_prim', '_not_equals_ref'],
      }
      if self.left_expr.expr_type.is_primitive:
        op_function = equality_ops[self.operator][0]
      else:
        op_function = equality_ops[self.operator][1]

      return [
          left_operand,
          right_operand,
          'call {0}'.format(op_function),
          'pop ebx  ; pop second param',
          'pop ebx  ; pop first param',
          '; eax contains a pointer to the result'
      ]

    return []