示例#1
0
def if_expression(copy_strings, expression, target, variables_name, vtypes):
    from expression import generate_expression
    code = ''
    c1, t1, tt1 = generate_expression(None, expression.cond, vtypes,
                                      variables_name, copy_strings, False)
    code += c1
    tv = get_temp()
    used_temps.append(tv)
    code += t1.cast(Int(), tt1, [tv])
    if_true = get_temp_func()
    if_true_f = open(f'{if_true}.mcfunction', 'w')
    c2, t2, tt2 = generate_expression(None, expression.iftrue, vtypes,
                                      variables_name, copy_strings, True)
    if expression.iffalse is not None:
        if_false = get_temp_func()
        if_false_f = open(f'{if_false}.mcfunction', 'w')
        c3, t3, tt3 = generate_expression(None, expression.iffalse, vtypes,
                                          variables_name, copy_strings, True)
        if_false_f.write(c3)
        if_false_f.close()
        if tt3 is not None:
            for ttt in tt3:
                used_temps.remove(ttt)
        code += f'execute if score {tv} {NAMESPACE} matches 0 run function {NAMESPACE}:{if_false}\n'
    if_true_f.write(c2)
    if_true_f.close()
    code += f'execute unless score {tv} {NAMESPACE} matches 0 run function {NAMESPACE}:{if_true}\n'
    used_temps.remove(tv)
    for ttt in tt1:
        used_temps.remove(ttt)
    for ttt in tt2:
        used_temps.remove(ttt)
    return code, Void(), target
示例#2
0
def for_expression(copy_strings, expression, target, variables_name, vtypes):
    from expression import generate_expression
    code = ''
    if expression.init is not None:
        c1, t1, tt1 = generate_expression([], expression.init, vtypes,
                                          variables_name, copy_strings, True)
        code += c1
        for ttt in tt1:
            used_temps.remove(ttt)
    temp_name = get_temp_func()
    code += f'function {NAMESPACE}:{temp_name}\n'
    new = open(f'{temp_name}.mcfunction', 'w')
    a, b, c = generate_expression([], expression.stmt, vtypes, variables_name,
                                  copy_strings, True)
    for t in c:
        used_temps.remove(t)
    if expression.cond is not None:
        nc, nt, temps = generate_expression(None, expression.cond, vtypes,
                                            variables_name, copy_strings,
                                            False)
        new.write(nc)
        t2 = get_temp_func()
        new.write(
            f'execute unless score {temps[0]} {NAMESPACE} matches 0 if score $broken {NAMESPACE} matches 0 run function {NAMESPACE}:{t2}\n'
        )
        new.write(
            f'execute unless score {temps[0]} {NAMESPACE} matches 0 if score $returned {NAMESPACE} matches 0 if score $broken {NAMESPACE} matches 0 run function {NAMESPACE}:{temp_name}\n'
        )
        for temp in temps:
            used_temps.remove(temp)
        f2 = open(f'{t2}.mcfunction', 'w')
        f2.write(a)
        if expression.next is not None:
            a, b, c = generate_expression(None, expression.next, vtypes,
                                          variables_name, copy_strings, True)
            for t in c:
                used_temps.remove(t)
            f2.write(a)
        f2.close()
    else:
        new.write(a)
        if expression.next is not None:
            a, b, c = generate_expression(None, expression.next, vtypes,
                                          variables_name, copy_strings, True)
            for t in c:
                used_temps.remove(t)
            new.write(a)
        new.write(
            f'execute if score $broken {NAMESPACE} matches 0 run function {NAMESPACE}:{temp_name}\n'
        )
    new.close()
    if target is None:
        target = []
    code += f'scoreboard players set $broken {NAMESPACE} 0\n'
    return code, Void(), target
