Beispiel #1
0
def print_main(main, modules):
    with open(main, 'w') as f:
        print("#include <stdio.h>", "\n", '#include "runtime.h"', "\n", sep='', file=f)
        for name in modules:
            print('void load_', w(name), '(struct thread *);', sep='', file=f)
            print('void clean_', w(name), '(struct thread *);', sep='', file=f)

        prints("""
                  """, """
                  extern struct str_obj *__main__;

                  int main(int argc, char *argv[])
                  {
                      struct thread thread = {0};
                      if (argc < 2) {
                          printf("Usage: %s main_module_name\\n", argv[0]);
                          return 1;
                      }
                  
                      rt_thread_init(&thread);
                      __main__ = rt_chars_to_str(&thread, (unsigned char *)argv[1], strlen(argv[1]));
                  """, f)
        for name in modules:
            print('    load_', w(name), '(&thread);', sep='', file=f)
        for name in modules:
            print('    clean_', w(name), '(&thread);', sep='', file=f)
        print('    rt_str_free(&thread, __main__);', file=f)
        print('}', file=f)
Beispiel #2
0
def put_vars(state, _id, pref, args, init=True):
    for _name, tp in interpreter.LIB.types[_id].items():
        if not _name or _name in args or _name.startswith('@') or _name.startswith('(cast)'):
            continue
        if tp.startswith('class:') or tp.startswith('f:') or tp.startswith('module:'):
            continue
        if is_ref(tp):
            ref_op(CleanupPrinter(state), tp, 'DEC_STACK', pref + w(_name))
        if init and is_ref(tp):
            tpstr = definer.typestrt(tp)
            state.print(tpstr, ' ', w(_name), f' = ({tpstr})0;')
        else:
            state.print(definer.typestrt(tp), ' ', w(_name), ';')
Beispiel #3
0
def gen_init(printer, scope_id, args, pref):
    var = interpreter.LIB.types[scope_id].items()
    #ret = interpreter.LIB.types[scope_id]['']

    for name, tp in var:
        if not name:
            continue
        if name in args:
            printer.print(pref, w(name), ' = ', w(name), ';')
            if is_ref(tp):
                ref_op(printer, tp, 'INC_HEAP', pref + w(name))
        elif is_ref(tp):
            ref_reset(printer, tp, pref + wrap(name))

    printer.print(pref, 'jump = 0;')
Beispiel #4
0
def func(phrases, j, state):
    s = phrases[j]
    _id = s.tree.phrase_id
    if not Scope.can_create(_id):
        return skip_segment(phrases, j)

    if _id in interpreter.LIB.generators:
        return gen_block(phrases, j, state, _id)

    scope = Scope(_id, state.scope)
    ret = definer.typestr(interpreter.LIB.types[_id][''])
    args = interpreter.LIB.func_args[_id]
    scope_name = scope_id_to_name(_id)

    alst = [definer.typestr(scope.find(arg)) + ' ' + w(arg) for arg in args]
    asep = ', ' if args else ''
    astr = 'struct thread *thread' + asep + ', '.join(alst)

    state.print(ret, ' f_', scope_name, '(', astr, ')')
    state.print('{')

    inner = State(scope, state.n_tabs)
    inner.shift(1)
    put_vars(inner, _id, '', args)
    inner.shift(-1)

    j = segment(phrases, j + 1, inner)
    
    inner.shift(1)
    inner.flush_cleanup()
    inner.shift(-1)

    state.print('}')

    return j
Beispiel #5
0
def maker(state, scope_id):
    scope = Scope.create_from_type('class:' + scope_id)
    name = scope_id_to_name(scope_id)
    init = definer.init_id(scope_id)

    state.print(f'static void unmake_', name, '(struct thread *thread, struct o_', name, ' *self)')
    state.msg_shift('{', 1)
    free_vars(state, scope_id + '[instance]', 'self->')
    state.print('free(self);')
    state.msg_shift('}', -1)

    if not init:
        state.print(f'struct o_{name}* f_', name, '(struct thread *thread)')
        state.msg_shift('{', 1)
        state.print(f'struct o_{name}* obj = NEW(o_{name});')
        state.print(f'obj->obj.free = (delete)unmake_{name};')
        zero_vars(state, scope_id + '[instance]', 'obj->')
        state.msg_shift('}', -1)
        return

    args = interpreter.LIB.func_args[init]
    init_name = scope_id_to_name(init)
    init_scope = Scope(init, scope)

    alst = [definer.typestr(init_scope.find(arg)) + ' ' + w(arg) for arg in args]
    asep = ', ' if len(args) > 1 else ''
    astr = 'struct thread *thread' + asep + ', '.join(alst[1:])

    state.print(f'struct o_{name}* f_', name, '(', astr, ')')
    state.msg_shift('{', 1)
    state.print(f'struct o_{name}* obj = NEW(o_{name});')
    state.print(f'obj->obj.free = (delete)unmake_{name};')
    zero_vars(state, scope_id + '[instance]', 'obj->')

    wargs = ', '.join(w(arg) for arg in args[1:])
    state.print(f'f_{init_name}(thread, obj', asep, wargs, ');')
    state.print(f'return obj;')
    state.msg_shift('}', -1)
