A diagrammatic approach to programming language semantics