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

Implement basics of first subtask

parent efb5605c
No related branches found
No related tags found
1 merge request!4Task 3 odevzdání
#pragma once
#include "bc_compiler.c"
#include "bc_compiler.h"
#include <assert.h>
 
void string_init ( String * str ) {
str -> capacity = 1000;
str -> capacity = INIT_STRING_LENGTH;
str -> len = 0;
str -> str = (u8*) malloc ( 1000 );
str -> str = (u8*) malloc ( INIT_STRING_LENGTH );
}
 
void string_destroy ( String * str ) {
free ( str -> str );
}
 
void ast_to_bc ( Ast * ast ) {
void string_write_byte ( String * str, const u8 data ) {
if ( str -> capacity == str -> len ) {
u8 * tmp = (u8*) malloc ( str -> capacity * 2 );
assert ( tmp );
memcpy ( tmp, str -> str, str -> len );
free ( str -> str );
str -> str = tmp;
str -> capacity *= 2;
}
str -> str [ str -> len ++ ] = data;
}
void string_write_u16 ( String * str, const u16 data ) {
string_write_byte ( str, data & 255 );
string_write_byte ( str, data >> 8 );
}
void string_write_i32 ( String * str, const i32 data ) {
string_write_byte ( str, data & 255 );
string_write_byte ( str, (data >> 8) & 255 );
string_write_byte ( str, (data >> 16) & 255 );
string_write_byte ( str, (data >> 24) & 255 );
}
BCConstant create_function ( u8 parameters ) {
BCFunction function = (BCFunction) { .parameters = parameters, .locals = 0 };
string_init ( & function . bc );
return (BCConstant) { .kind = CONSTANT_FUNCTION, .function = function };
}
LocalScope * create_function_scope ( u8 parameters ) {
LocalScope * scope = (LocalScope*) malloc ( sizeof (LocalScope*) + sizeof (u32) + sizeof (Str) * parameters );
scope -> locals [ 0 ] = STR ( "this" );
scope -> used_locals = 1;
return scope;
}
u16 get_string_index ( BCCompilerState * state, Str str ) {
u16 i;
for ( i = 0; i < state -> constants . constant_count; ++i )
if ( state -> constants . constants [ i ] . kind == CONSTANT_STRING && str_eq ( state -> constants . constants [ i ] . string, str ) );
return i;
insert_constant ( state, (BCConstant) { .kind = CONSTANT_STRING, .string = str } );
return i;
}
void gen_bc_constant ( BCCompilerState * state, u16 index ) {
BCFunction * function = & state -> constants . constants [ state -> fp ];
string_write_byte ( function -> bc, 0x01 );
string_write_u16 ( function -> bc, index );
}
void insert_constant ( BCCompilerState * state, BCConstant constant ) {
state -> constants . constants [ state -> constants . constant_count ++ ] = constant;
}
void bc_state_init ( BCCompilerState * state ) {
state -> constants . constant_count = 0;
state -> constants . null_pos = -1;
state -> constants . bool_pos [ 0 ] = -1;
state -> constants . bool_pos [ 1 ] = -1;
state -> globals . global_count = 0;
state -> scope = NULL;
//state -> fp = 0;
}
void bc_state_destroy ( BCCompilerState * state ) {
// TODO ( free strings )
}
void ast_to_bc ( BCCompilerState * state, Ast * ast ) {
switch ( ast -> kind ) {
case AST_TOP: {
AstTop * top = (AstTop*) ast;
state -> ep = state -> fp = state -> constants . constant_count;
insert_constant ( state, create_function ( 1 ) );
state -> scope = create_function_scope ( 1 );
state -> scope -> prev = NULL;
state -> scope -> used_locals = 1;
state -> scope -> local_count = 1;
for ( size_t i = 0; i < top -> expression_cnt; ++i )
ast_to_bc ( state, top -> expressions [ i ] );
return;
}
case AST_NULL: {
if ( state -> constants . null_pos < 0 ) {
state -> constants . null_pos = state -> constants . constant_count;
insert_constant ( state, (BCConstant) { .kind = CONSTANT_NULL } );
}
gen_bc_constant ( state, state -> constants . null_pos );
return;
}
case AST_INTEGER: {
AstInteger * integer = (AstInteger*) ast;
u16 i;
for ( i = 0; i < state -> constants . constant_count; ++i )
if ( state -> constants . constants [ i ] . kind == CONSTANT_INTEGER && state -> constants . constants [ i ] . integer == integer -> value );
break;
if ( i == state -> constants . constant_count; ++i )
insert_constant ( state, (BCConstant) { .kind = CONSTANT_INTEGER, .integer = integer -> value } );
gen_bc_constant ( state, i );
}
case AST_BOOLEAN: {
AstBoolean * boolean = (AstBoolean*) ast;
size_t pos = boolean -> value ? 1 : 0;
if ( state -> constants . bool_pos [ pos ] < 0 ) {
state -> constants . bool_pos [ pos ] = state -> constants . constant_count;
insert_constant ( state, (BCConstant) { .kind = CONSTANT_BOOLEAN, .boolean = boolean -> value } );
}
gen_bc_constant ( state, state -> constants . bool_pos [ pos ] );
}
case AST_BLOCK: {
AstBlock * block = (AstBlock*) ast;
// make local scope
LocalScope * scope = (LocalScope*) malloc ( sizeof (LocalScope*) + sizeof (u32) + sizeof (Str) * MAX_SCOPE_VARIABLES );
scope -> local_count = state -> scope -> local_count;
scope -> used_locals = 0;
scope -> prev = state -> scope;
state -> scope = scope;
for ( size_t i = 0; i < top -> expression_cnt; ++i )
ast_to_bc ( state, top -> expressions [ i ] );
// delete local scope
state -> scope = state -> scope -> prev;
free ( scope );
return;
}
case AST_FUNCTION: {
AstFunction * func = (AstFunction*) ast;
LocalScope * old_scope = state -> scope;
u16 old_ep = state -> ep;
state -> ep = state -> fp = state -> constants . constant_count;
insert_constant ( state, create_function ( func -> parameters ) );
state -> scope = create_function_scope ( func -> parameters );
state -> scope -> prev = NULL;
state -> scope -> used_locals = func -> parameters;
state -> scope -> local_count = func -> parameters;
for ( u16 i = 1; i < func -> parameters )
state -> scope -> locals [ i ] = func -> parameters [ i ];
ast_to_bc ( state, func -> body );
free ( state -> scope );
state -> ep = old_ep;
state -> scope = old_scope;
return;
}
case AST_FUNCTION_CALL: {
AstFunctionCall * call = (AstFunctionCall*) ast;
ast_to_bc ( state, call -> function );
for ( size_t i = 0; i < call -> argument_cnt; ++i )
ast_to_bc ( state, call -> arguments [ i ] );
BCFunction * function = & state -> constants . constants [ state -> fp ];
string_write_byte ( & function -> bc, 0x08 );
string_write_byte ( & function -> bc, call -> argument_cnt & 255 );
return;
}
case AST_PRINT: {
AstPrint * print = (AstPrint*) ast;
u16 index = get_string_index ( state, print -> format );
for ( size_t i = 0; i < print -> argument_cnt; ++i )
ast_to_bc ( state, print -> arguments [ i ] );
BCFunction * function = & state -> constants . constants [ state -> fp ];
string_write_byte ( & function -> bc, 0x02 );
string_write_u16 ( & function -> bc, index );
string_write_byte ( & function -> bc, print -> argument_cnt & 255 );
return;
}
default:
assert ( false );
}
}
 
void generate_bc ( Ast * ast, String * bc ) {
String generate_bc ( Ast * ast ) {
// init
BCCompilerState bc_state;
bc_state_init ( & bc_state );
// generate header
 
// generate internals (constants (exp. functions), globals)
ast_to_bc ( ast );
ast_to_bc ( &state, ast );
 
// header
// constants to bc
// globals to bc
// EP
// free
bc_state_init_destroy ( & bc_state );
}
\ No newline at end of file
#pragma once
#include "parser.h"
#include "heap.h"
#include "string.h"
#define INIT_STRING_LENGTH 512
#define MAX_SCOPE_VARIABLES 128
 
typedef struct String {
u32 len;
......@@ -7,17 +12,27 @@ typedef struct String {
u8 * str;
} String;
 
typedef struct Function {
Str name;
typedef struct BCFunction {
u8 parameters;
u16 locals;
String bc;
} Function;
} BCFunction;
 
typedef struct Class {
typedef struct BCClass {
u16 fields;
u16 * indexes;
} Class;
} BCClass;
typedef struct BCConstant {
ConstantType kind;
union {
i32 integer;
bool boolean;
Str string;
BCFunction function;
BCClass class;
};
} BCConstant;
 
void string_init ( String * str );
void string_destroy ( String * str );
......@@ -27,29 +42,42 @@ void string_write_u16 ( String * str, const u16 data );
void string_write_i32 ( String * str, const i32 data );
 
typedef struct Constants {
Str * strings;
i32 * integers;
bool bools [2];
BCConstant constants [ 256 * 256 ];
u16 constant_count;
i32 null_pos;
Function * functions;
Class * classes;
i32 bool_pos [2];
} Constants;
 
typedef struct Globals {
Str * names;
Str names [ 256 * 256 ];
u16 global_count;
} Globals;
 
typedef struct LocalScope {
LocalScope * prev;
Str * names;
u16 * locals;
struct LocalScope * prev;
u16 used_locals;
u32 local_count;
Str locals [];
} LocalScope;
 
typedef struct BCCompilerState {
Constants constants;
Globals globals;
LocalScope scope;
LocalScope * scope;
u16 fp;
u16 ep;
} BCCompilerState;
 
void ast_to_bc ( Ast * ast, String * bc );
void generate_bc ( Ast * ast, String * bc );
\ No newline at end of file
BCConstant create_function ( Str name, u8 parameters );
LocalScope * create_function_scope ( u8 parameters );
u16 get_string_index ( BCCompilerState * state, Str str );
void gen_bc_constant ( BCCompilerState * state, u16 index );
void insert_constant ( BCCompilerState * state, Constant constant );
void bc_state_init ( BCCompilerState * state );
void bc_state_destroy ( BCCompilerState * state );
void ast_to_bc ( BCCompilerState * state, Ast * ast );
void generate_bc ( Ast * ast );
\ No newline at end of file
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