OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-atomspace / cmake / OpenCogGenPythonTypes.cmake

120 lines · cmake ref:
#
# OpenCogGenPythonTypes.cmake
#
# Definitions for automatically building a Python `atom_types.pyx`
# file, given a master file `atom_types.script`.
#
# Example usage:
# OPENCOG_PYTHON_ATOMTYPES(atom_types.script core_types.pyx)
#
# ===================================================================

MACRO(OPENCOG_PYTHON_SETUP SCRIPT_FILE PYTHON_FILE)
	SET(PYTHON_SUPPORTED_VALUE_LIST)

	IF (NOT PYTHON_FILE)
		MESSAGE(FATAL_ERROR "OPENCOG_PYTHON_ATOMTYPES missing PYTHON_FILE")
	ENDIF (NOT PYTHON_FILE)

	MESSAGE(DEBUG "Generating Python Atom Type definitions from ${SCRIPT_FILE}.")

	FILE(WRITE "${PYTHON_FILE}"
		"\n"
		"# DO NOT EDIT THIS FILE! This file was automatically\n"
		"# generated from atom definitions in\n"
		"# ${SCRIPT_FILE}\n"
		"# by the macro OPENCOG_PYTHON_ATOMTYPES\n"
		"#\n"
		"# This file contains basic python wrappers for atom creation.\n"
		"#\n"
		"\n"
	)
ENDMACRO()

# ------------
# Print out the python definitions. Note: We special-case Atom
# since we don't want to create a function with the same
# identifier as the Python Atom object.
MACRO(OPENCOG_PYTHON_WRITE_DEFS PYTHON_FILE)

	# Args and Sigs are not "real types"; they are helpers for the dynamic
	# type constructors and type signatures. Skip generating python bindings.
	IF (NOT ISARG STREQUAL "ARG" AND NOT ISSIG STREQUAL "SIG")

		IF (NOT TYPE_NAME STREQUAL "Atom")

			# XXX This is broken in two ways. First, createValue() is
			# a C++ template, and so it can't be used like this.
			# Also, PYTHON_SUPPORTED_VALUE_LIST is an empty list (above)
			# so this is a no-op, anyway. XXX FIXME someday, I guess
			# Until then, the value ctors are hard-coded into
			# opencog/cython/opencog/type_constructors.pyx
			IF (ISVALUE STREQUAL "VALUE" OR ISSTREAM STREQUAL "STREAM")
				LIST(FIND PYTHON_SUPPORTED_VALUE_LIST ${TYPE_NAME} _INDEX)
				IF (${_INDEX} GREATER -1)
					# Single arg will work as all of the value constructors
					# have a single argument: either a value or a vector.
					FILE(APPEND "${PYTHON_FILE}"
						"def ${TYPE_NAME}(arg):\n"
						"    return createValue(types.${TYPE_NAME}, arg)\n"
					)
				ENDIF (${_INDEX} GREATER -1)
			ENDIF (ISVALUE STREQUAL "VALUE" OR ISSTREAM STREQUAL "STREAM")

			IF (ISNODE STREQUAL "NODE")
				FILE(APPEND "${PYTHON_FILE}"
					"def ${TYPE_NAME}(node_name):\n"
					"    return add_node(types.${TYPE_NAME}, node_name)\n"
				)
				# Generate short name if it differs from TYPE_NAME OR if custom name
				# Skip "Type" as it conflicts with Cython's Type keyword
				IF (NOT SHORT_NAME STREQUAL "" AND
					NOT SHORT_NAME STREQUAL "Type" AND
					(HAS_CUSTOM_NAME OR NOT SHORT_NAME STREQUAL TYPE_NAME))
					FILE(APPEND "${PYTHON_FILE}"
						"def ${SHORT_NAME}(node_name):\n"
						"    return add_node(types.${TYPE_NAME}, node_name)\n"
					)
				ENDIF ()
			ENDIF (ISNODE STREQUAL "NODE")

			IF (ISLINK STREQUAL "LINK")
				FILE(APPEND "${PYTHON_FILE}"
					"def ${TYPE_NAME}(*args):\n"
					"    return add_link(types.${TYPE_NAME}, args)\n"
				)
				# Generate short name if it differs from TYPE_NAME OR if custom name
				IF (NOT SHORT_NAME STREQUAL "" AND
					(HAS_CUSTOM_NAME OR NOT SHORT_NAME STREQUAL TYPE_NAME))
					FILE(APPEND "${PYTHON_FILE}"
						"def ${SHORT_NAME}(*args):\n"
						"    return add_link(types.${TYPE_NAME}, args)\n"
					)
				ENDIF ()
			ENDIF (ISLINK STREQUAL "LINK")
		ENDIF (NOT TYPE_NAME STREQUAL "Atom")

	ENDIF (NOT ISARG STREQUAL "ARG" AND NOT ISSIG STREQUAL "SIG")
ENDMACRO(OPENCOG_PYTHON_WRITE_DEFS PYTHON_FILE)

# ------------
# Main entry point.
MACRO(OPENCOG_PYTHON_ATOMTYPES SCRIPT_FILE PYTHON_FILE)

	OPENCOG_PYTHON_SETUP(${SCRIPT_FILE} ${PYTHON_FILE})
	FILE(STRINGS "${SCRIPT_FILE}" TYPE_SCRIPT_CONTENTS)
	FOREACH (LINE ${TYPE_SCRIPT_CONTENTS})
		OPENCOG_TYPEINFO_REGEX()
		IF (MATCHED AND CMAKE_MATCH_1)

			OPENCOG_TYPEINFO_SETUP()
			OPENCOG_PYTHON_WRITE_DEFS(${PYTHON_FILE})  # Print out python definitions
		ELSEIF (NOT MATCHED)
			MESSAGE(FATAL_ERROR "Invalid line in ${SCRIPT_FILE} file: [${LINE}]")
		ENDIF ()
	ENDFOREACH (LINE)

ENDMACRO()

#####################################################################