You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2014/04/12 08:49:48 UTC
[lucy-commits] [13/27] Remove bundled Clownfish.
http://git-wip-us.apache.org/repos/asf/lucy/blob/1704c275/clownfish/compiler/src/CFCParseHeader.y
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCParseHeader.y b/clownfish/compiler/src/CFCParseHeader.y
deleted file mode 100644
index 40530be..0000000
--- a/clownfish/compiler/src/CFCParseHeader.y
+++ /dev/null
@@ -1,648 +0,0 @@
-%name CFCParseHeader
-
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-%token_type {char*}
-%token_prefix CFC_TOKENTYPE_
-
-%extra_argument { CFCParser *state }
-
-%include {
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <stdlib.h>
-#include "CFC.h"
-#ifndef true
- #define true 1
- #define false 0
-#endif
-
-static CFCClass*
-S_start_class(CFCParser *state, CFCDocuComment *docucomment, char *exposure,
- char *modifiers, char *class_name, char *class_cnick,
- char *inheritance) {
- CFCFileSpec *file_spec = CFCParser_get_file_spec(state);
- int is_final = false;
- int is_inert = false;
- if (modifiers) {
- /* TODO: Decide how to handle abstract classes. */
- if (strstr(modifiers, "inline")) {
- CFCUtil_die("Illegal class modifiers: '%s'", modifiers);
- }
- is_final = !!strstr(modifiers, "final");
- is_inert = !!strstr(modifiers, "inert");
- }
- CFCParser_set_class_name(state, class_name);
- CFCParser_set_class_cnick(state, class_cnick);
- CFCClass *klass = CFCClass_create(CFCParser_get_parcel(state), exposure,
- class_name, class_cnick, NULL,
- docucomment, file_spec, inheritance,
- is_final, is_inert);
- CFCBase_decref((CFCBase*)docucomment);
- return klass;
-}
-
-static CFCVariable*
-S_new_var(CFCParser *state, char *exposure, char *modifiers, CFCType *type,
- char *name) {
- int inert = false;
- if (modifiers) {
- if (strcmp(modifiers, "inert") != 0) {
- CFCUtil_die("Illegal variable modifiers: '%s'", modifiers);
- }
- inert = true;
- }
-
- CFCParcel *parcel = NULL;
- const char *class_name = NULL;
- const char *class_cnick = NULL;
- if (exposure && strcmp(exposure, "local") != 0) {
- parcel = CFCParser_get_parcel(state);
- class_name = CFCParser_get_class_name(state);
- class_cnick = CFCParser_get_class_cnick(state);
- }
- CFCVariable *var = CFCVariable_new(parcel, exposure, class_name,
- class_cnick, name, type, inert);
-
- /* Consume tokens. */
- CFCBase_decref((CFCBase*)type);
-
- return var;
-}
-
-static CFCBase*
-S_new_sub(CFCParser *state, CFCDocuComment *docucomment,
- char *exposure, char *modifiers, CFCType *type, char *name,
- CFCParamList *param_list) {
- CFCParcel *parcel = CFCParser_get_parcel(state);
- const char *class_name = CFCParser_get_class_name(state);
- const char *class_cnick = CFCParser_get_class_cnick(state);
-
- /* Find modifiers by scanning the list. */
- int is_abstract = false;
- int is_final = false;
- int is_inline = false;
- int is_inert = false;
- if (modifiers) {
- is_abstract = !!strstr(modifiers, "abstract");
- is_final = !!strstr(modifiers, "final");
- is_inline = !!strstr(modifiers, "inline");
- is_inert = !!strstr(modifiers, "inert");
- }
-
- /* If "inert", it's a function, otherwise it's a method. */
- CFCBase *sub;
- if (is_inert) {
- if (is_abstract) {
- CFCUtil_die("Inert functions must not be abstract");
- }
- if (is_final) {
- CFCUtil_die("Inert functions must not be final");
- }
- sub = (CFCBase*)CFCFunction_new(parcel, exposure, class_name,
- class_cnick, name, type, param_list,
- docucomment, is_inline);
- }
- else {
- if (is_inline) {
- CFCUtil_die("Methods must not be inline");
- }
- sub = (CFCBase*)CFCMethod_new(parcel, exposure, class_name,
- class_cnick, name, type, param_list,
- docucomment, is_final, is_abstract);
- }
-
- /* Consume tokens. */
- CFCBase_decref((CFCBase*)docucomment);
- CFCBase_decref((CFCBase*)type);
- CFCBase_decref((CFCBase*)param_list);
-
- return sub;
-}
-
-static CFCType*
-S_new_type(CFCParser *state, int flags, char *type_name,
- char *asterisk_postfix, char *array_postfix) {
- (void)state; /* unused */
- CFCType *type = NULL;
- size_t type_name_len = strlen(type_name);
- int indirection = asterisk_postfix ? (int)strlen(asterisk_postfix) : 0;
-
- /* Apply "nullable" to outermost pointer, but "const", etc to innermost
- * type. This is an ugly kludge and the Clownfish header language needs to
- * be fixed, either to support C's terrible pointer type syntax, or to do
- * something better. */
- int composite_flags = 0;
- if (indirection) {
- composite_flags = flags & CFCTYPE_NULLABLE;
- flags &= ~CFCTYPE_NULLABLE;
- }
-
- if (!strcmp(type_name, "int8_t")
- || !strcmp(type_name, "int16_t")
- || !strcmp(type_name, "int32_t")
- || !strcmp(type_name, "int64_t")
- || !strcmp(type_name, "uint8_t")
- || !strcmp(type_name, "uint16_t")
- || !strcmp(type_name, "uint32_t")
- || !strcmp(type_name, "uint64_t")
- || !strcmp(type_name, "char")
- || !strcmp(type_name, "short")
- || !strcmp(type_name, "int")
- || !strcmp(type_name, "long")
- || !strcmp(type_name, "size_t")
- || !strcmp(type_name, "bool")
- ) {
- type = CFCType_new_integer(flags, type_name);
- }
- else if (!strcmp(type_name, "float")
- || !strcmp(type_name, "double")
- ) {
- type = CFCType_new_float(flags, type_name);
- }
- else if (!strcmp(type_name, "void")) {
- type = CFCType_new_void(!!(flags & CFCTYPE_CONST));
- }
- else if (!strcmp(type_name, "va_list")) {
- type = CFCType_new_va_list();
- }
- else if (type_name_len > 2
- && !strcmp(type_name + type_name_len - 2, "_t")
- ) {
- type = CFCType_new_arbitrary(CFCParser_get_parcel(state), type_name);
- }
- else if (indirection > 0) {
- /* The only remaining possibility is an object type, and we can let
- * the constructor perform the complex validation of the type name. */
- indirection--;
- if (indirection == 0) {
- flags |= composite_flags;
- composite_flags = 0;
- }
- type = CFCType_new_object(flags, CFCParser_get_parcel(state), type_name, 1);
- }
- else {
- CFCUtil_die("Invalid type specification at/near '%s'", type_name);
- }
-
- if (indirection) {
- CFCType *composite = CFCType_new_composite(composite_flags, type,
- indirection, NULL);
- CFCBase_decref((CFCBase*)type);
- type = composite;
- }
- else if (array_postfix) {
- CFCType *composite = CFCType_new_composite(composite_flags, type,
- 0, array_postfix);
- CFCBase_decref((CFCBase*)type);
- type = composite;
- }
-
- return type;
-}
-
-} /* End include block. */
-
-%syntax_error {
- (void)yymajor;
- (void)yyminor;
- CFCParser_set_errors(state, true);
-}
-
-%type result {CFCBase*}
-%type file {CFCFile*}
-%type major_block {CFCBase*}
-%type parcel_definition {CFCParcel*}
-%type class_declaration {CFCClass*}
-%type class_head {CFCClass*}
-%type class_defs {CFCClass*}
-%type var_declaration_statement {CFCVariable*}
-%type subroutine_declaration_statement {CFCBase*}
-%type type {CFCType*}
-%type param_variable {CFCVariable*}
-%type param_list {CFCParamList*}
-%type param_list_elems {CFCParamList*}
-%type docucomment {CFCDocuComment*}
-%type cblock {CFCCBlock*}
-%type type_qualifier {int}
-%type type_qualifier_list {int}
-
-%destructor result { CFCBase_decref((CFCBase*)$$); }
-%destructor file { CFCBase_decref((CFCBase*)$$); }
-%destructor major_block { CFCBase_decref((CFCBase*)$$); }
-%destructor parcel_definition { CFCBase_decref((CFCBase*)$$); }
-%destructor class_declaration { CFCBase_decref((CFCBase*)$$); }
-%destructor class_head { CFCBase_decref((CFCBase*)$$); }
-%destructor class_defs { CFCBase_decref((CFCBase*)$$); }
-%destructor var_declaration_statement { CFCBase_decref((CFCBase*)$$); }
-%destructor subroutine_declaration_statement { CFCBase_decref((CFCBase*)$$); }
-%destructor type { CFCBase_decref((CFCBase*)$$); }
-%destructor param_variable { CFCBase_decref((CFCBase*)$$); }
-%destructor param_list { CFCBase_decref((CFCBase*)$$); }
-%destructor param_list_elems { CFCBase_decref((CFCBase*)$$); }
-%destructor docucomment { CFCBase_decref((CFCBase*)$$); }
-%destructor cblock { CFCBase_decref((CFCBase*)$$); }
-
-result ::= type(A).
-{
- CFCParser_set_result(state, (CFCBase*)A);
- CFCBase_decref((CFCBase*)A);
-}
-result ::= param_list(A).
-{
- CFCParser_set_result(state, (CFCBase*)A);
- CFCBase_decref((CFCBase*)A);
-}
-result ::= param_variable(A).
-{
- CFCParser_set_result(state, (CFCBase*)A);
- CFCBase_decref((CFCBase*)A);
-}
-result ::= docucomment(A).
-{
- CFCParser_set_result(state, (CFCBase*)A);
- CFCBase_decref((CFCBase*)A);
-}
-result ::= parcel_definition(A).
-{
- CFCParser_set_result(state, (CFCBase*)A);
- CFCBase_decref((CFCBase*)A);
-}
-result ::= cblock(A).
-{
- CFCParser_set_result(state, (CFCBase*)A);
- CFCBase_decref((CFCBase*)A);
-}
-result ::= var_declaration_statement(A).
-{
- CFCParser_set_result(state, (CFCBase*)A);
- CFCBase_decref((CFCBase*)A);
-}
-result ::= subroutine_declaration_statement(A).
-{
- CFCParser_set_result(state, (CFCBase*)A);
- CFCBase_decref((CFCBase*)A);
-}
-result ::= class_declaration(A).
-{
- CFCParser_set_result(state, (CFCBase*)A);
- CFCBase_decref((CFCBase*)A);
-}
-result ::= file(A).
-{
- CFCParser_set_result(state, (CFCBase*)A);
- CFCBase_decref((CFCBase*)A);
-}
-
-file(A) ::= FILE_START. /* Pseudo token, not passed by lexer. */
-{
- A = CFCFile_new(CFCParser_get_file_spec(state));
-}
-file(A) ::= file(B) major_block(C).
-{
- A = B;
- CFCFile_add_block(A, C);
- CFCBase_decref((CFCBase*)C);
-}
-
-major_block(A) ::= class_declaration(B). { A = (CFCBase*)B; }
-major_block(A) ::= cblock(B). { A = (CFCBase*)B; }
-major_block(A) ::= parcel_definition(B). { A = (CFCBase*)B; }
-
-parcel_definition(A) ::= PARCEL qualified_id(B) SEMICOLON.
-{
- A = CFCParcel_fetch(B);
- if (!A) {
- CFCFileSpec *file_spec = CFCParser_get_file_spec(state);
- int is_included = false;
- if (file_spec) {
- is_included = CFCFileSpec_included(file_spec);
- }
- A = CFCParcel_new(B, NULL, NULL, is_included);
- CFCParcel_register(A);
- CFCBase_decref((CFCBase*)A);
- }
- CFCBase_incref((CFCBase*)A);
- CFCParser_set_parcel(state, A);
-}
-
-class_declaration(A) ::= class_defs(B) RIGHT_CURLY_BRACE.
-{
- A = B;
- CFCParser_set_class_name(state, NULL);
- CFCParser_set_class_cnick(state, NULL);
-}
-
-class_head(A) ::= docucomment(B) exposure_specifier(C) declaration_modifier_list(D) CLASS qualified_id(E) cnick(F) class_inheritance(G). { A = S_start_class(state, B, C, D, E, F, G ); }
-class_head(A) ::= exposure_specifier(C) declaration_modifier_list(D) CLASS qualified_id(E) cnick(F) class_inheritance(G). { A = S_start_class(state, NULL, C, D, E, F, G ); }
-class_head(A) ::= docucomment(B) declaration_modifier_list(D) CLASS qualified_id(E) cnick(F) class_inheritance(G). { A = S_start_class(state, B, NULL, D, E, F, G ); }
-class_head(A) ::= declaration_modifier_list(D) CLASS qualified_id(E) cnick(F) class_inheritance(G). { A = S_start_class(state, NULL, NULL, D, E, F, G ); }
-class_head(A) ::= docucomment(B) exposure_specifier(C) CLASS qualified_id(E) cnick(F) class_inheritance(G). { A = S_start_class(state, B, C, NULL, E, F, G ); }
-class_head(A) ::= exposure_specifier(C) CLASS qualified_id(E) cnick(F) class_inheritance(G). { A = S_start_class(state, NULL, C, NULL, E, F, G ); }
-class_head(A) ::= docucomment(B) CLASS qualified_id(E) cnick(F) class_inheritance(G). { A = S_start_class(state, B, NULL, NULL, E, F, G ); }
-class_head(A) ::= CLASS qualified_id(E) cnick(F) class_inheritance(G). { A = S_start_class(state, NULL, NULL, NULL, E, F, G ); }
-class_head(A) ::= docucomment(B) exposure_specifier(C) declaration_modifier_list(D) CLASS qualified_id(E) class_inheritance(G). { A = S_start_class(state, B, C, D, E, NULL, G ); }
-class_head(A) ::= exposure_specifier(C) declaration_modifier_list(D) CLASS qualified_id(E) class_inheritance(G). { A = S_start_class(state, NULL, C, D, E, NULL, G ); }
-class_head(A) ::= docucomment(B) declaration_modifier_list(D) CLASS qualified_id(E) class_inheritance(G). { A = S_start_class(state, B, NULL, D, E, NULL, G ); }
-class_head(A) ::= declaration_modifier_list(D) CLASS qualified_id(E) class_inheritance(G). { A = S_start_class(state, NULL, NULL, D, E, NULL, G ); }
-class_head(A) ::= docucomment(B) exposure_specifier(C) CLASS qualified_id(E) class_inheritance(G). { A = S_start_class(state, B, C, NULL, E, NULL, G ); }
-class_head(A) ::= exposure_specifier(C) CLASS qualified_id(E) class_inheritance(G). { A = S_start_class(state, NULL, C, NULL, E, NULL, G ); }
-class_head(A) ::= docucomment(B) CLASS qualified_id(E) class_inheritance(G). { A = S_start_class(state, B, NULL, NULL, E, NULL, G ); }
-class_head(A) ::= CLASS qualified_id(E) class_inheritance(G). { A = S_start_class(state, NULL, NULL, NULL, E, NULL, G ); }
-class_head(A) ::= docucomment(B) exposure_specifier(C) declaration_modifier_list(D) CLASS qualified_id(E) cnick(F) . { A = S_start_class(state, B, C, D, E, F, NULL ); }
-class_head(A) ::= exposure_specifier(C) declaration_modifier_list(D) CLASS qualified_id(E) cnick(F) . { A = S_start_class(state, NULL, C, D, E, F, NULL ); }
-class_head(A) ::= docucomment(B) declaration_modifier_list(D) CLASS qualified_id(E) cnick(F) . { A = S_start_class(state, B, NULL, D, E, F, NULL ); }
-class_head(A) ::= declaration_modifier_list(D) CLASS qualified_id(E) cnick(F) . { A = S_start_class(state, NULL, NULL, D, E, F, NULL ); }
-class_head(A) ::= docucomment(B) exposure_specifier(C) CLASS qualified_id(E) cnick(F) . { A = S_start_class(state, B, C, NULL, E, F, NULL ); }
-class_head(A) ::= exposure_specifier(C) CLASS qualified_id(E) cnick(F) . { A = S_start_class(state, NULL, C, NULL, E, F, NULL ); }
-class_head(A) ::= docucomment(B) CLASS qualified_id(E) cnick(F) . { A = S_start_class(state, B, NULL, NULL, E, F, NULL ); }
-class_head(A) ::= CLASS qualified_id(E) cnick(F) . { A = S_start_class(state, NULL, NULL, NULL, E, F, NULL ); }
-class_head(A) ::= docucomment(B) exposure_specifier(C) declaration_modifier_list(D) CLASS qualified_id(E) . { A = S_start_class(state, B, C, D, E, NULL, NULL ); }
-class_head(A) ::= exposure_specifier(C) declaration_modifier_list(D) CLASS qualified_id(E) . { A = S_start_class(state, NULL, C, D, E, NULL, NULL ); }
-class_head(A) ::= docucomment(B) declaration_modifier_list(D) CLASS qualified_id(E) . { A = S_start_class(state, B, NULL, D, E, NULL, NULL ); }
-class_head(A) ::= declaration_modifier_list(D) CLASS qualified_id(E) . { A = S_start_class(state, NULL, NULL, D, E, NULL, NULL ); }
-class_head(A) ::= docucomment(B) exposure_specifier(C) CLASS qualified_id(E) . { A = S_start_class(state, B, C, NULL, E, NULL, NULL ); }
-class_head(A) ::= exposure_specifier(C) CLASS qualified_id(E) . { A = S_start_class(state, NULL, C, NULL, E, NULL, NULL ); }
-class_head(A) ::= docucomment(B) CLASS qualified_id(E) . { A = S_start_class(state, B, NULL, NULL, E, NULL, NULL ); }
-class_head(A) ::= CLASS qualified_id(E) . { A = S_start_class(state, NULL, NULL, NULL, E, NULL, NULL ); }
-
-class_defs(A) ::= class_head(B) LEFT_CURLY_BRACE.
-{
- A = B;
-}
-class_defs(A) ::= class_defs(B) var_declaration_statement(C).
-{
- A = B;
- if (CFCVariable_inert(C)) {
- CFCClass_add_inert_var(A, C);
- }
- else {
- CFCClass_add_member_var(A, C);
- }
- CFCBase_decref((CFCBase*)C);
-}
-class_defs(A) ::= class_defs(B) subroutine_declaration_statement(C).
-{
- A = B;
- if (strcmp(CFCBase_get_cfc_class(C), "Clownfish::CFC::Model::Function") == 0) {
- CFCClass_add_function(A, (CFCFunction*)C);
- }
- else {
- CFCClass_add_method(A, (CFCMethod*)C);
- }
- CFCBase_decref((CFCBase*)C);
-}
-
-var_declaration_statement(A) ::=
- type(D) declarator(E) SEMICOLON.
-{
- A = S_new_var(state, CFCParser_dupe(state, "private"), NULL, D, E);
-}
-var_declaration_statement(A) ::=
- declaration_modifier_list(C)
- type(D) declarator(E) SEMICOLON.
-{
- A = S_new_var(state, CFCParser_dupe(state, "parcel"), C, D, E);
-}
-var_declaration_statement(A) ::=
- exposure_specifier(B)
- declaration_modifier_list(C)
- type(D) declarator(E) SEMICOLON.
-{
- A = S_new_var(state, B, C, D, E);
-}
-
-subroutine_declaration_statement(A) ::=
- type(E) declarator(F) param_list(G) SEMICOLON.
-{
- A = S_new_sub(state, NULL, NULL, NULL, E, F, G);
-}
-subroutine_declaration_statement(A) ::=
- declaration_modifier_list(D)
- type(E) declarator(F) param_list(G) SEMICOLON.
-{
- A = S_new_sub(state, NULL, NULL, D, E, F, G);
-}
-subroutine_declaration_statement(A) ::=
- exposure_specifier(C)
- declaration_modifier_list(D)
- type(E) declarator(F) param_list(G) SEMICOLON.
-{
- A = S_new_sub(state, NULL, C, D, E, F, G);
-}
-subroutine_declaration_statement(A) ::=
- exposure_specifier(C)
- type(E) declarator(F) param_list(G) SEMICOLON.
-{
- A = S_new_sub(state, NULL, C, NULL, E, F, G);
-}
-subroutine_declaration_statement(A) ::=
- docucomment(B)
- type(E) declarator(F) param_list(G) SEMICOLON.
-{
- A = S_new_sub(state, B, NULL, NULL, E, F, G);
-}
-subroutine_declaration_statement(A) ::=
- docucomment(B)
- declaration_modifier_list(D)
- type(E) declarator(F) param_list(G) SEMICOLON.
-{
- A = S_new_sub(state, B, NULL, D, E, F, G);
-}
-subroutine_declaration_statement(A) ::=
- docucomment(B)
- exposure_specifier(C)
- declaration_modifier_list(D)
- type(E) declarator(F) param_list(G) SEMICOLON.
-{
- A = S_new_sub(state, B, C, D, E, F, G);
-}
-subroutine_declaration_statement(A) ::=
- docucomment(B)
- exposure_specifier(C)
- type(E) declarator(F) param_list(G) SEMICOLON.
-{
- A = S_new_sub(state, B, C, NULL, E, F, G);
-}
-
-type(A) ::= type_name(C).
-{
- A = S_new_type(state, 0, C, NULL, NULL);
-}
-type(A) ::= type_name(C) asterisk_postfix(D).
-{
- A = S_new_type(state, 0, C, D, NULL);
-}
-type(A) ::= type_name(C) array_postfix(E).
-{
- A = S_new_type(state, 0, C, NULL, E);
-}
-type(A) ::= type_qualifier_list(B) type_name(C).
-{
- A = S_new_type(state, B, C, NULL, NULL);
-}
-type(A) ::= type_qualifier_list(B) type_name(C) asterisk_postfix(D).
-{
- A = S_new_type(state, B, C, D, NULL);
-}
-type(A) ::= type_qualifier_list(B) type_name(C) array_postfix(E).
-{
- A = S_new_type(state, B, C, NULL, E);
-}
-
-type_name(A) ::= VOID(B). { A = B; }
-type_name(A) ::= VA_LIST(B). { A = B; }
-type_name(A) ::= INTEGER_TYPE_NAME(B). { A = B; }
-type_name(A) ::= FLOAT_TYPE_NAME(B). { A = B; }
-type_name(A) ::= IDENTIFIER(B). { A = B; }
-
-exposure_specifier(A) ::= PUBLIC(B). { A = B; }
-
-type_qualifier(A) ::= CONST. { A = CFCTYPE_CONST; }
-type_qualifier(A) ::= NULLABLE. { A = CFCTYPE_NULLABLE; }
-type_qualifier(A) ::= INCREMENTED. { A = CFCTYPE_INCREMENTED; }
-type_qualifier(A) ::= DECREMENTED. { A = CFCTYPE_DECREMENTED; }
-
-type_qualifier_list(A) ::= type_qualifier(B).
-{
- A = B;
-}
-type_qualifier_list(A) ::= type_qualifier_list(B) type_qualifier(C).
-{
- A = B;
- A |= C;
-}
-
-declaration_modifier(A) ::= INERT(B). { A = B; }
-declaration_modifier(A) ::= INLINE(B). { A = B; }
-declaration_modifier(A) ::= ABSTRACT(B). { A = B; }
-declaration_modifier(A) ::= FINAL(B). { A = B; }
-
-declaration_modifier_list(A) ::= declaration_modifier(B). { A = B; }
-declaration_modifier_list(A) ::= declaration_modifier_list(B) declaration_modifier(C).
-{
- size_t size = strlen(B) + strlen(C) + 2;
- A = (char*)CFCParser_allocate(state, size);
- sprintf(A, "%s %s", B, C);
-}
-
-asterisk_postfix(A) ::= ASTERISK(B). { A = B; }
-asterisk_postfix(A) ::= asterisk_postfix(B) ASTERISK.
-{
- size_t size = strlen(B) + 2;
- A = (char*)CFCParser_allocate(state, size);
- sprintf(A, "%s*", B);
-}
-
-array_postfix_elem(A) ::= LEFT_SQUARE_BRACKET RIGHT_SQUARE_BRACKET.
-{
- A = CFCParser_dupe(state, "[]");
-}
-array_postfix_elem(A) ::= LEFT_SQUARE_BRACKET INTEGER_LITERAL(B) RIGHT_SQUARE_BRACKET.
-{
- size_t size = strlen(B) + 3;
- A = (char*)CFCParser_allocate(state, size);
- sprintf(A, "[%s]", B);
-}
-
-array_postfix(A) ::= array_postfix_elem(B). { A = B; }
-array_postfix(A) ::= array_postfix(B) array_postfix_elem(C).
-{
- size_t size = strlen(B) + strlen(C) + 1;
- A = (char*)CFCParser_allocate(state, size);
- sprintf(A, "%s%s", B, C);
-}
-
-scalar_constant(A) ::= HEX_LITERAL(B). { A = B; }
-scalar_constant(A) ::= FLOAT_LITERAL(B). { A = B; }
-scalar_constant(A) ::= INTEGER_LITERAL(B). { A = B; }
-scalar_constant(A) ::= STRING_LITERAL(B). { A = B; }
-scalar_constant(A) ::= TRUE(B). { A = B; }
-scalar_constant(A) ::= FALSE(B). { A = B; }
-scalar_constant(A) ::= NULL(B). { A = B; }
-
-declarator(A) ::= IDENTIFIER(B).
-{
- A = B;
-}
-
-param_variable(A) ::= type(B) declarator(C).
-{
- A = S_new_var(state, NULL, NULL, B, C);
-}
-
-param_list(A) ::= LEFT_PAREN RIGHT_PAREN.
-{
- A = CFCParamList_new(false);
-}
-param_list(A) ::= LEFT_PAREN param_list_elems(B) RIGHT_PAREN.
-{
- A = B;
-}
-param_list(A) ::= LEFT_PAREN param_list_elems(B) COMMA ELLIPSIS RIGHT_PAREN.
-{
- A = B;
- CFCParamList_set_variadic(A, true);
-}
-param_list_elems(A) ::= param_list_elems(B) COMMA param_variable(C).
-{
- A = B;
- CFCParamList_add_param(A, C, NULL);
- CFCBase_decref((CFCBase*)C);
-}
-param_list_elems(A) ::= param_list_elems(B) COMMA param_variable(C) EQUALS scalar_constant(D).
-{
- A = B;
- CFCParamList_add_param(A, C, D);
- CFCBase_decref((CFCBase*)C);
-}
-param_list_elems(A) ::= param_variable(B).
-{
- A = CFCParamList_new(false);
- CFCParamList_add_param(A, B, NULL);
- CFCBase_decref((CFCBase*)B);
-}
-param_list_elems(A) ::= param_variable(B) EQUALS scalar_constant(C).
-{
- A = CFCParamList_new(false);
- CFCParamList_add_param(A, B, C);
- CFCBase_decref((CFCBase*)B);
-}
-
-qualified_id(A) ::= IDENTIFIER(B). { A = B; }
-qualified_id(A) ::= qualified_id(B) SCOPE_OP IDENTIFIER(C).
-{
- size_t size = strlen(B) + strlen(C) + 3;
- A = (char*)CFCParser_allocate(state, size);
- sprintf(A, "%s::%s", B, C);
-}
-
-docucomment(A) ::= DOCUCOMMENT(B). { A = CFCDocuComment_parse(B); }
-class_inheritance(A) ::= INHERITS qualified_id(B). { A = B; }
-cnick(A) ::= CNICK IDENTIFIER(B). { A = B; }
-cblock(A) ::= CBLOCK_START blob(B) CBLOCK_CLOSE. { A = CFCCBlock_new(B); }
-cblock(A) ::= CBLOCK_START CBLOCK_CLOSE. { A = CFCCBlock_new(""); }
-
-blob(A) ::= BLOB(B). { A = B; }
-blob(A) ::= blob(B) BLOB(C).
-{
- size_t size = strlen(B) + strlen(C) + 1;
- A = (char*)CFCParser_allocate(state, size);
- sprintf(A, "%s%s", B, C);
-}
-
http://git-wip-us.apache.org/repos/asf/lucy/blob/1704c275/clownfish/compiler/src/CFCParser.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCParser.c b/clownfish/compiler/src/CFCParser.c
deleted file mode 100644
index 0a16d65..0000000
--- a/clownfish/compiler/src/CFCParser.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define CFC_NEED_BASE_STRUCT_DEF
-#include "CFCBase.h"
-#include "CFCParser.h"
-#include "CFCParcel.h"
-#include "CFCFile.h"
-#include "CFCFileSpec.h"
-#include "CFCUtil.h"
-#include "CFCMemPool.h"
-#include "CFCLexHeader.h"
-#include "CFCParseHeader.h"
-
-#ifndef true
- #define true 1
- #define false 0
-#endif
-
-struct CFCParser {
- CFCBase base;
- void *header_parser;
- struct CFCBase *result;
- int errors;
- char *class_name;
- char *class_cnick;
- CFCFileSpec *file_spec;
- CFCMemPool *pool;
- CFCParcel *parcel;
-};
-
-static const CFCMeta CFCPARSER_META = {
- "Clownfish::CFC::Parser",
- sizeof(CFCParser),
- (CFCBase_destroy_t)CFCParser_destroy
-};
-
-CFCParser*
-CFCParser_new(void) {
- CFCParser *self = (CFCParser*)CFCBase_allocate(&CFCPARSER_META);
- return CFCParser_init(self);
-}
-
-CFCParser*
-CFCParser_init(CFCParser *self) {
- self->header_parser = CFCParseHeaderAlloc(malloc);
- if (self->header_parser == NULL) {
- CFCUtil_die("Failed to allocate header parser");
- }
- self->result = NULL;
- self->errors = false;
- self->class_name = NULL;
- self->class_cnick = NULL;
- self->file_spec = NULL;
- self->pool = NULL;
- self->parcel = NULL;
- return self;
-}
-
-void
-CFCParser_destroy(CFCParser *self) {
- CFCParseHeaderFree(self->header_parser, free);
- FREEMEM(self->class_name);
- FREEMEM(self->class_cnick);
- CFCBase_decref((CFCBase*)self->file_spec);
- CFCBase_decref((CFCBase*)self->pool);
- CFCBase_decref(self->result);
- CFCBase_decref((CFCBase*)self->parcel);
- CFCBase_destroy((CFCBase*)self);
-}
-
-CFCParser *CFCParser_current_state = NULL;
-void *CFCParser_current_parser = NULL;
-
-CFCBase*
-CFCParser_parse(CFCParser *self, const char *string) {
- self->pool = CFCMemPool_new(0);
-
- // Make Lemon-based parser and parser state available from Flex-based scanner.
- CFCParser_current_state = self;
- CFCParser_current_parser = self->header_parser;
-
- // Zero out, then parse.
- self->errors = false;
- YY_BUFFER_STATE buffer = yy_scan_bytes(string, (int)strlen(string));
- yylex();
- yy_delete_buffer(buffer);
-
- // Finish up.
- CFCParseHeader(CFCParser_current_parser, 0, NULL, self);
- CFCBase_decref((CFCBase*)self->pool);
- self->pool = NULL;
- CFCBase *result = self->result;
- self->result = NULL;
- if (self->errors) {
- CFCBase_decref((CFCBase*)result);
- result = NULL;
- }
- return result;
-}
-
-CFCFile*
-CFCParser_parse_file(CFCParser *self, const char *string,
- CFCFileSpec *file_spec) {
- CFCParser_set_parcel(self, NULL);
- CFCParser_set_file_spec(self, file_spec);
- CFCParseHeader(self->header_parser, CFC_TOKENTYPE_FILE_START, NULL, self);
- CFCFile *result = (CFCFile*)CFCParser_parse(self, string);
- CFCParser_set_file_spec(self, NULL);
- return result;
-}
-
-char*
-CFCParser_dupe(CFCParser *self, const char *string) {
- size_t len = strlen(string);
- char *dupe = (char*)CFCMemPool_allocate(self->pool, len + 1);
- memcpy(dupe, string, len + 1);
- return dupe;
-}
-
-void*
-CFCParser_allocate(CFCParser *self, size_t size) {
- return CFCMemPool_allocate(self->pool, size);
-}
-
-void
-CFCParser_set_result(CFCParser *self, CFCBase *result) {
- CFCBase_decref(self->result);
- self->result = CFCBase_incref(result);
-}
-
-void
-CFCParser_set_errors(CFCParser *self, int errors) {
- self->errors = errors;
-}
-
-void
-CFCParser_set_parcel(CFCParser *self, CFCParcel *parcel) {
- CFCBase_incref((CFCBase*)parcel);
- CFCBase_decref((CFCBase*)self->parcel);
- self->parcel = parcel;
-}
-
-CFCParcel*
-CFCParser_get_parcel(CFCParser *self) {
- return self->parcel;
-}
-
-void
-CFCParser_set_class_name(CFCParser *self, const char *class_name) {
- FREEMEM(self->class_name);
- if (class_name) {
- self->class_name = CFCUtil_strdup(class_name);
- }
- else {
- self->class_name = NULL;
- }
-}
-
-const char*
-CFCParser_get_class_name(CFCParser *self) {
- return self->class_name;
-}
-
-void
-CFCParser_set_class_cnick(CFCParser *self, const char *class_cnick) {
- FREEMEM(self->class_cnick);
- if (class_cnick) {
- self->class_cnick = CFCUtil_strdup(class_cnick);
- }
- else {
- self->class_cnick = NULL;
- }
-}
-
-const char*
-CFCParser_get_class_cnick(CFCParser *self) {
- return self->class_cnick;
-}
-
-void
-CFCParser_set_file_spec(CFCParser *self, CFCFileSpec *file_spec) {
- CFCBase_decref((CFCBase*)self->file_spec);
- self->file_spec = (CFCFileSpec*)CFCBase_incref((CFCBase*)file_spec);
-}
-
-CFCFileSpec*
-CFCParser_get_file_spec(CFCParser *self) {
- return self->file_spec;
-}
-
http://git-wip-us.apache.org/repos/asf/lucy/blob/1704c275/clownfish/compiler/src/CFCParser.h
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCParser.h b/clownfish/compiler/src/CFCParser.h
deleted file mode 100644
index 19300cf..0000000
--- a/clownfish/compiler/src/CFCParser.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/** Clownfish::CFC::Parser - Parse Clownfish header files.
- *
- * Clownfish::CFC::Parser is a combined lexer/parser which parses Clownfish header
- * files. It is not at all strict, as it relies heavily on the C parser to
- * pick up errors such as misspelled type names.
- */
-
-#ifndef H_CFCPARSER
-#define H_CFCPARSER
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct CFCParser CFCParser;
-struct CFCBase;
-struct CFCParcel;
-struct CFCFile;
-struct CFCFileSpec;
-
-extern CFCParser *CFCParser_current_state;
-extern void *CFCParser_current_parser;
-
-CFCParser*
-CFCParser_new(void);
-
-CFCParser*
-CFCParser_init(CFCParser *self);
-
-void
-CFCParser_destroy(CFCParser *self);
-
-struct CFCBase*
-CFCParser_parse(CFCParser *self, const char *string);
-
-struct CFCFile*
-CFCParser_parse_file(CFCParser *self, const char *string,
- struct CFCFileSpec *file_spec);
-
-char*
-CFCParser_dupe(CFCParser *self, const char *string);
-
-void*
-CFCParser_allocate(CFCParser *self, size_t size);
-
-void
-CFCParser_set_result(CFCParser *self, struct CFCBase *result);
-
-void
-CFCParser_set_errors(CFCParser *self, int errors);
-
-void
-CFCParser_set_text(CFCParser *self, const char *text, size_t len);
-
-const char*
-CFCParser_get_text(CFCParser *self);
-
-void
-CFCParser_set_parcel(CFCParser *self, struct CFCParcel *parcel);
-
-struct CFCParcel*
-CFCParser_get_parcel(CFCParser *self);
-
-void
-CFCParser_set_class_name(CFCParser *self, const char *class_name);
-
-const char*
-CFCParser_get_class_name(CFCParser *self);
-
-void
-CFCParser_set_class_cnick(CFCParser *self, const char *class_cnick);
-
-const char*
-CFCParser_get_class_cnick(CFCParser *self);
-
-void
-CFCParser_set_file_spec(CFCParser *self, struct CFCFileSpec *file_spec);
-
-struct CFCFileSpec*
-CFCParser_get_file_spec(CFCParser *self);
-
-/* Routines generated by Lemon. */
-void*
-CFCParseHeaderAlloc(void * (*allocate)(size_t));
-
-void
-CFCParseHeader(void *header_parser, int token_type, char *value,
- CFCParser *state);
-
-void
-CFCParseHeaderFree(void *header_parser, void(*freemem)(void*));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* H_CFCPARSER */
-
http://git-wip-us.apache.org/repos/asf/lucy/blob/1704c275/clownfish/compiler/src/CFCPerl.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCPerl.c b/clownfish/compiler/src/CFCPerl.c
deleted file mode 100644
index 3f51df2..0000000
--- a/clownfish/compiler/src/CFCPerl.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "charmony.h"
-
-#include <string.h>
-#include <stdio.h>
-#include <ctype.h>
-#define CFC_NEED_BASE_STRUCT_DEF
-#include "CFCBase.h"
-#include "CFCPerl.h"
-#include "CFCParcel.h"
-#include "CFCClass.h"
-#include "CFCMethod.h"
-#include "CFCHierarchy.h"
-#include "CFCUtil.h"
-#include "CFCPerlClass.h"
-#include "CFCPerlSub.h"
-#include "CFCPerlConstructor.h"
-#include "CFCPerlMethod.h"
-#include "CFCPerlTypeMap.h"
-#include "CFCBindCore.h"
-
-struct CFCPerl {
- CFCBase base;
- CFCHierarchy *hierarchy;
- char *lib_dir;
- char *boot_class;
- char *header;
- char *footer;
- char *xs_path;
- char *boot_func;
-};
-
-// Modify a string in place, swapping out "::" for the supplied character.
-static void
-S_replace_double_colons(char *text, char replacement);
-
-static void
-S_write_callbacks_c(CFCPerl *self);
-
-static const CFCMeta CFCPERL_META = {
- "Clownfish::CFC::Binding::Perl",
- sizeof(CFCPerl),
- (CFCBase_destroy_t)CFCPerl_destroy
-};
-
-CFCPerl*
-CFCPerl_new(CFCHierarchy *hierarchy, const char *lib_dir,
- const char *boot_class, const char *header, const char *footer) {
- CFCPerl *self = (CFCPerl*)CFCBase_allocate(&CFCPERL_META);
- return CFCPerl_init(self, hierarchy, lib_dir, boot_class, header, footer);
-}
-
-CFCPerl*
-CFCPerl_init(CFCPerl *self, CFCHierarchy *hierarchy, const char *lib_dir,
- const char *boot_class, const char *header, const char *footer) {
- CFCUTIL_NULL_CHECK(hierarchy);
- CFCUTIL_NULL_CHECK(lib_dir);
- CFCUTIL_NULL_CHECK(boot_class);
- CFCUTIL_NULL_CHECK(header);
- CFCUTIL_NULL_CHECK(footer);
- self->hierarchy = (CFCHierarchy*)CFCBase_incref((CFCBase*)hierarchy);
- self->lib_dir = CFCUtil_strdup(lib_dir);
- self->boot_class = CFCUtil_strdup(boot_class);
- self->header = CFCUtil_strdup(header);
- self->footer = CFCUtil_strdup(footer);
-
- // Derive path to generated .xs file.
- self->xs_path = CFCUtil_sprintf("%s" CHY_DIR_SEP "%s.xs", lib_dir,
- boot_class);
- S_replace_double_colons(self->xs_path, CHY_DIR_SEP_CHAR);
-
- // Derive the name of the bootstrap function.
- self->boot_func = CFCUtil_sprintf("cfish_%s_bootstrap", boot_class);
- for (int i = 0; self->boot_func[i] != 0; i++) {
- if (!isalnum(self->boot_func[i])) {
- self->boot_func[i] = '_';
- }
- }
-
- return self;
-}
-
-void
-CFCPerl_destroy(CFCPerl *self) {
- CFCBase_decref((CFCBase*)self->hierarchy);
- FREEMEM(self->lib_dir);
- FREEMEM(self->boot_class);
- FREEMEM(self->header);
- FREEMEM(self->footer);
- FREEMEM(self->xs_path);
- FREEMEM(self->boot_func);
- CFCBase_destroy((CFCBase*)self);
-}
-
-static void
-S_replace_double_colons(char *text, char replacement) {
- size_t pos = 0;
- for (char *ptr = text; *ptr != '\0'; ptr++) {
- if (strncmp(ptr, "::", 2) == 0) {
- text[pos++] = replacement;
- ptr++;
- }
- else {
- text[pos++] = *ptr;
- }
- }
- text[pos] = '\0';
-}
-
-char**
-CFCPerl_write_pod(CFCPerl *self) {
- CFCPerlClass **registry = CFCPerlClass_registry();
- size_t num_registered = 0;
- while (registry[num_registered] != NULL) { num_registered++; }
- char **pod_paths = (char**)CALLOCATE(num_registered + 1, sizeof(char*));
- char **pods = (char**)CALLOCATE(num_registered + 1, sizeof(char*));
- size_t count = 0;
-
- // Generate POD, but don't write. That way, if there's an error while
- // generating pod, we leak memory but don't clutter up the file system.
- for (size_t i = 0; i < num_registered; i++) {
- const char *class_name = CFCPerlClass_get_class_name(registry[i]);
- char *pod = CFCPerlClass_create_pod(registry[i]);
- if (!pod) { continue; }
- char *pod_path = CFCUtil_sprintf("%s" CHY_DIR_SEP "%s.pod",
- self->lib_dir, class_name);
- S_replace_double_colons(pod_path, CHY_DIR_SEP_CHAR);
-
- pods[count] = pod;
- pod_paths[count] = pod_path;
- count++;
- }
-
- // Write out any POD files that have changed.
- size_t num_written = 0;
- for (size_t i = 0; i < count; i++) {
- char *pod = pods[i];
- char *pod_path = pod_paths[i];
- if (CFCUtil_write_if_changed(pod_path, pod, strlen(pod))) {
- pod_paths[num_written] = pod_path;
- num_written++;
- }
- else {
- FREEMEM(pod_path);
- }
- FREEMEM(pod);
- }
- pod_paths[num_written] = NULL;
-
- return pod_paths;
-}
-
-static void
-S_write_boot_h(CFCPerl *self) {
- char *guard = CFCUtil_sprintf("%s_BOOT", self->boot_class);
- S_replace_double_colons(guard, '_');
- for (char *ptr = guard; *ptr != '\0'; ptr++) {
- if (isalpha(*ptr)) {
- *ptr = toupper(*ptr);
- }
- }
-
- const char pattern[] =
- "%s\n"
- "\n"
- "#ifndef %s\n"
- "#define %s 1\n"
- "\n"
- "void\n"
- "%s();\n"
- "\n"
- "#endif /* %s */\n"
- "\n"
- "%s\n";
- char *content
- = CFCUtil_sprintf(pattern, self->header, guard, guard, self->boot_func,
- guard, self->footer);
-
- const char *inc_dest = CFCHierarchy_get_include_dest(self->hierarchy);
- char *boot_h_path = CFCUtil_sprintf("%s" CHY_DIR_SEP "boot.h", inc_dest);
- CFCUtil_write_file(boot_h_path, content, strlen(content));
- FREEMEM(boot_h_path);
-
- FREEMEM(content);
- FREEMEM(guard);
-}
-
-static void
-S_write_boot_c(CFCPerl *self) {
- CFCClass **ordered = CFCHierarchy_ordered_classes(self->hierarchy);
- CFCParcel **parcels = CFCParcel_all_parcels();
- char *pound_includes = CFCUtil_strdup("");
- char *bootstrap_code = CFCUtil_strdup("");
- char *alias_adds = CFCUtil_strdup("");
- char *isa_pushes = CFCUtil_strdup("");
-
- for (size_t i = 0; parcels[i]; ++i) {
- if (!CFCParcel_included(parcels[i])) {
- const char *prefix = CFCParcel_get_prefix(parcels[i]);
- bootstrap_code = CFCUtil_cat(bootstrap_code, " ", prefix,
- "bootstrap_parcel();\n", NULL);
- }
- }
-
- for (size_t i = 0; ordered[i] != NULL; i++) {
- CFCClass *klass = ordered[i];
- if (CFCClass_included(klass)) { continue; }
-
- const char *class_name = CFCClass_get_class_name(klass);
- const char *include_h = CFCClass_include_h(klass);
- pound_includes = CFCUtil_cat(pound_includes, "#include \"",
- include_h, "\"\n", NULL);
-
- if (CFCClass_inert(klass)) { continue; }
-
- // Add aliases for selected KinoSearch classes which allow old indexes
- // to be read.
- CFCPerlClass *class_binding = CFCPerlClass_singleton(class_name);
- if (class_binding) {
- const char *vtable_var = CFCClass_full_vtable_var(klass);
- const char **aliases
- = CFCPerlClass_get_class_aliases(class_binding);
- for (size_t j = 0; aliases[j] != NULL; j++) {
- const char *alias = aliases[j];
- size_t alias_len = strlen(alias);
- const char pattern[] =
- " cfish_VTable_add_alias_to_registry("
- "%s, \"%s\", %u);\n";
- char *alias_add
- = CFCUtil_sprintf(pattern, vtable_var, alias,
- (unsigned)alias_len);
- alias_adds = CFCUtil_cat(alias_adds, alias_add, NULL);
- FREEMEM(alias_add);
- }
-
- char *metadata_code
- = CFCPerlClass_method_metadata_code(class_binding);
- alias_adds = CFCUtil_cat(alias_adds, metadata_code, NULL);
- FREEMEM(metadata_code);
- }
-
- CFCClass *parent = CFCClass_get_parent(klass);
- if (parent) {
- const char *parent_class_name = CFCClass_get_class_name(parent);
- isa_pushes
- = CFCUtil_cat(isa_pushes, " isa = get_av(\"",
- class_name, "::ISA\", 1);\n", NULL);
- isa_pushes
- = CFCUtil_cat(isa_pushes, " av_push(isa, newSVpv(\"",
- parent_class_name, "\", 0));\n", NULL);
- }
- }
-
- const char pattern[] =
- "%s\n"
- "\n"
- "#include \"cfish_parcel.h\"\n"
- "#include \"EXTERN.h\"\n"
- "#include \"perl.h\"\n"
- "#include \"XSUB.h\"\n"
- "#include \"boot.h\"\n"
- "#include \"Clownfish/String.h\"\n"
- "#include \"Clownfish/VTable.h\"\n"
- "%s\n"
- "\n"
- "void\n"
- "%s() {\n"
- "%s"
- "\n"
- "%s"
- "\n"
- " AV *isa;\n"
- "%s"
- "}\n"
- "\n"
- "%s\n"
- "\n";
- char *content
- = CFCUtil_sprintf(pattern, self->header, pound_includes,
- self->boot_func, bootstrap_code, alias_adds,
- isa_pushes, self->footer);
-
- const char *src_dest = CFCHierarchy_get_source_dest(self->hierarchy);
- char *boot_c_path = CFCUtil_sprintf("%s" CHY_DIR_SEP "boot.c", src_dest);
- CFCUtil_write_file(boot_c_path, content, strlen(content));
- FREEMEM(boot_c_path);
-
- FREEMEM(content);
- FREEMEM(isa_pushes);
- FREEMEM(alias_adds);
- FREEMEM(bootstrap_code);
- FREEMEM(pound_includes);
- FREEMEM(parcels);
- FREEMEM(ordered);
-}
-
-void
-CFCPerl_write_hostdefs(CFCPerl *self) {
- const char pattern[] =
- "%s\n"
- "\n"
- "#ifndef H_CFISH_HOSTDEFS\n"
- "#define H_CFISH_HOSTDEFS 1\n"
- "\n"
- "/* Refcount / host object */\n"
- "typedef union {\n"
- " size_t count;\n"
- " void *host_obj;\n"
- "} cfish_ref_t;\n"
- "\n"
- "#define CFISH_OBJ_HEAD\\\n"
- " cfish_ref_t ref;\n"
- "\n"
- "#endif /* H_CFISH_HOSTDEFS */\n"
- "\n"
- "%s\n";
- char *content
- = CFCUtil_sprintf(pattern, self->header, self->footer);
-
- // Unlink then write file.
- const char *inc_dest = CFCHierarchy_get_include_dest(self->hierarchy);
- char *filepath = CFCUtil_sprintf("%s" CHY_DIR_SEP "cfish_hostdefs.h",
- inc_dest);
- remove(filepath);
- CFCUtil_write_file(filepath, content, strlen(content));
- FREEMEM(filepath);
-
- FREEMEM(content);
-}
-
-void
-CFCPerl_write_boot(CFCPerl *self) {
- S_write_boot_h(self);
- S_write_boot_c(self);
-}
-
-static char*
-S_xs_file_contents(CFCPerl *self, const char *generated_xs,
- const char *xs_init, const char *hand_rolled_xs) {
- const char pattern[] =
- "%s"
- "\n"
- "#include \"XSBind.h\"\n"
- "#include \"boot.h\"\n"
- "\n"
- "%s\n"
- "\n"
- "MODULE = %s PACKAGE = %s\n"
- "\n"
- "void\n"
- "_init_autobindings()\n"
- "PPCODE:\n"
- "{\n"
- " const char* file = __FILE__;\n"
- " CFISH_UNUSED_VAR(cv);\n"
- " CFISH_UNUSED_VAR(items); %s\n"
- "}\n"
- "\n"
- "%s\n"
- "\n"
- "%s";
- char *contents
- = CFCUtil_sprintf(pattern, self->header, generated_xs,
- self->boot_class, self->boot_class, xs_init,
- hand_rolled_xs, self->footer);
-
- return contents;
-}
-
-static char*
-S_add_xs_init(char *xs_init, CFCPerlSub *xsub) {
- const char *c_name = CFCPerlSub_c_name(xsub);
- const char *perl_name = CFCPerlSub_perl_name(xsub);
- if (strlen(xs_init)) {
- xs_init = CFCUtil_cat(xs_init, "\n ", NULL);
- }
- xs_init = CFCUtil_cat(xs_init, "newXS(\"", perl_name, "\", ", c_name,
- ", file);", NULL);
- return xs_init;
-}
-
-void
-CFCPerl_write_bindings(CFCPerl *self) {
- CFCClass **ordered = CFCHierarchy_ordered_classes(self->hierarchy);
- CFCPerlClass **registry = CFCPerlClass_registry();
- char *hand_rolled_xs = CFCUtil_strdup("");
- char *generated_xs = CFCUtil_strdup("");
- char *xs_init = CFCUtil_strdup("");
-
- // Pound-includes for generated headers.
- for (size_t i = 0; ordered[i] != NULL; i++) {
- CFCClass *klass = ordered[i];
- // TODO: Don't include headers for parcels the source parcels don't
- // depend on.
- const char *include_h = CFCClass_include_h(klass);
- generated_xs = CFCUtil_cat(generated_xs, "#include \"", include_h,
- "\"\n", NULL);
- }
- generated_xs = CFCUtil_cat(generated_xs, "\n", NULL);
-
- for (size_t i = 0; ordered[i] != NULL; i++) {
- CFCClass *klass = ordered[i];
- if (CFCClass_included(klass)) { continue; }
-
- // Constructors.
- CFCPerlConstructor **constructors
- = CFCPerlClass_constructor_bindings(klass);
- for (size_t j = 0; constructors[j] != NULL; j++) {
- CFCPerlSub *xsub = (CFCPerlSub*)constructors[j];
-
- // Add the XSUB function definition.
- char *xsub_def = CFCPerlConstructor_xsub_def(constructors[j]);
- generated_xs = CFCUtil_cat(generated_xs, xsub_def, "\n",
- NULL);
- FREEMEM(xsub_def);
-
- // Add XSUB initialization at boot.
- xs_init = S_add_xs_init(xs_init, xsub);
- }
- FREEMEM(constructors);
-
- // Methods.
- CFCPerlMethod **methods = CFCPerlClass_method_bindings(klass);
- for (size_t j = 0; methods[j] != NULL; j++) {
- CFCPerlSub *xsub = (CFCPerlSub*)methods[j];
-
- // Add the XSUB function definition.
- char *xsub_def = CFCPerlMethod_xsub_def(methods[j]);
- generated_xs = CFCUtil_cat(generated_xs, xsub_def, "\n",
- NULL);
- FREEMEM(xsub_def);
-
- // Add XSUB initialization at boot.
- xs_init = S_add_xs_init(xs_init, xsub);
- }
- FREEMEM(methods);
- }
-
- // Hand-rolled XS.
- for (size_t i = 0; registry[i] != NULL; i++) {
- const char *xs = CFCPerlClass_get_xs_code(registry[i]);
- hand_rolled_xs = CFCUtil_cat(hand_rolled_xs, xs, "\n", NULL);
- }
-
- // Write out if there have been any changes.
- char *xs_file_contents
- = S_xs_file_contents(self, generated_xs, xs_init, hand_rolled_xs);
- CFCUtil_write_if_changed(self->xs_path, xs_file_contents,
- strlen(xs_file_contents));
-
- FREEMEM(xs_file_contents);
- FREEMEM(hand_rolled_xs);
- FREEMEM(xs_init);
- FREEMEM(generated_xs);
- FREEMEM(ordered);
-}
-
-void
-CFCPerl_write_callbacks(CFCPerl *self) {
- CFCBindCore *core_binding
- = CFCBindCore_new(self->hierarchy, self->header, self->footer);
- CFCBindCore_write_callbacks_h(core_binding);
- CFCBase_decref((CFCBase*)core_binding);
-
- S_write_callbacks_c(self);
-}
-
-static void
-S_write_callbacks_c(CFCPerl *self) {
- CFCClass **ordered = CFCHierarchy_ordered_classes(self->hierarchy);
- static const char pattern[] =
- "%s"
- "\n"
- "#include \"XSBind.h\"\n"
- "#include \"callbacks.h\"\n"
- "\n"
- "static void\n"
- "S_finish_callback_void(const char *meth_name) {\n"
- " int count = call_method(meth_name, G_VOID | G_DISCARD);\n"
- " if (count != 0) {\n"
- " CFISH_THROW(CFISH_ERR, \"Bad callback to '%%s': %%i32\",\n"
- " meth_name, (int32_t)count);\n"
- " }\n"
- " FREETMPS;\n"
- " LEAVE;\n"
- "}\n"
- "\n"
- "static CFISH_INLINE SV*\n"
- "SI_do_callback_sv(const char *meth_name) {\n"
- " int count = call_method(meth_name, G_SCALAR);\n"
- " if (count != 1) {\n"
- " CFISH_THROW(CFISH_ERR, \"Bad callback to '%%s': %%i32\",\n"
- " meth_name, (int32_t)count);\n"
- " }\n"
- " dSP;\n"
- " SV *return_sv = POPs;\n"
- " PUTBACK;\n"
- " return return_sv;\n"
- "}\n"
- "\n"
- "static int64_t\n"
- "S_finish_callback_i64(const char *meth_name) {\n"
- " SV *return_sv = SI_do_callback_sv(meth_name);\n"
- " int64_t retval;\n"
- " if (sizeof(IV) == 8) {\n"
- " retval = (int64_t)SvIV(return_sv);\n"
- " }\n"
- " else {\n"
- " if (SvIOK(return_sv)) {\n"
- " // It's already no more than 32 bits, so don't convert.\n"
- " retval = SvIV(return_sv);\n"
- " }\n"
- " else {\n"
- " // Maybe lossy.\n"
- " double temp = SvNV(return_sv);\n"
- " retval = (int64_t)temp;\n"
- " }\n"
- " }\n"
- " FREETMPS;\n"
- " LEAVE;\n"
- " return retval;\n"
- "}\n"
- "\n"
- "static double\n"
- "S_finish_callback_f64(const char *meth_name) {\n"
- " SV *return_sv = SI_do_callback_sv(meth_name);\n"
- " double retval = SvNV(return_sv);\n"
- " FREETMPS;\n"
- " LEAVE;\n"
- " return retval;\n"
- "}\n"
- "\n"
- "static cfish_Obj*\n"
- "S_finish_callback_obj(void *vself, const char *meth_name,\n"
- " int nullable) {\n"
- " SV *return_sv = SI_do_callback_sv(meth_name);\n"
- " cfish_Obj *retval = XSBind_perl_to_cfish(return_sv);\n"
- " FREETMPS;\n"
- " LEAVE;\n"
- " if (!nullable && !retval) {\n"
- " CFISH_THROW(CFISH_ERR, \"%%o#%%s cannot return NULL\",\n"
- " CFISH_Obj_Get_Class_Name((cfish_Obj*)vself),\n"
- " meth_name);\n"
- " }\n"
- " return retval;\n"
- "}\n"
- "\n";
- char *content = CFCUtil_sprintf(pattern, self->header);
-
- for (size_t i = 0; ordered[i] != NULL; i++) {
- CFCClass *klass = ordered[i];
- if (CFCClass_included(klass) || CFCClass_inert(klass)) { continue; }
-
- CFCMethod **fresh_methods = CFCClass_fresh_methods(klass);
- for (int meth_num = 0; fresh_methods[meth_num] != NULL; meth_num++) {
- CFCMethod *method = fresh_methods[meth_num];
-
- // Define callback.
- if (CFCMethod_novel(method) && !CFCMethod_final(method)) {
- char *cb_def = CFCPerlMethod_callback_def(method);
- content = CFCUtil_cat(content, cb_def, "\n", NULL);
- FREEMEM(cb_def);
- }
- }
- FREEMEM(fresh_methods);
- }
-
- content = CFCUtil_cat(content, self->footer, NULL);
-
- // Write if changed.
- const char *src_dest = CFCHierarchy_get_source_dest(self->hierarchy);
- char *filepath = CFCUtil_sprintf("%s" CHY_DIR_SEP "callbacks.c",
- src_dest);
- CFCUtil_write_if_changed(filepath, content, strlen(content));
-
- FREEMEM(filepath);
- FREEMEM(content);
- FREEMEM(ordered);
-}
-
-void
-CFCPerl_write_xs_typemap(CFCPerl *self) {
- CFCPerlTypeMap_write_xs_typemap(self->hierarchy);
-}
-
http://git-wip-us.apache.org/repos/asf/lucy/blob/1704c275/clownfish/compiler/src/CFCPerl.h
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCPerl.h b/clownfish/compiler/src/CFCPerl.h
deleted file mode 100644
index eef10ac..0000000
--- a/clownfish/compiler/src/CFCPerl.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef H_CFCPERL
-#define H_CFCPERL
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct CFCPerl CFCPerl;
-struct CFCParcel;
-struct CFCHierarchy;
-
-/** Clownfish::CFC::Binding::Perl - Perl bindings for a
- * Clownfish::CFC::Model::Hierarchy.
- *
- * Clownfish::CFC::Binding::Perl presents an interface for auto-generating XS
- * and Perl code to bind C code for a Clownfish class hierarchy to Perl.
- *
- * In theory this module could be much more flexible and its API could be more
- * elegant. There are many ways which you could walk the parsed parcels,
- * classes, methods, etc. in a Clownfish::CFC::Model::Hierarchy and generate
- * binding code. However, our needs are very limited, so we are content with
- * a "one size fits one" solution.
- *
- * In particular, this module assumes that the XS bindings for all classes in
- * the hierarchy should be assembled into a single shared object which belongs
- * to the primary, "boot" class. There's no reason why it could not write one
- * .xs file per class, or one per parcel, instead.
- *
- * The files written by this class are derived from the name of the boot class.
- * If it is "Crustacean", the following files will be generated.
- *
- * # Generated by write_bindings()
- * $lib_dir/Crustacean.xs
- *
- * # Generated by write_boot()
- * $hierarchy_dest_dir/crust_boot.h
- * $hierarchy_dest_dir/crust_boot.c
- */
-
-/**
- * @param parcel The L<Clownfish::CFC::Model::Parcel> to which the
- * C<boot_class> belongs.
- * @param hierarchy A Clownfish::CFC::Model::Hierarchy.
- * @param lib_dir location of the Perl lib directory to which files will be
- * written.
- * @param boot_class The name of the main class, which will own the shared
- * object.
- * @param header Text which will be prepended to generated C/XS files --
- * typically, an "autogenerated file" warning.
- * @param footer Text to be appended to the end of generated C/XS files --
- * typically copyright information.
- */
-CFCPerl*
-CFCPerl_new(struct CFCHierarchy *hierarchy, const char *lib_dir,
- const char *boot_class, const char *header, const char *footer);
-
-CFCPerl*
-CFCPerl_init(CFCPerl *self, struct CFCHierarchy *hierarchy,
- const char *lib_dir, const char *boot_class, const char *header,
- const char *footer);
-
-void
-CFCPerl_destroy(CFCPerl *self);
-
-/** Auto-generate POD for all class bindings where pod specs were created.
- * See whether a .pod file exists and is up-to-date; if not, write it out.
- *
- * @return an array of filepaths where POD was written out.
- */
-char**
-CFCPerl_write_pod(CFCPerl *self);
-
-/** Write out "boot" files to the Hierarchy's "dest_dir" which contain code
- * for bootstrapping Clownfish classes.
- */
-void
-CFCPerl_write_boot(CFCPerl *self);
-
-/** Generate the XS bindings for all classes in the hierarchy.
- */
-void
-CFCPerl_write_bindings(CFCPerl *self);
-
-/** Generate routines which call back from C into Perl for all methods.
- */
-void
-CFCPerl_write_callbacks(CFCPerl *self);
-
-/** Generate hostdefs file.
- */
-void
-CFCPerl_write_hostdefs(CFCPerl *self);
-
-/** Generate the "typemap" file needed by the XS compiler.
- */
-void
-CFCPerl_write_xs_typemap(CFCPerl *self);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* H_CFCPERL */
-
http://git-wip-us.apache.org/repos/asf/lucy/blob/1704c275/clownfish/compiler/src/CFCPerlClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCPerlClass.c b/clownfish/compiler/src/CFCPerlClass.c
deleted file mode 100644
index ca44a3b..0000000
--- a/clownfish/compiler/src/CFCPerlClass.c
+++ /dev/null
@@ -1,582 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-#define CFC_NEED_BASE_STRUCT_DEF
-#include "CFCBase.h"
-#include "CFCPerlClass.h"
-#include "CFCUtil.h"
-#include "CFCClass.h"
-#include "CFCMethod.h"
-#include "CFCParcel.h"
-#include "CFCParamList.h"
-#include "CFCFunction.h"
-#include "CFCDocuComment.h"
-#include "CFCSymbol.h"
-#include "CFCVariable.h"
-#include "CFCType.h"
-#include "CFCPerlPod.h"
-#include "CFCPerlMethod.h"
-#include "CFCPerlConstructor.h"
-#include "CFCPerlTypeMap.h"
-
-struct CFCPerlClass {
- CFCBase base;
- CFCParcel *parcel;
- char *class_name;
- CFCClass *client;
- char *xs_code;
- CFCPerlPod *pod_spec;
- char **cons_aliases;
- char **cons_inits;
- size_t num_cons;
- int exclude_cons;
- char **class_aliases;
- size_t num_class_aliases;
-};
-
-static CFCPerlClass **registry = NULL;
-static size_t registry_size = 0;
-static size_t registry_cap = 0;
-
-static const CFCMeta CFCPERLCLASS_META = {
- "Clownfish::CFC::Binding::Perl::Class",
- sizeof(CFCPerlClass),
- (CFCBase_destroy_t)CFCPerlClass_destroy
-};
-
-CFCPerlClass*
-CFCPerlClass_new(CFCParcel *parcel, const char *class_name) {
- CFCPerlClass *self = (CFCPerlClass*)CFCBase_allocate(&CFCPERLCLASS_META);
- return CFCPerlClass_init(self, parcel, class_name);
-}
-
-CFCPerlClass*
-CFCPerlClass_init(CFCPerlClass *self, CFCParcel *parcel,
- const char *class_name) {
- CFCUTIL_NULL_CHECK(parcel);
- CFCUTIL_NULL_CHECK(class_name);
- self->parcel = (CFCParcel*)CFCBase_incref((CFCBase*)parcel);
- self->class_name = CFCUtil_strdup(class_name);
- // Client may be NULL, since fetch_singleton() does not always succeed.
- self->client = CFCClass_fetch_singleton(parcel, class_name);
- self->pod_spec = NULL;
- self->xs_code = NULL;
- self->cons_aliases = NULL;
- self->cons_inits = NULL;
- self->num_cons = 0;
- self->exclude_cons = 0;
- self->class_aliases = (char**)CALLOCATE(1, sizeof(char*));
- self->num_class_aliases = 0;
- return self;
-}
-
-void
-CFCPerlClass_destroy(CFCPerlClass *self) {
- CFCBase_decref((CFCBase*)self->parcel);
- CFCBase_decref((CFCBase*)self->client);
- CFCBase_decref((CFCBase*)self->pod_spec);
- FREEMEM(self->class_name);
- FREEMEM(self->xs_code);
- for (size_t i = 0; i < self->num_cons; i++) {
- FREEMEM(self->cons_aliases[i]);
- FREEMEM(self->cons_inits[i]);
- }
- FREEMEM(self->cons_aliases);
- FREEMEM(self->cons_inits);
- for (size_t i = 0; i < self->num_class_aliases; i++) {
- FREEMEM(self->class_aliases[i]);
- }
- FREEMEM(self->class_aliases);
- CFCBase_destroy((CFCBase*)self);
-}
-
-static int
-S_compare_cfcperlclass(const void *va, const void *vb) {
- CFCPerlClass *a = *(CFCPerlClass**)va;
- CFCPerlClass *b = *(CFCPerlClass**)vb;
- return strcmp(a->class_name, b->class_name);
-}
-
-void
-CFCPerlClass_add_to_registry(CFCPerlClass *self) {
- if (registry_size == registry_cap) {
- size_t new_cap = registry_cap + 10;
- registry = (CFCPerlClass**)REALLOCATE(registry,
- (new_cap + 1) * sizeof(CFCPerlClass*));
- for (size_t i = registry_cap; i <= new_cap; i++) {
- registry[i] = NULL;
- }
- registry_cap = new_cap;
- }
- CFCPerlClass *existing = CFCPerlClass_singleton(self->class_name);
- if (existing) {
- CFCUtil_die("Class '%s' already registered", self->class_name);
- }
- registry[registry_size] = (CFCPerlClass*)CFCBase_incref((CFCBase*)self);
- registry_size++;
- qsort(registry, registry_size, sizeof(CFCPerlClass*),
- S_compare_cfcperlclass);
-}
-
-CFCPerlClass*
-CFCPerlClass_singleton(const char *class_name) {
- CFCUTIL_NULL_CHECK(class_name);
- for (size_t i = 0; i < registry_size; i++) {
- CFCPerlClass *existing = registry[i];
- if (strcmp(class_name, existing->class_name) == 0) {
- return existing;
- }
- }
- return NULL;
-}
-
-CFCPerlClass**
-CFCPerlClass_registry() {
- return registry;
-}
-
-void
-CFCPerlClass_clear_registry(void) {
- for (size_t i = 0; i < registry_size; i++) {
- CFCBase_decref((CFCBase*)registry[i]);
- }
- FREEMEM(registry);
- registry_size = 0;
- registry_cap = 0;
- registry = NULL;
-}
-
-void
-CFCPerlClass_bind_method(CFCPerlClass *self, const char *alias,
- const char *meth_name) {
- if (!self->client) {
- CFCUtil_die("Can't bind_method %s -- can't find client for %s",
- alias, self->class_name);
- }
- CFCMethod *method = CFCClass_method(self->client, meth_name);
- if (!method) {
- CFCUtil_die("Can't bind_method %s -- can't find method %s in %s",
- alias, meth_name, self->class_name);
- }
- if (strcmp(CFCMethod_get_class_name(method), self->class_name) != 0) {
- CFCUtil_die("Can't bind_method %s -- method %s not fresh in %s",
- alias, meth_name, self->class_name);
- }
- CFCMethod_set_host_alias(method, alias);
-}
-
-void
-CFCPerlClass_exclude_method(CFCPerlClass *self, const char *meth_name) {
- if (!self->client) {
- CFCUtil_die("Can't exclude_method %s -- can't find client for %s",
- meth_name, self->class_name);
- }
- CFCMethod *method = CFCClass_method(self->client, meth_name);
- if (!method) {
- CFCUtil_die("Can't exclude_method %s -- method not found in %s",
- meth_name, self->class_name);
- }
- if (strcmp(CFCMethod_get_class_name(method), self->class_name) != 0) {
- CFCUtil_die("Can't exclude_method %s -- method not fresh in %s",
- meth_name, self->class_name);
- }
- CFCMethod_exclude_from_host(method);
-}
-
-void
-CFCPerlClass_bind_constructor(CFCPerlClass *self, const char *alias,
- const char *initializer) {
- alias = alias ? alias : "new";
- initializer = initializer ? initializer : "init";
- size_t size = (self->num_cons + 1) * sizeof(char*);
- self->cons_aliases = (char**)REALLOCATE(self->cons_aliases, size);
- self->cons_inits = (char**)REALLOCATE(self->cons_inits, size);
- self->cons_aliases[self->num_cons] = (char*)CFCUtil_strdup(alias);
- self->cons_inits[self->num_cons] = (char*)CFCUtil_strdup(initializer);
- self->num_cons++;
- if (!self->client) {
- CFCUtil_die("Can't bind_constructor %s -- can't find client for %s",
- alias, self->class_name);
- }
-}
-
-void
-CFCPerlClass_exclude_constructor(CFCPerlClass *self) {
- self->exclude_cons = 1;
-}
-
-static int
-S_can_be_bound(CFCParamList *param_list, CFCType *return_type) {
- int success = 1;
- CFCVariable **arg_vars = CFCParamList_get_variables(param_list);
-
- for (size_t i = 0; arg_vars[i] != NULL; i++) {
- CFCType *type = CFCVariable_get_type(arg_vars[i]);
- char *conversion = CFCPerlTypeMap_from_perl(type, "foo");
- if (conversion) { FREEMEM(conversion); }
- else { success = 0; }
- }
- if (!CFCType_is_void(return_type)) {
- char *conversion = CFCPerlTypeMap_to_perl(return_type, "foo");
- if (conversion) { FREEMEM(conversion); }
- else { success = 0; }
- }
-
- return success;
-}
-
-CFCPerlMethod**
-CFCPerlClass_method_bindings(CFCClass *klass) {
- CFCClass *parent = CFCClass_get_parent(klass);
- size_t num_bound = 0;
- CFCMethod **fresh_methods = CFCClass_fresh_methods(klass);
- CFCPerlMethod **bound
- = (CFCPerlMethod**)CALLOCATE(1, sizeof(CFCPerlMethod*));
-
- // Iterate over the class's fresh methods.
- for (size_t i = 0; fresh_methods[i] != NULL; i++) {
- CFCMethod *method = fresh_methods[i];
-
- // Skip private methods.
- if (CFCSymbol_private((CFCSymbol*)method)) { continue; }
-
- CFCMethod *novel_method;
- if (CFCMethod_novel(method)) {
- novel_method = method;
- }
- else {
- const char *meth_name = CFCMethod_get_macro_sym(method);
- novel_method = CFCClass_find_novel_method(parent, meth_name);
- if (!novel_method) {
- CFCUtil_die("Novel method not found");
- }
- }
-
- // Skip methods which have been explicitly excluded.
- if (CFCMethod_excluded_from_host(novel_method)) {
- continue;
- }
-
- // Skip methods with types which cannot be mapped automatically.
- CFCParamList *param_list = CFCMethod_get_param_list(method);
- CFCType *return_type = CFCMethod_get_return_type(method);
- if (!S_can_be_bound(param_list, return_type)) {
- continue;
- }
-
- // See if the user wants the method to have a specific alias.
- const char *alias = CFCMethod_get_host_alias(novel_method);
- if (!alias) {
- alias = CFCMethod_micro_sym(method);
- }
-
- /* Create the binding, add it to the array.
- *
- * Also create an XSub binding for each override. Each of these
- * directly calls the implementing function, rather than invokes the
- * method on the object using VTable method dispatch. Doing things
- * this way allows SUPER:: invocations from Perl-space to work
- * properly.
- */
- CFCPerlMethod *meth_binding = CFCPerlMethod_new(method, alias);
- size_t size = (num_bound + 2) * sizeof(CFCPerlMethod*);
- bound = (CFCPerlMethod**)REALLOCATE(bound, size);
- bound[num_bound] = meth_binding;
- num_bound++;
- bound[num_bound] = NULL;
- }
-
- FREEMEM(fresh_methods);
-
- return bound;
-}
-
-static const char NEW[] = "new";
-
-CFCPerlConstructor**
-CFCPerlClass_constructor_bindings(CFCClass *klass) {
- const char *class_name = CFCClass_get_class_name(klass);
- CFCPerlClass *perl_class = CFCPerlClass_singleton(class_name);
- CFCFunction **functions = CFCClass_functions(klass);
- size_t num_bound = 0;
- CFCPerlConstructor **bound
- = (CFCPerlConstructor**)CALLOCATE(1, sizeof(CFCPerlConstructor*));
-
- // Iterate over the list of possible initialization functions.
- for (size_t i = 0; functions[i] != NULL; i++) {
- CFCFunction *function = functions[i];
- const char *micro_sym = CFCFunction_micro_sym(function);
- CFCParamList *param_list = CFCFunction_get_param_list(function);
- CFCType *return_type = CFCFunction_get_return_type(function);
- const char *alias = NULL;
-
- // Find user-specified alias.
- if (perl_class == NULL) {
- // Bind init() to new() when possible.
- if (strcmp(micro_sym, "init") == 0
- && S_can_be_bound(param_list, return_type)
- ) {
- alias = NEW;
- }
- }
- else {
- for (size_t j = 0; j < perl_class->num_cons; j++) {
- if (strcmp(micro_sym, perl_class->cons_inits[j]) == 0) {
- alias = perl_class->cons_aliases[j];
- if (!S_can_be_bound(param_list, return_type)) {
- CFCUtil_die("Can't bind %s as %s"
- " -- types can't be mapped",
- micro_sym, alias);
- }
- break;
- }
- }
-
- // Automatically bind init() to new() when possible.
- if (!alias
- && !perl_class->exclude_cons
- && strcmp(micro_sym, "init") == 0
- && S_can_be_bound(param_list, return_type)
- ) {
- int saw_new = 0;
- for (size_t j = 0; j < perl_class->num_cons; j++) {
- if (strcmp(perl_class->cons_aliases[j], "new") == 0) {
- saw_new = 1;
- }
- }
- if (!saw_new) {
- alias = NEW;
- }
- }
- }
-
- if (!alias) {
- continue;
- }
-
- // Create the binding, add it to the array.
- CFCPerlConstructor *cons_binding
- = CFCPerlConstructor_new(klass, alias, micro_sym);
- size_t size = (num_bound + 2) * sizeof(CFCPerlConstructor*);
- bound = (CFCPerlConstructor**)REALLOCATE(bound, size);
- bound[num_bound] = cons_binding;
- num_bound++;
- bound[num_bound] = NULL;
- }
-
- return bound;
-}
-
-char*
-CFCPerlClass_create_pod(CFCPerlClass *self) {
- CFCPerlPod *pod_spec = self->pod_spec;
- const char *class_name = self->class_name;
- CFCClass *client = self->client;
- if (!pod_spec) {
- return NULL;
- }
- if (!client) {
- CFCUtil_die("No client for %s", class_name);
- }
- CFCDocuComment *docucom = CFCClass_get_docucomment(client);
- if (!docucom) {
- CFCUtil_die("No DocuComment for %s", class_name);
- }
-
- // Get the class's brief description.
- const char *raw_brief = CFCDocuComment_get_brief(docucom);
- char *brief = CFCPerlPod_perlify_doc_text(pod_spec, raw_brief);
-
- // Get the class's long description.
- const char *raw_description = CFCPerlPod_get_description(pod_spec);
- if (!raw_description || !strlen(raw_description)) {
- raw_description = CFCDocuComment_get_long(docucom);
- }
- char *description = CFCPerlPod_perlify_doc_text(pod_spec, raw_description);
-
- // Create SYNOPSIS.
- const char *raw_synopsis = CFCPerlPod_get_synopsis(pod_spec);
- char *synopsis = CFCUtil_strdup("");
- if (raw_synopsis && strlen(raw_synopsis)) {
- synopsis = CFCUtil_cat(synopsis, "=head1 SYNOPSIS\n\n", raw_synopsis,
- "\n", NULL);
- }
-
- // Create CONSTRUCTORS.
- char *constructor_pod = CFCPerlPod_constructors_pod(pod_spec, client);
-
- // Create METHODS, possibly including an ABSTRACT METHODS section.
- char *methods_pod = CFCPerlPod_methods_pod(pod_spec, client);
-
- // Build an INHERITANCE section describing class ancestry.
- char *inheritance = CFCUtil_strdup("");
- if (CFCClass_get_parent(client)) {
- inheritance = CFCUtil_cat(inheritance, "=head1 INHERITANCE\n\n",
- class_name, NULL);
- CFCClass *ancestor = client;
- while (NULL != (ancestor = CFCClass_get_parent(ancestor))) {
- const char *ancestor_klass = CFCClass_get_class_name(ancestor);
- if (CFCPerlClass_singleton(ancestor_klass)) {
- inheritance = CFCUtil_cat(inheritance, " isa L<",
- ancestor_klass, ">", NULL);
- }
- else {
- inheritance = CFCUtil_cat(inheritance, " isa ",
- ancestor_klass, NULL);
- }
- }
- inheritance = CFCUtil_cat(inheritance, ".\n", NULL);
- }
-
- // Put it all together.
- const char pattern[] =
- "# Auto-generated file -- DO NOT EDIT!!!!!\n"
- "\n"
- "# Licensed to the Apache Software Foundation (ASF) under one or more\n"
- "# contributor license agreements. See the NOTICE file distributed with\n"
- "# this work for additional information regarding copyright ownership.\n"
- "# The ASF licenses this file to You under the Apache License, Version 2.0\n"
- "# (the \"License\"); you may not use this file except in compliance with\n"
- "# the License. You may obtain a copy of the License at\n"
- "#\n"
- "# http://www.apache.org/licenses/LICENSE-2.0\n"
- "#\n"
- "# Unless required by applicable law or agreed to in writing, software\n"
- "# distributed under the License is distributed on an \"AS IS\" BASIS,\n"
- "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
- "# See the License for the specific language governing permissions and\n"
- "# limitations under the License.\n"
- "\n"
- "=head1 NAME\n"
- "\n"
- "%s - %s\n"
- "\n"
- "%s\n"
- "\n"
- "=head1 DESCRIPTION\n"
- "\n"
- "%s\n"
- "\n"
- "%s\n"
- "\n"
- "%s\n"
- "\n"
- "%s\n"
- "\n"
- "=cut\n"
- "\n";
- char *pod
- = CFCUtil_sprintf(pattern, class_name, brief, synopsis, description,
- constructor_pod, methods_pod, inheritance);
-
- FREEMEM(brief);
- FREEMEM(synopsis);
- FREEMEM(description);
- FREEMEM(constructor_pod);
- FREEMEM(methods_pod);
- FREEMEM(inheritance);
-
- return pod;
-}
-
-CFCClass*
-CFCPerlClass_get_client(CFCPerlClass *self) {
- return self->client;
-}
-
-const char*
-CFCPerlClass_get_class_name(CFCPerlClass *self) {
- return self->class_name;
-}
-
-void
-CFCPerlClass_append_xs(CFCPerlClass *self, const char *xs) {
- if (!self->xs_code) {
- self->xs_code = CFCUtil_strdup("");
- }
- self->xs_code = CFCUtil_cat(self->xs_code, xs, NULL);
-}
-
-const char*
-CFCPerlClass_get_xs_code(CFCPerlClass *self) {
- return self->xs_code;
-}
-
-void
-CFCPerlClass_set_pod_spec(CFCPerlClass *self, CFCPerlPod *pod_spec) {
- CFCPerlPod *old_pod_spec = self->pod_spec;
- self->pod_spec = (CFCPerlPod*)CFCBase_incref((CFCBase*)pod_spec);
- CFCBase_decref((CFCBase*)old_pod_spec);
-}
-
-CFCPerlPod*
-CFCPerlClass_get_pod_spec(CFCPerlClass *self) {
- return self->pod_spec;
-}
-
-void
-CFCPerlClass_add_class_alias(CFCPerlClass *self, const char *alias) {
- for (size_t i = 0; i < self->num_class_aliases; i++) {
- if (strcmp(alias, self->class_aliases[i]) == 0) {
- CFCUtil_die("Alias '%s' already added for class '%s'", alias,
- self->class_name);
- }
- }
- size_t size = (self->num_class_aliases + 2) * sizeof(char*);
- self->class_aliases = (char**)REALLOCATE(self->class_aliases, size);
- self->class_aliases[self->num_class_aliases] = CFCUtil_strdup(alias);
- self->num_class_aliases++;
- self->class_aliases[self->num_class_aliases] = NULL;
-}
-
-const char**
-CFCPerlClass_get_class_aliases(CFCPerlClass *self) {
- return (const char **)self->class_aliases;
-}
-
-// Generate C code which initializes method metadata.
-char*
-CFCPerlClass_method_metadata_code(CFCPerlClass *self) {
- const char *vtable_var = CFCClass_full_vtable_var(self->client);
- CFCMethod **fresh_methods = CFCClass_fresh_methods(self->client);
- char *code = CFCUtil_strdup("");
-
- for (int i = 0; fresh_methods[i] != NULL; i++) {
- CFCMethod *method = fresh_methods[i];
- if (!CFCMethod_novel(method)) { continue; }
-
- const char *macro_sym = CFCMethod_get_macro_sym(method);
- const char *alias = CFCMethod_get_host_alias(method);
- if (alias) {
- code = CFCUtil_cat(code, " CFISH_VTable_Add_Host_Method_Alias(",
- vtable_var, ", \"", alias, "\", \"", macro_sym,
- "\");\n", NULL);
- }
- if (CFCMethod_excluded_from_host(method)) {
- code = CFCUtil_cat(code, " CFISH_VTable_Exclude_Host_Method(",
- vtable_var, ", \"", macro_sym, "\");\n", NULL);
- }
- }
-
- FREEMEM(fresh_methods);
- return code;
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucy/blob/1704c275/clownfish/compiler/src/CFCPerlClass.h
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCPerlClass.h b/clownfish/compiler/src/CFCPerlClass.h
deleted file mode 100644
index 7051b82..0000000
--- a/clownfish/compiler/src/CFCPerlClass.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef H_CFCPERLCLASS
-#define H_CFCPERLCLASS
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct CFCPerlClass CFCPerlClass;
-struct CFCParcel;
-struct CFCClass;
-struct CFCFunction;
-struct CFCPerlPod;
-struct CFCPerlMethod;
-struct CFCPerlConstructor;
-
-/** Clownfish::CFC::Binding::Perl::Class - Generate Perl binding code for a
- * Clownfish::CFC::Model::Class.
- */
-
-/**
- * @param parcel A Clownfish::CFC::Model::Parcel.
- * @param class_name The name of the class to be registered.
- */
-CFCPerlClass*
-CFCPerlClass_new(struct CFCParcel *parcel, const char *class_name);
-
-CFCPerlClass*
-CFCPerlClass_init(CFCPerlClass *self, struct CFCParcel *parcel,
- const char *class_name);
-
-void
-CFCPerlClass_destroy(CFCPerlClass *self);
-
-/** Add a new class binding to the registry. Each unique parcel/class-name
- * combination may only be registered once.
- */
-void
-CFCPerlClass_add_to_registry(CFCPerlClass *self);
-
-/** Given a class name, return a class binding if one exists.
- */
-CFCPerlClass*
-CFCPerlClass_singleton(const char *class_name);
-
-/** All registered class bindings.
- */
-CFCPerlClass**
-CFCPerlClass_registry();
-
-/** Release all memory and references held by the registry.
- */
-void
-CFCPerlClass_clear_registry(void);
-
-/** Override the specification for a method being made available from Perl.
- * The default spec is to make the method available under a lower-cased alias
- * of the Clownfish method name.
- *
- * @param alias The Perl name for the method.
- * @param method The Clownfish name for the method.
- */
-void
-CFCPerlClass_bind_method(CFCPerlClass *self, const char *alias,
- const char *method);
-
-/** Specify that a constructor should be made available from Perl-space.
- *
- * @param alias The Perl name for the constructor (default "new").
- * @param initializer The Clownfish name for the initialization function which
- * will be invoked (default "init").
- */
-void
-CFCPerlClass_bind_constructor(CFCPerlClass *self, const char *alias,
- const char *initializer);
-
-/** Block the automatic generation of a method binding.
- */
-void
-CFCPerlClass_exclude_method(CFCPerlClass *self, const char *method);
-
-/** Block the automatic generation of a constructor binding.
- */
-void
-CFCPerlClass_exclude_constructor(CFCPerlClass *self);
-
-/** Return an array of Clownfish::CFC::Binding::Perl::Method objects
- * representing all bound methods.
- */
-struct CFCPerlMethod**
-CFCPerlClass_method_bindings(struct CFCClass *klass);
-
-/** Return an array of Clownfish::CFC::Binding::Perl::Constructor objects
- * representing all bound constructors.
- */
-struct CFCPerlConstructor**
-CFCPerlClass_constructor_bindings(struct CFCClass *klass);
-
-/** Auto-generate POD according to the spec supplied via set_pod_spec(). If
- * no spec was supplied, return NULL.
- */
-char*
-CFCPerlClass_create_pod(CFCPerlClass *self);
-
-/** Accessor for the Clownfish::CFC::Model::Class module to be bound.
- */
-struct CFCClass*
-CFCPerlClass_get_client(CFCPerlClass *self);
-
-/** Accessor for class name.
- */
-const char*
-CFCPerlClass_get_class_name(CFCPerlClass *self);
-
-/** Concatenate verbatim XS code.
- */
-void
-CFCPerlClass_append_xs(CFCPerlClass *self, const char *xs);
-
-/** Accessor for verbatim XS code.
- */
-const char*
-CFCPerlClass_get_xs_code(CFCPerlClass *self);
-
-/** Supply a specification which will cause POD to be generated for this class
- * binding.
- */
-void
-CFCPerlClass_set_pod_spec(CFCPerlClass *self, struct CFCPerlPod *pod_spec);
-
-/** Accessor for pod spec.
- */
-struct CFCPerlPod*
-CFCPerlClass_get_pod_spec(CFCPerlClass *self);
-
-/** Alias a class name to this class.
- *
- * TODO: remove this feature as soon as KinoSearch compatibility is no longer
- * necessary.
- */
-void
-CFCPerlClass_add_class_alias(CFCPerlClass *self, const char *alias);
-
-/** Return a NULL-terminated list of class names which will be aliased to this
- * class.
- */
-const char**
-CFCPerlClass_get_class_aliases(CFCPerlClass *self);
-
-/** Return C code which initializes method metadata.
- */
-char*
-CFCPerlClass_method_metadata_code(CFCPerlClass *self);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* H_CFCPERLCLASS */
-