local ffi = FFI or require("ffi") Simulation = Simulation or {} function Simulation.compile_code(sim, text) -- todo: compile some kind of DSL into machine code return code, size end --local net_program_code = Simulation.compile_code( [[ -- --]] ) function Simulation.compile(sim) sim.compilation = { gates = {}, wires = {}, cgates = {}, cwires = {}, } local comp = sim.compilation -- assemble a list of all nets local all_nets_t = {} for k, wire in pairs(sim.wires) do local net = Wire.getgroup(wire) all_nets_t[net] = net end local all_nets = {} for net_id, net in pairs(all_nets_t) do table.insert(comp.nets, net) local cdata = ffi.new("char["..(ffi.sizeof("struct Net") + ffi.sizeof("struct Gate*")*net.num_gates_update).."]") local cnet = ffi.cast(cdata, "struct Net") comp.cnets[net] = cnet end -- assemble a list of all gates local all_gates = {} for k, gate in pairs(sim.gates) do table.insert(comp.gates, gate) local cdata = ffi.new("char["..(ffi.sizeof("struct Gate") + ffi.sizeof("struct OutPort")*gate.num_ports_out).."]") local cgate = ffi.cast(cdata, "struct Gate") comp.cgates[gate] = cgate end for netidx, net in ipairs(comp.nets) do local cnet = comp.cnets[net] or error("no cnet") cnet.in_queue = net.in_queue cnet.num_out_ports_on = net.state_num cnet.state = net.state cnet.update_tick = net.update_tick for i = 1, net.num_gates_update do local gate = net.gates_update[i] local cgate = comp.cgates[gate] or error("no cgate") cnet.gates_update[i-1] = cgate end end for gateidx, gate in ipairs(comp.gates) do local cgate = comp.cgates[gate] or error("no cgate") cgate.in_queue = gate.in_queue local j = 0 for i, port in ipairs(gate.ports) do if port.type == PortTypes.output then local net = port.group if net then local cnet = comp.cnets[net] or error("no cnet") cgate.out_ports[j].net = cnet else cgate.out_ports[j].net = 0 end cgate.out_ports[j].state = gate.port_states[i] or error("no gate port_state") j = j + 1 end end end end function Simulation.decompile(sim) local comp = sim.compilation for netidx, net in ipairs(comp.nets) do local cnet = comp.cnets[net] or error("no cnet") net.in_queue = cnet.in_queue net.state_num = cnet.num_out_ports_on net.state = cnet.state net.update_tick = cnet.update_tick end for gateidx, gate in ipairs(comp.gates) do local cgate = comp.cgates[gate] or error("no cgate") gate.in_queue = cgate.in_queue local j = 0 for i, port in ipairs(gate.ports) do if port.type == PortTypes.output then gate.port_states[i] = cgate.out_ports[j].state j = j + 1 end end end end function Simulation.tick_compiled(sim, count) end