Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 8 additions & 16 deletions compiler/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,14 @@ void set_current_compiler(Compiler *compiler)
st_current_compiler = compiler;
}

void add_definitions_to_compiler(DefinitionList *definitions)
void add_func_definition_to_compiler(FuncDefinition *func_definition)
{
Compiler *compiler = get_current_compiler();
for (DefinitionList *pos = definitions; pos != NULL; pos = pos->next)
{
switch (pos->definition->kind)
{
case FUNC_DEFINITION:
compiler->func_definition_list = chain_func_definition_list(
compiler->func_definition_list, pos->definition->u.func_d);
break;
case DECLARATION_DEFINITION:
compiler->declaration_list = chain_declaration_list(
compiler->declaration_list, pos->definition->u.declaration);
default:
break;
}
}
compiler->func_definition_list = chain_func_definition_list(compiler->func_definition_list, func_definition);
}

void add_stmt_to_compiler(Statement *stmt)
{
Compiler *compiler = get_current_compiler();
compiler->stmt_list = chain_stmt_list(compiler->stmt_list, stmt);
}
47 changes: 6 additions & 41 deletions compiler/create.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,27 +270,21 @@ ParameterList *chain_parameter(ParameterList *list, ParameterList *parameter)
return list;
}

Definition *alloc_definition(DefinitionKind kind)
{
Definition *definition = (Definition *)malloc(sizeof(Definition));
definition->kind = kind;
return definition;
}

Definition *alloc_func_definition(char *name, ParameterList *parameters, TypeSpecifier *return_type, Block *block)
FuncDefinition *alloc_func_definition(char *name, ParameterList *parameters, TypeSpecifier *return_type, Block *block)
{
FuncDefinition *func_d = (FuncDefinition *)malloc(sizeof(FuncDefinition));
func_d->name = name;
func_d->parameters = parameters;
func_d->return_type = return_type;
if (!return_type)
{
func_d->return_type = alloc_type_specifier(VOID_TYPE);
}
func_d->block = block;
func_d->local_variable_count = 0;
func_d->local_variable = NULL;
func_d->next = NULL;

Definition *definition = alloc_definition(FUNC_DEFINITION);
definition->u.func_d = func_d;
return definition;
return func_d;
}

FuncDefinition *chain_func_definition_list(FuncDefinition *list, FuncDefinition *next)
Expand All @@ -308,35 +302,6 @@ FuncDefinition *chain_func_definition_list(FuncDefinition *list, FuncDefinition
return list;
}

Definition *alloc_declaration_definition(Statement *declaration_stmt)
{
Definition *definition = alloc_definition(DECLARATION_DEFINITION);
definition->u.declaration = declaration_stmt->u.decl_s;
return definition;
}

DefinitionList *alloc_definition_list(Definition *definition)
{
DefinitionList *list = (DefinitionList *)malloc(sizeof(DefinitionList));
list->definition = definition;
list->next = NULL;
return list;
}

DefinitionList *chain_definition_list(DefinitionList *list, Definition *definition)
{
if (list == NULL)
{
list->next = alloc_definition_list(definition);
return list;
}
DefinitionList *pos;
for (pos = list; pos->next; pos = pos->next)
;
pos->next = alloc_definition_list(definition);
return list;
}

Declaration *chain_declaration_list(Declaration *list, Declaration *next)
{
if (list == NULL)
Expand Down
2 changes: 2 additions & 0 deletions compiler/error.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ static ErrorDefinition dkc_error_message_format[] = {
{"字符字面量中包含了2个以上的字符。"},
{"类型转换不匹配。"},
{"函数调用类型不匹配。"},
{"变量声明类型与表达式类型不匹配。"},
{"返回值类型不匹配."},
{"dummy"}};

typedef struct
Expand Down
2 changes: 2 additions & 0 deletions compiler/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ typedef enum
TOO_LONG_CHARACTER_LITERAL_ERR,
TYPE_CAST_MISMATH_ERR,
FUNCTION_CALL_TYPE_MISMATCH_ERR,
DECLARATION_TYPE_MISMATCH_ERR,
RETURN_TYPE_MISMATCH_ERR,
COMPILE_ERROR_COUNT_PLUS_1,
} CompileError;

Expand Down
178 changes: 165 additions & 13 deletions compiler/fix_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,22 @@

extern BuiltinFun *search_builtin_function(char *name);
static Expression *fix_expression(Block *current_block, Expression *expr);
static void fix_statement_list(Block *current_block, StatementList *list, FuncDefinition *fd);

Declaration *
search_declaration(char *identifier, Block *block)
Declaration *search_declaration_in_current_block(char *identifier, Block *block)
{
Declaration *d_pos;
for (d_pos = block->declaration_list; d_pos; d_pos = d_pos->next)
{
if (!strcmp(identifier, d_pos->name))
{
return d_pos;
}
}
return NULL;
}

Declaration *search_declaration(char *identifier, Block *block)
{
Block *b_pos;
Declaration *d_pos;
Expand Down Expand Up @@ -589,6 +602,28 @@ fix_function_call_expression(Block *current_block, Expression *expr)
return expr;
}

static Expression *init_expression(BasicType basic_type)
{
switch (basic_type)
{
case AMOUNT_TYPE:
case INT_TYPE:
return alloc_int_expression(0);
case DOUBLE_TYPE:
return alloc_double_expression(0);
case STRING_TYPE:
case ASSET_TYPE:
case HASH_TYPE:
case PUBKEY_TYPE:
case SIG_TYPE:
case HEX_TYPE:
return alloc_string_expression("");
default:
DBG_assert(0, ("bad case. type..%d\n", basic_type));
}
return NULL;
}

