//сохранение лок. переменной
		private void VisitLocalVariable(local_variable var)
		{
			SavePosition(var);
			//bw.Write((byte)var.semantic_node_type);
			bw.Write(var.name);
			WriteTypeReference(var.type);
			bw.Write(var.is_used_as_unlocal);
            if (CanWriteObject(var.inital_value))
            {
            	SaveExpressionAndOffset(var.inital_value);
            	bw.Write(0);
            	//VisitExpression((expression_node)var.inital_value);
            }
        }
        //\ssyy

        //ssyy
        public void generate_inherited_from_base_and_interface_function(common_type_node ctype, function_node func)
        {
            common_method_node gen_func = context.create_function(func.name, null) as common_method_node;
            gen_func.polymorphic_state = SemanticTree.polymorphic_state.ps_common;
            gen_func.newslot_awaited = true;
            gen_func.is_final = true;
            gen_func.is_overload = true;
            gen_func.field_access_level = SemanticTree.field_access_level.fal_public;
            gen_func.return_value_type = func.return_value_type;
            //gen_func.return_variable = func.retu

            foreach (parameter par in func.parameters)
            {
                concrete_parameter_type cpt =
                    (par.parameter_type == SemanticTree.parameter_type.value) ?
                    concrete_parameter_type.cpt_const :
                    concrete_parameter_type.cpt_var;
                common_parameter c_p = new common_parameter(par.name,
                    par.parameter_type, gen_func, cpt, null);
                c_p.type = par.type;
                c_p.set_param_is_params(par.is_params);
                c_p.inital_value = par.inital_value;
                gen_func.parameters.AddElement(c_p);
            }

            local_variable lv = new local_variable(compiler_string_consts.self_word, gen_func.cont_type, gen_func, null);
            gen_func.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(lv));
            gen_func.self_variable = lv;

            base_function_call bfc;
            this_node tn = null;

            common_method_node commn = func as common_method_node;
            if (commn != null)
            {
                tn = new this_node(commn.comperehensive_type as type_node, null);
                bfc = new common_method_call(commn, tn, null);
            }
            else
            {
                compiled_function_node compn = func as compiled_function_node;
                tn = new this_node(compn.comperehensive_type as type_node, null);
                bfc = new compiled_function_call(compn, tn, null);
            }

            foreach (parameter p in gen_func.parameters)
            {
                bfc.parameters.AddElement(
                    create_variable_reference(p, null));
            }

            //Это запретит чистку стека
            bfc.last_result_function_call = true;

            statements_list snlist = new statements_list(null);
            snlist.statements.AddElement(bfc);
            snlist.statements.AddElement(new empty_statement(null));
            gen_func.function_code = snlist;
            context.pop_top_function();
            //context.leave_block();
        }
 private void visit_class_member_realizations(SyntaxTree.class_body _class_body)
 {
 	foreach (SyntaxTree.class_members clmem in _class_body.class_def_blocks)
     {
 		foreach (SyntaxTree.declaration sd in clmem.members)
     	{
 			common_method_node cmn = context.get_method_to_realize(sd) as common_method_node;
 			
 			if (cmn != null)
 			{
 				context.push_function(cmn);
 				if (!cmn.IsStatic)
         		{
                     type_node self_type = cmn.cont_type;
                     if (cmn.cont_type.is_generic_type_definition)
                         self_type = cmn.cont_type.get_instance(cmn.cont_type.generic_params.ConvertAll<type_node>(o => (type_node)o));// new generic_instance_type_node(self_type, self_type.generic_params.ConvertAll<type_node>(o => (type_node)o), self_type.base_type, self_type.name, self_type.type_access_level, self_type.comprehensive_namespace, self_type.loc);
             		local_variable lv = new local_variable(compiler_string_consts.self_word, self_type, cmn, null);
             		cmn.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(lv));
             		cmn.self_variable = lv;
         		}
 				if ((sd as SyntaxTree.procedure_definition).proc_body != null)
         		{
             		hard_node_test_and_visit((sd as SyntaxTree.procedure_definition).proc_body);
             		add_clip_for_set(context.top_function);
             		context.leave_block();
         		}
 			}
     	}
 	}
 	context.clear_member_bindings();
 }
