You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

431 lines
12 KiB

// pEpACIDLang - IG-C99
// TODO: Lic. etc...
include yslt.yml2
tstylesheet {
include standardlib.ysl2
include idl_api.ysl2
// ----------------------------------------------------------------------
// pEpACIDLang LM-C99-API
// The C99 Language mapping API
// ----------------------------------------------------------------------
def "func:c99_typename_of_basetype" {
param "idltype";
choose {
when "func:idl_type_is_defined($idltype)"
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»
}
otherwise
error > func:c99_typename_of_basetype - idltype: «$idltype» is not defined
}
}
def "func:c99_typename_of_enum" {
param "idl_enum_name";
result "yml:ucase(concat(func:idl_get_package_name(), '_', $idl_enum_name))";
}
def "func:c99_typename_of_struct" {
param "idl_struct_name";
result > «yml:capit(func:idl_get_package_name())»_«yml:capit($idl_struct_name)»
}
def "func:c99_typename_of_idltype" {
param "idltype";
const "idl_typekind", "func:idl_type_get_typekind_of_type($idltype)";
choose {
when "func:idl_type_is_defined($idltype)"
choose {
when "$idl_typekind = 'basetype'"
result "func:c99_typename_of_basetype($idltype)";
when "$idl_typekind = 'deftype'"
result "$idltype";
when "$idl_typekind = 'enum'"
result "func:c99_typename_of_enum($idltype)";
when "$idl_typekind = 'struct'"
result "func:c99_typename_of_struct($idltype)";
when "$idl_typekind = 'generic'"
error > c99_typename_of_type - idltype «$idltype» is a generic type and can only be used in deftype declarations.
otherwise
error > c99_typename_of_type - cant determine c99 typename for idltype: «$idltype»
}
otherwise
error > c99_typename_of_idltype - is not an idltype: «$idltype»
}
}
// typeclass is either
// * primitive
// * object
def "func:c99_typeclass_of_idltype" {
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_idltype - cant determine typeclass of: «$idltype»
}
otherwise
error > c99_typeclass_of_idltype - is not an idltype: «$idltype»
}
};
def "func:c99_itemname_of_enumitem" {
param "idl_enum_name";
param "idl_item_name";
result "yml:ucase(concat($idl_enum_name, '_', $idl_item_name))";
}
// ----------------------------------------------------------------------
// pEpACIDLang IG-C99
// The C99 Interface Generator for pEpACIDLang
// ----------------------------------------------------------------------
// The idl-api owns the root template and executes validation
// of the interface description.
// Errors will be printed to stdout.
// After successful validation, the idl-api applies the
// template called "pEpACIDLang"
template "pEpACIDLang" {
apply "idl|package", 0
}
// 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
// -------------
``call "basetypes"
#ifdef __cplusplus
} // extern "C"
#endif
||
}
function "basetypes" {
for "func:idl_get_basetypes()" {
const "name", "name()";
if "func:c99_typename_of_idltype($name) != $name" {
| «func:typedef(func:c99_typename_of_idltype($name), $name)»
}
}
}
template "package" {
apply "api", 0
}
template "api" document "ig-c99/{@name}_api.h", "text" {
const "api_name", "@name";
||
// «yml:ucase(func:idl_get_package_name())» version «func:idl_get_package_version()»
// «$api_name»_api.h
// «func:idl_get_package_license()»
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "idl_core.h"
``call "deftypes"
``call "enums"
``call "structs"
``call "methods"
#ifdef __cplusplus
} // extern "C"
#endif
||
}
// DEFTYPE
// -------
function "deftypes" {
||
// Deftypes
// --------
``apply "deftype"
||
}
template "deftype" {
call "deftype"
with "new_typename", "@name",
with "aliased_type_or_typekind", "as/@type";
}
function "deftype" {
param "new_typename";
param "aliased_type_or_typekind";
choose {
when 'func:idl_typekind_is_generic($aliased_type_or_typekind)'
choose {
when "$aliased_type_or_typekind = 'list'"
| «func:typedef($aliased_type_or_typekind, $new_typename)»
otherwise
error > deftype - typekind must be generic «$type_or_typeind»
}
otherwise
| «func:typedef($aliased_type_or_typekind, $new_typename)»
}
}
def "func:typedef" {
param "is_type";
param "new_typename";
result > typedef «$is_type» «$new_typename»;
}
// ENUM
// ----
function "enums" {
||
// Enums
// -----
``apply "enum"
||
}
template "enum" {
call "enum" with "idl_enum_name", "@name";
}
function "enum" {
param "idl_enum_name";
const "enum_name", "func:c99_typename_of_idltype($idl_enum_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:c99_enum_item_value($idl_value)";
apply "@doc", 0, mode="multiline";
| «$c99_item_name»«$c99_value»«func:autocomma()»`apply "@doc" , 0, mode="oneline"`
}
def "func:c99_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" {
call "struct" with "idl_struct_name", "@name";
}
function "struct" {
param "idl_struct_name";
const "c99_struct_name", "func:c99_typename_of_idltype($idl_struct_name)";
||
typedef struct _«$c99_struct_name» {
``apply "field"
} «$c99_struct_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
// ------
function "methods" {
||
// Functions
// ---------
``apply "method"
||
}
template "method" {
call "method"
with "idl_method_name", "@name";
}
function "method" {
param "idl_method_name";
||
PEP_STATUS «$idl_method_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_idltype($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»
}
}
}
}
}
}