// pEpACIDLang - IG-C99 // TODO: Lic. etc... include yslt.yml2 tstylesheet { include standardlib.ysl2 include idl_api.ysl2 // ---------------------------------------------------------------------- // pEpACIDLang IG-C99 // The C99 Interface Generator for pEpACIDLang // ---------------------------------------------------------------------- // generate basetype declarations defined by the idl template "idl" document "ig-c99/idl_core.h", "text" { || #pragma once #ifdef __cplusplus extern "C" { #endif // idl basetypes // ------------- ``apply "basetypes", 0 #ifdef __cplusplus } // extern "C" #endif || } template "basetypes" { for "*" { const "name", "name()"; if "func:c99_typename_of_basetype($name) != $name" { > «func:typedef(func:c99_typename_of_basetype($name), $name)» } } } template "api" document "ig-c99/{@name}_api.h", "text" { const "pkg_name", "../@name"; const "pkg_version", "../version/text()"; const "pkg_license", "../license/text()"; const "pkg_copyleft", "../copyleft/text()"; const "api_name", "@name"; || // «yml:ucase($pkg_name)» «$pkg_version» // «$api_name»_api.h // «$pkg_license» // «$pkg_copyleft» #pragma once #ifdef __cplusplus extern "C" { #endif #include "idl_core.h" // deftypes // -------- ``apply "deftype", 0 ``call "enums" // Structs // ------- ``apply "struct", 0 // Functions // --------- ``apply "method", 0 #ifdef __cplusplus } // extern "C" #endif || } def "func:c99_typename_of_basetype" { param "idltype"; // TODO: test for is_basetype choose { when "$idltype = 'string'" result > char* when "$idltype = 'binary'" result > char* when "$idltype = 'uint'" result > unsigned int when "$idltype = 'size'" result > size_t when "$idltype = 'opaque'" result > void* when "$idltype = 'int'" result > int when "$idltype = 'bool'" result > bool otherwise error > func:c99_typename_of_basetype - basetype not supported by ig-c99: «$idltype» } } def "func:c99_typename_of_enum" { param "name"; param "pkg_name"; result "yml:ucase(concat($pkg_name, '_', $name))"; } def "func:c99_itemname_of_enumitem" { param "enum_name"; param "idl_item_name"; result "yml:ucase(concat($enum_name, '_', $idl_item_name))"; } def "func:c99_typename_of_struct" { param "pkg_name"; param "idl_name"; result "concat(yml:capit($pkg_name), '_', yml:capit($idl_name))"; } // typeclass is either // * primitive // * object def "func:c99_typeclass_of_type" { param "idltype"; const "resolved_type", "func:idl_type_get_resolved_type($idltype)"; const "resolved_typekind", "func:idl_type_get_typekind_of_type($resolved_type)"; choose { when "func:idl_type_is_defined($idltype)" choose { when "$resolved_typekind = 'basetype'" choose { when "$resolved_type = 'string'" result > object when "$resolved_type = 'binary'" result > object otherwise result > primitive } when "$resolved_typekind = 'enum'" result > primitive when "$resolved_typekind = 'struct'" result > object when "$resolved_typekind = 'generic'" result > object otherwise error > c99_typeclass_of_type - cant determine typeclass of: «$idltype» } otherwise error > c99_typeclass_of_type - is not a type: «$idltype» } }; // TYPEALIAS // --------- template "deftype" { const "alias_name", "@name"; const "type_or_typekind", "as/@type"; choose { when 'func:idl_typekind_is_generic($type_or_typekind)' choose { when "$type_or_typekind = 'list'" > «func:typedef($type_or_typekind, $alias_name)» otherwise error > deftype - typekind must be generic «$type_or_typeind» } otherwise > «func:typedef($type_or_typekind, $alias_name)» } } def "func:typedef" { param "is_type"; param "alias_name"; result > typedef «$is_type» «$alias_name»;\n } // ENUM // ---- function "enums" { || // Enums // ----- ``apply "enum" || } template "enum" { call "enum" with "idl_enum_name", "@name", with "idl_pkg_name", "../../@name"; } function "enum" { param "idl_enum_name"; param "idl_pkg_name"; const "enum_name", "func:c99_typename_of_enum($idl_enum_name, $idl_pkg_name)"; || typedef enum _«$enum_name» { ``apply "item" with "enum_name", "$enum_name" } «$enum_name»; || } template "item" { param "enum_name"; const "idl_item_name", "@name"; const "c99_item_name", "func:c99_itemname_of_enumitem($enum_name, $idl_item_name)"; const "idl_value", "text()"; const "c99_value", "func:enum_item_value($idl_value)"; apply "@doc", 0, mode="multiline"; | «$c99_item_name»«$c99_value»«func:autocomma()»`apply "@doc" , 0, mode="oneline"` } def "func:enum_item_value" { param "idl_value"; choose { when "string-length($idl_value) > 0" result > = «$idl_value» otherwise result > } } // STRUCT // ------ function "structs" { || // Structs // ------- ``apply "struct" || } template "struct" { const "idl_name", "@name"; const "pkg_name", "../../@name"; const "c_name", "func:c99_typename_of_struct($pkg_name, $idl_name)"; || typedef struct _«$c_name» { ``apply "field" } «$c_name»; || } template "field" { const "field_name", "@name"; const "field_type", "@type"; || ``apply "@doc", 0, mode="multiline" «$field_type» «$field_name»;`apply "@doc" , 0, mode="oneline"` || } // METHOD // ------ template "method" { const "name", "@name"; || PEP_STATUS «$name»( ``apply "param", 0 ); || } template "param" { const "name", "@name"; const "type", "@type"; const "mode", "@mode"; |> «func:idlparam_to_cparam($type, $mode)» «@name»«func:autocomma()» } def "func:idlparam_to_cparam" { param "idltype"; param "mode"; const "typeclass", "func:c99_typeclass_of_type($idltype)"; choose { when "$mode = 'borrow'" choose { when "$typeclass = 'primitive'" result > «$idltype» when "$typeclass = 'object'" result > «$idltype» } when "$mode = 'mborrow'" choose { when "$typeclass = 'primitive'" result > «$idltype»* when "$typeclass = 'object'" result > «$idltype»* } when "$mode = 'claim'" choose { when "$typeclass = 'primitive'" error > invalid mode «$mode» for typeclass «$typeclass» when "$typeclass = 'object'" result > «$idltype» } when "$mode = 'provide'" choose { when "$typeclass = 'primitive'" error > invalid mode «$mode» for typeclass «$typeclass» when "$typeclass = 'object'" result > «$idltype»* } } } // DOC // --- template "doc|@doc", mode="oneline" { const "docstring", "."; const "doc_lines_count", "count(str:split($docstring, '\n'))"; if "$doc_lines_count = 1" { const "doc_line", "normalize-space($docstring)"; if "string-length($doc_line) > 0" { > // «$doc_line» } } } template "doc|@doc", mode="multiline" { const "docstring", "."; const "doc_lines_count", "count(str:split($docstring, '\n'))"; if "$doc_lines_count > 1" { if "string-length($docstring) > 0" { | for "str:split($docstring, '\n')" { const "doc_line", "normalize-space(.)"; if "string-length($doc_line) > 0" { | // «$doc_line» } } } } } }