Пример #1
0
def _exp_ge(code: Code, exp):
    left = exp['left']
    right = exp['right']
    left_type = exp['left']['type']
    _expression(code, left)
    _expression(code, right)

    if isinstance(left_type, TypeInt) or isinstance(left_type, TypeReal):
        if isinstance(left_type, TypeReal):
            code.cmp_double_g()
            cmp_pos = code.pos()
            code.if_ge()
        else:
            cmp_pos = code.pos()
            code.if_cmp_int_ge()
        code.const_int(0)
        goto_pos = code.pos()
        code.goto()
        true_pos = code.pos()
        code.const_int(1)
        end_pos = code.pos()

        code.update_jump(cmp_pos, true_pos)
        code.update_jump(goto_pos, end_pos)
    else:
        raise NotImplementedError()
Пример #2
0
def _exp_eq(code: Code, exp):
    left = exp['left']
    right = exp['right']
    left_type = exp['left']['type']
    _expression(code, left)
    _expression(code, right)

    if isinstance(left_type, TypeInt) or isinstance(
            left_type, TypeBool) or isinstance(left_type, TypeReal):
        if isinstance(left_type, TypeReal):
            code.cmp_double_l()
            cmp_pos = code.pos()
            code.if_eq()
        else:
            cmp_pos = code.pos()
            code.if_cmp_int_eq()
        code.const_int(0)
        goto_pos = code.pos()
        code.goto()
        true_pos = code.pos()
        code.const_int(1)
        end_pos = code.pos()

        code.update_jump(cmp_pos, true_pos)
        code.update_jump(goto_pos, end_pos)
    elif isinstance(left_type, TypeStr):
        code.invoke_virtual(*JM_STRING_EQUALS)
    else:
        raise NotImplementedError()
Пример #3
0
def _statement_if_else(code: Code,
                       statement,
                       loop_start: Optional[int] = None,
                       breaks: Optional[List[int]] = None):
    condition = statement['condition']
    if_statements = statement['if_statements']
    else_statements = statement['else_statements']

    _expression(code, condition)
    cond_pos = code.pos()
    code.if_eq()

    for s in if_statements:
        _statement(code, s, loop_start, breaks)

    goto_pos = code.pos()
    code.goto()

    else_pos = code.pos()
    for s in else_statements:
        _statement(code, s, loop_start, breaks)

    end_pos = code.pos()

    code.update_jump(cond_pos, else_pos)
    code.update_jump(goto_pos, end_pos)
Пример #4
0
def _statement_if(code: Code,
                  statement,
                  loop_start: Optional[int] = None,
                  breaks: Optional[List[int]] = None):
    condition = statement['condition']
    statements = statement['statements']

    _expression(code, condition)
    cond_pos = code.pos()
    code.if_eq()

    for s in statements:
        _statement(code, s, loop_start, breaks)

    end_pos = code.pos()
    code.update_jump(cond_pos, end_pos)
Пример #5
0
def _statement_while(code: Code, statement):
    condition = statement['condition']
    statements = statement['statements']

    start = code.pos()
    _expression(code, condition)
    cond_pos = code.pos()
    code.if_eq()

    breaks = []
    for s in statements:
        _statement(code, s, start, breaks)

    code.goto(start)
    end_pos = code.pos()
    code.update_jump(cond_pos, end_pos)
    for b in breaks:
        code.update_jump(b, end_pos)
Пример #6
0
def _exp_not(code: Code, exp):
    expression = exp['expression']
    exp_type = exp['expression']['type']
    _expression(code, expression)

    if isinstance(exp_type, TypeBool):
        cmp_pos = code.pos()
        code.if_eq()
        code.const_int(0)
        goto_pos = code.pos()
        code.goto()
        false_pos = code.pos()
        code.const_int(1)
        end_pos = code.pos()

        code.update_jump(cmp_pos, false_pos)
        code.update_jump(goto_pos, end_pos)
    else:
        raise NotImplementedError()
Пример #7
0
def _exp_or(code: Code, exp):
    left = exp['left']
    right = exp['right']
    t = exp['type']
    _expression(code, left)
    _expression(code, right)

    if isinstance(t, TypeBool):
        cmp1_pos = code.pos()
        code.if_ne()
        cmp2_pos = code.pos()
        code.if_ne()
        code.const_int(0)
        goto_pos = code.pos()
        code.goto()
        true_pos = code.pos()
        code.const_int(1)
        end_pos = code.pos()

        code.update_jump(cmp1_pos, true_pos)
        code.update_jump(cmp2_pos, true_pos)
        code.update_jump(goto_pos, end_pos)
    else:
        raise NotImplementedError()
