*** empty log message ***
This commit is contained in:
parent
d8b4f8b710
commit
b795ce8408
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: bytecode.c,v 1.4 2005-07-08 11:32:50 bacon Exp $
|
* $Id: bytecode.c,v 1.5 2005-07-10 09:21:46 bacon Exp $
|
||||||
*/
|
*/
|
||||||
#include <xp/stx/bytecode.h>
|
#include <xp/stx/bytecode.h>
|
||||||
#include <xp/stx/class.h>
|
#include <xp/stx/class.h>
|
||||||
@ -33,33 +33,21 @@ static void __decode1 (xp_stx_t* stx, xp_word_t idx, void* data)
|
|||||||
__decode2 (stx, data, method_obj);
|
__decode2 (stx, data, method_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const xp_char_t* opcode_names[] =
|
|
||||||
{
|
|
||||||
XP_TEXT("PUSH_VARIABLE"),
|
|
||||||
XP_TEXT("PUSH_TEMPORARY"),
|
|
||||||
XP_TEXT("PUSH_LITERAL_CONSTANT"),
|
|
||||||
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("PUSH_VARIABLE_EXTENDED"),
|
|
||||||
XP_TEXT("PUSH_TEMPORARY_EXTENDED"),
|
|
||||||
XP_TEXT("STORE_VARIABLE_EXTENDED"),
|
|
||||||
XP_TEXT("STORE_TEMPORARY_EXTENDED"),
|
|
||||||
XP_TEXT("DO_SPECIAL_EXTENDED"),
|
|
||||||
XP_TEXT("DO_PRIMITIVE_EXTENDED")
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __decode2 (xp_stx_t* stx,
|
static int __decode2 (xp_stx_t* stx,
|
||||||
xp_stx_class_t* class_obj, xp_stx_method_t* method_obj)
|
xp_stx_class_t* class_obj, xp_stx_method_t* method_obj)
|
||||||
{
|
{
|
||||||
xp_stx_byte_object_t* bytecodes;
|
xp_stx_byte_object_t* bytecodes;
|
||||||
xp_word_t bytecode_size, pc = 0;
|
xp_word_t bytecode_size, pc = 0;
|
||||||
xp_byte_t code;
|
int code, next;
|
||||||
int opcode, operand;
|
|
||||||
|
static const xp_char_t* stack_opcode_names[] = {
|
||||||
|
XP_TEXT("push_receiver_variable"),
|
||||||
|
XP_TEXT("push_temporary_location"),
|
||||||
|
XP_TEXT("push_literal_constant"),
|
||||||
|
XP_TEXT("push_literal_variable"),
|
||||||
|
XP_TEXT("store_receiver_variable"),
|
||||||
|
XP_TEXT("store_temporary_location")
|
||||||
|
};
|
||||||
|
|
||||||
bytecodes = XP_STX_BYTE_OBJECT(stx, method_obj->bytecodes);
|
bytecodes = XP_STX_BYTE_OBJECT(stx, method_obj->bytecodes);
|
||||||
bytecode_size = XP_STX_SIZE(stx, method_obj->bytecodes);
|
bytecode_size = XP_STX_SIZE(stx, method_obj->bytecodes);
|
||||||
@ -67,23 +55,36 @@ static int __decode2 (xp_stx_t* stx,
|
|||||||
while (pc < bytecode_size) {
|
while (pc < bytecode_size) {
|
||||||
code = bytecodes->data[pc++];
|
code = bytecodes->data[pc++];
|
||||||
|
|
||||||
opcode = (code & 0xF0) >> 4;
|
if (code >= 0x00 && code <= 0x5F) {
|
||||||
operand = code & 0x0F;
|
/* stack */
|
||||||
if (opcode > 0x9) {
|
xp_printf (XP_TEXT("%s %d\n"),
|
||||||
if (pc >= bytecode_size) {
|
stack_opcode_names[code >> 4], code & 0x0F);
|
||||||
/* TODO: */
|
|
||||||
xp_printf (XP_TEXT("error in bytecodes\n"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
code = bytecodes->data[pc++];
|
|
||||||
operand |= (code << 4);
|
|
||||||
}
|
}
|
||||||
|
else if (code >= 0x60 && code <= 0x65) {
|
||||||
|
/* stack extended */
|
||||||
|
next = bytecodes->data[pc++];
|
||||||
|
xp_printf (XP_TEXT("%s %d\n"),
|
||||||
|
stack_opcode_names[code & 0x0F], next);
|
||||||
|
}
|
||||||
|
else if (code >= 0x70 && code <= 0x73 ) {
|
||||||
|
/* send */
|
||||||
|
}
|
||||||
|
else if (code >= 0x78 && code <= 0x7D) {
|
||||||
|
// return
|
||||||
|
}
|
||||||
|
else if (code >= 0x80 && code <= 0x8F) {
|
||||||
|
// jump
|
||||||
|
}
|
||||||
|
else if (code >= 0xF0 && code <= 0xFF) {
|
||||||
|
// primitive
|
||||||
|
next = bytecodes->data[pc++];
|
||||||
|
xp_printf (XP_TEXT("do_primitive %d\n"), ((code & 0x0F) << 8) | next);
|
||||||
|
|
||||||
xp_printf (XP_TEXT("%s(0x%x), operand = %d\n"),
|
}
|
||||||
opcode_names[opcode], opcode, operand);
|
else {
|
||||||
|
xp_printf (XP_TEXT("unknown byte code 0x%x\n"), code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: bytecode.h,v 1.6 2005-07-10 03:16:40 bacon Exp $
|
* $Id: bytecode.h,v 1.7 2005-07-10 09:21:46 bacon Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _XP_STX_BYTECODE_H_
|
#ifndef _XP_STX_BYTECODE_H_
|
||||||
@ -24,10 +24,10 @@
|
|||||||
#define DUPLICATE_POP_STACK_TOP 0x69
|
#define DUPLICATE_POP_STACK_TOP 0x69
|
||||||
#define PUSH_ACTIVE_CONTEXT 0x6A
|
#define PUSH_ACTIVE_CONTEXT 0x6A
|
||||||
|
|
||||||
#define SEND_SELECTOR_TO_SELF 0x70
|
#define SEND_TO_SELF 0x70
|
||||||
#define SEND_SELECTOR_TO_SUPER 0x71
|
#define SEND_TO_SUPER 0x71
|
||||||
#define SEND_SELECTOR_TO_SELF_EXTENDED 0x72
|
#define SEND_TO_SELF_EXTENDED 0x72
|
||||||
#define SEND_SELECTOR_TO_SUPER_EXTENDED 0x73
|
#define SEND_TO_SUPER_EXTENDED 0x73
|
||||||
|
|
||||||
#define RETURN_RECEIVER 0x78
|
#define RETURN_RECEIVER 0x78
|
||||||
#define RETURN_TRUE 0x79
|
#define RETURN_TRUE 0x79
|
||||||
@ -36,29 +36,7 @@
|
|||||||
#define RETURN_FROM_MESSAGE 0x7C
|
#define RETURN_FROM_MESSAGE 0x7C
|
||||||
#define RETURN_FROM_BLOCK 0x7D
|
#define RETURN_FROM_BLOCK 0x7D
|
||||||
|
|
||||||
#define PUSH_VARIABLE 0x0
|
#define DO_PRIMITIVE 0xF0
|
||||||
#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 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
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
222
ase/stx/parser.c
222
ase/stx/parser.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: parser.c,v 1.60 2005-07-10 03:16:40 bacon Exp $
|
* $Id: parser.c,v 1.61 2005-07-10 09:21:46 bacon Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xp/stx/parser.h>
|
#include <xp/stx/parser.h>
|
||||||
@ -115,12 +115,6 @@ void xp_stx_parser_close (xp_stx_parser_t* parser)
|
|||||||
if (parser->__malloced) xp_free (parser);
|
if (parser->__malloced) xp_free (parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EMIT_CODE_TEST(parser,high,low) \
|
|
||||||
do { if (__emit_code_test(parser,high,low) == -1) return -1; } while (0)
|
|
||||||
|
|
||||||
#define EMIT_CODE(parser,code) \
|
|
||||||
do { if (__emit_code(parser,code) == -1) return -1; } while(0)
|
|
||||||
|
|
||||||
#define GET_CHAR(parser) \
|
#define GET_CHAR(parser) \
|
||||||
do { if (__get_char(parser) == -1) return -1; } while (0)
|
do { if (__get_char(parser) == -1) return -1; } while (0)
|
||||||
#define UNGET_CHAR(parser,c) \
|
#define UNGET_CHAR(parser,c) \
|
||||||
@ -241,6 +235,69 @@ static INLINE xp_bool_t __is_closing_char (xp_cint_t c)
|
|||||||
c == XP_CHAR('\"') || c == XP_CHAR('\'');
|
c == XP_CHAR('\"') || c == XP_CHAR('\'');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define EMIT_CODE_TEST(parser,high,low) \
|
||||||
|
do { if (__emit_code_test(parser,high,low) == -1) return -1; } while (0)
|
||||||
|
|
||||||
|
#define EMIT_CODE(parser,code) \
|
||||||
|
do { if (__emit_code(parser,code) == -1) return -1; } while(0)
|
||||||
|
|
||||||
|
#define EMIT_PUSH_RECEIVER_VARIABLE(parser,pos) \
|
||||||
|
do { \
|
||||||
|
if (__emit_stack_positional ( \
|
||||||
|
parser, PUSH_RECEIVER_VARIABLE, pos) == -1) return -1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define EMIT_PUSH_TEMPORARY_LOCATION(parser,pos) \
|
||||||
|
do { \
|
||||||
|
if (__emit_stack_positional ( \
|
||||||
|
parser, PUSH_TEMPORARY_LOCATION, pos) == -1) return -1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define EMIT_PUSH_LITERAL_CONSTANT(parser,pos) \
|
||||||
|
do { \
|
||||||
|
if (__emit_stack_positional ( \
|
||||||
|
parser, PUSH_LITERAL_CONSTANT, pos) == -1) return -1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
#define EMIT_PUSH_LITERAL_VARIABLE(parser,pos) \
|
||||||
|
do { \
|
||||||
|
if (__emit_stack_positional ( \
|
||||||
|
parser, PUSH_LITERAL_VARIABLE, pos) == -1) return -1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define EMIT_STORE_RECEIVER_VARIABLE(parser,pos) \
|
||||||
|
do { \
|
||||||
|
if (__emit_stack_positional ( \
|
||||||
|
parser, STORE_RECEIVER_VARIABLE, pos) == -1) return -1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define EMIT_STORE_TEMPORARY_LOCATION(parser,pos) \
|
||||||
|
do { \
|
||||||
|
if (__emit_stack_positional ( \
|
||||||
|
parser, STORE_TEMPORARY_LOCATION, pos) == -1) return -1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
#define EMIT_POP_STACK_TOP(parser) EMIT_CODE(parser, POP_STACK_TOP)
|
||||||
|
#define EMIT_DUPLICATE_STACK_TOP(parser) EMIT_CODE(parser, DUPLICATE_STACK_TOP)
|
||||||
|
#define EMIT_PUSH_ACTIVE_CONTEXT(parser) EMIT_CODE(parser, PUSH_ACTIVE_CONTEXT)
|
||||||
|
#define EMIT_RETURN_FROM_MESSAGE(parser) EMIT_CODE(parser, RETURN_FROM_MESSAGE)
|
||||||
|
#define EMIT_RETURN_FROM_BLOCK(parser) EMIT_CODE(parser, RETURN_FROM_BLOCK)
|
||||||
|
|
||||||
|
#define EMIT_SEND_TO_SELF(parser,selector,nargs) \
|
||||||
|
do { \
|
||||||
|
if (__emit_send_to_self(parser,selector,nargs) == -1) return -1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define EMIT_SEND_TO_SUPER(parser,selector,nargs) \
|
||||||
|
do { \
|
||||||
|
if (__emit_send_to_super(parser,selector,nargs) == -1) return -1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define EMIT_DO_PRIMITIVE(parser,no) \
|
||||||
|
do { if (__emit_do_primitive(parser,no) == -1) return -1; } while(0)
|
||||||
|
|
||||||
static INLINE int __emit_code_test (
|
static INLINE int __emit_code_test (
|
||||||
xp_stx_parser_t* parser, const xp_char_t* high, const xp_char_t* low)
|
xp_stx_parser_t* parser, const xp_char_t* high, const xp_char_t* low)
|
||||||
{
|
{
|
||||||
@ -258,73 +315,44 @@ static INLINE int __emit_code (xp_stx_parser_t* parser, xp_byte_t code)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE int __emit_stack_code_positional (
|
static INLINE int __emit_stack_positional (
|
||||||
xp_stx_parser_t* parser, int opcode, int pos)
|
xp_stx_parser_t* parser, int opcode, int pos)
|
||||||
{
|
{
|
||||||
static int mapping[] = {
|
xp_assert (pos < 0xFF);
|
||||||
PUSH_RECEIVER_VARIABLE_EXTENDED,
|
|
||||||
PUSH_TEMPORARY_LOCATION_EXTENDED,
|
|
||||||
PUSH_LITERAL_CONSTANT_EXTENDED,
|
|
||||||
PUSH_LITERAL_VARIABLE_EXTENDED,
|
|
||||||
STORE_RECEIVER_VARIABLE,
|
|
||||||
STORE_TEMPORARY_VARIABLE
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE int __emit_push_receiver_variable (xp_stx_parser_t* parser, int pos)
|
if (pos <= 0x0F) {
|
||||||
{
|
EMIT_CODE (parser, (opcode & 0xF0) | (pos & 0x0F));
|
||||||
if (pos > 0x0F) {
|
|
||||||
EMIT_CODE (parser, PUSH_RECEIVER_VARIABLE | (pos & 0x0F));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
EMIT_CODE (parser, PUSH_RECEIVER_VARIABLE_EXTENDED);
|
EMIT_CODE (parser, (opcode >> 4) & 0x6F);
|
||||||
EMIT_CODE (parser, pos & 0xFF)
|
EMIT_CODE (parser, pos & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE int __emit_push_temporary_location (xp_stx_parser_t* parser, int pos)
|
static INLINE int __emit_send_to_self (
|
||||||
|
xp_stx_parser_t* parser, int selector, int nargs)
|
||||||
{
|
{
|
||||||
if (pos > 0x0F) {
|
xp_assert (selector >= 0x00 && selector <= 0xFF);
|
||||||
EMIT_CODE (parser, PUSH_TEMPORARY_LOCATION | (pos & 0x0F));
|
xp_assert (nargs >= 0x00 nargs <= 0xFF);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
EMIT_CODE (parser, PUSH_RECEIVER_VARIABLE_EXTENDED);
|
static INLINE int __emit_send_to_super (
|
||||||
EMIT_CODE (parser, pos & 0xFF)
|
xp_stx_parser_t* parser, int selector, int nargs)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE int __emit_do_primitive (xp_stx_parser_t* parser, int no)
|
||||||
|
{
|
||||||
|
xp_assert (no >= 0x0 && no <= 0xFFF);
|
||||||
|
|
||||||
|
EMIT_CODE (parser, DO_PRIMITIVE & ((no >> 8) & 0x0F));
|
||||||
|
EMIT_CODE (parser, no & 0xFF);
|
||||||
|
|
||||||
return 0;
|
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 (
|
int xp_stx_parser_parse_method (
|
||||||
xp_stx_parser_t* parser, xp_word_t method_class, void* input)
|
xp_stx_parser_t* parser, xp_word_t method_class, void* input)
|
||||||
{
|
{
|
||||||
@ -615,20 +643,12 @@ static int __parse_primitive (xp_stx_parser_t* parser)
|
|||||||
}
|
}
|
||||||
|
|
||||||
XP_STRTOI (prim_no, parser->token.name.buffer, XP_NULL, 10);
|
XP_STRTOI (prim_no, parser->token.name.buffer, XP_NULL, 10);
|
||||||
if (prim_no < 0 || prim_no > 0x0FFF) {
|
if (prim_no < 0 || prim_no > 0xFF) {
|
||||||
parser->error_code = XP_STX_PARSER_ERROR_PRIMITIVE_NUMBER_RANGE;
|
parser->error_code = XP_STX_PARSER_ERROR_PRIMITIVE_NUMBER_RANGE;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prim_no <= 0x0F) {
|
EMIT_DO_PRIMITIVE (parser, prim_no);
|
||||||
EMIT_CODE_TEST (parser, XP_TEXT("DO_PRIMITIVE"), parser->token.name.buffer);
|
|
||||||
EMIT_CODE (parser, (DO_PRIMITIVE << 4) | prim_no);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
EMIT_CODE_TEST (parser, XP_TEXT("DO_PRIMITIVE_EXTENDED"), parser->token.name.buffer);
|
|
||||||
EMIT_CODE (parser, (DO_PRIMITIVE_EXTENDED << 4) | (prim_no & 0x0F));
|
|
||||||
EMIT_CODE (parser, prim_no >> 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
GET_TOKEN (parser);
|
GET_TOKEN (parser);
|
||||||
if (!__is_primitive_closer(&parser->token)) {
|
if (!__is_primitive_closer(&parser->token)) {
|
||||||
@ -691,17 +711,7 @@ static int __parse_statement (xp_stx_parser_t* parser)
|
|||||||
if (parser->token.type == XP_STX_TOKEN_RETURN) {
|
if (parser->token.type == XP_STX_TOKEN_RETURN) {
|
||||||
GET_TOKEN (parser);
|
GET_TOKEN (parser);
|
||||||
if (__parse_expression(parser) == -1) return -1;
|
if (__parse_expression(parser) == -1) return -1;
|
||||||
|
EMIT_RETURN_FROM_MESSAGE (parser);
|
||||||
/* 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 {
|
else {
|
||||||
if (__parse_expression(parser) == -1) return -1;
|
if (__parse_expression(parser) == -1) return -1;
|
||||||
@ -779,40 +789,16 @@ static int __parse_assignment (
|
|||||||
|
|
||||||
for (i = parser->argument_count; i < parser->temporary_count; i++) {
|
for (i = parser->argument_count; i < parser->temporary_count; i++) {
|
||||||
if (xp_strcmp (target, parser->temporaries[i]) == 0) {
|
if (xp_strcmp (target, parser->temporaries[i]) == 0) {
|
||||||
xp_char_t buf[100];
|
|
||||||
if (__parse_expression(parser) == -1) return -1;
|
if (__parse_expression(parser) == -1) return -1;
|
||||||
xp_sprintf (buf, xp_countof(buf), XP_TEXT("%d"), i);
|
EMIT_STORE_TEMPORARY_LOCATION (parser, i);
|
||||||
if (i <= 0x0F) {
|
|
||||||
EMIT_CODE_TEST (parser, XP_TEXT("STORE_TEMPORARY"), buf);
|
|
||||||
EMIT_CODE (parser, (STORE_TEMPORARY << 4) | i);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
EMIT_CODE_TEST (parser, XP_TEXT("STORE_TEMPORARY_EXTENDED"), buf);
|
|
||||||
EMIT_CODE (parser, (STORE_TEMPORARY_EXTENDED << 4) | (i & 0x0F));
|
|
||||||
EMIT_CODE (parser, i >> 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xp_stx_get_instance_variable_index (
|
if (xp_stx_get_instance_variable_index (
|
||||||
stx, parser->method_class, target, &i) == 0) {
|
stx, parser->method_class, target, &i) == 0) {
|
||||||
xp_char_t buf[100];
|
|
||||||
if (__parse_expression(parser) == -1) return -1;
|
if (__parse_expression(parser) == -1) return -1;
|
||||||
xp_sprintf (buf, xp_countof(buf), XP_TEXT("%d"), i);
|
EMIT_STORE_RECEIVER_VARIABLE (parser, i);
|
||||||
|
|
||||||
/* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -822,6 +808,7 @@ xp_sprintf (buf, xp_countof(buf), XP_TEXT("%d"), i);
|
|||||||
|
|
||||||
/* TODO */
|
/* TODO */
|
||||||
EMIT_CODE_TEST (parser, XP_TEXT("ASSIGN_CLASSVAR #"), target);
|
EMIT_CODE_TEST (parser, XP_TEXT("ASSIGN_CLASSVAR #"), target);
|
||||||
|
//EMIT_STORE_CLASS_VARIABLE (parser, target);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,7 +830,7 @@ static int __parse_primary (xp_stx_parser_t* parser, const xp_char_t* ident)
|
|||||||
|
|
||||||
if (ident == XP_NULL) {
|
if (ident == XP_NULL) {
|
||||||
if (parser->token.type == XP_STX_TOKEN_IDENT) {
|
if (parser->token.type == XP_STX_TOKEN_IDENT) {
|
||||||
if (__parse_primary_ident (parser, parser->token.buffer) == -1) return -1;
|
if (__parse_primary_ident(parser, parser->token.name.buffer) == -1) return -1;
|
||||||
GET_TOKEN (parser);
|
GET_TOKEN (parser);
|
||||||
}
|
}
|
||||||
else if (parser->token.type == XP_STX_TOKEN_CHARLIT) {
|
else if (parser->token.type == XP_STX_TOKEN_CHARLIT) {
|
||||||
@ -884,7 +871,7 @@ static int __parse_primary (xp_stx_parser_t* parser, const xp_char_t* ident)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (__parse_primary_ident (parser, parser->token.buffer) == -1) return -1;
|
if (__parse_primary_ident(parser, parser->token.name.buffer) == -1) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -893,27 +880,34 @@ 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_primary_ident (xp_stx_parser_t* parser, const xp_char_t* ident)
|
||||||
{
|
{
|
||||||
xp_word_t i;
|
xp_word_t i;
|
||||||
|
xp_stx_t* stx = parser->stx;
|
||||||
|
|
||||||
/* Refer to __parse_assignment for identifier lookup */
|
/* Refer to __parse_assignment for identifier lookup */
|
||||||
|
|
||||||
for (i = 0; i < parser->temporary_count; i++) {
|
for (i = 0; i < parser->temporary_count; i++) {
|
||||||
if (xp_strcmp (target, parser->temporaries[i]) == 0) {
|
if (xp_strcmp(ident, parser->temporaries[i]) == 0) {
|
||||||
EMIT_CODE_1 (parser, PUSH_TEMPORARY_VARIABLE, i);
|
EMIT_PUSH_TEMPORARY_LOCATION (parser, i);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xp_stx_get_instance_variable_index (
|
if (xp_stx_get_instance_variable_index (
|
||||||
stx, parser->method_class, target, &i) == 0) {
|
stx, parser->method_class, ident, &i) == 0) {
|
||||||
EMIT_CODE_1 (parser, PUSH_RECEIVER_VARIABLE, i);
|
EMIT_PUSH_RECEIVER_VARIABLE (parser, i);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: what is the best way to look up a class variable? */
|
||||||
|
/* 1. Use the class containing it and using its position */
|
||||||
|
/* 2. Use a primitive method after pushing the name as a symbol */
|
||||||
|
/* 3. Implement a vm instruction to do it */
|
||||||
|
/*
|
||||||
if (xp_stx_lookup_class_variable (
|
if (xp_stx_lookup_class_variable (
|
||||||
stx, parser->method_class, target) != stx->nil) {
|
stx, parser->method_class, ident) != stx->nil) {
|
||||||
//PUSH_CLASS_VARIABLE
|
//EMIT_LOOKUP_CLASS_VARIABLE (parser, ident);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/* TODO: IMPLEMENT POOL DICTIONARIES */
|
/* TODO: IMPLEMENT POOL DICTIONARIES */
|
||||||
|
|
||||||
|
159
ase/stx/stx.txt
159
ase/stx/stx.txt
@ -36,141 +36,6 @@ SEE ALSO
|
|||||||
xpkit(7)
|
xpkit(7)
|
||||||
|
|
||||||
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
/*
|
|
||||||
&unsupportedByte, //--- 00
|
|
||||||
&bytePushInstance, //--- 01
|
|
||||||
&bytePushArgument, //--- 02
|
|
||||||
&bytePushTemporary, //--- 03
|
|
||||||
&bytePushLiteral, //--- 04
|
|
||||||
&bytePushConstant, //--- 05
|
|
||||||
&byteAssignInstance, //--- 06
|
|
||||||
&byteAssignTemporary, //--- 07
|
|
||||||
&byteMarkArguments, //--- 08
|
|
||||||
&byteSendMessage, //--- 09
|
|
||||||
&byteSendUnary, //--- 10
|
|
||||||
&byteSendBinary, //--- 11
|
|
||||||
&unsupportedByte, //--- 12
|
|
||||||
&byteDoPrimitive, //--- 13
|
|
||||||
&unsupportedByte, //--- 14
|
|
||||||
&byteDoSpecial //--- 15
|
|
||||||
|
|
||||||
|
|
||||||
* Directly access by byte codes
|
|
||||||
> the receiver and arguments of the invoking message
|
|
||||||
> the values of the receiver's instance variables
|
|
||||||
> the values of any temporary variables required by the method
|
|
||||||
> seven special constants (true, false, nil, -1, 0, 1, and 2)
|
|
||||||
> 32 special message selectors
|
|
||||||
|
|
||||||
* contained in literal frame.
|
|
||||||
> shared variables (global, class, and pool)
|
|
||||||
> most literal constants (numbers, characters, strings, arrays, and symbols)
|
|
||||||
> most message selectors (those that are not special)
|
|
||||||
|
|
||||||
PushInstance
|
|
||||||
PushArgument -> normal arguments plus self/super(0)
|
|
||||||
PushTemporary
|
|
||||||
PushConstant -> nil, true, false, etc....
|
|
||||||
PushLiteral -> global variables, literal constants... -> access literal frame
|
|
||||||
|
|
||||||
AssignInstance
|
|
||||||
AssignTemporary
|
|
||||||
*/
|
|
||||||
|
|
||||||
Pocket Smalltalk
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
-- stack bytecodes --
|
-- stack bytecodes --
|
||||||
0 0000 XXXX push_receiver_variable
|
0 0000 XXXX push_receiver_variable
|
||||||
1 0001 XXXX push_temporary_location
|
1 0001 XXXX push_temporary_location
|
||||||
@ -184,22 +49,22 @@ FF extended op
|
|||||||
0110 0011 XXXXXXXX push_literal_variable_extended
|
0110 0011 XXXXXXXX push_literal_variable_extended
|
||||||
0110 0100 XXXXXXXX store_receiver_variable_extended
|
0110 0100 XXXXXXXX store_receiver_variable_extended
|
||||||
0110 0101 XXXXXXXX store_temporary_location_extended
|
0110 0101 XXXXXXXX store_temporary_location_extended
|
||||||
0110 0110 XXXXXXXX unused
|
0110 0110 unused
|
||||||
0110 0111 XXXXXXXX unused
|
0110 0111 unused
|
||||||
0110 1000 pop_stack_top
|
0110 1000 pop_stack_top
|
||||||
0110 1001 duplicate_stack_top
|
0110 1001 duplicate_stack_top
|
||||||
0110 1010 push_active_context
|
0110 1010 push_active_context
|
||||||
0110 1011 XXXXXXXX unused
|
0110 1011 unused
|
||||||
0110 1100 XXXXXXXX unused
|
0110 1100 unused
|
||||||
0110 1101 XXXXXXXX unused
|
0110 1101 unused
|
||||||
0110 1110 XXXXXXXX unused
|
0110 1110 unused
|
||||||
0110 1111 XXXXXXXX unused
|
0110 1111 unused
|
||||||
|
|
||||||
-- send bytecodes --
|
-- send bytecodes --
|
||||||
7 0111 0000 JJJKKKKK send_selector_to_self
|
7 0111 0000 JJJKKKKK send_to_self
|
||||||
0111 0001 JJJKKKKK send_selector_to_super
|
0111 0001 JJJKKKKK send_to_super
|
||||||
0111 0010 JJJJJJJJ KKKKKKKK send_selector_to_self_extended
|
0111 0010 JJJJJJJJ KKKKKKKK send_to_self_extended
|
||||||
0111 0011 JJJJJJJJ KKKKKKKK send_selector_to_super_extended
|
0111 0011 JJJJJJJJ KKKKKKKK send_to_super_extended
|
||||||
|
|
||||||
0111 0100 XXXXXXXX
|
0111 0100 XXXXXXXX
|
||||||
0111 0101 XXXXXXXX
|
0111 0101 XXXXXXXX
|
||||||
@ -221,3 +86,5 @@ FF extended op
|
|||||||
8 1000 0XXX jump_forward
|
8 1000 0XXX jump_forward
|
||||||
1000 1XXX XXXXXXXX jump_forward
|
1000 1XXX XXXXXXXX jump_forward
|
||||||
|
|
||||||
|
-- primitive --
|
||||||
|
F 1111 XXXX XXXXXXXX do_primitive
|
||||||
|
@ -10,9 +10,9 @@ perform: method with: x with: y with: z with: a1 with: b2 with: c2
|
|||||||
"
|
"
|
||||||
b := -30 xxx nil this.
|
b := -30 xxx nil this.
|
||||||
"instanceClass := 10."
|
"instanceClass := 10."
|
||||||
selector := 20.
|
|
||||||
"Win32Errors := 10."
|
|
||||||
|
|
||||||
|
selector := 20.
|
||||||
|
"
|
||||||
(jjj xxx: 10 xy) zzz: (10 fuck: 20 you: 40) yyy: kkk.
|
(jjj xxx: 10 xy) zzz: (10 fuck: 20 you: 40) yyy: kkk.
|
||||||
[ spec plus: 20].
|
[ spec plus: 20].
|
||||||
^10.
|
^10."
|
||||||
|
Loading…
Reference in New Issue
Block a user