Beispiel #1
0
def post_visit(g, code, tmp, d_stack, expd_dels, n, visited) :

#	print "post_visit", n, n.prototype

	if core.compare_proto_to_type(n.prototype, core.ConstProto) :
		return None # handled elsewhere

	if core.compare_proto_to_type(n.prototype, core.DelayInProto) :
		del_in, del_out = expd_dels[n.delay]
#		print 1
		if not del_out in visited :
#			print 2
			slot = add_tmp_ref(tmp, [ (del_in, del_in.terms[0], 0) ])
			code.append("del%i to tmp%i" % (n.nr, slot))
		code.append("to del%i" % n.nr)
	elif core.compare_proto_to_type(n.prototype, core.DelayOutProto) :
		del_in, del_out = expd_dels[n.delay]
		if del_in in visited :
			slot = pop_tmp_ref(tmp, del_in, del_in.terms[0], 0)
			code.append("tmp%i" % slot)
		else :
			code.append("del%i" % n.nr)
	else :
		assert(n.prototype.exe_name != None)
		code.append(n.prototype.exe_name)

	#manage outputs
	outputs = g[n].s
	for out_term, out_t_nr, succs in outputs :
#		print "out_term, succs", out_term, succs
		if len(succs) == 1 :
			if len(n.prototype.outputs) == 1 :
#XXX				d_stack.append(succs[0])
				d_stack.append((n, out_term, out_t_nr))
			else :
				slot = add_tmp_ref(tmp, list(succs))
				code.append("to tmp%i" % slot)
			pass # store on d stack, OR NO!?! (allways) possible only with single-output block
		elif len(succs) > 1 :
			if len(n.prototype.outputs) == 1 :
				code.append("dup")
#				print "post_visit, leaving on d:", succs[0]
#XXX				d_stack.append(succs[0])
				d_stack.append((n, out_term, out_t_nr))
#			print "list(succs)=", list(succs)
			slot = add_tmp_ref(tmp, list(succs)) #XXX including one to be taken from d, not good
			code.append("to tmp%i" % slot)
			pass # leading to multiple inputs, store in temp
		else :
			code.append("drop")# unconnected, drop
Beispiel #2
0
def expand_macroes(g, library, known_types, local_block_sheets, block_cache=None) :
	cache = block_cache_init() if block_cache is None else block_cache
	new_delays = {}
	prev_batch = set()
	macroes = { b for b in g if core.compare_proto_to_type(b.prototype, core.MacroProto) }
	while macroes != prev_batch :
		for n in sorted(macroes) :
			delays, = __expand_macro(g, library, n, known_types, cache, local_block_sheets)
			new_delays.update(delays)
		prev_batch = set(macroes)
		macroes = { b for b in g if core.compare_proto_to_type(b.prototype, core.MacroProto) }
	if macroes :
		raise Exception("failed to {0} expand macroes".format(len(macroes)))
	return (new_delays, )
Beispiel #3
0
def __expand_macro(g, library, n, known_types, cache, local_block_sheets) :
	name = n.prototype.exe_name
	full_name = n.prototype.library + "." + name

#	print here(), full_name

	sheet = None
	if n.prototype.library == "<local>" :
#		print here(), full_name
		sheet_name = "@macro:" + name
		if sheet_name in local_block_sheets :
			sheet = core.clone_sheet(local_block_sheets[sheet_name][1], library)
	else :
		sheet = core.load_library_sheet(library, full_name, "@macro:" + name)

	if sheet is None :
		raise Exception("failed to expand macro '" + full_name + "'")

	offset = reduce(max, (b.nr for b in g if core.compare_proto_to_type(b.prototype, core.DelayInProto)), 0)#TODO
	gm, delays = make_dag(sheet, None, known_types, do_join_taps=False, delay_numbering_start=offset+1)

#TODO
#	print here(), full_name, full_name in cache
#	if full_name in cache :
#		block = cache[full_name]
#	else :
#		block = __instantiate_macro(library, full_name)
#		cache[full_name] = block

	inputs = { b.value[0] : (b, s[0][2]) for b, (_, s) in gm.items() if core.compare_proto_to_type(b.prototype, core.InputProto) }
	outputs = { b.value[0] : (b, p[0][2]) for b, (p, _) in gm.items() if core.compare_proto_to_type(b.prototype, core.OutputProto) }

	for io_blocks in (inputs, outputs) :
		for io, _ in io_blocks.values() :
			remove_block(gm, io)

	p, s = g[n]

	#XXX to handle variadic terms map p -> inputs

	map_in = { (it, it_nr) : tuple((b, t, nr) for b, t, nr in inputs[it.name][1])
		for it, it_nr, _ in p }
	map_out = { (ot, ot_nr) : tuple((b, t, nr) for b, t, nr in outputs[ot.name][1])
		for ot, ot_nr, _ in s }

	remove_block_and_patch(g, n, gm, map_in, map_out)

	return (delays, )