예제 #4
0
 public void add_special_local_var(local_variable lv)
 {
     _special_local_vars.Add(lv);
 }
        //\lroman//
		
        public override void visit(SyntaxTree.procedure_definition _procedure_definition)
        {
            // SSM 20.07.13 если это - узел с коротким определением функции без типа возвращаемого значения, то вывести этот тип
            var fh = (_procedure_definition.proc_header as SyntaxTree.function_header);
            if (fh != null && fh.return_type == null)
            {
                var bl = _procedure_definition.proc_body as SyntaxTree.block;
                if (bl != null && bl.program_code != null)
                {
                    if (bl.program_code.subnodes.Count != 1)
                        AddError(get_location(fh.name), "ONLY_IN_SHORT_FUNC_DEFS_RETURN_TYPE_CANBE_OMITTED");

                    var ass = bl.program_code.subnodes[0] as SyntaxTree.assign;
                    if (ass != null && ass.to is ident && (ass.to as ident).name.ToLower()=="result")
                    {
                        if (ass.from is nil_const)
                            AddError(get_location(ass.from), "CAN_NOT_DEDUCE_TYPE_{0}","nil");
                        
                        // undefined_type означает, что где-то в будущем это надо исправить. Потому что и Result будет этого типа
                        var typ = new semantic_type_node(new undefined_type("#Und",null));//SyntaxTreeBuilder.BuildSameType(ass.from);
                        fh.return_type = typ;
                    }
                    else AddError(get_location(fh.name), "ONLY_IN_SHORT_FUNC_DEFS_RETURN_TYPE_CANBE_OMITTED");
                }
            }
            //\ SSM

            var proc_name = _procedure_definition.proc_header != null && _procedure_definition.proc_header.name != null
                                ? _procedure_definition.proc_header.name.meth_name
                                : null;
            if (_procedure_definition.proc_header.attributes != null && context.converted_func_stack.size >= 1)
                AddError(get_location(_procedure_definition.proc_header), "ATTRIBUTES_FOR_NESTED_FUNCTIONS_NOT_ALLOWED");
            if (context.top_function != null && context.top_function.generic_params != null && !LambdaHelper.IsLambdaName(proc_name))
                AddError(get_location(_procedure_definition.proc_header), "NESTED_FUNCTIONS_IN_GENERIC_FUNCTIONS_NOT_ALLOWED");
            if (context.top_function != null && _procedure_definition.proc_header.template_args != null && !LambdaHelper.IsLambdaName(proc_name))
                AddError(get_location(_procedure_definition.proc_header), "GENERIC_NESTED_FUNCTIONS_NOT_ALLOWED");
        	if (_procedure_definition.proc_header.name != null)
                current_converted_method_not_in_class_defined = _procedure_definition.proc_header.name.class_name != null;
            else
            {
                if (_procedure_definition.proc_header is SyntaxTree.constructor)
                {
                    current_converted_method_not_in_class_defined = false;
                }
            }
            bool must_visit_body = true;
            if (SemanticRules.OrderIndependedMethodNames && !disable_order_independ && context.converting_block() == block_type.type_block && _procedure_definition.proc_body != null)
            {
            	if (_procedure_definition.proc_header.name != null)
            	{
            		if (_procedure_definition.proc_header.name.class_name == null)
            		{
            			must_visit_body = false;
            			context.is_order_independed_method_description = true;
            		}
            	}
            	else
            	{
            		must_visit_body = false;
            		context.is_order_independed_method_description = true;
            	}
            }
            if (SemanticRules.OrderIndependedFunctionNames && !disable_order_independ && context.converting_block() == block_type.namespace_block && _procedure_definition.proc_body != null && _procedure_definition.proc_header.name.class_name == null)
            {
            	if (_procedure_definition.proc_header.name != null)
            	{
            		if (_procedure_definition.proc_header.name.class_name == null)
            		{
            			must_visit_body = false;
            			context.is_order_independed_method_description = true;
            		}
            	}
            	else
            	{
            		must_visit_body = false;
            		context.is_order_independed_method_description = true;
            	}
            }
            //ssyy
            if (context.converting_block() == block_type.type_block &&
                context.converted_type.IsInterface)
            {
                AddError(get_location(_procedure_definition), "INVALID_INTERFACE_MEMBER");
            }
            //\ssyy

            //ssyy добавил
            if (context.converting_block() == block_type.function_block)
            {
                common_method_node cmnode = context.top_function as common_method_node;
                if (cmnode != null && cmnode.is_constructor)
                {
                    //throw new NotSupportedError(get_location(_procedure_definition));
                }
            }
            //\ssyy

            if (_procedure_definition.proc_body == null)
            {
                body_exists = false;
            }
            else
            {
                body_exists = true;
            }

            //lroman//
            if (_procedure_definition != null &&
                _procedure_definition.proc_header != null &&
                _procedure_definition.proc_header is SyntaxTree.function_header && 
                _procedure_definition.proc_header.name != null &&
                _procedure_definition.proc_header.name.meth_name != null &&
                LambdaHelper.IsLambdaName(_procedure_definition.proc_header.name.meth_name))
            {
                //!!!!!!!!!!!!!!!!!! 
                convertion_data_and_alghoritms.check_node_parser_error(_procedure_definition.proc_header);
                visit_lambda_header(_procedure_definition.proc_header as SyntaxTree.function_header, _procedure_definition.proc_body);
            }
            else
            {
                hard_node_test_and_visit(_procedure_definition.proc_header);
            }
            //\lroman//
            

            //ssyy
            if (context.converted_template_type != null)
            {
                if ((context.converted_template_type.type_dec.type_def as SyntaxTree.class_definition).keyword == PascalABCCompiler.SyntaxTree.class_keyword.Interface)
                {
                    AddError(new InterfaceFunctionWithBody(get_location(_procedure_definition)));
                }
                context.converted_template_type.external_methods.Add(
                    new procedure_definition_info(context.converted_namespace, _procedure_definition));
                context.converted_template_type = null;
                return;
            }
            //\ssyy
            if (context.top_function == null)
            {
                return;
            }
            if (context.converted_explicit_interface_type != null)
                (context.top_function as common_method_node).explicit_interface = context.converted_explicit_interface_type;
            if (has_dll_import_attribute(context.top_function))
            {
                if (_procedure_definition.proc_body != null)
                    if (!is_pinvoke(_procedure_definition.proc_body))
                        AddError(get_location(_procedure_definition.proc_body), "EXPECTED_EXTERNAL_STATEMENT");
            }

            if (contextChanger.IsActive())
            {
                must_visit_body = true;
            }

            if (context.top_function.return_value_type is undefined_type) // значит, это короткое определение функции, и тело есть, и его надо обойти
            {
                must_visit_body = true;
            }

            // try
            {

                if (context.top_function.is_forward)
                {
                    if (_procedure_definition.proc_body != null)
                    {
                        AddError(context.top_function.loc, "FORWARD_DEFINITION_WITH_FUNCTION_BODY");
                    }
                }
                else
                {
                    if (must_visit_body)
                    {
                        common_method_node cmn = context.top_function as common_method_node;
                        if (cmn != null && !cmn.IsStatic)
                        {
                            //if (cmn.find_only_in_namespace(compiler_string_consts.self_word) == null)
                            //self variable
                            //добавляем self, обращение к ней заменяется на this_node
                            type_node self_type = cmn.cont_type;
                            if (cmn.cont_type.is_generic_type_definition)
                                self_type = cmn.cont_type.get_instance(cmn.cont_type.generic_params.ConvertAll<type_node>(o => (type_node)o));
                            local_variable lv = new local_variable(compiler_string_consts.self_word, self_type, cmn, null);
                            cmn.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(lv));
                            cmn.self_variable = lv;
                        }
                        if (_procedure_definition.proc_body != null)
                        {
                            hard_node_test_and_visit(_procedure_definition.proc_body);
                        }

                        // SSM 12/04/16 - short func definitions - calc return_value_type
                        var ttt = context.top_function.return_value_type;
                        if (ttt is undefined_type)
                        {
                            var cd = context.top_function.function_code as statements_list;

                            if (cd == null || cd.statements == null || cd.statements.Count == 0)
                            {
                                AddError(context.top_function.loc, "IMPOSSIBLE!SHORT_FUNC_WITHOUT_BODY");
                            }

                            // Проблема в том, что если в теле короткого определения функции - лямбда
                            // и происходит захват переменной, то в тело выносится вызов конструктора сгенерированного класса
                            // Поэтому result := ... - это не первый оператор, а последний!!!
                            statement_node aa = cd.statements[cd.statements.Count-1];
                            var bfc = aa as basic_function_call;
                            if (bfc != null)
                            {
                                var ttt1 = bfc.type;
                                context.top_function.return_value_type = ttt1;
                                context.top_function.var_definition_nodes_list[0].type = ttt1;
                            }
                        }

                        add_clip_for_set(context.top_function);
                    }
                    else // if (!must_visit_body)
                    {
                        context.add_method_header(_procedure_definition, context.top_function);
                    }

                }
            }
            //finally
            {
                if (_procedure_definition.proc_header.name.class_name != null)
                {
                    context.leave_type_method();
                }
                context.is_order_independed_method_description = false;
                context.leave_block();
            }
        }
