diff --git a/ase/stx/parser.c b/ase/stx/parser.c index c4b31fec..8c701c24 100644 --- a/ase/stx/parser.c +++ b/ase/stx/parser.c @@ -1,5 +1,5 @@ /* - * $Id: parser.c,v 1.27 2005-06-12 14:40:35 bacon Exp $ + * $Id: parser.c,v 1.28 2005-06-12 15:46:02 bacon Exp $ */ #include @@ -9,7 +9,12 @@ static int __parse_method ( xp_stx_parser_t* parser, xp_word_t method_class, void* input); + static int __parse_message_pattern (xp_stx_parser_t* parser); +static int __parse_unary_pattern (xp_stx_parser_t* parser); +static int __parse_binary_pattern (xp_stx_parser_t* parser); +static int __parse_keyword_pattern (xp_stx_parser_t* parser); + static int __parse_temporaries (xp_stx_parser_t* parser); static int __parse_statements (xp_stx_parser_t* parser); static int __parse_statements_2 (xp_stx_parser_t* parser); @@ -38,7 +43,7 @@ xp_stx_parser_t* xp_stx_parser_open (xp_stx_parser_t* parser, xp_stx_t* stx) } else parser->__malloced = xp_false; - if (xp_stx_token_open (&parser->token, 256) == XP_NULL) { + if (xp_stx_token_open (&parser->token, 0) == XP_NULL) { if (parser->__malloced) xp_free (parser); return XP_NULL; } @@ -58,6 +63,10 @@ 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) { + while (parser->argument_count > 0) { + xp_free (parser->argument[--parser->argument_count]); + } + xp_stx_token_close (&parser->token); if (parser->__malloced) xp_free (parser); } @@ -147,40 +156,93 @@ static int __parse_message_pattern (xp_stx_parser_t* parser) * ::= binarySelector * ::= (keyword )+ */ + int n; - parser->argument_count = 0; + while (parser->argument_count > 0) { + xp_free (parser->argument[--parser->argument_count]); + } if (parser->token.type == XP_STX_TOKEN_IDENT) { - /* unary pattern */ - GET_TOKEN (parser); + n = __parse_unary_pattern (parser); } else if (parser->token.type == XP_STX_TOKEN_BINARY) { - /* binary pattern */ + n = __parse_binary_pattern (parser); + } + else if (parser->token.type == XP_STX_TOKEN_KEYWORD) { + n = __parse_keyword_pattern (parser); + } + else { + parser->error_code = XP_STX_PARSER_ERROR_MESSAGE_SELECTOR; + n = -1; + } + + return n; +} + +static int __parse_unary_pattern (xp_stx_parser_t* parser) +{ + /* TODO: check if the method name exists */ + GET_TOKEN (parser); + return 0; +} + +static int __parse_binary_pattern (xp_stx_parser_t* parser) +{ + /* TODO: check if the method name exists */ + + GET_TOKEN (parser); + if (parser->token.type != XP_STX_TOKEN_IDENT) { + parser->error_code = XP_STX_PARSER_ERROR_ARGUMENT_NAME; + return -1; + } + + if (parser->argument_count >= xp_countof(parser->argument)) { + parser->error_code = XP_STX_PARSER_ERROR_TOO_MANY_ARGUMENTS; + return -1; + } + + /* TODO: decide whether to use symbol */ + parser->argument[parser->argument_count] = + xp_stx_token_yield (&parser->token, 0); + if (parser->argument[parser->argument_count] == XP_NULL) { + parser->error_code = XP_STX_PARSER_ERROR_MEMORY; + return -1; + } + parser->argument_count++; + + GET_TOKEN (parser); + return 0; +} + +static int __parse_keyword_pattern (xp_stx_parser_t* parser) +{ + do { GET_TOKEN (parser); if (parser->token.type != XP_STX_TOKEN_IDENT) { parser->error_code = XP_STX_PARSER_ERROR_ARGUMENT_NAME; return -1; } + if (parser->argument_count >= xp_countof(parser->argument)) { + parser->error_code = XP_STX_PARSER_ERROR_TOO_MANY_ARGUMENTS; + return -1; + } + /* TODO: decide whether to use symbol */ - //parser->arguments[parser->argument_count++] = + parser->argument[parser->argument_count] = + xp_stx_token_yield (&parser->token, 0); + if (parser->argument[parser->argument_count] == XP_NULL) { + parser->error_code = XP_STX_PARSER_ERROR_MEMORY; + return -1; + } + /* TODO: check for duplicate entries... */ + parser->argument_count++; + GET_TOKEN (parser); - } - else if (parser->token.type == XP_STX_TOKEN_KEYWORD) { - /* keyword pattern */ - do { - GET_TOKEN (parser); - if (parser->token.type != XP_STX_TOKEN_IDENT) { - parser->error_code = XP_STX_PARSER_ERROR_ARGUMENT_NAME; - return -1; - } - GET_TOKEN (parser); - } while (parser->token.type == XP_STX_TOKEN_KEYWORD); - } - else { - parser->error_code = XP_STX_PARSER_ERROR_MESSAGE_SELECTOR; - return -1; - } + } while (parser->token.type == XP_STX_TOKEN_KEYWORD); + + /* TODO: check if the method name exists */ + /* if it exists, collapse arguments */ return 0; } diff --git a/ase/stx/parser.h b/ase/stx/parser.h index 51741353..06314ab3 100644 --- a/ase/stx/parser.h +++ b/ase/stx/parser.h @@ -1,5 +1,5 @@ /* - * $Id: parser.h,v 1.17 2005-06-12 14:40:35 bacon Exp $ + * $Id: parser.h,v 1.18 2005-06-12 15:46:02 bacon Exp $ */ #ifndef _XP_STX_PARSER_H_ @@ -47,7 +47,7 @@ struct xp_stx_parser_t xp_stx_t* stx; int error_code; - xp_word_t argument[32]; + xp_char_t* argument[32]; xp_size_t argument_count; xp_stx_token_t token; diff --git a/ase/stx/token.c b/ase/stx/token.c index 60e94054..9bb743ce 100644 --- a/ase/stx/token.c +++ b/ase/stx/token.c @@ -1,5 +1,5 @@ /* - * $Id: token.c,v 1.6 2005-06-12 14:40:35 bacon Exp $ + * $Id: token.c,v 1.7 2005-06-12 15:46:02 bacon Exp $ */ #include @@ -8,7 +8,8 @@ xp_stx_token_t* xp_stx_token_open ( xp_stx_token_t* token, xp_word_t capacity) { - xp_assert (capacity > 0); + if (capacity == 0) + capacity = xp_countof(token->static_buffer) - 1; if (token == XP_NULL) { token = (xp_stx_token_t*) @@ -44,7 +45,7 @@ xp_stx_token_t* xp_stx_token_open ( void xp_stx_token_close (xp_stx_token_t* token) { - if (token->capacity < xp_countof(token->static_buffer)) { + if (token->capacity >= xp_countof(token->static_buffer)) { xp_assert (token->buffer != token->static_buffer); xp_free (token->buffer); } @@ -100,6 +101,9 @@ void xp_stx_token_clear (xp_stx_token_t* token) xp_char_t* xp_stx_token_yield (xp_stx_token_t* token, xp_word_t capacity) { xp_char_t* old_buffer, * new_buffer; + + if (capacity == 0) + capacity = xp_countof(token->static_buffer) - 1; if (token->capacity < xp_countof(token->static_buffer)) { old_buffer = (xp_char_t*) diff --git a/ase/stx/token.h b/ase/stx/token.h index 12371cff..8b5e45fe 100644 --- a/ase/stx/token.h +++ b/ase/stx/token.h @@ -1,5 +1,5 @@ /* - * $Id: token.h,v 1.12 2005-06-12 14:40:35 bacon Exp $ + * $Id: token.h,v 1.13 2005-06-12 15:46:02 bacon Exp $ */ #ifndef _XP_STX_TOKEN_H_ @@ -39,7 +39,7 @@ struct xp_stx_token_t xp_word_t capacity; xp_word_t size; xp_char_t* buffer; - xp_char_t static_buffer[16]; + xp_char_t static_buffer[128]; xp_bool_t __malloced; }; diff --git a/ase/test/stx/makefile.in b/ase/test/stx/makefile.in index 9a947865..37b5c193 100644 --- a/ase/test/stx/makefile.in +++ b/ase/test/stx/makefile.in @@ -6,13 +6,13 @@ LIBS = @LIBS@ -lxpstx -lxpbas all: stx parser stx: stx.o - $(CC) $(LDFLAGS) -o $@ $< $(LIBS) + $(CC) $(LDFLAGS) -o $@.x $< $(LIBS) parser: parser.o - $(CC) $(LDFLAGS) -o $@ $< $(LIBS) + $(CC) $(LDFLAGS) -o $@.x $< $(LIBS) clean: - rm -rf $(OUTS) *.o + rm -rf *.x *.o .SUFFIXES: .c .o .c.o: diff --git a/ase/test/stx/test.st b/ase/test/stx/test.st index 8b0943e5..d1ed406d 100644 --- a/ase/test/stx/test.st +++ b/ase/test/stx/test.st @@ -1,5 +1,5 @@ "isNil" "test if self is nil" -perform: method with: x with: y +perform: method with: x with: y with: z with: a with: b with: c | a b c d e f g | 'this is very bad''this is'.