public void push_function(common_function_node fn) { _func_stack.push(fn); }
private void WriteGenericFunctionInformation(common_function_node func) { if (func.is_generic_function) { bw.Write((byte)1); //Число типов-параметров bw.Write(func.generic_params.Count); //Имена параметров foreach (common_type_node par in func.generic_params) { bw.Write(par.name); } WriteTypeParamsEliminations(func.generic_params); } else { bw.Write((byte)0); } }
public bool IsExternal(common_function_node cfn) { return ext_funcs[cfn] != null; }
private bool has_var_char_parameters(common_function_node fn) { for (int i=0; i<fn.parameters.Count; i++) { if (fn.parameters[i].type == SystemLibrary.SystemLibrary.char_type && fn.parameters[i].parameter_type == SemanticTree.parameter_type.var) return true; } return false; }
private attribute_node get_dll_import_attribute(common_function_node cfn) { foreach (attribute_node attr in cfn.attributes) { if (attr.attribute_type == SystemLibrary.SystemLibrary.dllimport_type) return attr; } return null; }
private bool is_predefinition(common_function_node predef, common_function_node def, bool error_on_false) { if (convertion_data_and_alghoritms.function_eq_params(predef,def)) { for(int param_num=0;param_num<def.parameters.Count;param_num++) { int res=SystemLibrary.SystemLibrary.string_comparer.Compare(def.parameters[param_num].name, predef.parameters[param_num].name); if (res!=0) { throw new DifferentParameterNameInFunctionPredefinitionAndDefinition( (common_parameter)predef.parameters[param_num], (common_parameter)def.parameters[param_num], predef,def); } } return true; } if (error_on_false) { throw new FunctionDefinitionHaveDifferentParamsWithPredifinition(predef,def); } return false; }
private void visit_generic_params(common_function_node cfn, List<SyntaxTree.ident> idents) { /*if (SemanticRules.RuntimeInitVariablesOfGenericParameters) { SystemLibrary.SystemLibInitializer.RuntimeInitializeFunction.Restore(); }*/ //ctn.is_generic_type_definition = true; check_param_redeclared(idents); cfn.generic_params = new List<SemanticTree.ICommonTypeNode>(); foreach (SyntaxTree.ident id in idents) { common_type_node par = new common_type_node( id.name, SemanticTree.type_access_level.tal_public, context.converted_namespace, convertion_data_and_alghoritms.symbol_table.CreateInterfaceScope(null, SystemLibrary.SystemLibrary.object_type.Scope, null), get_location(id)); SystemLibrary.SystemLibrary.init_reference_type(par); par.SetBaseType(SystemLibrary.SystemLibrary.object_type); par.generic_function_container = cfn; cfn.generic_params.Add(par); cfn.scope.AddSymbol(id.name, new SymbolInfo(par)); /*if (SemanticRules.RuntimeInitVariablesOfGenericParameters && !ctn.IsInterface) { class_field cf = new class_field( compiler_string_consts.generic_param_kind_prefix + id.name, SystemLibrary.SystemLibrary.byte_type, ctn, PascalABCCompiler.SemanticTree.polymorphic_state.ps_static, SemanticTree.field_access_level.fal_public, null); ctn.fields.AddElement(cf); par.runtime_initialization_marker = cf; }*/ } }
/// <summary> /// Конструктор класса. /// </summary> /// <param name="name">Имя константы.</param> /// <param name="cn">Значение константы.</param> /// <param name="loc">Расположение константы.</param> /// <param name="comprehensive_function">Функция, содержащая константу.</param> public function_constant_definition(string name, constant_node cn, location loc, common_function_node comprehensive_function) : base(name, cn, loc) { _comprehensive_function = comprehensive_function; }
private string GetGenericFlag(common_function_node cfn) { if (!cfn.is_generic_function) return ""; return "``"+cfn.get_generic_params_list().Count.ToString(); }
public common_parameter(string name,type_node tp,SemanticTree.parameter_type pt, common_function_node cont_function, concrete_parameter_type conc_par_type,expression_node default_value, location loc): base(name,tp) { _par_type=pt; _cont_function=cont_function; _concrete_parameter_type = conc_par_type; _default_value = default_value; _loc = loc; }
public FunctionMustBeWithOverloadDirective(common_function_node first_function, common_function_node second_function) { _first_function = first_function; _second_function = second_function; }
public common_parameter(string name, SemanticTree.parameter_type pt, common_function_node cont_function, concrete_parameter_type conc_par_type, location loc) : base(name) { _par_type = pt; _cont_function = cont_function; _concrete_parameter_type = conc_par_type; _loc = loc; }
public local_variable(string name,type_node type,common_function_node cont_function, location loc) : base(name,type) { _cont_function=cont_function; _loc = loc; }
public CapturedVariablesTreeNodeProcedureScope(CapturedVariablesTreeNode parentNode, common_function_node function, int scopeNum, syntax_tree_node correspondingSyntaxTreeNode) : base(parentNode, scopeNum, correspondingSyntaxTreeNode) { FunctionNode = function; }
/// <summary> /// Этот метод вызывается если мы встречаем простой вызов функии, например f(1). /// Он определяет является ли эта функция методом класса, вложенной функцией и т.д. и создает соответствующее обращение. /// Например, для метода класса он добавляет this, а для вложенной функции вычисляет статическую глубину. /// </summary> /// <param name="exprs">Список параметров.</param> /// <param name="si">Список методов.</param> /// <param name="loc">Расположение вызова.</param> /// <param name="converted_type">Тип в котором мы находимся. null, если мы вне типа.</param> /// <param name="top_function">Функция в которой мы находимся.</param> /// <param name="allow_procedure">Может ли это быть вызов процедуры. false если вызов стоит в выражении или правой части опреатора присваивания.</param> /// <returns>Возвращает узел вызова метода.</returns> public expression_node create_full_function_call(expressions_list exprs,SymbolInfo si,location loc, common_type_node converted_type,common_function_node top_function,bool allow_procedure) { function_node fn=select_function(exprs,si,loc); /* if (fn.compile_time_executor != null) { expression_node ex = fn.compile_time_executor(loc, exprs.ToArray()); if (ex != null) { return ex; } } */ //allow_procedure = true; if ((!allow_procedure)&&(fn.return_value_type==null)) { throw new SimpleSemanticError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn.name); } expression_node expr_node=null; switch (fn.semantic_node_type) { case semantic_node_type.basic_function_node: case semantic_node_type.common_namespace_function_node: { expr_node=create_simple_function_call(fn,loc,exprs.ToArray()); break; } case semantic_node_type.common_method_node: case semantic_node_type.compiled_function_node: { SemanticTree.IClassMemberNode icmn=(SemanticTree.IClassMemberNode)fn; if (icmn.polymorphic_state==SemanticTree.polymorphic_state.ps_static) { expr_node=create_simple_function_call(fn,loc,exprs.ToArray()); break; } //expression_node tn = new this_node(converted_type,loc); base_function_call cmc=null; switch (fn.semantic_node_type) { case semantic_node_type.common_method_node: { //ssyy добавил if (((common_method_node)fn).is_constructor) { common_constructor_call ccc = new common_constructor_call((common_method_node)fn, loc); //(ssyy) По-видимому, здесь всегда можно присваивать false, так как при создании нового объекта мы сюда не заходим... ccc._new_obj_awaited = false; if (!syntax_tree_visitor.context.allow_inherited_ctor_call) { throw new SimpleSemanticError(loc, "INHERITED_CONSTRUCTOR_CALL_MUST_BE_FIRST"); } cmc = ccc; } else //\ssyy { cmc = new common_method_call((common_method_node)fn, syntax_tree_visitor.GetCurrentObjectReference(((common_method_node)fn).cont_type.Scope, fn, loc), loc); (cmc as common_method_call).virtual_call = !syntax_tree_visitor.inherited_ident_processing; } break; } case semantic_node_type.compiled_function_node: { cmc = new compiled_function_call((compiled_function_node)fn, syntax_tree_visitor.GetCurrentObjectReference(((compiled_function_node)fn).cont_type.Scope, fn, loc), loc); (cmc as compiled_function_call).virtual_call = !syntax_tree_visitor.inherited_ident_processing; break; } } cmc.parameters.AddRange(exprs); expr_node=cmc; break; } case semantic_node_type.common_in_function_function_node: { common_in_function_function_node cffn=(common_in_function_function_node)fn; common_in_function_function_call cffc=new common_in_function_function_call(cffn, symtab.GetRelativeScopeDepth(cffn.function.scope,top_function.scope),loc); cffc.parameters.AddRange(exprs); expr_node=cffc; break; } //ssyy добавил case semantic_node_type.compiled_constructor_node: { compiled_constructor_node ccn = fn as compiled_constructor_node; if (ccn == null) { throw new CompilerInternalError("compiled_constructor_node expected"); } compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc); ccc.parameters.AddRange(exprs); ccc._new_obj_awaited = false; if (!syntax_tree_visitor.context.allow_inherited_ctor_call) { throw new SimpleSemanticError(loc, "INHERITED_CONSTRUCTOR_CALL_MUST_BE_FIRST"); } expr_node = ccc; break; } case semantic_node_type.indefinite_definition_node: { indefinite_function_call ifc = new indefinite_function_call(fn, loc); ifc.parameters.AddRange(exprs); expr_node = ifc; break; } //\ssyy default: { throw new NotSupportedError(loc); } } return expr_node; }
private string GetParameters(common_function_node cfn) { StringBuilder sb = new StringBuilder(); if (cfn.parameters.Count > 0) { sb.Append("("); for (int i=0; i<cfn.parameters.Count; i++) { sb.Append(get_name(cfn.parameters[i].type)); if (cfn.parameters[i].parameter_type == SemanticTree.parameter_type.var) sb.Append('@'); if (i<cfn.parameters.Count-1) sb.Append(","); } sb.Append(")"); } return sb.ToString(); }
//Этот метод вызывается для предописания функции (только для предописания) private void check_function_not_exists(common_function_node fn) { SymbolInfo si=null; if (_func_stack.size<=1) { if (_ctn!=null) { si=_ctn.Scope.FindOnlyInScope(fn.name); } else { si=_cmn.scope.FindOnlyInScope(fn.name); } } else { common_function_node temp=_func_stack.pop(); si=_func_stack.top().scope.FindOnlyInScope(fn.name); _func_stack.push(temp); } //SymbolInfo si=find_only_in_namespace(fn.name); //И эта проверка наверно не нужна, но пусть пока повисит //Тем более с ней, наверное, быстрее работает //Лучше удалю пока //if (si.Next==null) //{ // return; //} while(si!=null) { if (si.sym_info==fn) { si=si.Next; continue; } #if (DEBUG) if (si.sym_info.general_node_type!=general_node_type.function_node) { throw new CompilerInternalError("Function name is used to define not function."); } #endif //compar - найденная функция common_function_node compar=((common_function_node)(si.sym_info)); if (compar.is_overload==false) { throw new FunctionMustBeWithOverloadDirective(compar,fn); } if (convertion_data_and_alghoritms.function_eq_params(fn,compar)) { throw new FunctionDuplicateDefinition(compar,fn); } si=si.Next; } }
protected parameter_list make_parameters(parameter_list orig_pl, common_function_node fn) { parameter_list pl = new parameter_list(); //TODO: разобраться с concrete_parameter_type foreach (parameter p in orig_pl) { common_parameter cp = new common_parameter( p.name, generic_convertions.determine_type(p.type, _instance_params, false), p.parameter_type, fn, concrete_parameter_type.cpt_none, p.inital_value, null); cp.intrenal_is_params = p.is_params; cp.is_special_name = p.is_special_name; cp.is_ret_value = p.is_ret_value; cp.default_value = p.default_value; pl.AddElement(cp); } return pl; }
//Я хочу модифицировать этот метод так, чтобы в случае предописания наличия метода //он не выкидывал исключение, а понимал все правильно //Этот метод вызывается только для функций с телом private void check_unique_or_predefined(common_function_node fn) { SymbolInfo si=null; if (_func_stack.size<=1) { if (_ctn!=null) { //TODO: Спрость у Саши насчет того, что возвращает этот метод. Он долхен возвращать список найденных методов, а не единственный экземпляр. si=_ctn.Scope.FindOnlyInScope(fn.name); } else { si=_cmn.scope.FindOnlyInScope(fn.name); } } else { common_function_node temp=_func_stack.pop(); si = _func_stack.top().scope.FindOnlyInScope(fn.name); _func_stack.push(temp); } //SymbolInfo si=find_only_in_namespace(fn.name); //И эта проверка наверно не нужна, но пусть пока повисит //Тем более с ней, наверное, быстрее работает //if (si.Next==null) //{ // return; //} //Тут я добавляю проверку: если это предописание, то все хорошо /*if (si.Next.Next==null) { if (fnd.function_code==null) { } }*/ //Как я понимаю все должно работать правильно без следующего фрагмента /*if (fn.is_overload==false) { //fnd - найденная функция common_function_node fnd=null; if (si.sym_info==fn) { fnd=(common_function_node)si.Next.sym_info; } else { fnd=(common_function_node)si.sym_info; } throw new FunctionMustBeWithOverloadDirective(fnd,fn); }*/ while(si!=null) { if (si.sym_info==fn) { si=si.Next; continue; } #if (DEBUG) if (si.sym_info.general_node_type!=general_node_type.function_node) { throw new CompilerInternalError("Function name is used to define not function."); } #endif //compar - найденная функция common_function_node compar=((common_function_node)(si.sym_info)); //Проверяем, если мы нашли не предописание if (compar.function_code!=null) { if (compar.is_overload==false) { throw new FunctionMustBeWithOverloadDirective(compar,fn); } if (convertion_data_and_alghoritms.function_eq_params(fn,compar)) { throw new FunctionDuplicateDefinition(compar,fn); } si=si.Next; continue; } bool is_find_predefinition=false; if (compar.is_overload==false) { //Если нет параметров в описании тела функции if (fn.parameters.Count==0) { is_find_predefinition=true; //Добавляем все описанные параметры /* foreach(parameter par in compar.parameters) { //Тут, конечно, приведение типа параметра, но оно вроде всегда должно быть такого типа. common_parameter intcpar=(common_parameter)par; common_parameter new_par = new common_parameter(intcpar.name, intcpar.type, intcpar.parameter_type, fn, intcpar.concrete_parameter_type, intcpar.default_value, intcpar.loc); fn.parameters.AddElement(new_par); fn.scope.AddSymbol(new_par.name,new SymbolInfo(new_par)); } compar.scope=fn.scope; */ } else { is_find_predefinition=is_predefinition(compar,fn,true); } } else { is_find_predefinition=is_predefinition(compar,fn,false); } if (!is_find_predefinition) { si = si.Next; continue; } if (compar.function_code!=null) { throw new FunctionAlreadyHaveABody(compar, fn); } common_method_node compiled_meth = fn as common_method_node; if (compiled_meth != null) { common_method_node finded_method = (common_method_node)compar; if (compiled_meth.is_constructor) { if (finded_method.pascal_associated_constructor == null) { throw new ConstructorMustBeRealizedWithConstructorKeyword(finded_method,compiled_meth,compiled_meth.loc); } compiled_meth.return_value_type = finded_method.return_value_type; convertion_data_and_alghoritms.create_function_return_variable(finded_method,null); } } if (compar.return_value_type!=fn.return_value_type) { throw new FunctionPredefinitionAndDefinitionHaveDifferentResultType(compar,fn); } //НУЖЕН СПИСОК ФУНКЦИЙ С ПРЕДОПРЕДЕЛЕНИЯМИ, ЧТОБЫ ОБНАРУЖИТЬ ОПИСАННЫЕ НО НЕ ОПРЕДЕЛЕННЫЕ //Или не нужен??? //TODO: СИНХРОНИЗИРОВАТЬ АТТРИБУТЫ!!!!! if (fn.is_overload) { compar.is_overload=true; } //TODO: Внимательно проверить следующий if. if (compar.is_overload) { fn.is_overload = true; last_created_function.symbol_kind = symbol_kind.sk_overload_function; } common_function_node cfn11=_func_stack.pop(); compar.scope = cfn11.scope; common_method_node cmnode=compar as common_method_node; if (cmnode != null) { SymbolInfo si_local = cfn11.scope.FindOnlyInScope(compiler_string_consts.self_word); if (si_local != null) { si_local.sym_info = cmnode.self_variable; } } //Удаляем текущую функцию SymbolInfo siint = null; //TODO: Возможно в коде ниже следует вызывать не Find а FindOnlyInNamespace. switch(converting_block()) { case block_type.function_block: { _func_stack.top().functions_nodes_list.remove((common_in_function_function_node)fn); siint = _func_stack.top().scope.FindOnlyInScope(fn.name); break; } case block_type.namespace_block: { _cmn.functions.remove((common_namespace_function_node)fn); siint = _cmn.scope.FindOnlyInScope(fn.name); break; } case block_type.type_block: { //TODO: Доделать описание методов класса. _ctn.methods.remove((common_method_node)fn); siint = _ctn.scope.FindOnlyInScope(fn.name); break; } default: { throw new CompilerInternalError("Undefined block type"); } } while (siint.sym_info != fn) { siint = siint.Next; } siint.sym_info = compar; //Мы удалили новую функцию. Сейчас мы должны перенести параметры из новой функции в старую. //TODO: У новой функции может вообще не быть параметров. Они все в старой. Разобраться с этим. А зачем вообще переносить параметры? if (compar.parameters.Count != 0) { if (fn.parameters.Count == 0) { foreach (common_parameter pr in compar.parameters) { compar.scope.AddSymbol(pr.name, new SymbolInfo(pr)); } } else { foreach (common_parameter pr in compar.parameters) { SymbolInfo par_sim_info=fn.scope.FindOnlyInScope(pr.name); par_sim_info.sym_info = pr; } } } /* compar.parameters.clear(); foreach (common_parameter pr in fn.parameters) { pr.common_function = compar; compar.parameters.AddElement(pr); } */ _func_stack.push(compar); //si.sym_info=fn; break; } }
private void ReadGenericFunctionInformation(common_function_node func) { if (CanReadObject()) { func.generic_params = ReadGenericParams(cun.namespaces[0]); foreach (common_type_node par in func.generic_params) { par.generic_function_container = func; ReadTypeParameterEliminations(par); } } }
internal void add_clip_for_set(common_function_node cfn) { statements_list sl = cfn.function_code as statements_list; if (sl == null) return; foreach (common_parameter prm in cfn.parameters) { if (prm.type.type_special_kind == SemanticTree.type_special_kind.set_type && prm.parameter_type == SemanticTree.parameter_type.value || prm.is_params && prm.type.element_type.type_special_kind == SemanticTree.type_special_kind.set_type) { if (!prm.is_params) { ordinal_type_interface oti = prm.type.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; if (oti == null) if (prm.type.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) { base_function_call cmc2 = null; if (SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info is common_namespace_function_node) cmc2 = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info as common_namespace_function_node, null); else cmc2 = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info as compiled_function_node, null); cmc2.parameters.AddElement(new common_parameter_reference(prm,0,null)); cmc2.parameters.AddElement(new int_const_node((prm.type.element_type as short_string_type_node).Length,null)); sl.statements.AddElementFirst(cmc2); continue; } else continue; base_function_call cmc = null; if (SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info is common_namespace_function_node) cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info as common_namespace_function_node, null); else cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info as compiled_function_node, null); cmc.parameters.AddElement(new common_parameter_reference(prm,0,null)); cmc.parameters.AddElement(oti.lower_value); cmc.parameters.AddElement(oti.upper_value); sl.statements.AddElementFirst(cmc); } else { var_definition_node var = context.create_for_temp_variable(prm.type.element_type,null); expression_node in_what = new common_parameter_reference(prm,0,null); statements_list what_do = new statements_list(null); ordinal_type_interface oti = prm.type.element_type.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; bool short_str = false; if (oti == null) if (prm.type.element_type.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) { short_str = true; } else continue; base_function_call cmc = null; if (!short_str) { if (SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info is common_namespace_function_node) cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info as common_namespace_function_node, null); else cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info as compiled_function_node, null); } else { if (SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info is common_namespace_function_node) cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info as common_namespace_function_node, null); else cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info as compiled_function_node, null); } if (var is local_block_variable) cmc.parameters.AddElement(new local_block_variable_reference(var as local_block_variable,null)); else cmc.parameters.AddElement(new local_variable_reference(var as local_variable,0,null)); if (!short_str) { cmc.parameters.AddElement(oti.lower_value); cmc.parameters.AddElement(oti.upper_value); } else { cmc.parameters.AddElement(new int_const_node((prm.type.element_type.element_type as short_string_type_node).Length,null)); } what_do.statements.AddElement(cmc); foreach_node fn = new foreach_node(var,in_what,what_do,null); sl.statements.AddElementFirst(fn); } } else if (prm.type.type_special_kind == SemanticTree.type_special_kind.short_string && prm.parameter_type == SemanticTree.parameter_type.value || prm.is_params && prm.type.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) { if (!prm.is_params) { base_function_call cmc = null; if (SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info is common_namespace_function_node) cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node, null); else cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as compiled_function_node, null); cmc.parameters.AddElement(new common_parameter_reference(prm, 0, null)); cmc.parameters.AddElement(new int_const_node((prm.type as short_string_type_node).Length, null)); concrete_parameter_type tmp_cpt = prm.concrete_parameter_type; prm.concrete_parameter_type = concrete_parameter_type.cpt_none; sl.statements.AddElementFirst(find_operator(compiler_string_consts.assign_name, new common_parameter_reference(prm, 0, null), cmc, null)); prm.concrete_parameter_type = tmp_cpt; } else { common_parameter_reference cpr = new common_parameter_reference(prm, 0, null); compiled_function_node get_func = (prm.type.find_in_type("Length").sym_info as compiled_property_node).get_function as compiled_function_node; local_variable var = context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null) as local_variable; local_variable len_var = context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null) as local_variable; statements_list body = new statements_list(null); //compiled_property_node item_prop = prm.type.find_in_type("Item").sym_info as compiled_property_node; base_function_call cmc = null; if (SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info is common_namespace_function_node) cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node, null); else cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as compiled_function_node, null); expression_node cond = new basic_function_call(SystemLibrary.SystemLibrary.int_sm as basic_function_node, null, new local_variable_reference(var, 0, null), new local_variable_reference(len_var, 0, null)); //compiled_function_call get_item = new compiled_function_call(item_prop.get_function as compiled_function_node,cpr,null); //get_item.parameters.AddElement(new local_variable_reference(var,0,null)); cmc.parameters.AddElement(new simple_array_indexing(cpr, new local_variable_reference(var, 0, null), prm.type.element_type, null)); cmc.parameters.AddElement(new int_const_node((prm.type.element_type as short_string_type_node).Length, null)); body.statements.AddElement(find_operator(compiler_string_consts.assign_name, new simple_array_indexing(cpr, new local_variable_reference(var, 0, null), prm.type.element_type, null), cmc, null)); body.statements.AddElement(new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node, null, new local_variable_reference(var, 0, null), new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node, null, new local_variable_reference(var, 0, null), new int_const_node(1, null)))); while_node wn = new while_node(cond, body, null); sl.statements.AddElementFirst(wn); sl.statements.AddElementFirst(new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node, null, new local_variable_reference(len_var, 0, null), new compiled_function_call(get_func, cpr, null))); } } } }
private local_variable GetLocalVariable(common_function_node func) { int offset = (int)br.BaseStream.Position-start_pos; //int tmp=br.ReadByte(); local_variable lv = new local_variable(br.ReadString(),func,null); lv.type = GetTypeReference(); if (br.ReadBoolean()) lv.set_used_as_unlocal(); //members[offset] = lv; AddMember(lv, offset); if (CanReadObject()) lv.inital_value = CreateExpressionWithOffset(); return lv; }
private bool has_dll_import_attribute(common_function_node cfn) { foreach (attribute_node attr in cfn.attributes) { if (attr.attribute_type == SystemLibrary.SystemLibrary.dllimport_type) return true; } return false; }
private function_constant_definition GetFunctionConstant(common_function_node func) { int offset = (int)br.BaseStream.Position-start_pos; //int tmp=br.ReadByte(); function_constant_definition fcd = new function_constant_definition(br.ReadString(),null,func); //members[offset] = lv; AddMember(fcd, offset); fcd.const_value = CreateExpressionWithOffset() as constant_node; return fcd; }
/// <summary> /// Конструктор узла. /// </summary> /// <param name="name">Имя функции.</param> /// <param name="ret_type">Тип возвращаемого значения функции.</param> /// <param name="loc">Расположение имени функции в программе.</param> /// <param name="up_function">Функция, в которой определена эта функция.</param> /// <param name="scope">Протсранство имен этой функции.</param> public common_in_function_function_node(string name, type_node ret_type, location loc, common_function_node up_function, SymbolTable.Scope scope) : base(name,ret_type,loc,scope) { _up_function=up_function; }
private common_parameter GetParameter(common_function_node func) { int offset = (int)br.BaseStream.Position-start_pos; br.ReadByte(); string s = br.ReadString(); type_node tn = GetTypeReference(); concrete_parameter_type cpt = (concrete_parameter_type)br.ReadByte(); SemanticTree.parameter_type pt = SemanticTree.parameter_type.value; switch (cpt) { case concrete_parameter_type.cpt_const: pt = SemanticTree.parameter_type.value; break; case concrete_parameter_type.cpt_var: pt = SemanticTree.parameter_type.var; break; case concrete_parameter_type.cpt_none: pt = SemanticTree.parameter_type.value; break; } common_parameter p = new common_parameter(s,pt,func,cpt,null); p.type = tn; if (br.ReadBoolean()) p.set_used_as_unlocal(); p.intrenal_is_params = br.ReadBoolean(); if (br.ReadByte() == 1) { p.default_value = CreateExpressionWithOffset(); } p.attributes.AddRange(GetAttributes()); //members[offset] = p; AddMember(p, offset); return p; }
public void MarkAsExternal(common_function_node cfn) { ext_funcs[cfn] = cfn; }
public void create_function_return_variable(common_function_node cfn, SymbolInfo ret_var) { if (!SemanticRules.AddResultVariable) return; //#if (DEBUG) if (cfn.return_value_type==null) { return; //throw new CompilerInternalError("Procedure can not return value"); } //#endif if (cfn.return_variable != null) { if (ret_var != null) ret_var.sym_info = cfn.return_variable; return; } cfn.return_variable=new local_variable(get_return_variable_name(cfn.name),cfn.return_value_type,cfn,cfn.loc); cfn.return_variable.inital_value = syntax_tree_visitor.context.GetInitalValueForVariable(cfn.return_variable,null); cfn.var_definition_nodes_list.AddElement(cfn.return_variable); if (ret_var != null) { ret_var.sym_info = cfn.return_variable; } }
private void VisitNestedFunction(common_in_function_function_node cnfn) { if (extended_mode) VisitVariables(cnfn.var_definition_nodes_list); foreach (var_definition_node vdn in cnfn.var_definition_nodes_list) helper.AddVariable(vdn); foreach (common_parameter prm in cnfn.parameters) helper.AddParameter(prm); foreach (common_in_function_function_node nested in cnfn.functions_nodes_list) VisitNestedFunction(nested); cur_func = cnfn; VisitStatement(cnfn.function_code); foreach (var_definition_node vdn2 in cnfn.var_definition_nodes_list) { if (vdn2 is local_variable) { local_variable vdn = vdn2 as local_variable; VarInfo vi = helper.GetVariable(vdn); if (vi.num_use == 0 && !vdn.is_special_name) warns.Add(new UnusedVariable(vdn.name, vdn.loc)); else if (vi.num_ass == 0 && vdn.is_ret_value && !cnfn.name.StartsWith("<>") && cnfn.return_value_type.type_special_kind != SemanticTree.type_special_kind.record && !cnfn.return_value_type.IsPointer && cnfn.return_value_type.type_special_kind != SemanticTree.type_special_kind.array_wrapper && !helper.IsExternal(cnfn)) warns.Add(new UndefinedReturnValue(cnfn.name, cnfn.function_code.location)); if (vi.num_ass > 0 && vi.act_num_use == 0 && !vdn.is_special_name) warns.Add(new AssignWithoutUsing(vdn.name, vi.last_ass_loc)); //if (vi.num_ass == 0 && vi.act_num_use > 0) helper.AddRealWarning(vdn, warns); } else if (vdn2 is local_block_variable) { local_block_variable vdn = vdn2 as local_block_variable; VarInfo vi = helper.GetVariable(vdn); if (vi.num_use == 0 && !vdn.is_special_name) warns.Add(new UnusedVariable(vdn.name, vdn.loc)); else if (vi.num_ass == 0 && vdn.is_ret_value && !cnfn.name.StartsWith("<>") && cnfn.return_value_type.type_special_kind != SemanticTree.type_special_kind.record && !cnfn.return_value_type.IsPointer && cnfn.return_value_type.type_special_kind != SemanticTree.type_special_kind.array_wrapper && !helper.IsExternal(cnfn)) warns.Add(new UndefinedReturnValue(cnfn.name, cnfn.function_code.location)); if (vi.num_ass > 0 && vi.act_num_use == 0 && !vdn.is_special_name) warns.Add(new AssignWithoutUsing(vdn.name, vi.last_ass_loc)); //if (vi.num_ass == 0 && vi.act_num_use > 0) helper.AddRealWarning(vdn, warns); } if (vdn2.inital_value != null) VisitExpression(vdn2.inital_value); } foreach (common_parameter prm in cnfn.parameters) { ParamInfo vi = helper.GetParameter(prm); if (prm.inital_value != null) VisitExpression(prm.inital_value); //if (vi.num_use == 0 && !prm.name.Contains("$")) warns.Add(new UnusedParameter(prm.name, prm.loc)); } foreach (var_definition_node vdn in cnfn.var_definition_nodes_list) { VarInfo vi = helper.GetVariable(vdn); if (vdn.inital_value != null) VisitExpression(vdn.inital_value); } }
//Этот метод вызывается для предописания функции (только для предописания) private void check_function_not_exists(common_function_node fn) { SymbolInfo si=null; if (_func_stack.size<=1) { if (_ctn!=null) { si=_ctn.Scope.FindOnlyInScope(fn.name); } else { si=_cmn.scope.FindOnlyInScope(fn.name); } } else { common_function_node temp=_func_stack.pop(); si=_func_stack.top().scope.FindOnlyInScope(fn.name); _func_stack.push(temp); } while(si!=null) { if (si.sym_info == fn || si.sym_info is basic_function_node) { si=si.Next; continue; } #if (DEBUG) if (si.sym_info.general_node_type!=general_node_type.function_node) { throw new CompilerInternalError("Function name is used to define not function."); } #endif //compar - найденная функция common_function_node compar=((common_function_node)(si.sym_info)); if (compar.is_overload==false) { AddError(new FunctionMustBeWithOverloadDirective(compar,fn)); } if (convertion_data_and_alghoritms.function_eq_params(fn,compar,false)) { if (fn.IsOperator && (fn.name == compiler_string_consts.explicit_operator_name || fn.name == compiler_string_consts.implicit_operator_name)) { if (convertion_data_and_alghoritms.function_eq_params_and_result(fn,compar)) AddError(new FunctionDuplicateDefinition(compar, fn)); } else AddError(new FunctionDuplicateDefinition(compar,fn)); } si = si.Next; } }