Beispiel #4
0
	def get_term_presentation_text(self, t, nr) :
		term_label = t.name
		if core.compare_proto_to_type(self.prototype, core.ConstProto) :
			term_label = ""#str(self.model.value)
		if t.variadic : #XXX nr != None
			term_label += str(self.get_term_index(t, nr))
		return term_label
Beispiel #5
0
def __infer_types_pre_dive(g, delays, types, known_types, n, nt, nt_nr, m, mt, mt_nr, visited) :
	mt_type_name = mt.type_name
#	print(here(), n, nt, nt_nr, "<-", m, mt, mt_nr, "type:", mt_type_name)
	if mt_type_name == core.TYPE_INFERRED :
		if core.compare_proto_to_type(m.prototype, core.DelayOutProto) :
			value_type, _ = parse_literal(delays[m], known_types=known_types)
			mt_type_name = types[m, mt, mt_nr] = value_type
		elif core.compare_proto_to_type(m.prototype, core.ConstProto) :
			value_type, _ = parse_literal(m.value[0], known_types=known_types)
			mt_type_name = types[m, mt, mt_nr] = value_type
		else :
			types[m, mt, mt_nr] = mt_type_name = infer_block_type(m, g[m].p, types, known_types)
			if core.compare_proto_to_type(m.prototype, core.DelayOutProto) :
				pass
	if nt.type_name == core.TYPE_INFERRED :
		types[n, nt, nt_nr] = mt_type_name
Beispiel #6
0
def __expand_delays(blocks, conns, delay_numbering_start) :

	delays = frozenset(b for b in blocks
		if core.compare_proto_to_type(b.prototype, core.DelayProto, core.InitDelayProto))
#	delays = { b for b in blocks if core.compare_proto_to_type(b.prototype, core.DelayProto) }
#	print here(), delays

	expd = dict(__expddel(delay, delay_numbering_start + nr) for delay, nr in zip(delays, count()))
#	print here(), expd

#	def mkvert(src, io) :
#		b, t = src
#		block, term = ( ( expd[b][io], expd[b][io].terms[0] )
#			if core.compare_proto_to_type(b.prototype, core.DelayProto)
#			else (b, t) )

#		return (block, ) + t_unpack(term)

	conns2 = {}
	for s, dests in conns.items() :
		k = __mkvert(s, expd)
		v = [ __mkvert(d, expd) for d in dests ]
#		print here(), "s:", s, "dests:", dests, #"k:", k, "v:", v
		conns2[k] = v

#	sys.exit(0)

#	conns2 = { __mkvert(s, 1, expd) : [ __mkvert(d, 0, expd) for d in dests ] for s, dests in conns.items() }

	return list((set(blocks)-delays).union(chain(*expd.values()))), conns2, expd
Beispiel #7
0
def get_taps(g) :
	"""
	return { tap_name : tap, ... }
	"""
	tap_list = [ b for b, (p, s) in g.items() if core.compare_proto_to_type(b.prototype, core.TapProto) ]
	taps = { b.value : b for b in tap_list }
	assert(len(tap_list)==len(taps))
	return taps
Beispiel #8
0
def get_tap_ends(g) :
	"""
	return { tap_name : [ tap_end1, ...], ... }
	"""
	tap_ends_list = { b for b in g.keys() if core.compare_proto_to_type(b.prototype, core.TapEndProto) }
	tap_ends = groupby_to_dict(tap_ends_list, lambda b: b.value, lambda b: b, lambda x: list(x))
	assert( len(tap_ends_list) == sum([len(v) for v in tap_ends.values()]) )
	return tap_ends
Beispiel #9
0
def extract_pipes(g, known_types, g_protos, pipe_replacement) :
	pipes = { n for n in g if core.compare_proto_to_type(n.prototype, core.PipeProto) }
	for n in pipes :
		pipe_name = block_value_by_name(n, "Name")
		pipe_default = block_value_by_name(n, "Default")
		pipe_type, v = parse_literal(pipe_default, known_types=known_types, variables={})
		gw_proto, gr_proto = g_protos[pipe_type]
		pipe_replacement[pipe_name] = (pipe_type, pipe_default, gw_proto, gr_proto)
