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)
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), ';')
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;')
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
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)
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('}')
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)
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))
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))
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
def wrap(name): assert not name.startswith('(cast)') return (anonymous(name) if name.startswith('@') else w(name))