Beispiel #6
0
def compile_ranges(name, ranges, phrases):
    scope = Scope.create_for_module(name, 'm_' + name + '.')
    state = State(scope, 0)

    Strings.append_named(name, 'module_name_str_' + name)

    state.print('struct {')
    state.shift(1)
    state.print('struct object obj;')
    put_vars(state, scope.scope_id, 'm_' + name + '.', [], init=False)
    state.shift(-1)
    state.print('} m_', name, ' = {0};')

    for start, tp in ranges:
        state.print('// ', phrases[start].debug)

        if tp == 'f':
            func(phrases, start, state)
        elif tp == 'class':
            obj(phrases, start, state)
        else:
            assert False, tp
    
    state.print('void load_', w(name), '(struct thread *thread)')
    state.print('{')

    segment(phrases, 0, state)

    state.print('}')

    state.print('void clean_', w(name), '(struct thread *thread)')
    state.print('{')
    state.shift(1)
    state.flush_cleanup()
    state.shift(-1)
    state.print('}')
Beispiel #7
0
    def find_full(self, name, depth=1):
        if name in self.types:
            wrapped = name if self.preserve_names else w(name)

            if self.stateless:
                full = (self.prefix * depth) + wrapped
            else:
                full = self.prefix + wrapped

            if name in self.casts:
                full = '(*(' + definer.typestr(
                    self.casts[name]) + ' *)' + full + ')'
                tp = self.casts[name]
            else:
                tp = self.types[name]

            return full, tp

        assert self.parent, name
        return self.parent.find_full(name, depth + 1)
Beispiel #8
0
def free_vars(state, scope_id, pref):
    var = interpreter.LIB.types[scope_id].items()
    for name, tp in var:
        if is_ref(tp):
            ref_op(state, tp, 'DEC_HEAP', pref + w(name))
Beispiel #9
0
def zero_vars(state, scope_id, pref):
    var = interpreter.LIB.types[scope_id].items()
    for name, tp in var:
        if is_ref(tp):
            ref_reset(state, tp, pref + w(name))
Beispiel #10
0
def gen_block(phrases, j, state, _id):
    scope = Scope(_id, state.scope, prefix='self->', stateless=True)
    ret = definer.typestr(interpreter.LIB.types[_id][''])
    args = interpreter.LIB.func_args[_id]

    if args:
        astr = ', ' + ', '.join(definer.typestr(interpreter.LIB.types[_id][a]) + ' ' + w(a) for a in args)
    else:
        astr = ''

    scope_name = scope_id_to_name(_id)
    comment_name = definer.Nest.comment_name(_id)

    state.print('/* free generator: ', comment_name, ' */')
    state.print('void free_', scope_name, f'(struct thread *thread, struct g_{scope_name} *it)')
    state.print('{')
    state.shift(1)
    gen_free(state, _id, args, 'it->')
    state.print('free(it);')
    state.shift(-1)
    state.print('}')

    state.print('/* init generator: ', comment_name, ' */')
    state.print('struct g_', scope_name, ' *f_', scope_name, f'(struct thread *thread', astr, ')')
    state.print('{')
    state.shift(1)
    state.print(f'struct g_{scope_name} *it = NEW(g_{scope_name});')
    gen_init(state, _id, args, 'it->')
    state.print('it->obj.free = (delete)free_', scope_name, ';')
    state.print('return it;')
    state.shift(-1)
    state.print('}')

    state.print('/* generator: ', comment_name, ' */')
    state.print(f'bool loop_{scope_name}(struct thread *thread, struct g_{scope_name} *self)')
    state.print('{')

    inner_state = State(scope, state.n_tabs + 1)
    j = gen_loop(inner_state, 'self->', phrases, j)

    state.print('}')

    return j
Beispiel #11
0
def wrap(name):
    assert not name.startswith('(cast)')
    return (anonymous(name) if name.startswith('@') else w(name))