diff --git a/ase/stx/parser.c b/ase/stx/parser.c index dda1a42c..d32260dd 100644 --- a/ase/stx/parser.c +++ b/ase/stx/parser.c @@ -1,5 +1,5 @@ /* - * $Id: parser.c,v 1.35 2005-06-17 04:39:17 bacon Exp $ + * $Id: parser.c,v 1.36 2005-06-19 16:16:33 bacon Exp $ */ #include @@ -19,8 +19,15 @@ static int __parse_statements (xp_stx_parser_t* parser); static int __parse_statements_2 (xp_stx_parser_t* parser); static int __parse_expression (xp_stx_parser_t* parser); -static int __parser_assignment (xp_stx_parser_t* parser); -static int __parser_message_continuation (xp_stx_parser_t* parser); +static int __parse_assignment ( + xp_stx_parser_t* parser, const xp_char_t* target); +static int __parse_message_continuation (xp_stx_parser_t* parser); +static int __parse_keyword_continuation (xp_stx_parser_t* parser); +static int __parse_binary_continuation (xp_stx_parser_t* parser); +static int __parse_unary_continuation (xp_stx_parser_t* parser); + +static int __emit_code ( + xp_stx_parser_t* parser, const xp_char_t* high, int low); static int __get_token (xp_stx_parser_t* parser); static int __get_ident (xp_stx_parser_t* parser); @@ -56,6 +63,15 @@ xp_stx_parser_t* xp_stx_parser_open (xp_stx_parser_t* parser, xp_stx_t* stx) return XP_NULL; } + if (xp_array_open ( + &parser->byte_code, 256, + xp_sizeof(xp_byte_t), XP_NULL) == XP_NULL) { + xp_stx_name_close (&parser->method_name); + xp_stx_token_close (&parser->token); + if (parser->__malloced) xp_free (parser); + return XP_NULL; + } + parser->stx = stx; parser->error_code = XP_STX_PARSER_ERROR_NONE; @@ -79,11 +95,16 @@ void xp_stx_parser_close (xp_stx_parser_t* parser) xp_free (parser->temporary[--parser->temporary_count]); } + xp_array_close (&parser->byte_code); xp_stx_name_close (&parser->method_name); xp_stx_token_close (&parser->token); + if (parser->__malloced) xp_free (parser); } +#define EMIT_CODE(parser,high,low) \ + do { if (__emit_code(parser,high,low) == -1) return -1; } while (0) + #define GET_CHAR(parser) \ do { if (__get_char(parser) == -1) return -1; } while (0) #define UNGET_CHAR(parser,c) \ @@ -117,6 +138,7 @@ const xp_char_t* xp_stx_parser_error_string (xp_stx_parser_t* parser) XP_TEXT("too many arguments"), XP_TEXT("temporary list not closed"), XP_TEXT("too many temporaries"), + XP_TEXT("cannot redefine pseudo variable"), XP_TEXT("invalid expression start"), XP_TEXT("no period at end of statement") @@ -128,6 +150,16 @@ const xp_char_t* xp_stx_parser_error_string (xp_stx_parser_t* parser) return XP_TEXT("unknown error"); } +static inline xp_bool_t __is_pseudo_variable (const xp_stx_token_t* token) +{ + return token->type == XP_STX_TOKEN_IDENT && + (xp_strcmp(token->name.buffer, XP_TEXT("self")) == 0 || + xp_strcmp(token->name.buffer, XP_TEXT("super")) == 0 || + xp_strcmp(token->name.buffer, XP_TEXT("nil")) == 0 || + xp_strcmp(token->name.buffer, XP_TEXT("true")) == 0 || + xp_strcmp(token->name.buffer, XP_TEXT("false")) == 0); +} + int xp_stx_parser_parse_method ( xp_stx_parser_t* parser, xp_word_t method_class, void* input) { @@ -263,6 +295,11 @@ static int __parse_keyword_pattern (xp_stx_parser_t* parser) return -1; } + if (__is_pseudo_variable(&parser->token)) { + parser->error_code = XP_STX_PARSER_ERROR_PSEUDO_VARIABLE; + return -1; + } + if (parser->argument_count >= xp_countof(parser->argument)) { parser->error_code = XP_STX_PARSER_ERROR_TOO_MANY_ARGUMENTS; return -1; @@ -311,6 +348,11 @@ static int __parse_temporaries (xp_stx_parser_t* parser) return -1; } + if (__is_pseudo_variable(&parser->token)) { + parser->error_code = XP_STX_PARSER_ERROR_PSEUDO_VARIABLE; + return -1; + } + parser->temporary[parser->temporary_count] = xp_stx_token_yield (&parser->token, 0); if (parser->temporary[parser->temporary_count] == XP_NULL) { @@ -385,24 +427,46 @@ static int __parse_expression (xp_stx_parser_t* parser) */ if (parser->token.type == XP_STX_TOKEN_IDENT) { - if (__identify_ident(parser) == -1) return -1; + xp_char_t* ident = xp_stx_token_yield ( + &parser->token, parser->token.name.capacity); + if (ident == XP_NULL) { + parser->error_code = XP_STX_PARSER_ERROR_MEMORY; + return -1; + } GET_TOKEN (parser); if (parser->token.type == XP_STX_TOKEN_ASSIGN) { GET_TOKEN (parser); - if (__parse_assignment(parser) == -1) return -1; + if (__parse_assignment(parser, ident) == -1) { + xp_free (ident); + return -1; + } } else { - if (__parse_message_continuation(parser) == -1) return -1; + if (__parse_message_continuation(parser) == -1) { + return -1; + xp_free (ident); + } } + + xp_free (ident); } - else if (parser->token.type == XP_STX_TOKEN_CHARLIT || - parser->token.type == XP_STX_TOKEN_STRLIT || - parser->token.type == XP_STX_TOKEN_NUMLIT) { - /* more literals - array symbol #xxx #(1 2 3) */ + else if (parser->token.type == XP_STX_TOKEN_CHARLIT) { + EMIT_CODE (parser, XP_TEXT("PushLiteral(CHAR)"), 0xFFFF); GET_TOKEN (parser); if (__parse_message_continuation(parser) == -1) return -1; } + else if (parser->token.type == XP_STX_TOKEN_STRLIT) { + EMIT_CODE (parser, XP_TEXT("PushLiteral(STR)"), 0xFFFF); + GET_TOKEN (parser); + if (__parse_message_continuation(parser) == -1) return -1; + } + else if (parser->token.type == XP_STX_TOKEN_NUMLIT) { + EMIT_CODE (parser, XP_TEXT("PushLiteral(NUM)"), 0xFFFF); + GET_TOKEN (parser); + if (__parse_message_continuation(parser) == -1) return -1; + } + /* TODO: more literals - array symbol #xxx #(1 2 3) */ else if (parser->token.type == XP_STX_TOKEN_LBRACKET) { } else if (parser->token.type == XP_STX_TOKEN_LPAREN) { @@ -455,23 +519,23 @@ AssignInstance AssignTemporary */ -staitc int __identify_ident (xp_stx_parser_t* parser, const xp_char_t* ident) +static int __identify_ident (xp_stx_parser_t* parser, const xp_char_t* ident) { xp_size_t i; - if (xp_strcmp (ident, XP_TEXT("self") == 0) { + if (xp_strcmp(ident, XP_TEXT("self")) == 0) { } - if (xp_strcmp (ident, XP_TEXT("super") == 0) { + if (xp_strcmp(ident, XP_TEXT("super")) == 0) { } for (i = 0; i < parser->temporary_count; i++) { - if (xp_strcmp (parser->temporaries[i], ident) == 0) { + if (xp_strcmp (parser->temporary[i], ident) == 0) { } } for (i = 0; i < parser->argument_count; i++) { - if (xp_strcmp (parser->arguments[i], ident) == 0) { + if (xp_strcmp (parser->argument[i], ident) == 0) { } } @@ -486,16 +550,76 @@ staitc int __identify_ident (xp_stx_parser_t* parser, const xp_char_t* ident) return 0; } -static int __parser_assignment (xp_stx_parser_t* parser) +static int __parse_assignment ( + xp_stx_parser_t* parser, const xp_char_t* target) { + /* + * ::= assignmentOperator + */ + + xp_size_t i; + + for (i = 0; i < parser->temporary_count; i++) { + if (xp_strcmp (target, parser->temporary[i]) == 0) { + if (__parse_expression(parser) == -1) return -1; + EMIT_CODE (parser, XP_TEXT("AssignTemporary"), i); + return 0; + } + } + + /* TODO: check it in instance variable */ + + /* TODO: check it in class variables */ + + /* TODO: global, but i don't like this idea */ + return -1; } -static int __parser_message_continuation (xp_stx_parser_t* parser) +static int __parse_message_continuation (xp_stx_parser_t* parser) { + if (__parse_keyword_continuation (parser) == -1) return -1; + + while (parser->token.type == XP_STX_TOKEN_SEMICOLON) { + EMIT_CODE (parser, XP_TEXT("DoSpecial(DUP_RECEIVER)"), 0); + GET_TOKEN (parser); + + if (__parse_keyword_continuation (parser) == -1) return -1; + EMIT_CODE (parser, XP_TEXT("DoSpecial(POP_TOP)"), 0); + } + + return 0; +} + +static int __parse_keyword_continuation (xp_stx_parser_t* parser) +{ + if (__parser_binary_continuation (parser) == -1) return -1; return -1; } +static int __parse_binary_continuation (xp_stx_parser_t* parser) +{ + if (__parser_unary_continuation (parser) == -1) return -1; + return -1; +} + +static int __parse_unary_continuation (xp_stx_parser_t* parser) +{ + while (parser->token.type == XP_STX_TOKEN_IDENT) { + + } + + return 0; +} + +static int __emit_code ( + xp_stx_parser_t* parser, const xp_char_t* high, int low) +{ + xp_printf (XP_TEXT("CODE: %s %d\n"), high, low); + return 0; +} + + static inline xp_bool_t __is_binary_char (xp_cint_t c) { /* @@ -591,6 +715,11 @@ static int __get_token (xp_stx_parser_t* parser) ADD_TOKEN_CHAR(parser, c); GET_CHAR (parser); } + else if (c == XP_CHAR(';')) { + parser->token.type = XP_STX_TOKEN_SEMICOLON; + ADD_TOKEN_CHAR(parser, c); + GET_CHAR (parser); + } else if (__is_binary_char(c)) { if (__get_binary(parser) == -1) return -1; } @@ -599,6 +728,7 @@ static int __get_token (xp_stx_parser_t* parser) return -1; } +//xp_printf (XP_TEXT("TOKEN: %s\n"), parser->token.name.buffer); return 0; } diff --git a/ase/stx/parser.h b/ase/stx/parser.h index 74b85cf4..af1a5946 100644 --- a/ase/stx/parser.h +++ b/ase/stx/parser.h @@ -1,5 +1,5 @@ /* - * $Id: parser.h,v 1.21 2005-06-17 04:39:17 bacon Exp $ + * $Id: parser.h,v 1.22 2005-06-19 16:16:33 bacon Exp $ */ #ifndef _XP_STX_PARSER_H_ @@ -8,6 +8,7 @@ #include #include #include +#include enum { @@ -29,6 +30,7 @@ enum XP_STX_PARSER_ERROR_TOO_MANY_ARGUMENTS, XP_STX_PARSER_ERROR_TEMPORARIES_NOT_CLOSED, XP_STX_PARSER_ERROR_TOO_MANY_TEMPORARIES, + XP_STX_PARSER_ERROR_PSEUDO_VARIABLE, XP_STX_PARSER_ERROR_EXPRESSION_START, XP_STX_PARSER_ERROR_NO_PERIOD }; @@ -57,6 +59,8 @@ struct xp_stx_parser_t xp_char_t* temporary[32]; xp_size_t temporary_count; + xp_array_t byte_code; + xp_stx_token_t token; xp_cint_t curc; xp_cint_t ungotc[5]; diff --git a/ase/stx/token.h b/ase/stx/token.h index 7291df94..06a2d8ad 100644 --- a/ase/stx/token.h +++ b/ase/stx/token.h @@ -1,5 +1,5 @@ /* - * $Id: token.h,v 1.15 2005-06-12 16:22:03 bacon Exp $ + * $Id: token.h,v 1.16 2005-06-19 16:16:33 bacon Exp $ */ #ifndef _XP_STX_TOKEN_H_ @@ -25,7 +25,8 @@ enum XP_STX_TOKEN_RBRACKET, XP_STX_TOKEN_LPAREN, XP_STX_TOKEN_RPAREN, - XP_STX_TOKEN_PERIOD + XP_STX_TOKEN_PERIOD, + XP_STX_TOKEN_SEMICOLON }; struct xp_stx_token_t diff --git a/ase/test/stx/test.st b/ase/test/stx/test.st index d1ed406d..d753c4d6 100644 --- a/ase/test/stx/test.st +++ b/ase/test/stx/test.st @@ -2,10 +2,14 @@ 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'. + a := 'this is ''good'. + b := -30. + +" $a. $b. ^true. a := b. ' this is bad +"