デジタル回路シミュレータ

30分プログラム、その393。SICPに載っていることで有名なデジタル回路シミュレータをErlangで作ってみる。
時間がなくて全部は無理だったので、ワイヤとプローブ、入力の3つだけ。そのうちANDやNOT、加算器とかも作るかもしれない。

使い方

test() ->
    Wire = wire(),
    probe(Wire),
    input(Wire,0).

ソースコード

-module(gate).
-compile([export_all]).

wire(Value,Actions) ->
    receive
	{set_value,Value} ->
	    wire(Value,Actions);
	{set_value,New} ->
	    lists:foreach(fun(A)->A ! {value,New} end,Actions),
	    wire(New,Actions);
	{get_value,From} ->
	    From ! {value,Value},
	    wire(Value,Actions);	
	{add_action,From} ->
	    From ! {value,Value},
	    wire(Value,[From|Actions])
    end.

wire() -> spawn(fun () ->wire(0,[]) end).

add_action(Wire,F)->
    Pid = spawn(fun()-> receive
			    {value,Value} -> F(Value)
			end
		end),
    Wire ! {add_action,Pid}.
    
input(Wire,Value) ->
    add_action(Wire,fun(_)-> Wire ! {set_value,Value} end),
    Wire ! {set_value,Value}.

probe(Wire) ->
    add_action(Wire,fun(X)->io:format("current value: ~p ~n",[X]) end).

test() ->
    Wire = wire(),
    probe(Wire),
    input(Wire,0).