コード例 #1
0
ファイル: udf.py プロジェクト: christophschubert/ulisp-python
def compile_expression(arg, destination, scope):
    if isinstance(arg, list):
        compile_call(arg[0], arg[1:], destination, scope)
    elif scope.get(arg) or isinstance(arg, int):
        emit(1, f'MOV {destination}, {scope.get(arg, arg)}')
    else:
        raise "referenced undef variable"
コード例 #2
0
def compile_call(fun, args, destination):
    for a, reg in zip(args, PARAM_REGISTERS):
        emit(1, "PUSH {}".format(reg))
    for a, reg in zip(args, PARAM_REGISTERS):
        compile_argument(a, reg)
    emit(1, 'CALL {}'.format(BUILDIN_FUNCTIONS.get(fun, fun)))
    for a, reg in list(zip(args, PARAM_REGISTERS))[::-1]:
        emit(1, 'POP ' + reg)
    if destination:
        emit(1, 'MOV {}, RAX'.format(destination))
    emit(0, '')
コード例 #3
0
ファイル: udf.py プロジェクト: christophschubert/ulisp-python
def compile_define(f_def, destination, scope):
    LOCAL_REGISTERS = ['RBX', 'RBP', 'R12']

    name, parameters, *body = f_def

    scope[name] = name.replace('-', '_')

    child_scope = scope.copy()
    emit(0, f'{scope[name]}:')
    for param, param_reg, local_reg in zip(parameters, PARAM_REGISTERS,
                                           LOCAL_REGISTERS):
        emit(1, f'PUSH {local_reg}')
        emit(1, f'MOV {local_reg}, {param_reg}')
        child_scope[param] = local_reg

    compile_expression(body[0], 'RAX', child_scope)

    for a, reg in list(zip(parameters, LOCAL_REGISTERS))[::-1]:
        emit(1, 'POP ' + reg)

    emit(1, 'RET\n')
コード例 #4
0
ファイル: udf.py プロジェクト: christophschubert/ulisp-python
def compile_call(fun, args, destination, scope):
    if PRIMITIVE_FUNCTIONS.get(fun):
        PRIMITIVE_FUNCTIONS.get(fun)(args, destination, scope)
        return

    for a, reg in zip(args, PARAM_REGISTERS):
        emit(1, "PUSH {}".format(reg))
    for a, reg in zip(args, PARAM_REGISTERS):
        compile_expression(a, reg, scope)
    valid_function = BUILDIN_FUNCTIONS.get(fun, scope.get(fun))
    if valid_function:
        emit(1, f'CALL {valid_function}')
    else:
        raise "ERROR, unknown function " + fun

    for a, reg in list(zip(args, PARAM_REGISTERS))[::-1]:
        emit(1, 'POP ' + reg)
    if destination and destination != 'RAX':
        emit(1, f'MOV {destination}, RAX')
コード例 #5
0
def compile_argument(arg, destination):
    if isinstance(arg, list):
        compile_call(arg[0], arg[1:], destination)
        return
    emit(1, "MOV {}, {}".format(destination, arg))
コード例 #6
0
    if isinstance(arg, list):
        compile_call(arg[0], arg[1:], destination)
        return
    emit(1, "MOV {}, {}".format(destination, arg))

BUILDIN_FUNCTIONS = { '+': 'plus'}

def compile_call(fun, args, destination):
    for a, reg in zip(args, PARAM_REGISTERS):
        emit(1, "PUSH {}".format(reg))
    for a, reg in zip(args, PARAM_REGISTERS):
        compile_argument(a, reg)
    emit(1, 'CALL {}'.format(BUILDIN_FUNCTIONS.get(fun, fun)))
    for a, reg in list(zip(args, PARAM_REGISTERS))[::-1]:
        emit(1, 'POP ' + reg)
    if destination:
        emit(1, 'MOV {}, RAX'.format(destination))
    emit(0, '')





if __name__ == '__main__':
    program = sys.argv[1] if len(sys.argv) > 1 else '(+ 3 (+ 1 2))'
    ast = parser.parse(program)
    emit_prefix()
    emit(0, '_main:')
    compile_call(ast[0], ast[1:], None)
    emit_exit_syscall()
コード例 #7
0
ファイル: udf.py プロジェクト: christophschubert/ulisp-python
    for a, reg in zip(args, PARAM_REGISTERS):
        emit(1, "PUSH {}".format(reg))
    for a, reg in zip(args, PARAM_REGISTERS):
        compile_expression(a, reg, scope)
    valid_function = BUILDIN_FUNCTIONS.get(fun, scope.get(fun))
    if valid_function:
        emit(1, f'CALL {valid_function}')
    else:
        raise "ERROR, unknown function " + fun

    for a, reg in list(zip(args, PARAM_REGISTERS))[::-1]:
        emit(1, 'POP ' + reg)
    if destination and destination != 'RAX':
        emit(1, f'MOV {destination}, RAX')


if __name__ == '__main__':

    scope = {}
    emit_prefix()
    for line in sys.stdin:
        ast = parser.parse(line)
        compile_call(ast[0], ast[1:], 'RAX', scope)

    # the '_main' program
    emit(0, '_main:')
    emit(1, 'CALL main')

    emit_exit_syscall()