static Expression *
fix_expression(Block *current_block, Expression *expr)
{
Expand Down Expand Up @@ -648,8 +683,9 @@ fix_expression(Block *current_block, Expression *expr)
return expr;
}

static void add_local_variable(FuncDefinition *fd, Declaration *decl,
bool is_parameter)
static void
add_local_variable(FuncDefinition *fd, Declaration *decl,
bool is_parameter)
{
fd->local_variable = realloc(fd->local_variable,
sizeof(Declaration *) * (fd->local_variable_count + 1));
Expand All @@ -663,7 +699,7 @@ add_declaration(Block *current_block, Declaration *decl,
FuncDefinition *fd, int line_number,
bool is_parameter)
{
if (search_declaration(decl->name, current_block))
if (search_declaration_in_current_block(decl->name, current_block))
{
compile_error(line_number,
VARIABLE_MULTIPLE_DEFINE_ERR,
Expand All @@ -686,29 +722,145 @@ add_declaration(Block *current_block, Declaration *decl,
}
}

static void fix_declaration_stmt(Declaration *decl, Block *current_block)
static void
fix_if_statement(Block *current_block, IfStatement *if_s, FuncDefinition *fd)
{
if_s->condition = fix_expression(current_block, if_s->condition);
if (if_s->condition->type->basic_type != BOOLEAN_TYPE)
{
compile_error(if_s->condition->line_number,
IF_CONDITION_NOT_BOOLEAN_ERR,
MESSAGE_ARGUMENT_END);
}

fix_statement_list(if_s->then_block, if_s->then_block->statement_list, fd);

for (Elseif *pos = if_s->elseif_list; pos; pos = pos->next)
{
pos->condition = fix_expression(current_block, pos->condition);
if (pos->block)
{
fix_statement_list(pos->block, pos->block->statement_list, fd);
}
}
if (if_s->else_block)
{
fix_statement_list(if_s->else_block, if_s->else_block->statement_list, fd);
}
}

static void
fix_return_statement(Block *current_block, Statement *statement, FuncDefinition *fd)
{
add_declaration(current_block, decl, NULL, 0, false);
Expression *return_value = fix_expression(current_block, statement->u.expr_s);
if (fd->return_type->basic_type == VOID_TYPE && return_value != NULL)
{
compile_error(statement->line_number,
RETURN_IN_VOID_FUNCTION_ERR,
MESSAGE_ARGUMENT_END);
}
if (fd->return_type->basic_type != VOID_TYPE)
{
if (return_value == NULL || return_value->type->basic_type != fd->return_type->basic_type)
compile_error(statement->line_number,
RETURN_TYPE_MISMATCH_ERR,
MESSAGE_ARGUMENT_END);
}

statement->u.expr_s = return_value;
}

static void
fix_declaration_stmt(Statement *stmt, Block *current_block, FuncDefinition *fd)
{
Declaration *decl = stmt->u.decl_s;
add_declaration(current_block, decl, fd, stmt->line_number, false);
if (decl->initializer)
{
decl->initializer = fix_expression(current_block, decl->initializer);
// decl->initializer = create_assign_cast(decl->initializer, decl->type);
if (!decl->type)
{
decl->type = decl->initializer->type;
}
else if (decl->initializer->kind == INT_EXPRESSION && decl->type->basic_type == DOUBLE_TYPE)
{
decl->initializer->kind = DOUBLE_EXPRESSION;
decl->initializer->type->basic_type = DOUBLE_TYPE;
decl->initializer->u.double_value = decl->initializer->u.int_value;
}
else if (decl->initializer->type->basic_type != decl->type->basic_type)
{
compile_error(stmt->line_number,
DECLARATION_TYPE_MISMATCH_ERR,
MESSAGE_ARGUMENT_END);
}
}
else
{
decl->initializer = init_expression(decl->type->basic_type);
}
}

static void
fix_statement(Block *current_block, Statement *statement, FuncDefinition *fd)
{
switch (statement->kind)
{
case IF_STATEMENT:
fix_if_statement(current_block, statement->u.if_s, fd);
break;
case RETURN_STATEMENT:
fix_return_statement(current_block, statement, fd);
break;
case DECLARATION_STATEMENT:
fix_declaration_stmt(statement, current_block, fd);
break;
default:
DBG_assert(0, ("bad case. kind..%d\n", statement->kind));
}
}

static void
fix_statement_list(Block *current_block, StatementList *list, FuncDefinition *fd)
{
StatementList *pos;

for (pos = list; pos; pos = pos->next)
{
fix_statement(current_block, pos->statement, fd);
}
}

static void
add_parameter_as_declaration(FuncDefinition *fd)
{
Declaration *decl;
ParameterList *param;

for (param = fd->parameters; param; param = param->next)
{
decl = alloc_declaration(param->name, param->type, NULL);
if (fd->block)
{
add_declaration(fd->block, decl, fd, param->line_number, true);
}
}
}

static void fix_function(FuncDefinition *fd)
{
add_parameter_as_declaration(fd);
if (fd->block)
{
fix_statement_list(fd->block, fd->block->statement_list, fd);
}
}

void fix_tree(Compiler *compiler)
{
FuncDefinition *func_pos;
Declaration *decl_pos;

for (decl_pos = compiler->declaration_list; decl_pos; decl_pos = decl_pos->next)
{
fix_declaration_stmt(decl_pos, NULL);
}
fix_statement_list(NULL, compiler->stmt_list, NULL);

for (func_pos = compiler->func_definition_list; func_pos; func_pos = func_pos->next)
{
Expand Down
Loading