示例#3
0
def goto_postprocess():
    labels = {}
    gotoers = {}
    for file in os.listdir('.'):
        if file == 'main.mcfunction': continue
        if os.path.isdir(file): continue
        content = open(file).read()
        m = re.findall(r'label (.*)', content)
        content = re.split(r'label .*', content)
        fname = file
        file = open(file, 'w')
        file.write(content[0].strip())
        for a, b in zip(m, content[1:]):
            new_file = get_temp_func()
            file.write(f'\nfunction {NAMESPACE}:{new_file}')
            file.close()
            file = open(new_file + '.mcfunction', 'a')
            file.write(b.strip())
            labels[a] = new_file
        file.write('\n')
        if len(m) != 0:
            gotoers[fname[:-len('.mcfunction')]] = file
    print(gotoers)
    while len(gotoers) > 0:
        ng = {}
        print(gotoers)
        for a in gotoers:
            c = get_callers(a)
            assert len(c) == 1, 'Too many callers for label'
            oc = c[0]
            c = c[0] + '.mcfunction'
            content = open(c).read().split(f'function {NAMESPACE}:{a}')
            assert len(content) == 2, 'Too many callers for label'
            file = open(c, 'w')
            file.write(content[0] + f'function {NAMESPACE}:{a}')
            file.close()
            new_file = get_temp_func()
            gotoers[a].write(f'\nfunction {NAMESPACE}:{new_file}')
            gotoers[a].close()
            file = open(new_file + '.mcfunction', 'w')
            file.write(content[1])
            if not oc.startswith('method_'):
                ng[oc] = file
        gotoers = ng
    for file in os.listdir('.'):
        if file == 'main.mcfunction': continue
        if os.path.isdir(file): continue
        content = open(file).read()
        open(file, 'w').write(
            re.sub(r'goto (.*)',
                   lambda a: f'function {NAMESPACE}:{labels[a.group(1)]}',
                   content))
示例#4
0
def binary_expression(copy_strings, expression, target, variables_name,
                      vtypes):
    from expression import generate_expression
    c1, t1, tt1 = generate_expression(None, expression.left, vtypes,
                                      variables_name, copy_strings, False)
    c2, t2, tt2 = generate_expression(None, expression.right, vtypes,
                                      variables_name, copy_strings, False)
    for ttt in tt1:
        used_temps.remove(ttt)
    for ttt in tt2:
        used_temps.remove(ttt)
    ot = cast(t1, t2)
    rt = ot
    if expression.op in ['<', '>', '<=', '>=', '==', '!=', '&&']:
        rt = Int()
    if target is None or target == []:
        target = [get_temp() for _ in range(ot.size)]
        used_temps.extend(target)
    code = ''
    if expression.op in ['&&', '||']:
        if expression.op == '&&':
            code += c1
            code += t1.cast(ot, tt1, target)
            f2 = get_temp_func()
            f2h = open(f'{f2}.mcfunction', 'w')
            f2h.write(c2)
            f2h.write(t2.cast(ot, tt2, target))
            f2h.close()
            code += f'execute unless score {target[0]} {NAMESPACE} matches 0 run function {NAMESPACE}:{f2}\n'
        elif expression.op == '||':
            code += c1
            code += t1.cast(ot, tt1, target)
            f2 = get_temp_func()
            f2h = open(f'{f2}.mcfunction', 'w')
            f2h.write(c2)
            f2h.write(t2.cast(ot, tt2, target))
            f2h.close()
            code += f'execute if score {target[0]} {NAMESPACE} matches 0 run function {NAMESPACE}:{f2}\n'
    else:
        if ot == t1:
            code += c1
            code += c2
            code += t2.cast(ot, tt2, target)
            code += ot.binary(expression.op, tt1, target, target)
        else:
            code += c1
            code += t1.cast(ot, tt1, target)
            code += c2
            code += ot.binary(expression.op, target, tt2, target)
    return code, rt, target