Beispiel #10
0
def __expddel(d, nr) :
	i = dfs.BlockModel(core.DelayInProto(), None)
#	print here(), d, nr
	if core.compare_proto_to_type(d.prototype, core.InitDelayProto) :
#		print here()
		o = dfs.BlockModel(core.InitDelayOutProto(), None)
	else :
		o = dfs.BlockModel(core.DelayOutProto(), None)
	i.nr = o.nr = nr
	i.delay = o.delay = d
	return d, (i, o)
Beispiel #11
0
def replace_pipes(g, g_protos, pipe_replacement) :
	pipe_ends = { n : block_value_by_name(n, "Name") for n in g if core.compare_proto_to_type(n.prototype, core.PipeEndProto) }

	unmatched = [ pe for pe in pipe_ends
		if not (block_value_by_name(pe, "Name") in pipe_replacement) ]
	if unmatched :
		raise Exception("unmatched pipes found! {0}".format(str(unmatched)))

	pipes = { n for n in g if core.compare_proto_to_type(n.prototype, core.PipeProto) }

	for n in pipes :
		pipe_name = block_value_by_name(n, "Name")
		pipe_type, pipe_default, gw_proto, gr_proto = pipe_replacement[pipe_name]
		gw_proto, gr_proto = g_protos[pipe_type]
		m = dfs.BlockModel(gw_proto, "itentionally left blank")
		m.value = (pipe_name, )
		replace_block(g, n, m)

	for pipe_end, pipe_name in pipe_ends.items() :
		pipe_type, pipe_default, gw_proto, gr_proto = pipe_replacement[pipe_name]
		m = dfs.BlockModel(gr_proto, "itentionally left blank")
		m.value = (pipe_name, )
		replace_block(g, pipe_end, m)
Beispiel #12
0
def __implement(g, n, tmp_args, args, outs, code) :
	"""
	return code to perform block n
	"""
	stmt = None
	if n.prototype.type_name in __OPS :
		assert(len(args) >= 2 or n.prototype.type_name in ("not", "abs"))
		assert(len([t for t in n.terms if t.direction==core.OUTPUT_TERM]) == 1)
		stmt = __OPS[n.prototype.type_name](n, tuple("({0})".format(a) for _, a in args))
	elif core.compare_proto_to_type(n.prototype, core.FunctionCallProto) :
		func_name = block_value_by_name(n, "Name")
		assert(func_name)
		stmt = func_name + "(" + ", ".join(tuple(a for _, a in (args + outs))) + ")"
	elif core.compare_proto_to_type(n.prototype, core.GlobalReadProto) :
		assert(len(args)==0)
		pipe_name = block_value_by_name(n, "Name")
		assert(pipe_name)
		stmt = pipe_name
	elif core.compare_proto_to_type(n.prototype, core.GlobalWriteProto) :
		assert(len(args)==1)
		pipe_name = block_value_by_name(n, "Name")
		assert(pipe_name)
		stmt = "{0} = {1}".format(pipe_name, args[0][1])
	elif core.compare_proto_to_type(n.prototype, core.MuxProto) :
		assert(len(args)==3)
		stmt = "({0} ? {2} : {1})".format(*tuple(a for _, a in args))#XXX cast sometimes needed!!!
	elif core.compare_proto_to_type(n.prototype, core.TypecastProto) :
		assert(len(args)==1)
		out = tuple(t for t in n.terms if t.direction==core.OUTPUT_TERM)
		assert(len(out)==1)
		stmt = "({0})({1})".format(out[0].type_name, args[0][1])
	else :
		stmt = __make_call(n, args, outs, tmp_args, code)
#		assert(n.prototype.exe_name != None)
#		return n.prototype.exe_name + "(" + ", ".join(args + outs) + ")"
	assert(not stmt is None)
	return stmt
Beispiel #13
0
def make_dag(model, meta, known_types, do_join_taps=True, delay_numbering_start=0) :
	conns0 = { k : v for k, v in model.connections.items() if v }
	model_blocks = tuple(b for b in model.blocks if not core.compare_proto_to_type(b.prototype, core.TextAreaProto))
	blocks, conns1, delays = __expand_delays(model_blocks, conns0, delay_numbering_start)

	conns_rev = reverse_dict_of_lists(conns1, lambda values: list(set(values)))
	graph = { b : adjs_t(
			[ (t, n, conns_rev[(b, t, n)] if (b, t, n) in conns_rev else []) for t, n in in_terms(b) ],
			[ (t, n, conns1[(b, t, n)] if (b, t, n) in conns1 else []) for t, n in out_terms(b) ])
		for b in blocks }

	is_sane = __dag_sanity_check(graph, stop_on_first=False)
	if not is_sane :
		raise Exception(here() + ": produced graph is insane")

	__expand_joints_new(graph)

	if do_join_taps :
		join_taps(graph)

	return graph, delays
