diff --git a/ase/stx/bytecode.c b/ase/stx/bytecode.c index 31147f22..4a2317e4 100644 --- a/ase/stx/bytecode.c +++ b/ase/stx/bytecode.c @@ -1,5 +1,5 @@ /* - * $Id: bytecode.c,v 1.3 2005-07-07 16:52:48 bacon Exp $ + * $Id: bytecode.c,v 1.4 2005-07-08 11:32:50 bacon Exp $ */ #include #include @@ -41,15 +41,15 @@ static const xp_char_t* opcode_names[] = XP_TEXT("PUSH_LITERAL_VARIABLE"), XP_TEXT("STORE_VARIABLE"), XP_TEXT("STORE_TEMPORARY"), + XP_TEXT("SEND"), + XP_TEXT("JUMP"), XP_TEXT("DO_SPECIAL"), XP_TEXT("DO_PRIMITIVE"), - XP_TEXT("UNKNOWN"), - XP_TEXT("UNKNOWN"), XP_TEXT("PUSH_VARIABLE_EXTENDED"), XP_TEXT("PUSH_TEMPORARY_EXTENDED"), + XP_TEXT("STORE_VARIABLE_EXTENDED"), XP_TEXT("STORE_TEMPORARY_EXTENDED"), - XP_TEXT("UNKNOWN"), - XP_TEXT("UNKNOWN"), + XP_TEXT("DO_SPECIAL_EXTENDED"), XP_TEXT("DO_PRIMITIVE_EXTENDED") }; diff --git a/ase/stx/bytecode.h b/ase/stx/bytecode.h index 00b03574..8ca2f1b7 100644 --- a/ase/stx/bytecode.h +++ b/ase/stx/bytecode.h @@ -1,5 +1,5 @@ /* - * $Id: bytecode.h,v 1.4 2005-07-07 16:52:48 bacon Exp $ + * $Id: bytecode.h,v 1.5 2005-07-08 11:32:50 bacon Exp $ */ #ifndef _XP_STX_BYTECODE_H_ @@ -7,18 +7,35 @@ #include -#define PUSH_VARIABLE 0x0 -#define PUSH_TEMPORARY 0x1 -#define PUSH_LITERAL_CONSTANT 0x2 -#define PUSH_LITERAL_VARIABLE 0x3 -#define STORE_VARIABLE 0x4 -#define STORE_TEMPORARY 0x5 -#define DO_SPECIAL 0x6 -#define DO_PRIMITIVE 0x7 -#define PUSH_VARIABLE_EXTENDED 0xA -#define PUSH_TEMPORARY_EXTENDED 0xB +#define PUSH_RECEIVER_VARIABLE 0x00 +#define PUSH_RECEIVER_VARIABLE_BIG 0x10 + +#define PUSH_VARIABLE 0x0 +#define PUSH_TEMPORARY 0x1 +#define PUSH_LITERAL_CONSTANT 0x2 +#define PUSH_LITERAL_VARIABLE 0x3 +#define STORE_VARIABLE 0x4 +#define STORE_TEMPORARY 0x5 +#define SEND 0x6 +#define JUMP 0x7 +#define DO_SPECIAL 0x8 +#define DO_PRIMITIVE 0x9 +#define PUSH_VARIABLE_EXTENDED 0xA +#define PUSH_TEMPORARY_EXTENDED 0xB #define STORE_TEMPORARY_EXTENDED 0xC -#define DO_PRIMITIVE_EXTENDED 0xF +#define STORE_VARIABLE_EXTENDED 0xD +#define DO_SPECIAL_EXTENDED 0xE +#define DO_PRIMITIVE_EXTENDED 0xF + +#define RETURN_RECEIVER 1 +#define RETURN_NIL 2 +#define RETURN_TRUE 3 +#define RETURN_FALSE 4 +#define RETURN_FROM_MESSAGE 5 +#define RETURN_FROM_BLOCK 6 + +#define PUSH_VARIABLE(i) ((i <= 0x0F)? (i): +#define PUSH_VARIABLE(i) i #ifdef __cplusplus extern "C" { diff --git a/ase/stx/parser.c b/ase/stx/parser.c index 7c3f00ba..7fd8e8c5 100644 --- a/ase/stx/parser.c +++ b/ase/stx/parser.c @@ -1,5 +1,5 @@ /* - * $Id: parser.c,v 1.58 2005-07-07 16:52:48 bacon Exp $ + * $Id: parser.c,v 1.59 2005-07-08 11:32:50 bacon Exp $ */ #include @@ -34,6 +34,9 @@ static int __parse_basic_expression ( xp_stx_parser_t* parser, const xp_char_t* ident); static int __parse_primary ( xp_stx_parser_t* parser, const xp_char_t* ident); +static int __parse_primary_ident ( + xp_stx_parser_t* parser, const xp_char_t* ident); + static int __parse_block_constructor (xp_stx_parser_t* parser); static int __parse_message_continuation (xp_stx_parser_t* parser); static int __parse_keyword_message (xp_stx_parser_t* parser); @@ -255,6 +258,42 @@ static INLINE int __emit_code (xp_stx_parser_t* parser, xp_byte_t code) return 0; } +static INLINE int __emit_push_receiver_variable (xp_stx_parser_t* parser, int pos) +{ + if (pos > 0xFF) + + if (pos > 0x0F) EMIT_CODE (parser, PUSH_RECEIVER_VARIABLE | (pos & 0x0F)); + else EMIT_CODE (parser, PUSH_RECEIVER_VARIABLE_BIG, pos); + return 0; +} + +/* +push_receiver_variable, +push_temporary_location, +push_literal_constant, +push_literal_variable, +store_receiver_variable, +store_temporary_location, +push_receiver, +push_true, +push_false, +push_nil, +push_minus_one, +push_zero, +push_one, +push_two, +return_receiver, +return_true, +return_false, +return_nil, +return_from_message, +return_from_block, +XP_NULL, +push_receiver_variable, +push_temporary_location, +push_literal_constant, +push_literal_variable, +*/ int xp_stx_parser_parse_method ( xp_stx_parser_t* parser, xp_word_t method_class, void* input) @@ -622,7 +661,17 @@ static int __parse_statement (xp_stx_parser_t* parser) if (parser->token.type == XP_STX_TOKEN_RETURN) { GET_TOKEN (parser); if (__parse_expression(parser) == -1) return -1; - EMIT_CODE_TEST (parser, XP_TEXT("RETURN"), XP_TEXT("stack top")); + + /* TODO */ + if (RETURN_FROM_MESSAGE <= 0x0F) { + EMIT_CODE_TEST (parser, XP_TEXT("DO_SPECIAL"), XP_TEXT("RETURN_FROM_MESSAGE")); + EMIT_CODE (parser, (DO_SPECIAL << 4) | RETURN_FROM_MESSAGE); + } + else { + EMIT_CODE_TEST (parser, XP_TEXT("DO_SPECIAL_EXTENDED"), XP_TEXT("RETURN_FROM_MESSAGE")); + EMIT_CODE (parser, (DO_SPECIAL_EXTENDED << 4) | (RETURN_FROM_MESSAGE & 0x0F)); + EMIT_CODE (parser, RETURN_FROM_MESSAGE >> 4); + } } else { if (__parse_expression(parser) == -1) return -1; @@ -722,13 +771,26 @@ xp_sprintf (buf, xp_countof(buf), XP_TEXT("%d"), i); xp_char_t buf[100]; if (__parse_expression(parser) == -1) return -1; xp_sprintf (buf, xp_countof(buf), XP_TEXT("%d"), i); - EMIT_CODE_TEST (parser, XP_TEXT("ASSIGN_INSTANCE"), buf); + + /* TODO */ + if (i <= 0x0F) { + EMIT_CODE_TEST (parser, XP_TEXT("STORE_VARIABLE"), buf); + EMIT_CODE (parser, (STORE_VARIABLE << 4) | i); + } + else { + EMIT_CODE_TEST (parser, XP_TEXT("STORE_VARIABLE_EXTENDED"), buf); + EMIT_CODE (parser, (STORE_VARIABLE_EXTENDED << 4) | (i & 0x0F)); + EMIT_CODE (parser, i >> 4); + } + return 0; } if (xp_stx_lookup_class_variable ( stx, parser->method_class, target) != stx->nil) { if (__parse_expression(parser) == -1) return -1; + + /* TODO */ EMIT_CODE_TEST (parser, XP_TEXT("ASSIGN_CLASSVAR #"), target); return 0; } @@ -751,8 +813,7 @@ static int __parse_primary (xp_stx_parser_t* parser, const xp_char_t* ident) if (ident == XP_NULL) { if (parser->token.type == XP_STX_TOKEN_IDENT) { - /* TODO - check what this identifier is and generate proper code*/ - EMIT_CODE_TEST (parser, XP_TEXT("PUSH_IDENT"), parser->token.name.buffer); + if (__parse_primary_ident (parser, parser->token.buffer) == -1) return -1; GET_TOKEN (parser); } else if (parser->token.type == XP_STX_TOKEN_CHARLIT) { @@ -793,13 +854,45 @@ static int __parse_primary (xp_stx_parser_t* parser, const xp_char_t* ident) } } else { - /* TODO - check what this identifier is and generate proper code*/ - EMIT_CODE_TEST (parser, XP_TEXT("PUSH_IDENT"), ident); + if (__parse_primary_ident (parser, parser->token.buffer) == -1) return -1; } return 0; } +static int __parse_primary_ident (xp_stx_parser_t* parser, const xp_char_t* ident) +{ + xp_word_t i; + + /* Refer to __parse_assignment for identifier lookup */ + + for (i = 0; i < parser->temporary_count; i++) { + if (xp_strcmp (target, parser->temporaries[i]) == 0) { + EMIT_CODE_1 (parser, PUSH_TEMPORARY_VARIABLE, i); + return 0; + } + } + + if (xp_stx_get_instance_variable_index ( + stx, parser->method_class, target, &i) == 0) { + EMIT_CODE_1 (parser, PUSH_RECEIVER_VARIABLE, i); + return 0; + } + + if (xp_stx_lookup_class_variable ( + stx, parser->method_class, target) != stx->nil) { + //PUSH_CLASS_VARIABLE + return 0; + } + + /* TODO: IMPLEMENT POOL DICTIONARIES */ + + /* TODO: IMPLEMENT GLOBLAS, but i don't like this idea */ + + parser->error_code = XP_STX_PARSER_ERROR_UNDECLARED_NAME; + return -1; +} + static int __parse_block_constructor (xp_stx_parser_t* parser) { /* @@ -1294,3 +1387,4 @@ static int __close_input (xp_stx_parser_t* parser) return 0; } + diff --git a/ase/stx/stx.txt b/ase/stx/stx.txt index d1de7843..1c6d0d4e 100644 --- a/ase/stx/stx.txt +++ b/ase/stx/stx.txt @@ -79,8 +79,93 @@ AssignInstance AssignTemporary */ -#define PUSH_VARIABLE 0x01 -#define PUSH_ARGUMENT 0x02 -#define PUSH_TEMPORARY 0x03 -#define PUSH_LITERAL 0x04 +0x push instance variable x +1x store instance variable x +2x push local x +3x store local x +40..43 xx jump forward by xxx +44..47 xx jump backward by xxx +48..4F xx (reserved) +50..53 xx jump forward if true by xxx +54..57 xx jump backward if true by xxx +58..5B xx jump forward if false by xxx +5C..5F xx jump backward if false by xxx +60 xx fetch inst var xx of stack top +61 xx store stack top inst var xx of stack level 2 +62..6F (reserved) +7x yyyy send self yyyy, x args +8x yyyy send yyyy, x args +9x yyyy send super yyyy, x args +Ax yy send self yy, x args + +B0 xx push object xx +B1 xxxx push object xxxx +B2 xx get instvar xx of next outer receiver +B3 xx store instvar xx of next outer receiver +B4 xx get next outer local x +B5 xx store next outer local +B6 xx yy get (y th) outer local +B7 xx yy store (y th) outer local +B8 nonlocal block return, next outer context +B9 xx make full block +BA xx make hybrid block +BB xx yy get instvar xx of yyth outer receiver +BC xx yy store instvar xx of yyth outer receiver +BD xx nonlocal block return, distance xx +BE push next outer receiver +BF xx push xxth outer receiver + +Cx send special selector: + 0: <= + 1: >= + 2: < + 3: > + 4: == + 5: ~~ + 6: not + 7: + + 8: - + 9: basicAt: + A: basicAt:put: + B: isNil + C: notNil + D: (reserved) + E: (reserved) + F: (reserved) + +Dx yy send yy to stack top, xx args + +E0 pop stack +E1 duplicate stacktop +E2 duplicate level 2 +E3 return stack top +E4 return true +E5 return false +E6 return nil +E7 return self +E8 push false +E9 push true +EA push nil +EB push self +EC xx push negative integer +ED xx push positive integer +EE xxxx push negative integer +EF xxxx push positive integer + +F0 xx push instvar xx +F1 xx store instvar xx +F2 xx push local xx +F3 xx store local xx +F4 xx push global xx +F5 xx store global xx +F6 xx push Character xx +F7 add 1 +F8 subtract 1 +F9 push thisContext +FA (reserved) +FB +FC +FD +FE xx primitive xx +FF extended op diff --git a/ase/test/stx/test.st b/ase/test/stx/test.st index 54e8141d..630fe87f 100644 --- a/ase/test/stx/test.st +++ b/ase/test/stx/test.st @@ -14,4 +14,5 @@ perform: method with: x with: y with: z with: a1 with: b2 with: c2 "Win32Errors := 10." (jjj xxx: 10 xy) zzz: (10 fuck: 20 you: 40) yyy: kkk. - [ spec plus: 20] + [ spec plus: 20]. + ^10.