Skip to content
Snippets Groups Projects
Commit ea000a0e authored by Michal Štěpánek's avatar Michal Štěpánek
Browse files

Implement objects and add naive implementation of arrays (all indexes same value)

parent 93b11e25
No related branches found
No related tags found
Loading
......@@ -71,6 +71,13 @@ void string_write_constant ( String * str, BCConstant constant ) {
string_write_byte ( str, constant . function . bc . str [ i ] );
break;
}
case CONSTANT_CLASS: {
string_write_byte ( str, 0x05 );
string_write_u16 ( str, constant . class . fields );
for ( size_t i = 0; i < constant . class . fields; ++i )
string_write_u16 ( str, constant . class . indexes [ i ] );
break;
}
default:
assert ( false );
break;
......@@ -163,6 +170,40 @@ u16 make_local_index ( BCCompilerState * state, Str name ) {
return *n - 1;
}
 
u16 get_or_make_class ( BCCompilerState * state, AstObject * object ) {
size_t i;
// create class
BCClass created_class = (BCClass) { .fields = object -> member_cnt, .indexes = (u16*) malloc ( sizeof (u16) * object -> member_cnt ) };
AstDefinition * def;
u16 index;
for ( size_t field = 0; field < created_class . fields; ++field ) {
assert ( object -> members [ field ] -> kind == AST_DEFINITION );
def = (AstDefinition*) object -> members [ field ];
index = get_string_index ( state, def -> name );
if ( index == 0 )
index = make_string_index ( state, def -> name );
created_class . indexes [ field ] = index;
for ( size_t prev = 0; prev < field; ++prev )
assert ( ! str_eq ( state -> constants . constants [ created_class . indexes [ prev ] ] . string, state -> constants . constants [ index ] . string ) );
}
// try to find same class as created
for ( i = 0; i < state -> constants . constant_count; ++i )
if ( state -> constants . constants [ i ] . kind == CONSTANT_CLASS ) {
BCClass class = state -> constants . constants [ i ] . class;
if ( class . fields == created_class . fields )
for ( size_t j = 0; j < class . fields; ++j ) {
if ( created_class . indexes [ j ] != class . indexes [ j ] )
continue;
}
}
// destroy created class, if class with same indexes is found nad return it's index, otherwise insert class into pool
if ( i != state -> constants . constant_count )
free ( created_class . indexes );
else
insert_constant ( state, (BCConstant) { .kind = CONSTANT_CLASS, .class = created_class } );
return i;
}
void gen_bc_constant ( BCCompilerState * state, u16 index ) {
BCFunction * function = & state -> constants . constants [ state -> fp ] . function;
string_write_byte ( & function -> bc, 0x01 );
......@@ -196,6 +237,8 @@ void bc_state_destroy ( BCCompilerState * state ) {
BCConstant * constant = & state -> constants . constants [ i ];
if ( constant -> kind == CONSTANT_FUNCTION )
string_destroy ( & constant -> function . bc );
if ( constant -> kind == CONSTANT_CLASS )
free ( constant -> class . indexes );
}
}
 