Beispiel #14
0
def post_dive(g, code, tmp, d_stack, n, nt, nt_nr, m, mt, mt_nr, visited) :
#	print "post_dive:", n, nt, "<-", m, mt
#	assert(n in visited)
#	assert(m in visited)
#	print "d_stack=", d_stack, "(n, nt)=", (n, nt)
	if core.compare_proto_to_type(m.prototype, core.ConstProto) :
		assert(m.value != None)
		assert(len(m.value) == 1)
		code.append(str(m.value[0]))
#		print "post_dive:", n, nt, "<-", m, mt, "code:", str(m.value)
	elif (m, mt, mt_nr) in d_stack : #XXX or (n, nt) == d_stack[-1] ??!?!? nope, it is equal
		d_stack.remove((m, mt, mt_nr))
		pop_tmp_ref(tmp, n, nt, nt_nr)
#		print "post_dive:", n, nt, "<-", m, mt, "code:", "nop, d stack"
	else :
		slot = pop_tmp_ref(tmp, n, nt, nt_nr)
		if slot != None:
			code.append("tmp%i" % slot)
#			print "post_dive:", n, nt, "<-", m, mt, "code:", "tmp%i" % slot
		else :
			raise Exception("holy shit!")
Beispiel #15
0
def __mkvert(src, expd) :
	b, t0 = src
	t, _ = t_unpack(t0)

	if core.compare_proto_to_type(b.prototype, core.DelayProto, core.InitDelayProto) :
		block = expd[b][ 1 if t.name in ("y", "init") else 0 ]
		term, = get_terms_flattened(block, direction=t.direction)
#	if core.compare_proto_to_type(b.prototype, core.DelayProto) :
#		io = 1 if t.direction == core.OUTPUT_TERM else 0
#		block = expd[b][io]
#		term, = block.terms
#	elif core.compare_proto_to_type(b.prototype, core.InitDelayProto) :
#		io = 1 if t.name in ("y", "init") else 0
#		block = expd[b][io]
#		print here(), src, block, tuple(get_terms_flattened(block, direction=t.direction)), io
#		term, = get_terms_flattened(block, direction=t.direction)
	else :
		block, term = src

	result_t, result_t_nr = t_unpack(term)
	assert(t.direction==result_t.direction)
	return (block, result_t, result_t_nr)
Beispiel #16
0
def __post_visit(g, code, tmp, tmp_args, subtrees, expd_dels, types, known_types,
		dummies, state_var_prefix, pipe_vars, libs_used, evaluated, n, visited) :
#	print "__post_visit:", n.to_string()

	if core.compare_proto_to_type(n.prototype, core.ConstProto) :
		return None # handled elsewhere

	if n.prototype.library :
		libs_used.add(n.prototype.library)

	inputs_all, outputs_all = g[n]
	inputs = [ (t, nr, ngh) for t, nr, ngh in inputs_all if not t.virtual ]
	outputs = [ (t, nr, ngh) for t, nr, ngh in outputs_all if not t.virtual ]

	args = []
	outs = []

#	print here(), n, tmp, subtrees
#	print here(), n, outputs

	expr_slot_type = None

	for out_term, out_t_nr, succs in outputs :
#		if out_term.virtual :
#			continue
		if out_term.type_name == core.TYPE_INFERRED :
			term_type = types[n, out_term, out_t_nr]
		else :
			term_type = out_term.type_name
#		print "out_term, out_t_nr, succs =", n, out_term, out_term.type_name, out_t_nr, succs
		if len(succs) > 1 or (len(outputs) > 1 and len(succs) == 1):
#			print "adding temps:", succs
			expr_slot_type = term_type
			expr_slot = add_tmp_ref(tmp, succs, slot_type=term_type)
#TODO if all succs have same type different from out_term, cast now and store as new type
#if storage permits, however
			if len(outputs) > 1 :
				outs.append(((out_term, out_t_nr), "&{}_tmp{}".format(expr_slot_type, expr_slot)))
		elif len(succs) == 1 and len(outputs) == 1 :
#			print here(), "passing by", n
			pass
		else :
			dummies.add(term_type)
			outs.append(((out_term, out_t_nr), "&{}_dummy".format(term_type)))

	for in_term, in_t_nr, preds in inputs :
#		print here(), n, preds
		assert(len(preds)==1)

