Ejemplo n.º 1
0
        /// <summary>
        /// Возвращает по семантическому типу соответсвующий ему синтаксический тип
        /// </summary>
        /// <param name="sem_type">семантический тип</param>
        /// <returns>Синтаксический тип</returns>
        public static SyntaxTree.type_definition ConvertToSyntaxType(type_node sem_type)
        {
            if (sem_type.IsPointer)// если указатель
            {
                SyntaxTree.ref_type rt = new PascalABCCompiler.SyntaxTree.ref_type();
                rt.pointed_to = ConvertToSyntaxType((sem_type as ref_type_node).pointed_type);
                return rt;

            }
            else
                if (sem_type.type_special_kind == SemanticTree.type_special_kind.none_kind
                    || sem_type.type_special_kind == SemanticTree.type_special_kind.record || sem_type.type_special_kind == SemanticTree.type_special_kind.text_file)
                {
                    if (sem_type.is_generic_type_instance)// это шаблонный тип
                    {
                        SyntaxTree.template_type_reference ttr = new PascalABCCompiler.SyntaxTree.template_type_reference();
                        SyntaxTree.named_type_reference ntr = new PascalABCCompiler.SyntaxTree.named_type_reference();
                        ttr.name = ntr;
                        ntr.names.AddRange(get_idents_from_generic_type(sem_type));
                        SyntaxTree.template_param_list tpl = new PascalABCCompiler.SyntaxTree.template_param_list();
                        ttr.params_list = tpl;
                        foreach (type_node tn in sem_type.instance_params)
                            tpl.params_list.Add(ConvertToSyntaxType(tn));

                        return ttr;
                    }
                    else if (sem_type.IsEnum)
                        return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.name));
                    else
                        return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.PrintableName));
                }
                else if (sem_type.type_special_kind == SemanticTree.type_special_kind.array_kind || sem_type.type_special_kind == SemanticTree.type_special_kind.array_wrapper)
                {
                    //значит тип-это массив
                    SyntaxTree.array_type arr_t = new PascalABCCompiler.SyntaxTree.array_type();
                    arr_t.source_context = new PascalABCCompiler.SyntaxTree.SourceContext(0xFFFFFF, 0, 0xFFFFFF, 0);
                    // Cоздаем индексер для массива
                    SyntaxTree.indexers_types indt = new PascalABCCompiler.SyntaxTree.indexers_types();
                    if (sem_type is common_type_node)
                    {
                        SyntaxTree.diapason diap = new PascalABCCompiler.SyntaxTree.diapason();
                        common_type_node ctn = sem_type as common_type_node;
                        if (ctn.constants.Length > 1)
                        {
                            diap.left = ConvertConstant(ctn.constants[0].constant_value);
                            diap.right = ConvertConstant(ctn.constants[1].constant_value);
                            indt.indexers.Add(diap);
                        }
                        else
                        {
                            for (int i = 0; i < ctn.rank; i++)
                                indt.indexers.Add(null);
                        }

                        arr_t.indexers = indt;
                    }
                    else if (sem_type is compiled_type_node)
                    {
                        compiled_type_node ctn = sem_type as compiled_type_node;
                        if (ctn.rank > 1)
                        {
                            for (int i = 0; i < ctn.rank; i++)
                                indt.indexers.Add(null);
                            arr_t.indexers = indt;
                        }
                        //Получаем индексеры из строки
                        //string ind_str = sem_type.PrintableName;
                        //ind_str = get_indexer_string(ind_str);

                        //if (ind_str.Length != 0)
                        //{
                        //    indt.indexers.AddRange(get_diapasons(ind_str).ToArray());
                        //    arr_t.indexers = indt;
                        //}
                    }
                    //проверяем тип элементов массива               
                    if (sem_type.element_type != null)
                    {
                        arr_t.elements_type = ConvertToSyntaxType(sem_type.element_type);
                    }
                    return arr_t;
                }
                else if (sem_type.type_special_kind == SemanticTree.type_special_kind.typed_file || sem_type.type_special_kind == SemanticTree.type_special_kind.binary_file)
                {
                    SyntaxTree.file_type ft = new PascalABCCompiler.SyntaxTree.file_type();
                    if (sem_type.element_type != null)
                        ft.file_of_type = ConvertToSyntaxType(sem_type.element_type);
                    //SyntaxTree.named_type_reference ntr = null;
                    //if (sem_type.element_type!= null)
                    //    ntr= new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.element_type.name));
                    //ft.file_of_type = ntr;
                    return ft;
                }
                else if (sem_type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.short_string)
                {
                    SyntaxTree.string_num_definition snd = new PascalABCCompiler.SyntaxTree.string_num_definition();
                    snd.name = new SyntaxTree.ident(sem_type.name.Substring(0, sem_type.name.IndexOf('[')));
                    snd.num_of_symbols = new SyntaxTree.int32_const(Int32.Parse(get_indexer_string(sem_type.PrintableName)));
                    return snd;
                }
                else if (sem_type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.set_type)
                {
                    SyntaxTree.set_type_definition std = new PascalABCCompiler.SyntaxTree.set_type_definition();
                    if (sem_type.element_type != null)
                        std.of_type = ConvertToSyntaxType(sem_type.element_type);
                    return std;
                }
                else if (sem_type.type_special_kind == SemanticTree.type_special_kind.diap_type)
                {
                    return get_diapason(sem_type);


                }

            return null;
        }
Ejemplo n.º 2
0
        private static SyntaxTree.type_definition get_diapason(type_node sem_type)
        {
            if (sem_type is compiled_type_node)
                return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.PrintableName));

            if (sem_type is common_type_node)
            {
                SyntaxTree.diapason diap = new PascalABCCompiler.SyntaxTree.diapason();
                common_type_node ctn = sem_type as common_type_node;
                diap.left = ConvertConstant(ctn.low_bound);
                diap.right = ConvertConstant(ctn.upper_bound);

                return diap;

            }
            return null;
        }