MicroController

by ljdp

Program circuit network logic using FAL, a Factorio Assembly Language.

Content
5 years ago
0.16
7
Circuit network

g Error while handling pluse signal

6 years ago
(updated 6 years ago)

I tried to handle pulse signals with the following code:

blr 1
fir mem24
mul mem1 2
mov mem1 out
jmp 1

The microcontroller is connected to a pulse source with the red line, and there is a RAM module correctly attached to it.
The output of microcontroller is connected to a electric pole with the red line.
Pulse signal type is stored in mem24.
When the script starts, I get this error:
line 2: _microcontroller__/compiler.lua:324: bad argument #1 to 'pairs' (table expected, got nil)

6 years ago

After reading the source code, I think blr and blg op codes need more than one operation in one tick. Currently, if blr and blg condition is satisfied, the compiler will return nil to microcontroller. In microcontroller.tick callback, this just add the program counter by 1. As pulse signals have only 1 tick lifetime, in next microcontroller.tick call, there will be no signal on the wire. This might be why I got that error.

So I suggest adding a new result type: do_more_tick. Here is my implement suggestion.

Add result type in Compiler.lua, line 542:

blr = function(_) -- BLR M/I -- Block until there are at least [a] red signals.
    assert_in(_)
    local _in = _[1]
    assert_in_mem_or_val(_in)
    local count = memcount_or_val(_in)
    if wires.red.signals == nil or #wires.red.signals < count then
        return {type = "block"}
    else -- Kiritow EDIT
        return {type = "do_more_tick" }
    end
end,
blg = function(_) -- BLG M/I -- Block until there are at least [a] green signals.
    assert_in(_)
    local _in = _[1]
    assert_in_mem_or_val(_in)
    local count = memcount_or_val(_in)
    if wires.green.signals == nil or #wires.green.signals < count then
        return {type = "block"}
    else -- Kiritow EDIT
        return {type = "do_more_tick" }
    end
end,

Add result handler for do_more_tick in microcontroller.lua, line 110:

elseif result then
    if result.type == 'halt' then
        microcontroller.halt(mc, state)
    elseif result.type == 'sleep' then
        state.program_state = PSTATE_SLEEPING
        state.sleep_time = result.val
    elseif result.type == 'jump' then
        microcontroller.set_program_counter(mc, state, result.val)
    elseif result.type == 'skip' then
        microcontroller.set_program_counter(mc, state, state.program_counter + 2)
    elseif result.type == 'sync' then
        state.program_state = PSTATE_SYNC
    elseif result.type == 'do_more_tick' then -- Kiritow EDIT
        state.program_counter = state.program_counter + 1
        if state.program_counter > #state.program_ast then
            microcontroller.halt(mc, state)
        end
        microcontroller.tick(mc,state)
        return 
    elseif result.type == 'block' then
        -- Do nothing, keeping the program_counter the same.
    end
else
5 years ago

I'm not going to add the 'do_more_tick' state as It can become confusing if a line can take more than 1 tick and can also have performance issues. It's best to set up a polling loop to handle pulses or use an arithmetic combinator in-between to delay the pulse 1 tick.

fir mem24
tgt mem1 0
jmp 1
mov mem1 out
jmp 1

New response