diff --git a/main/gbc/gbc_header.c b/main/gbc/gbc_header.c index 50c7b62d4..f88eec4d2 100644 --- a/main/gbc/gbc_header.c +++ b/main/gbc/gbc_header.c @@ -1,22 +1,22 @@ /*************************************************************************** - gbc_header.c + gbc_header.c - (c) 2000-2011 Benoît Minisini + (c) 2000-2011 Benoît Minisini - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ***************************************************************************/ @@ -42,157 +42,184 @@ static void check_public_private(PATTERN **look, bool *is_public) { - *is_public = JOB->is_module && JOB->public_module; + *is_public = JOB->is_module && JOB->public_module; - if (PATTERN_is(**look, RS_PUBLIC)) - { - *is_public = TRUE; - (*look)++; - } - else if (PATTERN_is(**look, RS_PRIVATE)) - { - *is_public = FALSE; - (*look)++; - } + if (PATTERN_is(**look, RS_PUBLIC)) + { + *is_public = TRUE; + (*look)++; + } + else if (PATTERN_is(**look, RS_PRIVATE)) + { + *is_public = FALSE; + (*look)++; + } +} + +static PATTERN *jump_expression(PATTERN *look) +{ + int niv = 0; + + for(;;) + { + if (PATTERN_is_newline(*look)) + break; + + if (PATTERN_is(*look, RS_LBRA) || PATTERN_is(*look, RS_LSQR)) + { + niv++; + } + else if (PATTERN_is(*look, RS_RBRA) || PATTERN_is(*look, RS_RSQR)) + { + if (niv > 0) + niv--; + else + break; + } + else if (niv == 0) + { + if (PATTERN_is(*look, RS_COMMA)) + break; + } + + look++; + } + + return look; } static void analyze_function_desc(TRANS_FUNC *func, int flag) { - PATTERN *look = JOB->current; - TRANS_PARAM *param; - //bool is_output; - bool is_optional = FALSE; - TRANS_DECL ttyp; - uint64_t byref_mask = 1; + PATTERN *look = JOB->current; + TRANS_PARAM *param; + //bool is_output; + bool is_optional = FALSE; + TRANS_DECL ttyp; + uint64_t byref_mask = 1; - if (!PATTERN_is_identifier(*look)) - THROW("Syntax error. Invalid identifier in function name"); + if (!PATTERN_is_identifier(*look)) + THROW("Syntax error. Invalid identifier in function name"); - func->index = PATTERN_index(*look); + func->index = PATTERN_index(*look); TYPE_clear(&func->type); - look++; + look++; - if (flag & HF_EVENT) - TABLE_copy_symbol_with_prefix(JOB->class->table, func->index, ':', &func->index); + if (flag & HF_EVENT) + TABLE_copy_symbol_with_prefix(JOB->class->table, func->index, ':', &func->index); - func->nparam = 0; - func->byref = 0; - func->vararg = FALSE; + func->nparam = 0; + func->byref = 0; + func->vararg = FALSE; - if ((flag & HF_VOID) && PATTERN_is_newline(*look)) - { - JOB->current = ++look; - return; - } + if ((flag & HF_VOID) && PATTERN_is_newline(*look)) + { + JOB->current = ++look; + return; + } - if (!PATTERN_is(*look, RS_LBRA)) + if (!PATTERN_is(*look, RS_LBRA)) THROW_UNEXPECTED(look); - look++; + look++; - for(;;) - { - param = &func->param[func->nparam]; + for(;;) + { + param = &func->param[func->nparam]; CLEAR(param); - if (PATTERN_is(*look, RS_RBRA)) - { - look++; - break; - } + if (PATTERN_is(*look, RS_RBRA)) + { + look++; + break; + } - if (func->nparam > 0) - { - if (!PATTERN_is(*look, RS_COMMA)) - THROW(E_SYNTAX_MISSING, "',' or ')'"); - look++; - } + if (func->nparam > 0) + { + if (!PATTERN_is(*look, RS_COMMA)) + THROW(E_SYNTAX_MISSING, "',' or ')'"); + look++; + } - if (PATTERN_is(*look, RS_3PTS)) - { - look++; - if (!PATTERN_is(*look, RS_RBRA)) - THROW("Syntax error. '...' must be the last argument"); //, get_num_desc(func->nparam + 1)); - look++; - func->vararg = TRUE; - break; - } + if (PATTERN_is(*look, RS_3PTS)) + { + look++; + if (!PATTERN_is(*look, RS_RBRA)) + THROW("Syntax error. '...' must be the last argument"); //, get_num_desc(func->nparam + 1)); + look++; + func->vararg = TRUE; + break; + } - //is_output = FALSE; + //is_output = FALSE; - if (!(flag & HF_NO_OPT)) - { - if (PATTERN_is(*look, RS_OPTIONAL)) - { - look++; - is_optional = TRUE; - } - } + if (!(flag & HF_NO_OPT)) + { + if (PATTERN_is(*look, RS_OPTIONAL)) + { + look++; + is_optional = TRUE; + } + } - if (PATTERN_is(*look, RS_AT) || PATTERN_is(*look, RS_BYREF)) - { - func->byref |= byref_mask; - look++; - } + if (PATTERN_is(*look, RS_AT) || PATTERN_is(*look, RS_BYREF)) + { + func->byref |= byref_mask; + look++; + } - if (!PATTERN_is_identifier(*look)) - THROW("Syntax error. The &1 argument is not a valid identifier", TRANS_get_num_desc(func->nparam + 1)); + if (!PATTERN_is_identifier(*look)) + THROW("Syntax error. The &1 argument is not a valid identifier", TRANS_get_num_desc(func->nparam + 1)); - param->index = PATTERN_index(*look); - look++; - JOB->current = look; + param->index = PATTERN_index(*look); + look++; + JOB->current = look; - if (!TRANS_type(TT_NOTHING, &ttyp)) - THROW("Syntax error. Invalid type description of &1 argument", TRANS_get_num_desc(func->nparam + 1)); + if (!TRANS_type(TT_NOTHING, &ttyp)) + THROW("Syntax error. Invalid type description of &1 argument", TRANS_get_num_desc(func->nparam + 1)); - param->type = ttyp.type; + param->type = ttyp.type; - /* - if (is_output) - TYPE_set_flag(¶m->type, TF_OUTPUT); - */ + /* + if (is_output) + TYPE_set_flag(¶m->type, TF_OUTPUT); + */ - look = JOB->current; + look = JOB->current; - if (is_optional) - { - param->optional = look; - for(;;) - { - if (PATTERN_is(*look, RS_COMMA) || PATTERN_is(*look, RS_RBRA) || PATTERN_is_newline(*look)) - break; - look++; - } - JOB->current = look; - } + if (is_optional) + { + param->optional = look; + look = jump_expression(look); + JOB->current = look; + } - func->nparam++; - byref_mask <<= 1; - } + func->nparam++; + byref_mask <<= 1; + } - JOB->current = look; + JOB->current = look; } static void header_module_type(void) { - const char *ext; + const char *ext; const char **p; - /*JOB->class->name = STR_copy(FILE_get_name(JOB->name));*/ + /*JOB->class->name = STR_copy(FILE_get_name(JOB->name));*/ - ext = FILE_get_ext(JOB->name); + ext = FILE_get_ext(JOB->name); - if (strcasecmp(ext, "module") == 0) - { - JOB->is_module = TRUE; - JOB->is_form = FALSE; - } - else if (strcasecmp(ext, "class") == 0) - { - JOB->is_module = FALSE; - JOB->is_form = FALSE; - } - else + if (strcasecmp(ext, "module") == 0) + { + JOB->is_module = TRUE; + JOB->is_form = FALSE; + } + else if (strcasecmp(ext, "class") == 0) + { + JOB->is_module = FALSE; + JOB->is_form = FALSE; + } + else { p = COMP_form_families; while (*p) @@ -210,277 +237,277 @@ static void header_module_type(void) THROW("Unknown file extension"); } - JOB->declared = TRUE; + JOB->declared = TRUE; } static bool header_event(TRANS_EVENT *event) { - PATTERN *look = JOB->current; - //TRANS_DECL ttyp; + PATTERN *look = JOB->current; + //TRANS_DECL ttyp; - if (!PATTERN_is(*look, RS_EVENT)) - return FALSE; + if (!PATTERN_is(*look, RS_EVENT)) + return FALSE; - CLEAR(event); + CLEAR(event); - if (JOB->is_module) - THROW("A module cannot raise events"); + if (JOB->is_module) + THROW("A module cannot raise events"); - JOB->current++; - analyze_function_desc((TRANS_FUNC *)event, HF_VOID); + JOB->current++; + analyze_function_desc((TRANS_FUNC *)event, HF_VOID); - /*if (PATTERN_is(*JOB->current, RS_AS)) - { - if (!TRANS_type(TT_CAN_SQUARE, &ttyp)) - THROW("Syntax error in return type"); - event->type = ttyp.type; - }*/ + /*if (PATTERN_is(*JOB->current, RS_AS)) + { + if (!TRANS_type(TT_CAN_SQUARE, &ttyp)) + THROW("Syntax error in return type"); + event->type = ttyp.type; + }*/ - TYPE_set_kind(&event->type, TK_EVENT); - TYPE_set_flag(&event->type, TF_PUBLIC); + TYPE_set_kind(&event->type, TK_EVENT); + TYPE_set_flag(&event->type, TF_PUBLIC); - return TRUE; + return TRUE; } static bool header_property(TRANS_PROPERTY *prop) { - TRANS_DECL ptype; - PATTERN *look = JOB->current; - bool is_static = FALSE; - bool is_public = TRUE; + TRANS_DECL ptype; + PATTERN *look = JOB->current; + bool is_static = FALSE; + bool is_public = TRUE; - CLEAR(prop); + CLEAR(prop); - /* static */ + /* static */ - if (JOB->is_module) - { - is_static = TRUE; - } - else if (PATTERN_is(*look, RS_STATIC)) - { - is_static = TRUE; - look++; - } + if (JOB->is_module) + { + is_static = TRUE; + } + else if (PATTERN_is(*look, RS_STATIC)) + { + is_static = TRUE; + look++; + } - /* public */ + /* public */ - if (PATTERN_is(*look, RS_PUBLIC) || PATTERN_is(*look, RS_PRIVATE)) - { - is_public = PATTERN_is(*look, RS_PUBLIC); - look++; - } + if (PATTERN_is(*look, RS_PUBLIC) || PATTERN_is(*look, RS_PRIVATE)) + { + is_public = PATTERN_is(*look, RS_PUBLIC); + look++; + } - if (!PATTERN_is(*look, RS_PROPERTY)) - return FALSE; - look++; - JOB->current = look; + if (!PATTERN_is(*look, RS_PROPERTY)) + return FALSE; + look++; + JOB->current = look; - if (!is_public) - THROW("A property must be public"); + if (!is_public) + THROW("A property must be public"); - /* read-only property */ + /* read-only property */ - if (PATTERN_is(*JOB->current, RS_READ)) - { - prop->read = TRUE; - JOB->current++; - } - else - prop->read = FALSE; + if (PATTERN_is(*JOB->current, RS_READ)) + { + prop->read = TRUE; + JOB->current++; + } + else + prop->read = FALSE; - /* property name */ + /* property name */ - if (!PATTERN_is_identifier(*JOB->current)) - THROW("Syntax error. Invalid identifier in property name"); + if (!PATTERN_is_identifier(*JOB->current)) + THROW("Syntax error. Invalid identifier in property name"); - prop->index = PATTERN_index(*JOB->current); - JOB->current++; + prop->index = PATTERN_index(*JOB->current); + JOB->current++; - if (!TRANS_type(TT_NOTHING, &ptype)) - THROW("Syntax error. Bad property type"); + if (!TRANS_type(TT_NOTHING, &ptype)) + THROW("Syntax error. Bad property type"); - prop->type = ptype.type; - prop->line = JOB->line; + prop->type = ptype.type; + prop->line = JOB->line; - TYPE_set_kind(&prop->type, TK_PROPERTY); - if (is_static) - TYPE_set_flag(&prop->type, TF_STATIC); - TYPE_set_flag(&prop->type, TF_PUBLIC); + TYPE_set_kind(&prop->type, TK_PROPERTY); + if (is_static) + TYPE_set_flag(&prop->type, TF_STATIC); + TYPE_set_flag(&prop->type, TF_PUBLIC); - if (PATTERN_is_string(*JOB->current)) - { - prop->comment = PATTERN_index(*JOB->current); - JOB->current++; - } - else - prop->comment = NO_SYMBOL; + if (PATTERN_is_string(*JOB->current)) + { + prop->comment = PATTERN_index(*JOB->current); + JOB->current++; + } + else + prop->comment = NO_SYMBOL; - return TRUE; + return TRUE; } static bool header_extern(TRANS_EXTERN *trans) { - PATTERN *look = JOB->current; - TRANS_DECL ttyp; - int index; - bool is_public; + PATTERN *look = JOB->current; + TRANS_DECL ttyp; + int index; + bool is_public; check_public_private(&look, &is_public); - if (!PATTERN_is(*look, RS_EXTERN)) - return FALSE; - look++; + if (!PATTERN_is(*look, RS_EXTERN)) + return FALSE; + look++; - CLEAR(trans); + CLEAR(trans); - JOB->current = look; - analyze_function_desc((TRANS_FUNC *)trans, HF_NO_3PTS); + JOB->current = look; + analyze_function_desc((TRANS_FUNC *)trans, HF_NO_3PTS); - if (PATTERN_is(*JOB->current, RS_AS)) - { - if (!TRANS_type(TT_NOTHING, &ttyp)) - THROW("Syntax error in return type"); - trans->type = ttyp.type; - } + if (PATTERN_is(*JOB->current, RS_AS)) + { + if (!TRANS_type(TT_NOTHING, &ttyp)) + THROW("Syntax error in return type"); + trans->type = ttyp.type; + } - if (TRANS_is(RS_IN)) - { - if (!PATTERN_is_string(*JOB->current)) - THROW("Library name must be a string"); + if (TRANS_is(RS_IN)) + { + if (!PATTERN_is_string(*JOB->current)) + THROW("Library name must be a string"); - index = PATTERN_index(*JOB->current); - JOB->current++; - } - else - { - if (JOB->default_library == NO_SYMBOL) - THROW(E_MISSING, "IN"); + index = PATTERN_index(*JOB->current); + JOB->current++; + } + else + { + if (JOB->default_library == NO_SYMBOL) + THROW(E_MISSING, "IN"); - index = JOB->default_library; - } + index = JOB->default_library; + } - trans->library = index; + trans->library = index; - if (TRANS_is(RS_EXEC)) - { - if (!PATTERN_is_string(*JOB->current)) - THROW("Alias name must be a string"); + if (TRANS_is(RS_EXEC)) + { + if (!PATTERN_is_string(*JOB->current)) + THROW("Alias name must be a string"); - trans->alias = PATTERN_index(*JOB->current); - JOB->current++; - } - else - trans->alias = NO_SYMBOL; + trans->alias = PATTERN_index(*JOB->current); + JOB->current++; + } + else + trans->alias = NO_SYMBOL; - TYPE_set_kind(&trans->type, TK_EXTERN); - TYPE_set_flag(&trans->type, TF_STATIC); - if (is_public) TYPE_set_flag(&trans->type, TF_PUBLIC); + TYPE_set_kind(&trans->type, TK_EXTERN); + TYPE_set_flag(&trans->type, TF_STATIC); + if (is_public) TYPE_set_flag(&trans->type, TF_PUBLIC); - return TRUE; + return TRUE; } static bool header_class(TRANS_DECL *decl) { - if (!TRANS_is(RS_CLASS)) - return FALSE; + if (!TRANS_is(RS_CLASS)) + return FALSE; - if (!PATTERN_is_identifier(*JOB->current)) - THROW("Syntax error. CLASS needs an identifier"); + if (!PATTERN_is_identifier(*JOB->current)) + THROW("Syntax error. CLASS needs an identifier"); - CLEAR(decl); - decl->index = PATTERN_index(*JOB->current); - JOB->current++; + CLEAR(decl); + decl->index = PATTERN_index(*JOB->current); + JOB->current++; - return TRUE; + return TRUE; } static bool header_declaration(TRANS_DECL *decl) { - PATTERN *look = JOB->current; - PATTERN *save; - bool is_static = FALSE; - bool is_public = FALSE; - bool is_const = FALSE; - /*bool other = FALSE;*/ + PATTERN *look = JOB->current; + PATTERN *save; + bool is_static = FALSE; + bool is_public = FALSE; + bool is_const = FALSE; + /*bool other = FALSE;*/ - /* static ! */ + /* static ! */ - if (JOB->is_module) - { - is_static = TRUE; - } - else if (PATTERN_is(*look, RS_STATIC)) - { - is_static = TRUE; - look++; - } + if (JOB->is_module) + { + is_static = TRUE; + } + else if (PATTERN_is(*look, RS_STATIC)) + { + is_static = TRUE; + look++; + } check_public_private(&look, &is_public); - /* const ? */ + /* const ? */ - is_const = FALSE; + is_const = FALSE; - if (PATTERN_is(*look, RS_CONST)) - { - /* static const <=> const */ + if (PATTERN_is(*look, RS_CONST)) + { + /* static const <=> const */ - is_const = TRUE; - look++; - } + is_const = TRUE; + look++; + } - if (!PATTERN_is_identifier(*look)) - return FALSE; + if (!PATTERN_is_identifier(*look)) + return FALSE; - CLEAR(decl); + CLEAR(decl); - decl->index = PATTERN_index(*look); - look++; + decl->index = PATTERN_index(*look); + look++; - save = JOB->current; - JOB->current = look; + save = JOB->current; + JOB->current = look; - if (!TRANS_type((!is_const ? TT_CAN_ARRAY | TT_CAN_EMBED : 0) | TT_CAN_NEW, decl)) - { - JOB->current = save; - return FALSE; - } + if (!TRANS_type((!is_const ? TT_CAN_ARRAY | TT_CAN_EMBED : 0) | TT_CAN_NEW, decl)) + { + JOB->current = save; + return FALSE; + } - if (is_static) TYPE_set_flag(&decl->type, TF_STATIC); - if (is_public) TYPE_set_flag(&decl->type, TF_PUBLIC); - if (is_const) - TYPE_set_kind(&decl->type, TK_CONST); - else - TYPE_set_kind(&decl->type, TK_VARIABLE); + if (is_static) TYPE_set_flag(&decl->type, TF_STATIC); + if (is_public) TYPE_set_flag(&decl->type, TF_PUBLIC); + if (is_const) + TYPE_set_kind(&decl->type, TK_CONST); + else + TYPE_set_kind(&decl->type, TK_VARIABLE); - if (is_const) - { - if (!decl->init) - THROW(E_SYNTAX_MISSING, "'='"); + if (is_const) + { + if (!decl->init) + THROW(E_SYNTAX_MISSING, "'='"); - JOB->current = decl->init; + JOB->current = decl->init; JOB->current = TRANS_get_constant_value(decl, JOB->current); - } + } - //JOB->current = look; + //JOB->current = look; - return TRUE; + return TRUE; } static bool header_enumeration(TRANS_DECL *decl) { - PATTERN *look = JOB->current; + PATTERN *look = JOB->current; bool is_public; int value = 0; check_public_private(&look, &is_public); - if (!PATTERN_is(*look, RS_ENUM)) - return FALSE; + if (!PATTERN_is(*look, RS_ENUM)) + return FALSE; look++; JOB->current = look; @@ -497,7 +524,7 @@ static bool header_enumeration(TRANS_DECL *decl) decl->index = PATTERN_index(*JOB->current); JOB->current++; - decl->type = TYPE_make(T_INTEGER, -1, 0); + decl->type = TYPE_make(T_INTEGER, -1, 0); if (is_public) TYPE_set_flag(&decl->type, TF_PUBLIC); TYPE_set_kind(&decl->type, TK_CONST); @@ -513,13 +540,13 @@ static bool header_enumeration(TRANS_DECL *decl) value++; } - CLASS_add_declaration(JOB->class, decl); + CLASS_add_declaration(JOB->class, decl); if (TRANS_newline()) break; if (!PATTERN_is(*JOB->current, RS_COMMA)) - THROW_UNEXPECTED(JOB->current); + THROW_UNEXPECTED(JOB->current); JOB->current++; } @@ -529,187 +556,187 @@ static bool header_enumeration(TRANS_DECL *decl) static bool header_function(TRANS_FUNC *func) { - static HEADER_SPECIAL spec[] = - { - { "_init", HS_PUBLIC + HS_STATIC + HS_PROCEDURE + HS_NOPARAM }, - { "_exit", HS_PUBLIC + HS_STATIC + HS_PROCEDURE + HS_NOPARAM}, - { "_new", HS_PUBLIC + HS_DYNAMIC + HS_PROCEDURE }, - { "_free", HS_PUBLIC + HS_DYNAMIC + HS_PROCEDURE + HS_NOPARAM }, - { "_call", HS_PUBLIC }, - { "_get", HS_PUBLIC + HS_FUNCTION }, - { "_put", HS_PUBLIC + HS_PROCEDURE + HS_PUT }, - { "_next", HS_PUBLIC + HS_NOPARAM }, - { "_property", HS_PUBLIC + HS_NOPARAM + HS_FUNCTION + HS_PROPERTY }, - { "_unknown", HS_PUBLIC + HS_UNKNOWN }, - { "_compare", HS_PUBLIC + HS_DYNAMIC + HS_FUNCTION + HS_COMPARE }, + static HEADER_SPECIAL spec[] = + { + { "_init", HS_PUBLIC + HS_STATIC + HS_PROCEDURE + HS_NOPARAM }, + { "_exit", HS_PUBLIC + HS_STATIC + HS_PROCEDURE + HS_NOPARAM}, + { "_new", HS_PUBLIC + HS_DYNAMIC + HS_PROCEDURE }, + { "_free", HS_PUBLIC + HS_DYNAMIC + HS_PROCEDURE + HS_NOPARAM }, + { "_call", HS_PUBLIC }, + { "_get", HS_PUBLIC + HS_FUNCTION }, + { "_put", HS_PUBLIC + HS_PROCEDURE + HS_PUT }, + { "_next", HS_PUBLIC + HS_NOPARAM }, + { "_property", HS_PUBLIC + HS_NOPARAM + HS_FUNCTION + HS_PROPERTY }, + { "_unknown", HS_PUBLIC + HS_UNKNOWN }, + { "_compare", HS_PUBLIC + HS_DYNAMIC + HS_FUNCTION + HS_COMPARE }, { "_attach", HS_PUBLIC + HS_DYNAMIC + HS_PROCEDURE + HS_ATTACH }, - { NULL, 0 } - }; + { NULL, 0 } + }; - PATTERN *look = JOB->current; - PATTERN pat; - TRANS_DECL ttyp; - SYMBOL *sym; - HEADER_SPECIAL *hsp; + PATTERN *look = JOB->current; + PATTERN pat; + TRANS_DECL ttyp; + SYMBOL *sym; + HEADER_SPECIAL *hsp; - bool is_proc = FALSE; - bool is_static = FALSE; - bool is_public = FALSE; + bool is_proc = FALSE; + bool is_static = FALSE; + bool is_public = FALSE; - /* static ? */ + /* static ? */ - if (JOB->is_module) - { - is_static = TRUE; - } - else if (PATTERN_is(*look, RS_STATIC)) - { - is_static = TRUE; - look++; - } + if (JOB->is_module) + { + is_static = TRUE; + } + else if (PATTERN_is(*look, RS_STATIC)) + { + is_static = TRUE; + look++; + } - /* public ou static ? */ + /* public ou static ? */ - is_public = JOB->is_module && JOB->public_module; + is_public = JOB->is_module && JOB->public_module; - if (PATTERN_is(*look, RS_PUBLIC)) - { - is_public = TRUE; - look++; - } - else if (PATTERN_is(*look, RS_PRIVATE)) - { - is_public = FALSE; - look++; - } + if (PATTERN_is(*look, RS_PUBLIC)) + { + is_public = TRUE; + look++; + } + else if (PATTERN_is(*look, RS_PRIVATE)) + { + is_public = FALSE; + look++; + } - if (PATTERN_is(*look, RS_PROCEDURE) || PATTERN_is(*look, RS_SUB)) - is_proc = TRUE; - else if (!PATTERN_is(*look, RS_FUNCTION)) - return FALSE; - look++; + if (PATTERN_is(*look, RS_PROCEDURE) || PATTERN_is(*look, RS_SUB)) + is_proc = TRUE; + else if (!PATTERN_is(*look, RS_FUNCTION)) + return FALSE; + look++; - //CLEAR(func); + //CLEAR(func); - JOB->current = look; - analyze_function_desc(func, HF_NORMAL); + JOB->current = look; + analyze_function_desc(func, HF_NORMAL); - //if (!is_proc) - if (PATTERN_is(*JOB->current, RS_AS)) - { - if (!TRANS_type(TT_NOTHING, &ttyp)) - THROW("Syntax error. Invalid return type"); - func->type = ttyp.type; - is_proc = FALSE; - } + //if (!is_proc) + if (PATTERN_is(*JOB->current, RS_AS)) + { + if (!TRANS_type(TT_NOTHING, &ttyp)) + THROW("Syntax error. Invalid return type"); + func->type = ttyp.type; + is_proc = FALSE; + } - TYPE_set_kind(&func->type, TK_FUNCTION); - if (is_static) TYPE_set_flag(&func->type, TF_STATIC); - if (is_public) TYPE_set_flag(&func->type, TF_PUBLIC); + TYPE_set_kind(&func->type, TK_FUNCTION); + if (is_static) TYPE_set_flag(&func->type, TF_STATIC); + if (is_public) TYPE_set_flag(&func->type, TF_PUBLIC); - // Check special methods + // Check special methods - sym = TABLE_get_symbol(JOB->class->table, func->index); + sym = TABLE_get_symbol(JOB->class->table, func->index); - if (*sym->name == '_') - { - for (hsp = spec; hsp->name; hsp++) - { - if (sym->len != strlen(hsp->name)) - continue; - if (strncmp(sym->name, hsp->name, sym->len)) - continue; + if (*sym->name == '_') + { + for (hsp = spec; hsp->name; hsp++) + { + if (sym->len != strlen(hsp->name)) + continue; + if (strncmp(sym->name, hsp->name, sym->len)) + continue; - if (hsp->flag == HS_ERROR) - THROW("The special method &1 cannot be implemented", hsp->name); + if (hsp->flag == HS_ERROR) + THROW("The special method &1 cannot be implemented", hsp->name); - if ((hsp->flag & HS_PUBLIC) && !is_public) - THROW("The special method &1 must be public", hsp->name); + if ((hsp->flag & HS_PUBLIC) && !is_public) + THROW("The special method &1 must be public", hsp->name); - if ((hsp->flag & HS_STATIC) && !is_static) - THROW("The special method &1 must be static", hsp->name); + if ((hsp->flag & HS_STATIC) && !is_static) + THROW("The special method &1 must be static", hsp->name); - if ((hsp->flag & HS_DYNAMIC) && is_static) - THROW("The special method &1 cannot be static", hsp->name); + if ((hsp->flag & HS_DYNAMIC) && is_static) + THROW("The special method &1 cannot be static", hsp->name); - if ((hsp->flag & HS_PROCEDURE) && !is_proc) - THROW("The special method &1 cannot be a function", hsp->name); + if ((hsp->flag & HS_PROCEDURE) && !is_proc) + THROW("The special method &1 cannot be a function", hsp->name); - if ((hsp->flag & HS_FUNCTION) && is_proc) - THROW("The special method &1 must be a function", hsp->name); + if ((hsp->flag & HS_FUNCTION) && is_proc) + THROW("The special method &1 must be a function", hsp->name); - if ((hsp->flag & HS_NOPARAM) && func->nparam > 0) - THROW("The special method &1 takes no arguments", hsp->name); + if ((hsp->flag & HS_NOPARAM) && func->nparam > 0) + THROW("The special method &1 takes no arguments", hsp->name); - if (hsp->flag & HS_PUT) - { - if (func->nparam < 1) - THROW("The special method &1 must take at least one argument", hsp->name); - } + if (hsp->flag & HS_PUT) + { + if (func->nparam < 1) + THROW("The special method &1 must take at least one argument", hsp->name); + } - if (hsp->flag & HS_UNKNOWN) - { - if (func->nparam > 0 || !func->vararg) - THROW("The special method &1 must take a variable number of arguments only", hsp->name); - } + if (hsp->flag & HS_UNKNOWN) + { + if (func->nparam > 0 || !func->vararg) + THROW("The special method &1 must take a variable number of arguments only", hsp->name); + } - if (hsp->flag & HS_PROPERTY) - { - if (TYPE_get_id(func->type) != T_BOOLEAN) - THROW("The special method &1 must return a boolean", hsp->name); - } + if (hsp->flag & HS_PROPERTY) + { + if (TYPE_get_id(func->type) != T_BOOLEAN) + THROW("The special method &1 must return a boolean", hsp->name); + } - if (hsp->flag & HS_COMPARE) - { - if (func->type.t.id != T_INTEGER) - THROW("The special method must return an integer"); + if (hsp->flag & HS_COMPARE) + { + if (func->type.t.id != T_INTEGER) + THROW("The special method must return an integer"); if (func->nparam != 1) - THROW("The special method must take exactly one argument"); - } + THROW("The special method must take exactly one argument"); + } if (hsp->flag & HS_ATTACH) { if (func->nparam != 2) - THROW("The special method must take exactly two arguments"); + THROW("The special method must take exactly two arguments"); if (func->param[0].type.t.id != T_OBJECT || func->param[1].type.t.id != T_STRING) - THROW("The special method signature is incorrect"); + THROW("The special method signature is incorrect"); } - break; - } - } + break; + } + } - /* on saute le corps de la fonction */ + /* on saute le corps de la fonction */ - if (!PATTERN_is_newline(*(JOB->current))) - THROW("Syntax error at function declaration"); + if (!PATTERN_is_newline(*(JOB->current))) + THROW("Syntax error at function declaration"); - func->line = PATTERN_index(*(JOB->current)) + 1; - func->start = JOB->current + 1; + func->line = PATTERN_index(*(JOB->current)) + 1; + func->start = JOB->current + 1; look = JOB->current; - for(;;) - { - pat = *look; + for(;;) + { + pat = *look; - if (PATTERN_is_newline(pat)) + if (PATTERN_is_newline(pat)) { JOB->line = PATTERN_index(pat) + 1; pat = look[1]; - if (PATTERN_is(pat, RS_END)) - { - if (PATTERN_is_newline(look[2])) - { - look += 2; - break; - } - if (TRANS_is_end_function(is_proc, &look[2])) - { - look += 3; - break; - } + if (PATTERN_is(pat, RS_END)) + { + if (PATTERN_is_newline(look[2])) + { + look += 2; + break; + } + if (TRANS_is_end_function(is_proc, &look[2])) + { + look += 3; + break; + } else { if (is_proc && PATTERN_is(look[2], RS_FUNCTION)) @@ -717,107 +744,107 @@ static bool header_function(TRANS_FUNC *func) else if (!is_proc && PATTERN_is(look[2], RS_SUB)) THROW(E_EXPECTED, "END FUNCTION"); } - } + } else if (UNLIKELY(PATTERN_is_end(pat))) // || PATTERN_is_command(pat))) THROW(E_MISSING, "END"); } - look++; - } + look++; + } JOB->current = look; - return TRUE; + return TRUE; } static bool header_inherits(void) { - int index; + int index; - if (!PATTERN_is(*JOB->current, RS_INHERITS)) - return FALSE; + if (!PATTERN_is(*JOB->current, RS_INHERITS)) + return FALSE; - /*{ - if (!(PATTERN_is(JOB->current[0], RS_CLASS) - && PATTERN_is(JOB->current[1], RS_INHERITS))) - return FALSE; - JOB->current++; - }*/ + /*{ + if (!(PATTERN_is(JOB->current[0], RS_CLASS) + && PATTERN_is(JOB->current[1], RS_INHERITS))) + return FALSE; + JOB->current++; + }*/ - JOB->current++; + JOB->current++; - if (!PATTERN_is_class(*JOB->current)) - THROW("Syntax error. INHERITS needs a class name"); + if (!PATTERN_is_class(*JOB->current)) + THROW("Syntax error. INHERITS needs a class name"); - if (JOB->class->parent != NO_SYMBOL) - THROW("Cannot inherit twice"); + if (JOB->class->parent != NO_SYMBOL) + THROW("Cannot inherit twice"); - index = PATTERN_index(*JOB->current); + index = PATTERN_index(*JOB->current); - JOB->class->parent = CLASS_add_class(JOB->class, index); - /*printf("JOB->class->parent = %d\n", JOB->class->parent);*/ + JOB->class->parent = CLASS_add_class(JOB->class, index); + /*printf("JOB->class->parent = %d\n", JOB->class->parent);*/ - JOB->current++; - return TRUE; + JOB->current++; + return TRUE; } static bool header_option(void) { - if (PATTERN_is(JOB->current[0], RS_EXPORT)) - { - JOB->current++; - JOB->class->exported = TRUE; + if (PATTERN_is(JOB->current[0], RS_EXPORT)) + { + JOB->current++; + JOB->class->exported = TRUE; if (PATTERN_is(JOB->current[0], RS_OPTIONAL)) - { - JOB->current++; - JOB->class->optional = TRUE; - } - - return TRUE; - } - - if (PATTERN_is(JOB->current[0], RS_CREATE)) - { - JOB->current++; - - if (PATTERN_is_newline(JOB->current[0]) || PATTERN_is(JOB->current[0], RS_STATIC)) { - JOB->class->autocreate = TRUE; - if (PATTERN_is(JOB->current[0], RS_STATIC)) - JOB->current++; - return TRUE; + JOB->current++; + JOB->class->optional = TRUE; } - else if (PATTERN_is(JOB->current[0], RS_PRIVATE)) - { - JOB->class->nocreate = TRUE; - JOB->current++; - return TRUE; - } - } - return FALSE; + return TRUE; + } + + if (PATTERN_is(JOB->current[0], RS_CREATE)) + { + JOB->current++; + + if (PATTERN_is_newline(JOB->current[0]) || PATTERN_is(JOB->current[0], RS_STATIC)) + { + JOB->class->autocreate = TRUE; + if (PATTERN_is(JOB->current[0], RS_STATIC)) + JOB->current++; + return TRUE; + } + else if (PATTERN_is(JOB->current[0], RS_PRIVATE)) + { + JOB->class->nocreate = TRUE; + JOB->current++; + return TRUE; + } + } + + return FALSE; } static bool header_library(void) { - if (!TRANS_is(RS_LIBRARY)) - return FALSE; + if (!TRANS_is(RS_LIBRARY)) + return FALSE; - if (!PATTERN_is_string(*JOB->current)) - THROW("Library name must be a string"); + if (!PATTERN_is_string(*JOB->current)) + THROW("Library name must be a string"); - JOB->default_library = PATTERN_index(*JOB->current); - JOB->current++; - return TRUE; + JOB->default_library = PATTERN_index(*JOB->current); + JOB->current++; + return TRUE; } static bool header_structure(void) { - PATTERN *look = JOB->current; + PATTERN *look = JOB->current; bool is_public; CLASS_STRUCT *structure; VARIABLE *field; @@ -827,23 +854,23 @@ static bool header_structure(void) check_public_private(&look, &is_public); - if (!PATTERN_is(*look, RS_STRUCT)) - return FALSE; - look++; + if (!PATTERN_is(*look, RS_STRUCT)) + return FALSE; + look++; JOB->current = look; if (!is_public) THROW("Structures must be public"); - if (!PATTERN_is_identifier(*JOB->current)) - THROW("Syntax error. STRUCT needs an identifier"); + if (!PATTERN_is_identifier(*JOB->current)) + THROW("Syntax error. STRUCT needs an identifier"); structure = ARRAY_add_void(&JOB->class->structure); ARRAY_create(&structure->field); nfield = 0; - structure->index = PATTERN_index(*JOB->current); - index = CLASS_add_class_exported(JOB->class, structure->index); + structure->index = PATTERN_index(*JOB->current); + index = CLASS_add_class_exported(JOB->class, structure->index); JOB->class->class[index].structure = TRUE; //fprintf(stderr, "Set structure flag to %s\n", TABLE_get_symbol_name(JOB->class->table, structure->index)); @@ -856,37 +883,37 @@ static bool header_structure(void) { do { - if (PATTERN_is_end(*JOB->current)) // || PATTERN_is_command(*JOB->current)) - THROW ("Missing END STRUCT"); + if (PATTERN_is_end(*JOB->current)) // || PATTERN_is_command(*JOB->current)) + THROW ("Missing END STRUCT"); } while (TRANS_newline()); if (PATTERN_is(*JOB->current, RS_END) && PATTERN_is(JOB->current[1], RS_STRUCT)) { - if (nfield == 0) - THROW ("Syntax error. A structure must have one field at least."); - + if (nfield == 0) + THROW ("Syntax error. A structure must have one field at least."); + JOB->current += 2; - + TRANS_want_newline(); - break; + break; } - if (!PATTERN_is_identifier(*JOB->current)) - THROW("Syntax error. The &1 field is not a valid identifier", TRANS_get_num_desc(nfield + 1)); + if (!PATTERN_is_identifier(*JOB->current)) + THROW("Syntax error. The &1 field is not a valid identifier", TRANS_get_num_desc(nfield + 1)); field = ARRAY_add(&structure->field); field->index = PATTERN_index(*JOB->current); - JOB->current++; - + JOB->current++; + CLEAR(&decl); - if (!TRANS_type(TT_CAN_ARRAY | TT_CAN_EMBED, &decl)) - THROW("Syntax error. Invalid type description of &1 field", TRANS_get_num_desc(nfield + 1)); + if (!TRANS_type(TT_CAN_ARRAY | TT_CAN_EMBED, &decl)) + THROW("Syntax error. Invalid type description of &1 field", TRANS_get_num_desc(nfield + 1)); TRANS_want_newline(); - + field->type = decl.type; nfield++; @@ -919,81 +946,81 @@ static void check_class_header() void HEADER_do(void) { - union { - TRANS_DECL decl; - TRANS_FUNC func; - TRANS_EVENT event; - TRANS_EXTERN ext; - TRANS_PROPERTY prop; - } trans; + union { + TRANS_DECL decl; + TRANS_FUNC func; + TRANS_EVENT event; + TRANS_EXTERN ext; + TRANS_PROPERTY prop; + } trans; - TRANS_reset(); + TRANS_reset(); - header_module_type(); + header_module_type(); if (JOB->line == 1) check_class_header(); - while (TRUE) //JOB->current < JOB->end) - { - if (PATTERN_is_end(*JOB->current)) - break; + while (TRUE) //JOB->current < JOB->end) + { + if (PATTERN_is_end(*JOB->current)) + break; - if (TRANS_newline()) + if (TRANS_newline()) { if (JOB->line == 1) check_class_header(); - continue; + continue; } - if (header_function(&trans.func)) - { - CLASS_add_function(JOB->class, &trans.func); - continue; - } + if (header_function(&trans.func)) + { + CLASS_add_function(JOB->class, &trans.func); + continue; + } - if (header_event(&trans.event)) - { - CLASS_add_event(JOB->class, &trans.event); - continue; - } + if (header_event(&trans.event)) + { + CLASS_add_event(JOB->class, &trans.event); + continue; + } - if (header_property(&trans.prop)) - { - CLASS_add_property(JOB->class, &trans.prop); - continue; - } + if (header_property(&trans.prop)) + { + CLASS_add_property(JOB->class, &trans.prop); + continue; + } - if (header_extern(&trans.ext)) - { - CLASS_add_extern(JOB->class, &trans.ext); - continue; - } - - if (header_enumeration(&trans.decl)) + if (header_extern(&trans.ext)) + { + CLASS_add_extern(JOB->class, &trans.ext); + continue; + } + + if (header_enumeration(&trans.decl)) continue; - if (header_declaration(&trans.decl)) - { - CLASS_add_declaration(JOB->class, &trans.decl); - continue; - } - - if (header_structure()) - continue; + if (header_declaration(&trans.decl)) + { + CLASS_add_declaration(JOB->class, &trans.decl); + continue; + } + + if (header_structure()) + continue; - if (header_class(&trans.decl)) - { - CLASS_add_class_exported(JOB->class, trans.decl.index); - continue; - } + if (header_class(&trans.decl)) + { + CLASS_add_class_exported(JOB->class, trans.decl.index); + continue; + } - if (header_inherits()) - continue; + if (header_inherits()) + continue; - if (header_library()) - continue; + if (header_library()) + continue; /*if (PATTERN_is_command(*JOB->current)) { @@ -1001,15 +1028,15 @@ void HEADER_do(void) continue; }*/ - THROW_UNEXPECTED(JOB->current); - } + THROW_UNEXPECTED(JOB->current); + } // Sort class declaration to avoid alignment problems. // This should be useless now, as it is done again by the interpreter // when loading the class. - CLASS_sort_declaration(JOB->class); + CLASS_sort_declaration(JOB->class); - if (JOB->verbose) - CLASS_dump(); + if (JOB->verbose) + CLASS_dump(); }