fincsys.c
来自「FinC编译器源代码」· C语言 代码 · 共 2,013 行 · 第 1/4 页
C
2,013 行
#include <finc/fincsys.h>#include <finc/finclang.h>#include <finc/finccontext.h>#include <finc/fincnode.h>#include <finc/finclib.h>#define FinC_ERROR printf/* Declarators */void finc_sys_global (FinCNode* p_node);void finc_sys_local (FinCNode* p_node);/* Low-level functions */void finc_sys_addr_of (FinCNode* p_node);void finc_sys_value_of (FinCNode* p_node);void finc_sys_access (FinCNode* p_node);/* Assignement */void finc_sys_assign (FinCNode* p_node);void finc_sys_cast (FinCNode* p_node);/* Logic */void finc_sys_logic_or (FinCNode* p_node);void finc_sys_logic_and (FinCNode* p_node);void finc_sys_not ( FinCNode* p_node );void finc_sys_or (FinCNode* p_node);void finc_sys_and (FinCNode* p_node);void finc_sys_xor (FinCNode* p_node);void finc_sys_bitwise (FinCNode* p_node);void finc_sys_shl (FinCNode* p_node);void finc_sys_shr (FinCNode* p_node);/* Mathematics */void finc_sys_add (FinCNode* p_node);void finc_sys_sub (FinCNode* p_node);void finc_sys_mul (FinCNode* p_node);void finc_sys_div (FinCNode* p_node);void finc_sys_mod (FinCNode* p_node);void finc_sys_inc (FinCNode* p_node);void finc_sys_dec (FinCNode* p_node);void finc_sys_preinc (FinCNode* p_node);void finc_sys_predec (FinCNode* p_node);/* Flow control */void finc_sys_block (FinCNode* p_node);void finc_sys_if (FinCNode* p_node);void finc_sys_for (FinCNode* p_node);void finc_sys_while (FinCNode* p_node);void finc_sys_return (FinCNode* p_node);void finc_sys_break (FinCNode* p_node);void finc_sys_continue (FinCNode* p_node);/* Comparaisons */void finc_sys_cmp_l (FinCNode* p_node);void finc_sys_cmp_g (FinCNode* p_node);void finc_sys_cmp_le (FinCNode* p_node);void finc_sys_cmp_ge (FinCNode* p_node);void finc_sys_cmp_ne (FinCNode* p_node);void finc_sys_cmp_e (FinCNode* p_node);/* Language control */void finc_sys_import (FinCNode* p_node);void finc_sys_array (FinCNode* p_node);void finc_sys_condition (FinCNode* p_node);void finc_sys_comma (FinCNode* p_node);void finc_sys_negative( FinCNode* p_node );FinCSys* finc_sys_new(){ FinCSys* self; self = (FinCSys*)mem_new(sizeof(FinCSys)); self->env = NULL; object_init_object((Object*)self, finc_sys_destroy); return self;}void finc_sys_destroy(Object* self){ unref( ((FinCSys*)self)->env ); mem_destroy(self);}void finc_sys_init (FinCSys* self){ /* Declarators */ finc_context_add_func_sys ( g_finc_context, "global", finc_sys_global ); finc_context_add_func_sys ( g_finc_context, "local", finc_sys_local ); finc_context_add_func_sys ( g_finc_context, "cast", finc_sys_cast ); finc_context_add_func_sys ( g_finc_context, "addr_of", finc_sys_addr_of ); finc_context_add_func_sys ( g_finc_context, "value_of", finc_sys_value_of ); finc_context_add_func_sys ( g_finc_context, ".", finc_sys_access ); finc_context_add_func_sys ( g_finc_context, "||", finc_sys_logic_or ); finc_context_add_func_sys ( g_finc_context, "&&", finc_sys_logic_and ); finc_context_add_func_sys ( g_finc_context, "!", finc_sys_not ); finc_context_add_func_sys ( g_finc_context, "|", finc_sys_or ); finc_context_add_func_sys ( g_finc_context, "&", finc_sys_and ); finc_context_add_func_sys ( g_finc_context, "^", finc_sys_xor ); finc_context_add_func_sys ( g_finc_context, "~", finc_sys_bitwise ); finc_context_add_func_sys ( g_finc_context, "<<", finc_sys_shl ); finc_context_add_func_sys ( g_finc_context, ">>", finc_sys_shr ); finc_context_add_func_sys ( g_finc_context, ",", finc_sys_comma ); finc_context_add_func_sys ( g_finc_context, "?", finc_sys_condition ); finc_context_add_func_sys ( g_finc_context, "+", finc_sys_add ); finc_context_add_func_sys ( g_finc_context, "-", finc_sys_sub ); finc_context_add_func_sys ( g_finc_context, "*", finc_sys_mul ); finc_context_add_func_sys ( g_finc_context, "/", finc_sys_div ); finc_context_add_func_sys ( g_finc_context, "%", finc_sys_mod ); finc_context_add_func_sys ( g_finc_context, "negative", finc_sys_negative ); finc_context_add_func_sys ( g_finc_context, "++", finc_sys_inc ); finc_context_add_func_sys ( g_finc_context, "--", finc_sys_dec ); finc_context_add_func_sys ( g_finc_context, "preinc", finc_sys_preinc ); finc_context_add_func_sys ( g_finc_context, "predec", finc_sys_predec ); finc_context_add_func_sys ( g_finc_context, "[]", finc_sys_array ); finc_context_add_func_sys ( g_finc_context, "if", finc_sys_if ); finc_context_add_func_sys ( g_finc_context, "for", finc_sys_for ); finc_context_add_func_sys ( g_finc_context, "while", finc_sys_while ); finc_context_add_func_sys ( g_finc_context, "return", finc_sys_return ); finc_context_add_func_sys ( g_finc_context, "continue", finc_sys_continue ); finc_context_add_func_sys ( g_finc_context, "break", finc_sys_break ); finc_context_add_func_sys ( g_finc_context, "<", finc_sys_cmp_l ); finc_context_add_func_sys ( g_finc_context, ">", finc_sys_cmp_g ); finc_context_add_func_sys ( g_finc_context, "<=", finc_sys_cmp_le ); finc_context_add_func_sys ( g_finc_context, ">=", finc_sys_cmp_ge ); finc_context_add_func_sys ( g_finc_context, "!=", finc_sys_cmp_ne ); finc_context_add_func_sys ( g_finc_context, "==", finc_sys_cmp_e ); finc_context_add_func_sys ( g_finc_context, "=", finc_sys_assign ); finc_context_add_func_sys ( g_finc_context, "++", finc_sys_inc ); finc_context_add_func_sys ( g_finc_context, "--", finc_sys_dec ); finc_context_add_func_sys ( g_finc_context, "@", finc_sys_block );}void finc_sys_global ( FinCNode* p_node ){ FinCNode* l_node; FinCNode* node_var; FinCType* l_type; String* l_name; FinCData* l_data; FinCVar* l_var; FinCNode* l_init_node; int l_size, i; l_node = (FinCNode*) vector_at ( p_node->vector_node, 0 ) ; l_type = l_node->type; l_size = finc_node_get_size(l_node); for ( i=0; i<l_size; i++) { node_var = (FinCNode*) vector_at ( l_node->vector_node, i ); l_name = node_var->identifier; l_data = finc_data_new ( l_type, NULL ); if ( vector_get_size(node_var->vector_node)!=0 )//if has init node! { l_init_node = (FinCNode*) vector_at( node_var->vector_node, 0); finc_node_evaluate (l_init_node); finc_data_assign (l_data, l_init_node->data); unref(l_init_node); } unref ( node_var ); l_var = finc_var_new ( l_name, l_data ); finc_context_add_var ( g_finc_context, l_var, TRUE ); unref ( l_data ); unref ( l_var ); } unref(l_node);}void finc_sys_local ( FinCNode* p_node ){ FinCNode* l_node; FinCNode* node_var; FinCType* l_type; String* l_name; FinCData* l_data; FinCVar* l_var; FinCNode* l_init_node; int l_size, i; l_node = (FinCNode*) vector_at ( p_node->vector_node, 0 ) ; l_type = l_node->type; l_size = finc_node_get_size(l_node); for ( i=0; i<l_size; i++) { node_var = (FinCNode*) vector_at ( l_node->vector_node, i ); l_name = node_var->identifier; l_data = finc_data_new ( l_type, NULL ); if ( vector_get_size(node_var->vector_node)!=0 )//if has init node! { l_init_node = (FinCNode*) vector_at( node_var->vector_node, 0); finc_node_evaluate (l_init_node); finc_data_assign (l_data, l_init_node->data); unref(l_init_node); } unref ( node_var ); l_var = finc_var_new ( l_name, l_data ); finc_context_add_var ( g_finc_context, l_var, FALSE ); unref ( l_data ); unref ( l_var ); } unref(l_node);}void finc_sys_access ( FinCNode* p_node ){ FinCNode* l_main; FinCNode* l_sub; FinCData* l_data; FinCData* l_field; FinCStruct* l_struct; int l_index; l_main = (FinCNode*) vector_at (p_node->vector_node, 0); l_sub = (FinCNode*) vector_at (p_node->vector_node, 1); finc_node_evaluate (l_main); if (!finc_node_check (l_sub, FinCNodeType_Identifier)) { printf("Error:struct access, right must be a identifer!\n"); unref(l_main); unref(l_sub); return; } l_data = addref(FinCData, l_main->data); if (!l_data) { printf("Runtime Error:struct variable not founded.\n"); finc_context_error_inc( g_finc_context ); unref(l_main); unref(l_sub); return; } l_struct = finc_context_get_struct (g_finc_context, l_data->type->name); l_index = finc_struct_get_field_index (l_struct, l_sub->identifier); l_field = finc_data_get_field(l_data, l_index); p_node->data = addref(FinCData, l_field); unref(l_main); unref(l_sub); unref(l_data); unref(l_field); unref(l_struct);}void finc_sys_array ( FinCNode* p_node ){ FinCNode * l_node; FinCData* l_data; FinCData* l_index; int index; l_node = (FinCNode*) vector_at ( p_node->vector_node, 0 ); finc_node_evaluate ( l_node ); l_data = addref ( FinCData, l_node->data ); unref ( l_node ); l_node = (FinCNode*) vector_at ( p_node->vector_node, 1 ); finc_node_evaluate ( l_node ); l_index = addref ( FinCData, l_node->data ); unref ( l_node ); index = finc_access(l_index->raw, 0, int); if ( (index<0) || (index>(l_data->type->array_size-1)) ) { printf("Runtime Error: array out of range.\n"); finc_context_error_inc( g_finc_context ); unref(l_data); unref(l_index); return; } unref ( p_node->data ); p_node->data = finc_data_get_index ( l_data, index ); l_data->array_stand = index; unref ( l_data ); unref ( l_index );}void finc_sys_assign ( FinCNode* p_node ){ FinCNode * l_node; FinCData* l_src; FinCData* l_dst; l_node = FinC_NODE ( vector_at ( p_node->vector_node, 0 ) ); finc_node_evaluate ( l_node ); l_dst = finc_node_take_data(l_node); unref ( l_node ); l_node = FinC_NODE ( vector_at ( p_node->vector_node, 1 ) ); finc_node_evaluate ( l_node ); l_src = finc_node_take_data(l_node); if ( l_node->node_type ==FinCNodeType_Func ) { if (strcmp(string_get_str(l_node->identifier), "cast") ==0 || strcmp(string_get_str(l_node->identifier), "contentof") == 0 ) /*that is variable alias*/ { l_dst = addref(FinCData, l_src); } else { finc_data_assign ( l_dst, l_src ); } } else { finc_data_assign ( l_dst, l_src ); } unref ( p_node->data ); p_node->data = l_src; unref ( l_node ); unref ( l_dst );}void finc_sys_cast ( FinCNode* p_node ){ FinCNode* l_type_node; FinCNode* l_data_node; FinCData* l_data; l_type_node = (FinCNode*) vector_at ( p_node->vector_node, 0 ); l_data_node = (FinCNode*) vector_at ( p_node->vector_node, 1 ); finc_node_evaluate ( l_data_node ); l_data = finc_data_new ( l_type_node->type, l_data_node->data->raw ); unref ( l_type_node ); unref ( l_data_node ); unref ( p_node->data ); p_node->data = l_data;}void finc_sys_addr_of ( FinCNode* p_node ){ FinCNode * l_node; FinCType* l_type; FinCData* l_data; l_type = finc_type_new ( FinCType_Pointer, FinCArrayType_None, 0 ); l_data = finc_data_new ( l_type, NULL ); unref ( l_type ); l_node = (FinCNode*) vector_at ( p_node->vector_node, 0 ); finc_node_evaluate ( l_node ); finc_data_set_pointer (l_data, l_node->data); unref ( l_node ); unref ( p_node->data ); p_node->data = l_data;}void finc_sys_value_of( FinCNode* p_node){ FinCNode * l_node; l_node = (FinCNode*) vector_at (p_node->vector_node, 0); finc_node_evaluate (l_node); unref (p_node->data); p_node->data = addref( FinCData, l_node->data->pointer ); unref (l_node);}void finc_sys_if ( FinCNode* p_node ){ FinCNode * l_test; FinCNode* l_true; FinCNode* l_false; FinCData* l_data_test; l_test = (FinCNode*)vector_at ( p_node->vector_node, 0 ); l_true = (FinCNode*)vector_at ( p_node->vector_node, 1 ); l_false = (FinCNode*)vector_at ( p_node->vector_node, 2 ); finc_node_evaluate ( l_test ); l_data_test = finc_node_take_data(l_test); if ( finc_access ( finc_data_get_raw_data ( l_data_test ), 0, Bool ) ) { finc_node_evaluate ( l_true ); } else { if ( l_false ) finc_node_evaluate ( l_false ); } unref ( l_test ); unref ( l_data_test ); unref ( l_true ); unref ( l_false );}void finc_sys_for ( FinCNode* p_node ){ FinCNode * node1; FinCNode* node2; FinCNode* node3; FinCNode* code; Bool old_continue, old_break, old_in_cycle; node1 = (FinCNode*)vector_at ( p_node->vector_node, 0 ); node2 = (FinCNode*)vector_at ( p_node->vector_node, 1 ); node3 = (FinCNode*)vector_at ( p_node->vector_node, 2 ); code = (FinCNode*)vector_at ( p_node->vector_node, 3 ); finc_node_evaluate ( node1 ); finc_node_evaluate ( node2 ); old_continue = g_finc_context->script_continue; old_break = g_finc_context->script_break; old_in_cycle = g_finc_context->script_in_cycle; while ( finc_access ( finc_data_get_raw_data ( node2->data ), 0, Bool ) ) { g_finc_context->script_in_cycle = TRUE; finc_node_evaluate ( code ); if (g_finc_context->script_break) { g_finc_context->script_break = FALSE; g_finc_context->script_in_cycle = FALSE; break; } g_finc_context->script_continue = FALSE; finc_node_evaluate ( node3 ); finc_node_evaluate ( node2 ); g_finc_context->script_in_cycle = FALSE; } unref ( node1 ); unref ( node2 ); unref ( node3 ); unref ( code ); g_finc_context->script_continue = old_continue; g_finc_context->script_break = old_break; g_finc_context->script_in_cycle = old_in_cycle;}void finc_sys_while ( FinCNode* p_node ){ FinCNode * l_test; FinCNode* l_code; Bool old_continue, old_break, old_in_cycle;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?