示例#5
0
def funccall_expression(copy_strings, expression, variables_name, vtypes):
    from expression import generate_expression
    arguments = []
    code = ''
    # print(vtypes)
    direct = True
    if expression.name.name in vtypes:
        crtype = vtypes[expression.name.name].ptr.ret_type
        funcargs = vtypes[expression.name.name].ptr.args
        direct = False
    else:
        crtype = return_types[expression.name.name]
        funcargs = fargs[expression.name.name]
    if expression.args is not None:
        for i, expr in enumerate(expression.args.exprs):
            c1, t1, tt1 = generate_expression(None, expr, vtypes,
                                              variables_name, copy_strings,
                                              False)
            code += c1
            if i < len(funcargs) and cname(funcargs[i]) != cname(t1):
                ctemps = [get_temp() for _ in range(funcargs[i].size)]
                code += t1.cast(funcargs[i], tt1, ctemps)
                arguments.extend(ctemps)
                used_temps.extend(ctemps)
                for arg in tt1:
                    used_temps.remove(arg)
            else:
                arguments.extend(tt1)
    for arg in arguments:
        used_temps.remove(arg)
    code += save_temps(used_temps)
    code += save_locals(local_size())
    for i, arg in enumerate(arguments):
        code += f'scoreboard players operation $l{i} {NAMESPACE} = {arg} {NAMESPACE}\n'
    if direct:
        code += f'function {NAMESPACE}:method_{expression.name.name.lower()}\n'
    else:
        if (crtype, tuple(funcargs)) not in functrees:
            functrees[(crtype, tuple(funcargs))] = get_temp_func()
            possibilities = list(
                filter(
                    lambda x: return_types[x] == crtype and fargs[x] ==
                    funcargs, list(return_types)))
            assert len(possibilities), 'No function of matching type'
            if len(possibilities) == 1:
                functrees[(crtype, tuple(funcargs))] = possibilities[0]
            else:
                code += f'scoreboard players operation $func_id {NAMESPACE} = {variables_name[expression.name.name][0]} {NAMESPACE}\n'
                raise NotImplementedError()
            # print(possibilities)
        # print(return_types, crtype, fargs, funcargs)
        code += f'function {NAMESPACE}:method_{functrees[(crtype, tuple(funcargs))]}\n'
    code += unsave_temps(used_temps)
    code += unsave_locals(local_size())
    targets = [get_temp() for _ in range(crtype.size)]
    used_temps.extend(targets)
    for i, t in enumerate(targets):
        code += f'scoreboard players operation {t} {NAMESPACE} = $r{i} {NAMESPACE}\n'
    return code, crtype, targets
示例#6
0
def compound_expression(copy_strings, expression, target, variables_name,
                        vtypes):
    from expression import generate_expression
    code = ''
    pausable = expression.block_items[:-1]
    returns = 'Return' in str(pausable)  # lolol
    breaks = 'Break' in str(pausable)  # lolol
    gotos = 'Goto' in str(pausable)  # lolol
    to_free = []
    clocals = 0
    for e in expression.block_items:
        if cname(e) == 'Decl':
            name = e.name
            ctype = e.type
            vtypes[name] = get_type(ctype)
            cvals = []
            for _ in range(vtypes[name].size):
                cvals.append(create_local())
                clocals += 1
            variables_name[name] = cvals
            if cname(ctype) == 'ArrayDecl':
                alloc_size = int(ctype.dim.value)
                assert alloc_size < 1024, 'Too big local array, make it global!'
                code += f'''data modify storage {NAMESPACE}:main temp set from storage {NAMESPACE}:main alloc[{{used:0}}].index
execute store result score $r0 {NAMESPACE} run data get storage {NAMESPACE}:main temp
function {NAMESPACE}:tree/mark_used
scoreboard players operation {cvals[0]} {NAMESPACE} = $r0 {NAMESPACE}
scoreboard players operation {cvals[0]} {NAMESPACE} *= $1024 {NAMESPACE}
scoreboard players add {cvals[0]} {NAMESPACE} 536870912
'''
                to_free.append(cvals[0])
    if not (returns or breaks or gotos):
        for e in expression.block_items:
            c1, t1, tt1 = generate_expression([], e, vtypes, variables_name,
                                              copy_strings, True)
            code += c1
            if tt1 is not None:
                for ttt in tt1:
                    used_temps.remove(ttt)
    else:
        for e in expression.block_items:
            cf = get_temp_func()
            cff = open(f'{cf}.mcfunction', 'w')
            c1, t1, tt1 = generate_expression([], e, vtypes, variables_name,
                                              copy_strings, True)
            cff.write(c1)
            if tt1 is not None:
                for ttt in tt1:
                    used_temps.remove(ttt)
            code += f'execute if score $returned {NAMESPACE} matches 0 if score $broken {NAMESPACE} matches 0 run function {NAMESPACE}:{cf}\n'
    if target is None:
        target = []
    remove_locals(clocals)
    for tof in to_free:
        code += f'scoreboard players operation $index {NAMESPACE} = {tof} {NAMESPACE}\n'
        code += f'function {NAMESPACE}:tree/free\n'
    return code, Void(), target