......@@ -425,6 +468,7 @@ void ast_to_bc ( BCCompilerState * state, Ast * ast ) {
u16 alt_len = cons_pos - alt_pos;
function -> bc . str [ alt_pos - 2 ] = alt_len & 255;
function -> bc . str [ alt_pos - 1 ] = (alt_len >> 8) & 255;
//string_write_byte ( & function -> bc, 0 );
add_scope ( state );
ast_to_bc ( state, cond -> consequent );
remove_scope ( state );
......@@ -444,6 +488,7 @@ void ast_to_bc ( BCCompilerState * state, Ast * ast ) {
string_write_byte ( & function -> bc, 0x0E );
string_write_u16 ( & function -> bc, 0 );
size_t body_pos = function -> bc . len;
//string_write_byte ( & function -> bc, 0x00 );
add_scope ( state );
ast_to_bc ( state, loop -> body );
remove_scope ( state );
......@@ -458,6 +503,97 @@ void ast_to_bc ( BCCompilerState * state, Ast * ast ) {
function -> bc . str [ body_pos - 1 ] = (body_len >> 8) & 255;
return;
}
case AST_OBJECT: {
AstObject * object = (AstObject*) ast;
u16 index = get_or_make_class ( state, object );
// push extends
ast_to_bc ( state, object -> extends );
// push members
AstDefinition * def;
add_scope ( state );
for ( size_t i = 0; i < object -> member_cnt; ++i ) {
def = (AstDefinition*) object -> members [ i ];
ast_to_bc ( state, def -> value );
}
remove_scope ( state );
// push class
BCFunction * function = & state -> constants . constants [ state -> fp ] . function;
string_write_byte ( & function -> bc, 0x04 );
string_write_u16 ( & function -> bc, index );
return;
}
case AST_FIELD_ASSIGNMENT: {
AstFieldAssignment * assign = (AstFieldAssignment*) ast;
BCFunction * function = & state -> constants . constants [ state -> fp ] . function;
ast_to_bc ( state, assign -> object );
ast_to_bc ( state, assign -> value );
u16 index = get_string_index ( state, assign -> field );
if ( index == 0 )
index = make_string_index ( state, assign -> field );
string_write_byte ( & function -> bc, 0x06 );
string_write_u16 ( & function -> bc, index );
return;
}
case AST_FIELD_ACCESS: {
AstFieldAccess * access = (AstFieldAccess*) ast;
BCFunction * function = & state -> constants . constants [ state -> fp ] . function;
ast_to_bc ( state, access -> object );
u16 index = get_string_index ( state, access -> field );
if ( index == 0 )
index = make_string_index ( state, access -> field );
string_write_byte ( & function -> bc, 0x05 );
string_write_u16 ( & function -> bc, index );
return;
}
case AST_METHOD_CALL: {
AstMethodCall * method_call = (AstMethodCall*) ast;
BCFunction * function = & state -> constants . constants [ state -> fp ] . function;
ast_to_bc ( state, method_call -> object );
for ( size_t i = 0; i < method_call -> argument_cnt; ++i )
ast_to_bc ( state, method_call -> arguments [ i ] );
u16 index = get_string_index ( state, method_call -> name );
if ( index == 0 )
index = make_string_index ( state, method_call -> name );
string_write_byte ( & function -> bc, 0x07 );
string_write_u16 ( & function -> bc, index );
string_write_byte ( & function -> bc, method_call -> argument_cnt + 1 );
return;
}
case AST_ARRAY: {
AstArray * array = (AstArray*) ast;
BCFunction * function = & state -> constants . constants [ state -> fp ] . function;
ast_to_bc ( state, array -> size );
ast_to_bc ( state, array -> initializer );
string_write_byte ( & function -> bc, 0x03 );
return;
}
case AST_INDEX_ASSIGNMENT: {
AstIndexAssignment * assign = (AstIndexAssignment*) ast;
BCFunction * function = & state -> constants . constants [ state -> fp ] . function;
ast_to_bc ( state, assign -> object );
ast_to_bc ( state, assign -> index );
ast_to_bc ( state, assign -> value );
u16 index = get_string_index ( state, STR ("set") );
if ( index == 0 )
index = make_string_index ( state, STR ("set") );
string_write_byte ( & function -> bc, 0x07 );
string_write_u16 ( & function -> bc, index );
string_write_byte ( & function -> bc, 3 );
return;
}
case AST_INDEX_ACCESS: {
AstIndexAccess * access = (AstIndexAccess*) ast;
BCFunction * function = & state -> constants . constants [ state -> fp ] . function;
ast_to_bc ( state, access -> object );
ast_to_bc ( state, access -> index );
u16 index = get_string_index ( state, STR ("get") );
if ( index == 0 )
index = make_string_index ( state, STR ("get") );
string_write_byte ( & function -> bc, 0x07 );
string_write_u16 ( & function -> bc, index );
string_write_byte ( & function -> bc, 2 );
return;
}
default:
assert ( false );
}
......
......@@ -82,6 +82,7 @@ void convert_function_to_bc ( BCCompilerState * state, u16 index );
u16 get_string_index ( BCCompilerState * state, Str str );
u16 get_local_index ( BCCompilerState * state, Str name );
u16 make_local_index ( BCCompilerState * state, Str name );
u16 get_or_make_class ( BCCompilerState * state, AstObject * object );
 
void gen_bc_constant ( BCCompilerState * state, u16 index );
void insert_constant ( BCCompilerState * state, BCConstant constant );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment