A modular approach to denotational semantics