예제 #6
0
		public common_function_node create_function(string name,location def_loc)
		{
			check_function_name(name,def_loc);
			common_function_node cfn=null;
			switch (converting_block())
			{
				case block_type.function_block:
				{
                    common_function_node top_func = _func_stack.top();
                    SymbolTable.Scope scope = convertion_data_and_alghoritms.symbol_table.CreateScope(top_func.scope);
					common_in_function_function_node ciffn;
					ciffn=new common_in_function_function_node(name,def_loc,top_func,scope);
					top_func.functions_nodes_list.AddElement(ciffn);
					_last_created_function=new SymbolInfo(ciffn);
					top_func.scope.AddSymbol(name,_last_created_function);
					cfn=ciffn;
					break;
				}
				case block_type.type_block:
				{
					common_method_node cmmn;
                    SymbolTable.Scope scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_cmn.scope, _ctn.Scope);
                    //TODO:сделать static и virtual.
                    //TODO: interface and implementation scopes.
					cmmn=new common_method_node(name,def_loc,_ctn,SemanticTree.polymorphic_state.ps_common,_fal,scope);
					_last_created_function=new SymbolInfo(cmmn);
					_ctn.Scope.AddSymbol(name,_last_created_function);
					_ctn.methods.AddElement(cmmn);

                    local_variable lv = new local_variable(compiler_string_consts.self_word, _ctn, cmmn, def_loc);
                    cmmn.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(lv));
                    cmmn.self_variable = lv;
                    cmmn.var_definition_nodes_list.AddElement(lv);

					cfn=cmmn;
					break;
				}
				case block_type.namespace_block:
				{
					common_namespace_function_node cnfnn;
                    SymbolTable.Scope scope = convertion_data_and_alghoritms.symbol_table.CreateScope(_cmn.scope);
					cnfnn=new common_namespace_function_node(name,def_loc,_cmn,scope);
					_cmn.functions.AddElement(cnfnn);
					_last_created_function=new SymbolInfo(cnfnn);
					_cmn.scope.AddSymbol(name,_last_created_function);
					cfn=cnfnn;
					break;
				}
			}
			_func_stack.push(cfn);
			return cfn;
		}
예제 #7
0
		public var_definition_node create_temp_variable(string name,type_node type,location loc)
		{
			var_definition_node vdn=null;
			switch (converting_block())
			{
				case block_type.function_block:
				{
                    common_function_node top_func = _func_stack.top();
					local_variable lv=new local_variable(name,type,top_func,loc);
					vdn=lv;
					top_func.var_definition_nodes_list.AddElement(lv);
					break;
				}
				case block_type.type_block:
				{
                    //TODO:сделать static и virtual.
					class_field cf=new class_field(name,type,_ctn,SemanticTree.polymorphic_state.ps_common,_fal,loc);
					vdn=cf;
					_ctn.fields.AddElement(cf);
					break;
				}
				case block_type.namespace_block:
				{
					namespace_variable nsv=new namespace_variable(name,type,_cmn,loc);
					vdn=nsv;
					_cmn.variables.AddElement(nsv);
					break;
				}
			}
			return vdn;
		}
		public SymbolInfo(local_variable value)
		{
			//_name_information_type=name_information_type.nit_local_variable;
			_sym_info=value;
			_access_level=access_level.al_public;
			_symbol_kind=symbol_kind.sk_none;
		}
        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;
		}
예제 #10
0
 public local_variable_reference(local_variable var, int static_depth, location loc) : base(var.type, loc)
 {
     _var = var;
     this.static_depth = static_depth;
 }