Пример #8
0
def _exp_and(code: Code, exp):
    left = exp['left']
    right = exp['right']
    left_type = exp['left']['type']
    _expression(code, left)
    _expression(code, right)

    if isinstance(left_type, TypeBool):
        cmp1_pos = code.pos()
        code.if_eq()
        cmp2_pos = code.pos()
        code.if_eq()
        code.const_int(1)
        goto_pos = code.pos()
        code.goto()
        false_pos = code.pos()
        code.const_int(0)
        end_pos = code.pos()

        code.update_jump(cmp1_pos, false_pos)
        code.update_jump(cmp2_pos, false_pos)
        code.update_jump(goto_pos, end_pos)
    else:
        raise NotImplementedError()
Пример #9
0
def _exp_function_call(code: Code, exp):
    name = exp['name']
    args_exps = exp['arguments']
    params = exp['parameters']
    ret = exp['type']

    for e in args_exps:
        _expression(code, e)

    # check for predefined functions
    if name == FN_LEN and len(params) == 1:
        if isinstance(params[0], TypeStr):
            code.invoke_virtual(*JM_STRING_LENGTH)
            return
        elif isinstance(params[0], TypeArray):
            code.array_length()
            return

    if name == FN_INT and len(params) == 1:
        if isinstance(params[0], TypeInt):
            # nothing to do
            return
        elif isinstance(params[0], TypeReal):
            code.double_to_int()
            return
        elif isinstance(params[0], TypeBool):
            # nothing to do
            return
        elif isinstance(params[0], TypeStr):
            code.invoke_static(*JSM_INT_PARSE)
            return

    if name == FN_REAL and len(params) == 1:
        if isinstance(params[0], TypeInt):
            code.int_to_double()
            return
        elif isinstance(params[0], TypeReal):
            # nothing to do
            return
        elif isinstance(params[0], TypeBool):
            code.int_to_double()
            return
        elif isinstance(params[0], TypeStr):
            code.invoke_static(*JSM_DOUBLE_PARSE)
            return

    if name == FN_BOOL and len(params) == 1:
        if isinstance(params[0], TypeInt):
            code.const_int(1)
            code.and_int()
            return
        elif isinstance(params[0], TypeReal):
            code.const_double(0.0)
            code.cmp_double_l()
            cmp_pos = code.pos()
            code.if_eq()
            code.const_int(1)
            goto_pos = code.pos()
            code.goto()
            false_pos = code.pos()
            code.const_int(0)
            end_pos = code.pos()

            code.update_jump(cmp_pos, false_pos)
            code.update_jump(goto_pos, end_pos)
            return
        elif isinstance(params[0], TypeBool):
            # nothing to do
            return
        elif isinstance(params[0], TypeStr):
            code.invoke_static(*JSM_BOOLEAN_PARSE)
            return

    if name == FN_STR and len(params) == 1:
        if isinstance(params[0], TypeInt):
            code.invoke_static(*JSM_INT_TO_STRING)
            return
        elif isinstance(params[0], TypeReal):
            code.invoke_static(*JSM_DOUBLE_TO_STRING)
            return
        elif isinstance(params[0], TypeBool):
            code.invoke_static(*JSM_BOOLEAN_TO_STRING)
            return

    if name == FN_SUBSTRING and len(params) == 3:
        if isinstance(params[0], TypeStr) and isinstance(
                params[1], TypeInt) and isinstance(params[2], TypeInt):
            code.invoke_static(*JM_STRING_SUBSTRING)
            return

    if name == FN_WRITE and len(params) == 1:
        if isinstance(params[0], TypeStr):
            code.load_static_field(*JSF_STDOUT)
            code.swap()
            code.invoke_virtual(*JM_PRINT)
            return

    if name == FN_READ_LINE and len(params) == 0:
        code.load_static_field(_class_name, BUFF_READER_FIELD,
                               ClassDesc(JC_BUFF_READER))
        code.invoke_virtual(*JM_READLINE)

        # if result null, set the eof field to true and load empty string
        code.dup()
        cmp_pos = code.pos()
        code.if_non_null()
        code.const_int(1)
        code.store_static_field(_class_name, EOF_FIELD, BooleanDesc())
        code.const_string('')
        end_pos = code.pos()
        code.update_jump(cmp_pos, end_pos)
        return

    if name == FN_EOF and len(params) == 0:
        code.load_static_field(_class_name, EOF_FIELD, BooleanDesc())
        return

    # custom function
    name = PREFIX + name
    desc = _create_method_descriptor(params, ret)
    code.invoke_static(_class_name, name, desc)