示例#7
0
def ternary_expression(copy_strings, expression, target, variables_name,
                       vtypes):
    from expression import generate_expression
    code = ''
    c1, t1, tt1 = generate_expression(None, expression.cond, vtypes,
                                      variables_name, copy_strings, False)
    code += c1
    tv = get_temp()
    used_temps.append(tv)
    code += t1.cast(Int(), tt1, [tv])
    if_true = get_temp_func()
    if_false = get_temp_func()
    if_true_f = open(f'{if_true}.mcfunction', 'w')
    if_false_f = open(f'{if_false}.mcfunction', 'w')
    c2, t2, tt2 = generate_expression(None, expression.iffalse, vtypes,
                                      variables_name, copy_strings, False)
    c3, t3, tt3 = generate_expression(None, expression.iftrue, vtypes,
                                      variables_name, copy_strings, False)
    ot = cast(t2, t3)
    if target is None:
        target = [get_temp() for _ in range(ot.size)]
        used_temps.extend(target)
    if_true_f.write(c3)
    if len(target) != 0:
        if_true_f.write(t3.cast(ot, tt3, target))
    if_false_f.write(c2)
    if len(target) != 0:
        if_false_f.write(t2.cast(ot, tt2, target))
    if_true_f.close()
    if_false_f.close()
    used_temps.remove(tv)
    for ttt in tt1:
        used_temps.remove(ttt)
    for ttt in tt2:
        used_temps.remove(ttt)
    for ttt in tt3:
        used_temps.remove(ttt)
    code += f'execute if score {tv} {NAMESPACE} matches 0 run function {NAMESPACE}:{if_false}\n'
    code += f'execute unless score {tv} {NAMESPACE} matches 0 run function {NAMESPACE}:{if_true}\n'
    return code, ot, target
示例#8
0
def while_expression(copy_strings, expression, target, variables_name, vtypes):
    from expression import generate_expression
    code = ''
    c1, t1, tt1 = generate_expression(None, expression.cond, vtypes, variables_name, copy_strings, False)
    code += c1
    tv = get_temp()
    used_temps.append(tv)
    code += t1.cast(Int(), tt1, [tv])
    loop = get_temp_func()
    loop_f = open(f'{loop}.mcfunction', 'w')
    if_true = get_temp_func()
    if_true_f = open(f'{if_true}.mcfunction', 'w')
    c2, t2, tt2 = generate_expression(None, expression.stmt, vtypes, variables_name, copy_strings, True)
    if_true_f.write(c2)
    if_true_f.write(f'function {NAMESPACE}:{loop}\n')
    if_true_f.close()
    code += f'execute unless score {tv} {NAMESPACE} matches 0 if score $returned {NAMESPACE} matches 0 if score $broken {NAMESPACE} matches 0 run function {NAMESPACE}:{if_true}\n'
    loop_f.write(code)
    loop_f.close()
    used_temps.remove(tv)
    for ttt in tt1: used_temps.remove(ttt)
    for ttt in tt2: used_temps.remove(ttt)
    return f'function {NAMESPACE}:{loop}\n' \
           f'scoreboard players set $broken {NAMESPACE} 0\n', Void(), target