예제 #11
0
		public local_variable_reference(local_variable var,int static_depth,location loc) : base(var.type,loc)
		{
			_var=var;
			this.static_depth=static_depth;   
		}
예제 #12
0
        //\lroman//
		
        public override void visit(SyntaxTree.procedure_definition _procedure_definition)
        {
            // SSM 20.07.13 если это - узел с коротким определением функции без типа возвращаемого значения, то вывести этот тип
            var fh = (_procedure_definition.proc_header as SyntaxTree.function_header);
            if (fh != null && fh.return_type == null)
            {
                // попытаемся поступить как в лямбдах
                //fh.return_type = new semantic_type_node(new LambdaResultTypeInferrer(fh, _procedure_definition.proc_body, this).InferResultType(1));
                var bl = _procedure_definition.proc_body as SyntaxTree.block;
                if (bl != null && bl.program_code != null)
                {
                    var ass = bl.program_code.subnodes[0] as SyntaxTree.assign;
                    if (ass != null)
                    {
                        var typ = SyntaxTreeBuilder.BuildSameType(ass.from);
                        fh.return_type = typ;
                    }
                }
            }
            //\ SSM

            var proc_name = _procedure_definition.proc_header != null && _procedure_definition.proc_header.name != null
                                ? _procedure_definition.proc_header.name.meth_name
                                : null;
            if (_procedure_definition.proc_header.attributes != null && context.converted_func_stack.size >= 1)
                AddError(get_location(_procedure_definition.proc_header), "ATTRIBUTES_FOR_NESTED_FUNCTIONS_NOT_ALLOWED");
            if (context.top_function != null && context.top_function.generic_params != null && !LambdaHelper.IsLambdaName(proc_name))
                AddError(get_location(_procedure_definition.proc_header), "NESTED_FUNCTIONS_IN_GENERIC_FUNCTIONS_NOT_ALLOWED");
            if (context.top_function != null && _procedure_definition.proc_header.template_args != null && !LambdaHelper.IsLambdaName(proc_name))
                AddError(get_location(_procedure_definition.proc_header), "GENERIC_NESTED_FUNCTIONS_NOT_ALLOWED");
        	if (_procedure_definition.proc_header.name != null)
                current_converted_method_not_in_class_defined = _procedure_definition.proc_header.name.class_name != null;
            else
            {
                if (_procedure_definition.proc_header is SyntaxTree.constructor)
                {
                    current_converted_method_not_in_class_defined = false;
                }
            }
            bool must_visit_body = true;
            if (SemanticRules.OrderIndependedMethodNames && !disable_order_independ && context.converting_block() == block_type.type_block && _procedure_definition.proc_body != null)
            {
            	if (_procedure_definition.proc_header.name != null)
            	{
            		if (_procedure_definition.proc_header.name.class_name == null)
            		{
            			must_visit_body = false;
            			context.is_order_independed_method_description = true;
            		}
            	}
            	else
            	{
            		must_visit_body = false;
            		context.is_order_independed_method_description = true;
            	}
            }
            if (SemanticRules.OrderIndependedFunctionNames && !disable_order_independ && context.converting_block() == block_type.namespace_block && _procedure_definition.proc_body != null && _procedure_definition.proc_header.name.class_name == null)
            {
            	if (_procedure_definition.proc_header.name != null)
            	{
            		if (_procedure_definition.proc_header.name.class_name == null)
            		{
            			must_visit_body = false;
            			context.is_order_independed_method_description = true;
            		}
            	}
            	else
            	{
            		must_visit_body = false;
            		context.is_order_independed_method_description = true;
            	}
            }
            //ssyy
            if (context.converting_block() == block_type.type_block &&
                context.converted_type.IsInterface)
            {
                AddError(get_location(_procedure_definition), "INVALID_INTERFACE_MEMBER");
            }
            //\ssyy

            //ssyy добавил
            if (context.converting_block() == block_type.function_block)
            {
                common_method_node cmnode = context.top_function as common_method_node;
                if (cmnode != null && cmnode.is_constructor)
                {
                    //throw new NotSupportedError(get_location(_procedure_definition));
                }
            }
            //\ssyy

            if (_procedure_definition.proc_body == null)
            {
                body_exists = false;
            }
            else
            {
                body_exists = true;
            }

            //lroman//
            if (_procedure_definition != null &&
                _procedure_definition.proc_header != null &&
                _procedure_definition.proc_header is SyntaxTree.function_header && 
                _procedure_definition.proc_header.name != null &&
                _procedure_definition.proc_header.name.meth_name != null &&
                LambdaHelper.IsLambdaName(_procedure_definition.proc_header.name.meth_name))
            {
                //!!!!!!!!!!!!!!!!!! 
                convertion_data_and_alghoritms.check_node_parser_error(_procedure_definition.proc_header);
                visit_lambda_header(_procedure_definition.proc_header as SyntaxTree.function_header, _procedure_definition.proc_body);
            }
            else
            {
                hard_node_test_and_visit(_procedure_definition.proc_header);
            }
            //\lroman//

            //ssyy
            if (context.converted_template_type != null)
            {
                if ((context.converted_template_type.type_dec.type_def as SyntaxTree.class_definition).keyword == PascalABCCompiler.SyntaxTree.class_keyword.Interface)
                {
                    AddError(new InterfaceFunctionWithBody(get_location(_procedure_definition)));
                }
                context.converted_template_type.external_methods.Add(
                    new procedure_definition_info(context.converted_namespace, _procedure_definition));
                context.converted_template_type = null;
                return;
            }
            //\ssyy
            if (context.top_function == null)
            {
                return;
            }
            if (has_dll_import_attribute(context.top_function))
            {
                if (_procedure_definition.proc_body != null)
                    if (!is_pinvoke(_procedure_definition.proc_body))
                        AddError(get_location(_procedure_definition.proc_body), "EXPECTED_EXTERNAL_STATEMENT");
            }

            if (contextChanger.IsActive())
            {
                must_visit_body = true;
            }

           // try
            {

                if (context.top_function.is_forward)
                {
                    if (_procedure_definition.proc_body != null)
                    {
                        AddError(context.top_function.loc, "FORWARD_DEFINITION_WITH_FUNCTION_BODY");
                    }
                }
                else if (must_visit_body)
                {
                    common_method_node cmn = context.top_function as common_method_node;
                    if (cmn != null && !cmn.IsStatic)
                    {
                        //if (cmn.find_only_in_namespace(compiler_string_consts.self_word) == null)
                        //self variable
                        //добавляем self, обращение к ней заменяется на this_node
                        type_node self_type = cmn.cont_type;
                        if (cmn.cont_type.is_generic_type_definition)
                            self_type = cmn.cont_type.get_instance(cmn.cont_type.generic_params.ConvertAll<type_node>(o => (type_node)o));
                        local_variable lv = new local_variable(compiler_string_consts.self_word, self_type, cmn, null);
                        cmn.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(lv));
                        cmn.self_variable = lv;
                    }
                    if (_procedure_definition.proc_body != null)
                    {
                        hard_node_test_and_visit(_procedure_definition.proc_body);
                    }

                    add_clip_for_set(context.top_function);
                }

                if (!must_visit_body)
                {
                    context.add_method_header(_procedure_definition, context.top_function);
                }

            }
            //finally
            {
                if (_procedure_definition.proc_header.name.class_name != null)
                {
                    context.leave_type_method();
                }
                context.is_order_independed_method_description = false;
                context.leave_block();
            }
        }
		public var_definition_node add_var_definition(string name, location loc, type_node tn, SemanticTree.polymorphic_state ps)
		{
			check_name_free(name,loc);
			var_definition_node vdn=null;
            if (CurrentScope is SymbolTable.BlockScope)
            {
                if (SemanticRules.DisabledDefinitionBlockVariablesWithSameNameThatInAboveScope)
                {
                    SymbolTable.Scope cs = CurrentScope;
                    while (cs.TopScope != null /*(cs.TopScope is SymbolTable.BlockScope || cs.TopScope is SymbolTable.UnitPartScope)*/)
                    {
                    	if (cs.TopScope is SymbolTable.BlockScope)//projdemsja po blokam koda
                    	{
                    		if (cs.TopScope.FindOnlyInScope(name) != null)
                                syntax_tree_visitor.AddError(loc, "BLOCK_VARIABLES_CANNOT_HAVE_NAMES_UPPER_SCOPE");
                    		cs = cs.TopScope;
                    	}
                    	else // a zdes proverjaem v verhnem bloke i vse, to chto eshe vyshe, tam ne proverjaem, tak dejstvuet princip blochnosti
                    	{
                    		if (cs.TopScope.FindOnlyInScope(name) != null)
                                syntax_tree_visitor.AddError(loc, "BLOCK_VARIABLES_CANNOT_HAVE_NAMES_UPPER_SCOPE");
                    		break;
                    	}
                        
                    }
                }
            	local_block_variable lv = new local_block_variable(name, tn, CurrentStatementList, loc);
                CurrentScope.AddSymbol(name, new SymbolInfo(lv));
                lv.block.local_variables.Add(lv);
                if (tn == null) //Тип еще неизвестен, будем закрывать.
                    var_defs.Add(lv);
                return lv;
            }
            switch (converting_block())
			{
				case block_type.function_block:
				{
                    common_function_node top_func = _func_stack.top();
					local_variable lv=new local_variable(name,tn,top_func,loc);
					vdn=lv;
					top_func.var_definition_nodes_list.AddElement(lv);
                    CurrentScope.AddSymbol(name, new SymbolInfo(lv));
					//top_func.scope.AddSymbol(name,new SymbolInfo(lv));
					break;
				}
				case block_type.type_block:
				{
                    //TODO:сделать static и virtual.
                    class_field cf = new class_field(name,tn, _ctn, ps,_fal,loc);
					vdn=cf;
					//_ctn.Scope.AddSymbol(name,new SymbolInfo(cf));
                    CurrentScope.AddSymbol(name, new SymbolInfo(cf));
					_ctn.fields.AddElement(cf);
					break;
				}
				case block_type.namespace_block:
				{
					namespace_variable nsv=new namespace_variable(name,tn,_cmn,loc);
					vdn=nsv;
					//_cmn.scope.AddSymbol(name,new SymbolInfo(nsv));
                    CurrentScope.AddSymbol(name, new SymbolInfo(nsv));
					_cmn.variables.AddElement(nsv);
					break;
				}
			}
            if (tn == null) //Тип еще неизвестен, будем закрывать.
                var_defs.Add(vdn);
            return vdn;
		}
