diff --git a/ase/stx/parser.c b/ase/stx/parser.c index ade9193f..cb6d5821 100644 --- a/ase/stx/parser.c +++ b/ase/stx/parser.c @@ -1,9 +1,10 @@ /* - * $Id: parser.c,v 1.43 2005-06-29 10:56:42 bacon Exp $ + * $Id: parser.c,v 1.44 2005-06-29 12:02:39 bacon Exp $ */ #include #include +#include #if defined(__BORLANDC__) || defined(_MSC_VER) #define INLINE @@ -158,7 +159,9 @@ const xp_char_t* xp_stx_parser_error_string (xp_stx_parser_t* parser) XP_TEXT("no closing parenthesis"), XP_TEXT("block argument name missing"), XP_TEXT("block argument list not closed"), - XP_TEXT("block not closed") + XP_TEXT("block not closed"), + + XP_TEXT("undeclared name") }; if (parser->error_code >= 0 && @@ -544,6 +547,7 @@ static int __parse_assignment ( */ xp_size_t i; + xp_stx_class_t* class_obj; for (i = 0; i < parser->temporary_count; i++) { if (xp_strcmp (target, parser->temporary[i]) == 0) { @@ -551,17 +555,43 @@ xp_char_t buf[100]; if (__parse_expression(parser) == -1) return -1; xp_sprintf (buf, xp_countof(buf), XP_TEXT("%d"), i); - EMIT_CODE (parser, XP_TEXT("AssignTemporary"), buf); + EMIT_CODE (parser, XP_TEXT("ASSIGN_TEMPORARY"), buf); return 0; } } - /* TODO: check it in instance variable */ + class_obj = (xp_stx_class_t*) + XP_STX_WORD_OBJECT(parser->stx, parser->method_class); + xp_assert (class_obj != XP_NULL); + if (class_obj->header.class == parser->stx->class_metaclass) { + /* metaclass */ + /* TODO: can metaclasses have instance variables? */ + } + else { + xp_size_t size; + xp_stx_word_object_t* array; + + size = XP_STX_SIZE(parser->stx, class_obj->variables); + array = XP_STX_WORD_OBJECT(parser->stx, class_obj->variables); + + for (i = 0; i < size; i++) { + const xp_char_t* iname = + &XP_STX_CHARAT(parser->stx, array->data[i], 0); + if (xp_strcmp(target, iname) == 0) { +xp_char_t buf[100]; + if (__parse_expression(parser) == -1) return -1; +xp_sprintf (buf, xp_countof(buf), XP_TEXT("%d"), i); + EMIT_CODE (parser, XP_TEXT("ASSIGN_INSTANCE"), buf); + return 0; + } + } + } /* TODO: check it in class variables */ /* TODO: global, but i don't like this idea */ + parser->error_code = XP_STX_PARSER_ERROR_UNDECLARED_NAME; return -1; } diff --git a/ase/stx/parser.h b/ase/stx/parser.h index 3a55fc61..46e7b529 100644 --- a/ase/stx/parser.h +++ b/ase/stx/parser.h @@ -1,5 +1,5 @@ /* - * $Id: parser.h,v 1.24 2005-06-23 07:20:44 bacon Exp $ + * $Id: parser.h,v 1.25 2005-06-29 12:02:39 bacon Exp $ */ #ifndef _XP_STX_PARSER_H_ @@ -38,7 +38,9 @@ enum XP_STX_PARSER_ERROR_NO_RPAREN, XP_STX_PARSER_ERROR_BLOCK_ARGUMENT_NAME, XP_STX_PARSER_ERROR_BLOCK_ARGUMENT_LIST, - XP_STX_PARSER_ERROR_BLOCK_NOT_CLOSED + XP_STX_PARSER_ERROR_BLOCK_NOT_CLOSED, + + XP_STX_PARSER_ERROR_UNDECLARED_NAME }; enum @@ -85,6 +87,7 @@ extern "C" { xp_stx_parser_t* xp_stx_parser_open (xp_stx_parser_t* parser, xp_stx_t* stx); void xp_stx_parser_close (xp_stx_parser_t* parser); +const xp_char_t* xp_stx_parser_error_string (xp_stx_parser_t* parser); int xp_stx_parser_parse_method ( xp_stx_parser_t* parser, xp_word_t method_class, void* input); diff --git a/ase/test/stx/parser.c b/ase/test/stx/parser.c index 4955e2c3..3ff94199 100644 --- a/ase/test/stx/parser.c +++ b/ase/test/stx/parser.c @@ -9,6 +9,8 @@ #endif #include +#include +#include #ifdef __linux #include @@ -90,6 +92,7 @@ int stdio_func (int cmd, void* owner, void* arg) int xp_main (int argc, xp_char_t* argv[]) { + xp_stx_t stx; xp_stx_parser_t parser; xp_word_t i; @@ -106,12 +109,29 @@ int xp_main (int argc, xp_char_t* argv[]) #endif */ + if (argc != 2) { + xp_printf (XP_TEXT("usage: %s class_name\n"), argv[0]); + return -1; + } - if (xp_stx_parser_open(&parser, XP_NULL) == XP_NULL) { + if (xp_stx_open (&stx, 10000) == XP_NULL) { + xp_printf (XP_TEXT("cannot open stx\n")); + return -1; + } + + if (xp_stx_bootstrap(&stx) == -1) { + xp_stx_close (&stx); + xp_printf (XP_TEXT("cannot bootstrap\n")); + return -1; + } + + + if (xp_stx_parser_open(&parser, &stx) == XP_NULL) { xp_printf (XP_TEXT("cannot open parser\n")); return -1; } + { /* ss_t ss; @@ -121,16 +141,26 @@ int xp_main (int argc, xp_char_t* argv[]) XP_TEXT("isNil\n^true")); */ stdio_t stdio; + xp_word_t n = xp_stx_lookup_class (&stx, argv[1]); + parser.input_owner = (void*)&stdio; parser.input_func = stdio_func; - if (xp_stx_parser_parse_method (&parser, 0, + + if (n == stx.nil) { + xp_printf (XP_TEXT("Cannot find class - %s\n"), argv[1]); + goto exit_program; + } + + if (xp_stx_parser_parse_method (&parser, n, (void*)XP_TEXT("test.st")) == -1) { xp_printf (XP_TEXT("parser error <%s>\n"), xp_stx_parser_error_string (&parser)); } } +exit_program: xp_stx_parser_close (&parser); + xp_stx_close (&stx); xp_printf (XP_TEXT("== End of program ==\n")); #ifdef __linux diff --git a/ase/test/stx/test.st b/ase/test/stx/test.st index 927c3e12..3d5ae9c8 100644 --- a/ase/test/stx/test.st +++ b/ase/test/stx/test.st @@ -6,9 +6,9 @@ perform: method with: x with: y with: z with: a with: b with: c " a := 'this is ''good'. a := #xxx niceMethod. - b := -30 xxx nil this. " + b := -30 xxx nil this. + spec := 10. (jjj xxx: 10 xy) zzz: (10 fuck: 20 you: 40) yyy: kkk. - - [ 10 plus: 20] + [ spec plus: 20]