#		if out_term.virtual :
#			continue

		((m, m_t, m_t_nr), ) = preds
#		print "\tgathering:", m, m_t, m_t_nr, "for", (n, in_term, in_t_nr), "subtrees:", subtrees, "tmp:", tmp
		if core.compare_proto_to_type(m.prototype, core.ConstProto) :
			assert(m.value != None)
			assert(len(m.value) == 1)
			args.append(((in_term, in_t_nr), str(m.value[0])))
		elif (n, in_term, in_t_nr) in subtrees :
			args.append(((in_term, in_t_nr), subtrees.pop((n, in_term, in_t_nr))))
		else :
			slot_type, slot = pop_tmp_ref(tmp, n, in_term, in_t_nr)
			if slot != None:
				args.append(((in_term, in_t_nr), "{0}_tmp{1}".format(slot_type, slot)))
			else :
				assert(False)

	if core.compare_proto_to_type(n.prototype, core.DelayInProto) :
		del_in, del_out = expd_dels[n.delay]
		assert(n==del_in)
#		is_initdel = core.compare_proto_to_type(del_out.prototype, core.InitDelayOutProto)
		if not del_out in evaluated :# or is_initdel :
#			print here(), del_in.terms
			del_type = types[del_out, del_out.terms[0], 0]
			slot = add_tmp_ref(tmp, [ (del_in, del_in.terms[0], 0) ], slot_type=del_type)
			if core.compare_proto_to_type(del_out.prototype, core.InitDelayOutProto) :# is_initdel :
#				print here(), args
				assert(len(args)==1 and len(outs)==0)
				__get_initdel_value(code, n, state_var_prefix, del_type, slot, args[0][1])
			else :
				code.append("{0}_tmp{1} = {2}del{3};".format(del_type, slot, state_var_prefix, n.nr))
		expr = "{0}del{1}={2}".format(state_var_prefix, n.nr, args[0][1])

	elif core.compare_proto_to_type(n.prototype, core.DelayOutProto, core.InitDelayOutProto) :
		del_in, del_out = expd_dels[n.delay]
		assert(n==del_out)
		if del_in in evaluated : #visited :
			slot_type, slot = pop_tmp_ref(tmp, del_in, del_in.terms[0], 0)
			expr = "{0}_tmp{1}".format(slot_type, slot)
		else :
			if core.compare_proto_to_type(n.prototype, core.InitDelayOutProto) :
				assert(len(args)==1 and len(outs)==0)
				del_type = types[del_out, del_out.terms[0], 0]
				slot = add_tmp_ref(tmp, [ (del_in, del_in.terms[0], 0) ], slot_type=del_type)
				__get_initdel_value(code, n, state_var_prefix, del_type, slot, args[0][1])
				slot_type, slot = pop_tmp_ref(tmp, del_in, del_in.terms[0], 0)
				expr = "{0}_tmp{1}".format(slot_type, slot)
			else :
				expr = "{0}del{1}".format(state_var_prefix, n.nr)
	else :
		expr = __implement(g, n, tmp_args, args, outs, code)#, types, known_types, pipe_vars)

	is_expr = len(outputs) == 1 and len(outputs[0][2]) == 1

	if is_expr :
		((out_term, out_t_nr, succs), ) = outputs
		subtrees[succs[0]] = expr
		assert(len(outputs)==1 and len(outputs[0][2])==1)
		subtrees[outputs[0][2][0]] = expr
	else :
		if len(outputs) == 0 :
			code.append(expr + ";")
		elif len(outputs) == 1 :
#			(out_term,) = [ trm for trm in n.terms if trm.direction == core.OUTPUT_TERM ]
#			term_type = types[ n, out_term, 0 ]
#			slot = add_tmp_ref(tmp, outputs[0][2], slot_type=term_type)
#			print here(), n, out_term, term_type, "slot=", slot
#			pprint(tmp)
			if expr_slot_type is None :
				code.append("(void){};".format(expr))
			else :
				code.append("{0}_tmp{1} = {2};".format(expr_slot_type, expr_slot, expr))
		else :
			code.append(expr + ";")

	evaluated[n] = True
Beispiel #17
0
def __expand_joints_new(g) :
	for j in [ b for b in g if core.compare_proto_to_type(b.prototype, core.JointProto) ] :
		__cut_joint_alt(g, j)
Beispiel #18
0
def __inferr_types_dft_roots_sorter(g, roots) :
	return sorted(dft_alt_roots_sorter(g, roots),
		key=lambda n: 0 if core.compare_proto_to_type(n.prototype, core.InitDelayOutProto) else 1)