예제 #14
0
		private type_node create_array_type(ordinal_type_interface oti_indexer, type_node element_type,common_namespace_node _cmn, location loc)
		{
			int arr_length = oti_indexer.ordinal_type_to_int(oti_indexer.upper_value) -
				oti_indexer.ordinal_type_to_int(oti_indexer.lower_value) + 1;

			if (arr_length <= 0)
			{
				throw new SimpleSemanticError(loc, "NEGATIVE_ARRAY_LENGTH_({0})_NOT_ALLOWED", arr_length);
			}

			simple_array sa = new simple_array(element_type, arr_length);
			//sa.length = arr_length;
			//sa.element_type = element_type;

			SymbolTable.Scope top_scope = null;
			if (_cmn != null)
			{
				top_scope = _cmn.scope;
			}
			string name = get_pascal_array_name();
			//if (_cmn.namespace_name != null)
			//    name = _cmn.namespace_name + name;
			common_type_node ctn = new common_type_node(null, name, SemanticTree.type_access_level.tal_public,
			                                            _cmn, convertion_data_and_alghoritms.symbol_table.CreateClassScope(top_scope, null), loc);

			ctn.SetBaseType(SystemLibrary.SystemLibrary.object_type);
			//DarkStar Add
			//loc не нужно мне это!  и некому не нужно!
			//loc = null;
			
			//ctn.internal_is_value = true;

			class_constant_definition cdn1 = new class_constant_definition(compiler_string_consts.lower_array_const_name,
			                                                               oti_indexer.lower_value, loc, ctn, SemanticTree.field_access_level.fal_public);
			ctn.scope.AddSymbol(cdn1.name, new SymbolInfo(cdn1));

			class_constant_definition cdn2 = new class_constant_definition(compiler_string_consts.upper_array_const_name,
			                                                               oti_indexer.upper_value, loc, ctn, SemanticTree.field_access_level.fal_public);
			ctn.scope.AddSymbol(cdn2.name, new SymbolInfo(cdn2));

			class_field int_arr = new class_field(compiler_string_consts.internal_array_name, sa, ctn,
			                                      SemanticTree.polymorphic_state.ps_common, SemanticTree.field_access_level.fal_public,loc);
			ctn.scope.AddSymbol(int_arr.name, new SymbolInfo(int_arr));
			ctn.fields.AddElement(int_arr);

			SystemLibrary.SystemLibrary.init_reference_type(ctn);

			ctn.const_defs.AddElement(cdn1);
			ctn.const_defs.AddElement(cdn2);

			common_method_node get_func = new common_method_node(compiler_string_consts.get_val_pascal_array_name,
			                                                     element_type, /*loc*/new location(0xFFFFFF, 0, 0xFFFFFF, 0, loc.doc), ctn, SemanticTree.polymorphic_state.ps_common, SemanticTree.field_access_level.fal_private,
			                                                     convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope));
			common_parameter get_param = new common_parameter(compiler_string_consts.unary_param_name,
			                                                  oti_indexer.lower_value.type, SemanticTree.parameter_type.value, get_func, concrete_parameter_type.cpt_none,
			                                                  null, loc);
			get_func.parameters.AddElement(get_param);

			common_parameter_reference cpr = new common_parameter_reference(get_param, 0, loc);
			expression_node en1 = convertion_data_and_alghoritms.create_simple_function_call(oti_indexer.value_to_int,
			                                                                                 loc, cpr);
			expression_node en2 = new int_const_node(oti_indexer.ordinal_type_to_int(oti_indexer.lower_value), loc);
			expression_node sub_expr = convertion_data_and_alghoritms.create_simple_function_call(
				SystemLibrary.SystemLibrary.int_sub, loc, en1, en2);

			this_node thisnode = new this_node(ctn, loc);

			class_field_reference cfr1 = new class_field_reference(int_arr, thisnode, loc);

			expression_node index_expr = new simple_array_indexing(cfr1, sub_expr, element_type, loc);

			statement_node sn = new return_node(index_expr, /*loc*/new location(0xFFFFFF, 0, 0xFFFFFF, 0, loc.doc));

			get_func.function_code = sn;

			common_method_node set_func = new common_method_node(compiler_string_consts.set_val_pascal_array_name,
			                                                     null, /*loc*/new location(0xFFFFFF, 0, 0xFFFFFF, 0, loc.doc), ctn, SemanticTree.polymorphic_state.ps_common, SemanticTree.field_access_level.fal_private,
			                                                     convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope));
			common_parameter set_ind = new common_parameter(compiler_string_consts.left_param_name,
			                                                oti_indexer.lower_value.type, SemanticTree.parameter_type.value, set_func, concrete_parameter_type.cpt_none,
			                                                null, loc);
			set_func.parameters.AddElement(set_ind);
			common_parameter set_val = new common_parameter(compiler_string_consts.right_param_name,
			                                                element_type, SemanticTree.parameter_type.value, set_func, concrete_parameter_type.cpt_none, null, loc);
			set_func.parameters.AddElement(set_val);

			common_parameter_reference cpr2 = new common_parameter_reference(set_ind, 0, loc);
			expression_node en3 = convertion_data_and_alghoritms.create_simple_function_call(oti_indexer.value_to_int,
			                                                                                 loc, cpr2);
			expression_node en4 = new int_const_node(oti_indexer.ordinal_type_to_int(oti_indexer.lower_value), loc);
			expression_node sub_expr2 = convertion_data_and_alghoritms.create_simple_function_call(
				SystemLibrary.SystemLibrary.int_sub, loc, en3, en4);

			class_field_reference cfr2 = new class_field_reference(int_arr, thisnode, loc);

			expression_node index_expr2 = new simple_array_indexing(cfr2, sub_expr2, element_type,loc);

			SymbolInfo si = element_type.find_in_type(compiler_string_consts.assign_name);
			if (si == null)
			{
				throw new NotSupportedError(loc);
				throw new CompilerInternalError("Varable of this type can not be assigned");
			}
			if (si.sym_info.general_node_type != general_node_type.function_node)
			{
				throw new CompilerInternalError("Invalid assign operator");
			}

			expression_node val_ref = new common_parameter_reference(set_val, 0, loc);

			function_node assign = (function_node)si.sym_info;
			statement_node assign_call = convertion_data_and_alghoritms.create_simple_function_call(assign,
			                                                                                        /*loc*/new location(0xFFFFFF, 0, 0xFFFFFF, 0, loc.doc), index_expr2, val_ref);

			set_func.function_code = assign_call;

			ctn.methods.AddElement(get_func);
			ctn.methods.AddElement(set_func);

			common_property_node cpn = new common_property_node(compiler_string_consts.index_property_pascal_array_name,
			                                                    ctn, element_type, get_func, set_func, loc, SemanticTree.field_access_level.fal_public, SemanticTree.polymorphic_state.ps_common);

			common_parameter prop_cp = new common_parameter(compiler_string_consts.unary_param_name, oti_indexer.lower_value.type,
			                                                SemanticTree.parameter_type.value, null, concrete_parameter_type.cpt_none, null, loc);
			cpn.parameters.AddElement(prop_cp);

			ctn.properties.AddElement(cpn);

			ctn.default_property = cpn;

			if (_cmn != null)
			{
				_cmn.types.AddElement(ctn);
			}

			bounded_array_interface bai = new bounded_array_interface(oti_indexer, element_type, cpn, oti_indexer.lower_value.type, int_arr);
			ctn.add_internal_interface(bai);
			ctn.type_special_kind = SemanticTree.type_special_kind.array_wrapper;

            if (element_type.type_special_kind != SemanticTree.type_special_kind.array_wrapper)
            {
                ctn.ImplementingInterfaces.Add(compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IEnumerableInterfaceName)));
                common_method_node en_cmn = new common_method_node(compiler_string_consts.GetEnumeratorMethodName, compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IEnumeratorInterfaceName)), null, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, null);

                compiled_function_node en_fnc = NetHelper.NetHelper.FindName(NetHelper.NetHelper.FindType(compiler_string_consts.IEnumerableInterfaceName), compiler_string_consts.GetEnumeratorMethodName).sym_info as compiled_function_node;
                statements_list sl = new statements_list(null);
                sl.statements.AddElement(new return_node(
                    new compiled_function_call(en_fnc, new class_field_reference(int_arr, new this_node(ctn, null), null), null), null));
                en_cmn.function_code = sl;
                en_cmn.newslot_awaited = true;
                ctn.methods.AddElement(en_cmn);

                if (!element_type.IsPointer)
                {
                    List<type_node> generic_args = new List<type_node>();
                    generic_args.Add(element_type);
                    type_node en_tn = compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IGenericEnumerableInterfaceName)).get_instance(generic_args);
                    ctn.ImplementingInterfaces.Add(en_tn);

                    en_cmn = new common_method_node(compiler_string_consts.GetEnumeratorMethodName, compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IGenericEnumeratorInterfaceName)).get_instance(generic_args), null, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, null);
                    //en_fnc = en_tn.find_in_type("GetEnumerator").sym_info as function_node;//NetHelper.NetHelper.FindName(NetHelper.NetHelper.FindType(compiler_string_consts.IGenericEnumerableInterfaceName), compiler_string_consts.GetEnumeratorMethodName).sym_info as compiled_function_node;
                    SymbolInfo en_si = en_tn.find_in_type("GetEnumerator");
                    if (en_si.Next != null && (en_si.Next.sym_info as function_node).return_value_type.is_generic_type_instance)
                        en_si = en_si.Next;
                    function_node en_fnc_inst = en_si.sym_info as function_node; ;//.get_instance(generic_args, true, loc);
                    sl = new statements_list(null);
                    if (en_fnc_inst is compiled_function_node)
                        sl.statements.AddElement(new return_node(
                            new compiled_function_call(en_fnc_inst as compiled_function_node, new class_field_reference(int_arr, new this_node(ctn, null), null), null), null));
                    else
                        sl.statements.AddElement(new return_node(
                            new common_method_call(en_fnc_inst as common_method_node, new class_field_reference(int_arr, new this_node(ctn, null), null), null), null));
                    en_cmn.function_code = sl;
                    en_cmn.newslot_awaited = true;
                    ctn.methods.AddElement(en_cmn);
                }
            }
			
			//= operation
			SymbolTable.ClassMethodScope scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_cmn.scope,ctn.scope);
        	common_method_node cmn_eq = new common_method_node(compiler_string_consts.GetNETOperName(compiler_string_consts.eq_name),SystemLibrary.SystemLibrary.bool_type,null,ctn,
        	                                                SemanticTree.polymorphic_state.ps_static,SemanticTree.field_access_level.fal_public,scope);
        	cmn_eq.IsOperator = true;
        	common_parameter prm1 = new common_parameter("a",ctn,SemanticTree.parameter_type.value,cmn_eq,concrete_parameter_type.cpt_none,null,null);
        	common_parameter prm2 = new common_parameter("b",ctn,SemanticTree.parameter_type.value,cmn_eq,concrete_parameter_type.cpt_none,null,null);
        	cmn_eq.parameters.AddElement(prm1);
        	cmn_eq.parameters.AddElement(prm2);
        	statements_list body = new statements_list(null);
        	local_variable vdn = new local_variable("$i",SystemLibrary.SystemLibrary.integer_type,cmn_eq,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null);
        	cmn_eq.var_definition_nodes_list.AddElement(vdn);
        	expression_node var_ref = new local_variable_reference(vdn,0,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.create_variable_reference(vdn,null);
        	basic_function_call cond = new basic_function_call(SystemLibrary.SystemLibrary.int_sm as basic_function_node,null);
        	cond.parameters.AddElement(var_ref);
        	cond.parameters.AddElement(new int_const_node(arr_length,null));
        	while_node while_stmt = new while_node(cond,null);
        	statements_list while_body = new statements_list(null);
        	while_stmt.body = while_body;
        	simple_array_indexing left_sar = new simple_array_indexing(new class_field_reference(int_arr, new common_parameter_reference(prm1,0,null), null),var_ref,element_type,null);
        	simple_array_indexing right_sar = new simple_array_indexing(new class_field_reference(int_arr, new common_parameter_reference(prm2,0,null), null),var_ref,element_type,null);
        	expression_node cond2 = SystemLibrary.SystemLibrary.syn_visitor.find_operator(compiler_string_consts.noteq_name,
        		                                                                            left_sar,right_sar,null);
        	if_node if_stmt = new if_node(cond2,new return_node(new bool_const_node(false,null),null),null,null);
        	while_body.statements.AddElement(if_stmt);
        	while_body.statements.AddElement(new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,null
        	                                                   ,var_ref,new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,null,var_ref,new int_const_node(1,null))));
        	
        	body.statements.AddElement(while_stmt);
        	body.statements.AddElement(new return_node(new bool_const_node(true,null),null));
        	cmn_eq.function_code = body;
        	cmn_eq.is_overload = true;
        	ctn.methods.AddElement(cmn_eq);
        	ctn.Scope.AddSymbol(compiler_string_consts.eq_name,new SymbolInfo(cmn_eq));
        	
        	//<> operation
			scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_cmn.scope,ctn.scope);
        	common_method_node cmn_noteq = new common_method_node(compiler_string_consts.GetNETOperName(compiler_string_consts.noteq_name),SystemLibrary.SystemLibrary.bool_type,null,ctn,
        	                                                SemanticTree.polymorphic_state.ps_static,SemanticTree.field_access_level.fal_public,scope);
        	cmn_noteq.IsOperator = true;
        	prm1 = new common_parameter("a",ctn,SemanticTree.parameter_type.value,cmn_noteq,concrete_parameter_type.cpt_none,null,null);
        	prm2 = new common_parameter("b",ctn,SemanticTree.parameter_type.value,cmn_noteq,concrete_parameter_type.cpt_none,null,null);
        	cmn_noteq.parameters.AddElement(prm1);
        	cmn_noteq.parameters.AddElement(prm2);
        	body = new statements_list(null);
        	vdn = new local_variable("$i",SystemLibrary.SystemLibrary.integer_type,cmn_noteq,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null);
        	cmn_noteq.var_definition_nodes_list.AddElement(vdn);
        	var_ref = new local_variable_reference(vdn,0,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.create_variable_reference(vdn,null);
        	cond = new basic_function_call(SystemLibrary.SystemLibrary.int_sm as basic_function_node,null);
        	cond.parameters.AddElement(var_ref);
        	cond.parameters.AddElement(new int_const_node(arr_length,null));
        	while_stmt = new while_node(cond,null);
        	while_body = new statements_list(null);
        	while_stmt.body = while_body;
        	left_sar = new simple_array_indexing(new class_field_reference(int_arr, new common_parameter_reference(prm1,0,null), null),var_ref,element_type,null);
        	right_sar = new simple_array_indexing(new class_field_reference(int_arr, new common_parameter_reference(prm2,0,null), null),var_ref,element_type,null);
        	cond2 = SystemLibrary.SystemLibrary.syn_visitor.find_operator(compiler_string_consts.noteq_name,
        		                                                                            left_sar,right_sar,null);
        	if_stmt = new if_node(cond2,new return_node(new bool_const_node(true,null),null),null,null);
        	while_body.statements.AddElement(if_stmt);
        	while_body.statements.AddElement(new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,null
        	                                                   ,var_ref,new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,null,var_ref,new int_const_node(1,null))));
        	
        	body.statements.AddElement(while_stmt);
        	body.statements.AddElement(new return_node(new bool_const_node(false,null),null));
        	cmn_noteq.function_code = body;
        	cmn_noteq.is_overload = true;
        	ctn.methods.AddElement(cmn_noteq);
        	ctn.Scope.AddSymbol(compiler_string_consts.noteq_name,new SymbolInfo(cmn_noteq));
        	
        	//Equals
        	/*scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_cmn.scope,ctn.scope);
        	common_method_node cmn_equals = new common_method_node("Equals",SystemLibrary.SystemLibrary.bool_type,null,ctn,
        	                                                SemanticTree.polymorphic_state.ps_virtual,SemanticTree.field_access_level.fal_public,scope);
        	prm1 = new common_parameter("a",SystemLibrary.SystemLibrary.object_type,SemanticTree.parameter_type.value,cmn_equals,concrete_parameter_type.cpt_none,null,null);
        	
        	cmn_equals.parameters.AddElement(prm1);
        	body = new statements_list(null);
        	vdn = new local_variable("$i",ctn,cmn_equals,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null);
        	cmn_equals.var_definition_nodes_list.AddElement(vdn);
        	var_ref = new local_variable_reference(vdn,0,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.create_variable_reference(vdn,null);
        	as_node _as = new as_node(new common_parameter_reference(prm1,0,null),ctn,null);
        	base_function_call ass_bfc = new basic_function_call(SystemLibrary.SystemLibrary.object_type.find(compiler_string_consts.assign_name).sym_info as basic_function_node,null);
        	ass_bfc.parameters.AddElement(var_ref);
        	ass_bfc.parameters.AddElement(_as);
        	body.statements.AddElement(ass_bfc);
        	common_static_method_call csmc = new common_static_method_call(ctn.find_in_type(compiler_string_consts.eq_name).sym_info as common_method_node,null);
        	csmc.parameters.AddElement(new this_node(ctn,null));
        	csmc.parameters.AddElement(var_ref);
        	body.statements.AddElement(new return_node(csmc,null));
        	ctn.methods.AddElement(cmn_equals);
        	ctn.Scope.AddSymbol("Equals",new SymbolInfo(cmn_equals));*/
        	return ctn;
		}