Here's a LuaLaTeX-based solution.
The Lua function that does all of the work is activated when LaTeX enters the foo environment and is deactivated when LaTeX exits the foo environment. By “activation”, I mean assignment to LuaTeX’s process_input_buffer callback. While active, the Lua function acts as a preprocessor, checking and modifying the input stream before TeX starts its usual input processing.

% !TEX TS-program = lualatex
\documentclass{article}
%% Lua-side code
\usepackage{luacode}
\begin{luacode}
function do_substitutions ( s )
s = s:gsub ( ":=" , "\mapsto " )
s = s:gsub ( ";" , "\\[2pt]" )
return s
end
\end{luacode}
%% LaTeX-side code
\newenvironment{foo}{%
\directlua { luatexbase.add_to_callback (%
"process_input_buffer" , do_substitutions , "do_subs" ) }}{%
\directlua { luatexbase.remove_from_callback (%
"process_input_buffer" , "do_subs" ) }}
\begin{document}
[
\begin{foo}
\begin{array}{c}
a := 42;
c := a
\end{array}
\end{foo}
]
\end{document}