예제 #1
0
		public type_declarations(type_declaration _type_declaration, SourceContext sc)
		{
		    Add(_type_declaration,sc);
		}
예제 #2
0
		public void visit(type_declaration _type_declaration)
		{
			bw.Write((Int16)44);
			write_type_declaration(_type_declaration);
		}
        public override void visit(procedure_definition pd)
        {
            // frninja
            // DEBUG for test
            // SORRY

            // Classification
            ISet<string> CollectedLocalsNames = new HashSet<string>();
            ISet<string> CollectedFormalParamsNames = new HashSet<string>();
            ISet<string> CollectedClassFieldsNames = new HashSet<string>();
            ISet<string> CollectedClassMethodsNames = new HashSet<string>();
            ISet<string> CollectedClassPropertiesNames = new HashSet<string>();
            ISet<string> CollectedUnitGlobalsNames = new HashSet<string>();

            ISet<var_def_statement> CollectedLocals = new HashSet<var_def_statement>();
            ISet<var_def_statement> CollectedFormalParams = new HashSet<var_def_statement>();

            // Map from ident idName -> captured ident idName
            IDictionary<string, string> CapturedLocalsNamesMap = new Dictionary<string, string>();
            IDictionary<string, string> CapturedFormalParamsNamesMap = new Dictionary<string, string>();

            hasYields = false;
            if (pd.proc_header is function_header)
                mids = new FindMainIdentsVisitor();

            base.visit(pd);

            if (!hasYields) // т.е. мы разобрали функцию и уже выходим. Это значит, что пока yield будет обрабатываться только в функциях. Так это и надо.
                return;

            LoweringVisitor.Accept(pd);

            // frninja 16/11/15: перенес ниже чтобы работал захват для lowered for

            var dld = new DeleteAllLocalDefs(); // mids.vars - все захваченные переменные
            pd.visit(dld); // Удалить в локальных и блочных описаниях этой процедуры все переменные и вынести их в отдельный список var_def_statement

            // frninja 08/12/15
            bool isClassMethod = IsClassMethod(pd);

            // Collect locals
            CollectedLocals.UnionWith(dld.LocalDeletedDefs);
            CollectedLocalsNames.UnionWith(dld.LocalDeletedDefs.SelectMany(vds => vds.vars.idents).Select(id => id.name));
            // Collect formal params
            CollectFormalParams(pd, CollectedFormalParams);
            CollectFormalParamsNames(pd, CollectedFormalParamsNames);
            // Collect class fields
            CollectClassFieldsNames(pd, CollectedClassFieldsNames);
            // Collect class methods
            CollectClassMethodsNames(pd, CollectedClassMethodsNames);
            // Collect class properties
            CollectClassPropertiesNames(pd, CollectedClassPropertiesNames);
            // Collect unit globals
            CollectUnitGlobalsNames(pd, CollectedUnitGlobalsNames);

            // Create maps :: idName -> captureName
            CreateCapturedLocalsNamesMap(CollectedLocalsNames, CapturedLocalsNamesMap);
            CreateCapturedFormalParamsNamesMap(CollectedFormalParamsNames, CapturedFormalParamsNamesMap);

            // AHAHA test!
            ReplaceCapturedVariablesVisitor rcapVis = new ReplaceCapturedVariablesVisitor(
                CollectedLocalsNames,
                CollectedFormalParamsNames,
                CollectedClassFieldsNames,
                CollectedClassMethodsNames,
                CollectedClassPropertiesNames,
                CollectedUnitGlobalsNames,
                CapturedLocalsNamesMap,
                CapturedFormalParamsNamesMap,
                isClassMethod
                );
            // Replace
            (pd.proc_body as block).program_code.visit(rcapVis);

            mids.vars.Except(dld.LocalDeletedDefsNames); // параметры остались. Их тоже надо исключать - они и так будут обработаны
            // В результате работы в mids.vars что-то осталось. Это не локальные переменные и с ними непонятно что делать

            // Обработать параметры!
            // Как? Ищем в mids formal_parametrs, но надо выделить именно обращение к параметрам - не полям класса, не глобальным переменным

            var cfa = new ConstructFiniteAutomata((pd.proc_body as block).program_code);
            cfa.Transform();
            (pd.proc_body as block).program_code = cfa.res;

            // Конструируем определение класса
            var cct = GenClassesForYield(pd, dld.LocalDeletedDefs, CapturedLocalsNamesMap, CapturedFormalParamsNamesMap); // все удаленные описания переменных делаем описанием класса

            //UpperNodeAs<declarations>().InsertBefore(pd, cct);
            if (isClassMethod)
            {
                var cd = UpperTo<class_definition>();
                if ((object)cd != null)
                {
                    var td = UpperTo<type_declarations>();
                    // Insert class predefenition!
                    var iteratorClassPredef = new type_declaration(GetClassName(pd), new class_definition(null));
                    td.types_decl.Insert(0, iteratorClassPredef);

                    foreach (var helperName in cct.types_decl.Select(ttd => ttd.type_name))
                    {
                        var helperPredef = new type_declaration(helperName, new class_definition());
                        td.types_decl.Insert(0, helperPredef);
                    }

                    foreach (var helper in cct.types_decl)
                    {
                        td.types_decl.Add(helper);
                    }

                    //UpperTo<declarations>().InsertAfter(td, cct);
                }
            }
            else
            {
                UpperTo<declarations>().InsertBefore(pd, cct);
            }

            mids = null; // вдруг мы выйдем из процедуры, не зайдем в другую, а там - оператор! Такого конечно не может быть
        }
예제 #4
0
		private type_declaration get_type_declaration(ICSharpCode.NRefactory.Ast.TypeDeclaration td)
		{
			type_declaration type_decl = new type_declaration();
			type_decl.type_name = new ident(td.Name);
			if (td.Type == ICSharpCode.NRefactory.Ast.ClassType.Enum)
			{
				type_decl.type_def = get_enum_type(td);
				type_decl.source_context = type_decl.type_def.source_context;
				return type_decl;
			}
			class_definition class_def = new class_definition();
			class_def.source_context = get_source_context(td);
			if (td.Type == ICSharpCode.NRefactory.Ast.ClassType.Interface)
				class_def.keyword = class_keyword.Interface;
			else if (td.Type == ICSharpCode.NRefactory.Ast.ClassType.Struct)
				class_def.keyword = class_keyword.Record;
			class_def.class_parents = get_base_classes(td.BaseTypes);
			class_def.body = get_class_body(td);
			type_decl.type_def = class_def;
			type_decl.source_context = class_def.source_context;
			return type_decl;
		}
예제 #5
0
 public override void visit(type_declaration _type_declaration)
 {
     //SymScope ss = entry_scope.FindScopeByLocation(_type_declaration.source_context.begin_position.line_num,_type_declaration.source_context.begin_position.column_num);
     IBaseScope ss = entry_scope.FindNameInAnyOrder(_type_declaration.type_name.name);
     if (for_refactoring && ss != null && ss.IsEqual(founded_scope) && string.Compare(ss.SymbolInfo.name, _type_declaration.type_name.name, true) == 0)
     {
         pos_list.Add(get_position(_type_declaration.type_name));
     }
     if (_type_declaration.type_def != null)
         _type_declaration.type_def.visit(this);
 }
		public void visit(type_declaration _type_declaration)
		{
			read_type_declaration(_type_declaration);
		}
예제 #7
0
		public override void visit(type_declaration _type_declaration)
		{
			throw new NotImplementedException();
		}
예제 #8
0
파일: Tree.cs 프로젝트: Slav76/pascalabcnet
		// Методы списка
		public type_declarations Add(type_declaration elem, SourceContext sc = null)
		{
			types_decl.Add(elem);
			if (sc != null)
				source_context = sc;
			return this;
		}
예제 #9
0
파일: Tree.cs 프로젝트: Slav76/pascalabcnet
		public void AddFirst(type_declaration el)
		{
			types_decl.Insert(0, el);
		}
예제 #10
0
 public void CompareInternal(type_declaration left, type_declaration right)
 {
     if (left == null && right != null || left != null && right == null)
         throw_not_equal(left, right);
     if (left != null && right != null)
     {
         CompareInternal(left.attributes, right.attributes);
         CompareInternal(left.type_name, right.type_name);
         CompareInternal(left.type_def, right.type_def);
     }
 }
예제 #11
0
파일: Tree.cs 프로젝트: Slav76/pascalabcnet
		// Конструкторы списка
		public type_declarations(type_declaration elem, SourceContext sc = null)
		{
			Add(elem, sc);
		}
 public override void visit(type_declaration _type_declaration)
 {
     connect(_type_declaration);
     visit_node(_type_declaration.type_def);
 }
예제 #13
0
		public type_declarations Add(type_declaration _type_declaration, SourceContext sc)
		{
		    types_decl.Add(_type_declaration);
		    source_context = sc;
		    return this;
		}
예제 #14
0
		public type_declarations Add(type_declaration _type_declaration)
		{
		    types_decl.Add(_type_declaration);
		    return this;
		}
 public override void visit(type_declaration _type_declaration)
 {
     visit_node(_type_declaration.type_name);
     //sb.Append(" = ");
     add_space_after = true;
     add_space_before = true;
     visit_node(_type_declaration.type_def);
 }
예제 #16
0
파일: Tree.cs 프로젝트: Slav76/pascalabcnet
		private int FindIndexInList(type_declaration el)
		{
			var ind = types_decl.FindIndex(x => x == el);
			if (ind == -1)
				throw new Exception(string.Format("У списка {0} не найден элемент {1} среди дочерних\n", this, el));
			return ind;
		}
예제 #17
0
		public override void visit(type_declaration _type_declaration)
		{
			prepare_node(_type_declaration.type_name,"type name");
			prepare_node(_type_declaration.type_def,"type definition");
		}
예제 #18
0
파일: Tree.cs 프로젝트: Slav76/pascalabcnet
		public void InsertAfter(type_declaration el, type_declaration newel)
		{
			types_decl.Insert(FindIndex(el) + 1, newel);
		}
		public void read_type_declaration(type_declaration _type_declaration)
		{
			read_declaration(_type_declaration);
			_type_declaration.type_name = _read_node() as ident;
			_type_declaration.type_def = _read_node() as type_definition;
		}
예제 #20
0
파일: Tree.cs 프로젝트: Slav76/pascalabcnet
		public void InsertBefore(type_declaration el, type_declaration newel)
		{
			types_decl.Insert(FindIndex(el), newel);
		}
        private Tuple<type_declaration, List<procedure_definition>> CreateTypeDeclarationWithForwardDeclaration(type_declaration cl)
        {
            var oldClDef = (class_definition) cl.type_def;
            var classDef = SyntaxTreeBuilder.BuildClassDefinition();
            var typeDeclaration = new type_declaration(cl.type_name, classDef);
            classDef.where_section = oldClDef.where_section;
            var procedures = new List<procedure_definition>();
            var classMembers = new class_members(access_modifer.public_modifer);
            classDef.body.class_def_blocks.Add(classMembers);

            foreach (var member in oldClDef.body.class_def_blocks.SelectMany(x => x.members))
            {
                if (member is var_def_statement)
                {
                    classMembers.Add(member);
                }
                else
                {
                    var procDef = (procedure_definition) member;
                    if (procDef.proc_header is constructor)
                    {
                        classMembers.Add(procDef);
                        continue;
                    }
                    procedure_header procHeader;
                    if (procDef.proc_header is function_header)
                    {
                        var fh = (function_header) procDef.proc_header;
                        procHeader = new function_header
                            {
                                name = new method_name(fh.name.meth_name.name),
                                source_context = fh.source_context,
                                parameters = fh.parameters,
                                of_object = fh.of_object,
                                class_keyword = fh.class_keyword
                            };
                        ((function_header)procHeader).return_type = fh.return_type;
                    }
                    else
                    {
                        procHeader = new procedure_header
                            {
                                name = new method_name(procDef.proc_header.name.meth_name.name),
                                source_context = procDef.proc_header.source_context,
                                parameters = procDef.proc_header.parameters,
                                of_object = procDef.proc_header.of_object,
                                class_keyword = procDef.proc_header.class_keyword
                            };
                    }

                    procDef.proc_header.name.class_name = cl.type_name;
                    procedures.Add(procDef);
                    classMembers.Add(procHeader);
                }
            }

            return new Tuple<type_declaration, List<procedure_definition>>(typeDeclaration, procedures);
        }
예제 #22
0
파일: Tree.cs 프로젝트: Slav76/pascalabcnet
		public void InsertBefore(type_declaration el, IEnumerable<type_declaration> newels)
		{
			types_decl.InsertRange(FindIndex(el), newels);
		}
예제 #23
0
        public override void visit(type_declaration _type_declaration)
        {
            //throw new Exception("The method or operation is not implemented.");
            cur_type_name = _type_declaration.type_name.name;
            if (_type_declaration.type_name is template_type_name)
            {
                template_args = (_type_declaration.type_name as template_type_name).template_args;
            }
            _type_declaration.type_def.visit(this);
            if (returned_scope != null && returned_scope is PointerScope && (returned_scope as PointerScope).ref_type is UnknownScope)
            {
                ref_type_wait_list.Add(returned_scope as PointerScope);
            }
            //else
            if (returned_scope != null && returned_scope is TypeScope)
            {
                //if (ret_tn is TypeScope)
                //{
                if (!(_type_declaration.type_def is named_type_reference))
                {
                    //(ret_tn as TypeScope).name = _type_declaration.type_name.name;
                    returned_scope.si.name = _type_declaration.type_name.name;
                    returned_scope.si.describe = returned_scope.GetDescription();
                    if (!(_type_declaration.type_def is class_definition))
                        returned_scope.MakeSynonimDescription();
                    returned_scope.loc = get_location(_type_declaration);//new location(loc.begin_line_num,loc.begin_column_num,ret_tn.loc.end_line_num,ret_tn.loc.end_column_num,ret_tn.loc.doc);
                    if (_type_declaration.type_def is class_definition)
                    {
                        string key = this.converter.controller.Parser.LanguageInformation.GetClassKeyword((_type_declaration.type_def as class_definition).keyword);
                        if (key != null && returned_scope.body_loc != null)
                        {
                            returned_scope.head_loc = new location(returned_scope.body_loc.begin_line_num, returned_scope.body_loc.begin_column_num, returned_scope.body_loc.begin_line_num, returned_scope.body_loc.begin_column_num + key.Length, doc);
                        }
                    }
                    if (add_doc_from_text && this.converter.controller.docs != null && this.converter.controller.docs.ContainsKey(_type_declaration))
                        returned_scope.AddDocumentation(this.converter.controller.docs[_type_declaration]);
                    if (!(_type_declaration.type_def is class_definition))
                        cur_scope.AddName(_type_declaration.type_name.name, returned_scope);
                }
                else
                {
                    TypeSynonim ts = new TypeSynonim(new SymInfo(_type_declaration.type_name.name, SymbolKind.Type, _type_declaration.type_name.name), returned_scope);
                    ts.loc = get_location(_type_declaration);
                    ts.topScope = cur_scope;
                    ts.declaringUnit = entry_scope;
                    //ts.si.describe = "type "+ret_tn.si.name+" = "+ret_tn.si.describe;
                    cur_scope.AddName(_type_declaration.type_name.name, ts);
                    if (add_doc_from_text && this.converter.controller.docs != null && this.converter.controller.docs.ContainsKey(_type_declaration))
                        ts.AddDocumentation(this.converter.controller.docs[_type_declaration]);
                }
                //}

            }
            else if (returned_scope != null)
            {
                if (returned_scope is ProcScope)
                {
                    returned_scope = new ProcType(returned_scope as ProcScope);
                    returned_scope.topScope = cur_scope;
                }
                cur_scope.AddName(_type_declaration.type_name.name, returned_scope);
                if (returned_scope is ProcType)
                {
                    returned_scope.MakeSynonimDescription();
                }
                location loc = get_location(_type_declaration);
                if (returned_scope.loc == null)
                {
                    returned_scope.loc = loc;
                    //ret_tn.loc = new location(loc.begin_line_num,loc.begin_column_num,ret_tn.loc.end_line_num,ret_tn.loc.end_column_num,ret_tn.loc.doc);
                }
            }
            returned_scope.declaringUnit = entry_scope;
            if (ref_type_wait_list.Count == 0) returned_scope = null;
            cur_type_name = null;
            template_args = null;
        }
예제 #24
0
파일: Tree.cs 프로젝트: Slav76/pascalabcnet
		public bool Remove(type_declaration el)
		{
			return types_decl.Remove(el);
		}
        /*public override void Enter(syntax_tree_node st)
        {
            base.Enter(st);
            countNodesVisited++;

            // сокращение обходимых узлов. Как сделать фильтр по тем узлам, которые необходимо обходить? Например, все операторы (без выражений и описаний), все описания (без операторов)
            if (st.GetType()==typeof(assign) || st.GetType()==typeof(var_def_statement) || st is procedure_call || st is procedure_header || st is expression)
            {
                visitNode = false; // фильтр - куда не заходить 
            }
        }*/

        /*public override void visit(class_members cm)
        {
            foreach (var decl in cm.members)
            {
                if (decl is procedure_header || decl is procedure_definition)
                    decl.visit(this);
            }
            base.visit(cm);
        }*/

        type_declarations GenClassesForYield(procedure_definition pd,
            IEnumerable<var_def_statement> fields, // локальные переменные
            IDictionary<string, string> localsMap, // отображение для захваченных имен локальных переменных
            IDictionary<string, string> formalParamsMap//, // отображение для захваченных имен формальных параметров
            //IDictionary<var_def_statement, var_def_statement> localsCloneMap // отображение для оберток локальных переменных 
            ) 
        {
            var fh = (pd.proc_header as function_header);
            if (fh == null)
                throw new SyntaxError("Only functions can contain yields", "", pd.proc_header.source_context, pd.proc_header);
            var seqt = fh.return_type as sequence_type;
            if (seqt == null)
                throw new SyntaxError("Functions with yields must return sequences", "", fh.return_type.source_context, fh.return_type);

            // Теперь на месте функции генерируем класс

            // Захваченные локальные переменные
            var cm = class_members.Public;
            var capturedFields = fields.Select(vds =>
                                    {
                                        ident_list ids = new ident_list(vds.vars.idents.Select(id => new ident(localsMap[id.name])).ToArray());
                                        if (vds.vars_type == null) //&& vds.inital_value != null)
                                        {
                                            if (vds.inital_value != null)
                                            {
                                                //return new var_def_statement(ids, new yield_unknown_expression_type(localsCloneMap[vds], varsTypeDetectorHelper), null);
                                                return new var_def_statement(ids, new yield_unknown_expression_type(vds), null); // SSM - убрал localsCloneMap[vds] - заменил на vds - не знаю, зачем вообще это отображение делалось - всё равно оно было тождественным!!!
                                            }
                                            else
                                            {
                                                throw new SyntaxVisitorError("Variable defenition without type and value!",vds.source_context); // SSM - быть такого не может - грамматика не пропустит
                                            }
                                        }
                                        else
                                        {
                                            return new var_def_statement(ids, vds.vars_type, null);
                                        }
                                        
                                        //return new var_def_statement(ids, vds.vars_type, vds.inital_value);
                                    });

            foreach (var m in capturedFields)
                cm.Add(m);

            // Параметры функции
            List<ident> lid = new List<ident>();
            var pars = fh.parameters;
            if (pars != null)
                foreach (var ps in pars.params_list)
                {
                    if (ps.param_kind != parametr_kind.none)
                        throw new SyntaxVisitorError("FUNCTIONS_WITH_YIELDS_CANNOT_CONTAIN_VAR_CONST_PARAMS_MODIFIERS", pars.source_context);
                    if (ps.inital_value != null)
                        throw new SyntaxVisitorError("FUNCTIONS_WITH_YIELDS_CANNOT_CONTAIN_DEFAULT_PARAMETERS", pars.source_context);
                    //var_def_statement vds = new var_def_statement(ps.idents, ps.vars_type);
                    ident_list ids = new ident_list(ps.idents.list.Select(id => new ident(formalParamsMap[id.name])).ToArray());
                    var_def_statement vds = new var_def_statement(ids, ps.vars_type);
                    cm.Add(vds); // все параметры функции делаем полями класса
                    //lid.AddRange(vds.vars.idents);
                    lid.AddRange(ps.idents.list);
                }

            var stels = seqt.elements_type;

            var iteratorClassName = GetClassName(pd);

            // frninja 08/18/15 - Для захвата self
            if (iteratorClassName != null)
            {
                // frninja 20/04/16 - поддержка шаблонных классов
                var iteratorClassRef = CreateClassReference(iteratorClassName);

                cm.Add(new var_def_statement(YieldConsts.Self, iteratorClassRef));
            }

            var GetEnumeratorBody = new statement_list();

            // Системные поля и методы для реализации интерфейса IEnumerable
            cm.Add(new var_def_statement(YieldConsts.State, "integer"),
                new var_def_statement(YieldConsts.Current, stels),
                procedure_definition.EmptyDefaultConstructor,
                new procedure_definition("Reset"),
                new procedure_definition("MoveNext", "boolean", pd.proc_body),
                new procedure_definition("System.Collections.IEnumerator.get_Current", "object", new assign("Result", YieldConsts.Current)),
                //new procedure_definition("System.Collections.IEnumerable.GetEnumerator", "System.Collections.IEnumerator", new assign("Result", "Self"))
                new procedure_definition("System.Collections.IEnumerable.GetEnumerator", "System.Collections.IEnumerator", GetEnumeratorBody)
                );

            // frninja 20/04/16 - поддержка шаблонных классов
            var yieldClassName = NewYieldClassName();
            var yieldClassHelperName = yieldClassName + "Helper";

            var className = this.CreateHelperClassName(yieldClassName, iteratorClassName, pd);
            var classNameHelper = this.CreateHelperClassName(yieldClassHelperName, iteratorClassName, pd);
            

            var interfaces = new named_type_reference_list("System.Collections.IEnumerator", "System.Collections.IEnumerable");

            // frninja 24/04/16 - поддержка шаблонных классов
            //var td = new type_declaration(classNameHelper, this.CreateHelperClassDefinition(classNameHelper, pd, interfaces, cm));
                //SyntaxTreeBuilder.BuildClassDefinition(interfaces, cm));

            // Изменение тела процедуры
            

            // frninja 20/04/16 - поддержка шаблонных классов
            var stl = new statement_list(new var_statement("$res", new new_expr(this.CreateClassReference(className), new expression_list())));
            

            //stl.AddMany(lid.Select(id => new assign(new dot_node("$res", id), id)));
            stl.AddMany(lid.Select(id => new assign(new dot_node("$res", new ident(formalParamsMap[id.name])), id)));

            // frninja 08/12/15 - захват self
            if (iteratorClassName != null && !pd.proc_header.class_keyword)
            {
                stl.Add(new assign(new dot_node("$res", YieldConsts.Self), new ident("self")));
            }

            stl.Add(new assign("Result", "$res"));

            // New body
            pd.proc_body = new block(stl);

            if (iteratorClassName != null)
            {
                var cd = UpperTo<class_definition>();
                if (cd != null)
                {
                    // Если метод описан в классе 
                    // frninja 10/12/15 - заменить на function_header и перенести описание тела в declarations
                    Replace(pd, fh);
                    var decls = UpperTo<declarations>();
                    if (decls != null)
                    {
                        // frninja 12/05/16 - забыли копировать return
                        function_header nfh = ObjectCopier.Clone(fh);
                        //function_header nfh = new function_header();
                        //nfh.name = new method_name(fh.name.meth_name.name);

                        // Set className
                        nfh.name.class_name = iteratorClassName;
                        //nfh.parameters = fh.parameters;
                        //nfh.proc_attributes = fh.proc_attributes;
                        //nfh.return_type = fh.return_type;

                        procedure_definition npd = new procedure_definition(nfh, new block(stl));

                        // Update header
                        //pd.proc_header.className.class_name = GetClassName(pd);
                        // Add to decls
                        decls.Add(npd);
                    }
                }
            }

            // Второй класс

            var tpl = new template_param_list(stels);

            var IEnumeratorT = new template_type_reference("System.Collections.Generic.IEnumerator", tpl);

            var cm1 = cm.Add( //class_members.Public.Add(
                //procedure_definition.EmptyDefaultConstructor,
                new procedure_definition(new function_header("get_Current", stels), new assign("Result", YieldConsts.Current)),
                new procedure_definition(new function_header("GetEnumerator", IEnumeratorT), GetEnumeratorBody),
                new procedure_definition("Dispose")
            );


            // frninja 20/04/16 - поддержка шаблонных классов
            var interfaces1 = new named_type_reference_list(/*this.CreateClassReference(classNameHelper) as named_type_reference*/);
            var IEnumerableT = new template_type_reference("System.Collections.Generic.IEnumerable", tpl);

            interfaces1.Add(IEnumerableT).Add(IEnumeratorT);

            // frninja 24/04/16 - поддержка шаблонных классов

            // frninja 05/06/16 - фикс. Поддержка where секции
            var helperClassDefinition = this.CreateHelperClassDefinition(className, pd, interfaces1, cm1);
            helperClassDefinition.where_section = this.GetMethodWhereSection(pd);

            var td1 = new type_declaration(className, helperClassDefinition);
            //SyntaxTreeBuilder.BuildClassDefinition(interfaces1, cm1));


            var stl1 = new statement_list(new var_statement("$res", new new_expr(this.CreateClassReference(className), new expression_list())));
            

            stl1.AddMany(lid.Select(id => new assign(new dot_node("$res", new ident(formalParamsMap[id.name])), new ident(formalParamsMap[id.name]))));

            // Переприсваивание self 
            if (iteratorClassName != null && !pd.proc_header.class_keyword)
            {
                stl1.Add(new assign(new dot_node("$res", YieldConsts.Self), new ident(YieldConsts.Self)));
            }

            stl1.Add(new assign("Result", "$res"));


            GetEnumeratorBody.Add(new if_node(new bin_expr(new ident(YieldConsts.State), new int32_const(0), Operators.Equal),
                new assign("Result", "Self"),
                stl1));

            var cct = new type_declarations(/*td*/);
            cct.Add(td1);

            return cct;
        }
예제 #26
0
파일: Tree.cs 프로젝트: Slav76/pascalabcnet
		public void ReplaceInList(type_declaration el, type_declaration newel)
		{
			types_decl[FindIndexInList(el)] = newel;
		}
예제 #27
0
		public void write_type_declaration(type_declaration _type_declaration)
		{
			write_declaration(_type_declaration);
			if (_type_declaration.type_name == null)
			{
				bw.Write((byte)0);
			}
			else
			{
				bw.Write((byte)1);
				_type_declaration.type_name.visit(this);
			}
			if (_type_declaration.type_def == null)
			{
				bw.Write((byte)0);
			}
			else
			{
				bw.Write((byte)1);
				_type_declaration.type_def.visit(this);
			}
		}
예제 #28
0
파일: Tree.cs 프로젝트: Slav76/pascalabcnet
		public void ReplaceInList(type_declaration el, IEnumerable<type_declaration> newels)
		{
			var ind = FindIndexInList(el);
			types_decl.RemoveAt(ind);
			types_decl.InsertRange(ind, newels);
		}
        /*public override void visit(class_members cm)
        {
            foreach (var decl in cm.members)
            {
                if (decl is procedure_header || decl is procedure_definition)
                    decl.visit(this);
            }
            base.visit(cm);
        }*/
        type_declarations GenClassesForYield(procedure_definition pd, IEnumerable<var_def_statement> fields,
            IDictionary<string, string> localsMap,
            IDictionary<string, string> formalParamsMap)
        {
            var fh = (pd.proc_header as function_header);
            if (fh == null)
                throw new SyntaxError("Only functions can contain yields", "", pd.proc_header.source_context, pd.proc_header);
            var seqt = fh.return_type as sequence_type;
            if (seqt == null)
                throw new SyntaxError("Functions with yields must return sequences", "", fh.return_type.source_context, fh.return_type);

            // Теперь на месте функции генерируем класс

            // Захваченные переменные
            var cm = class_members.Public;
            var capturedFields = fields.Select(vds =>
                                    {
                                        ident_list ids = new ident_list(vds.vars.idents.Select(id => new ident(localsMap[id.name])).ToArray());
                                        return new var_def_statement(ids, vds.vars_type, vds.inital_value);
                                    });

            foreach (var m in capturedFields)
                cm.Add(m);

            // Параметры функции
            List<ident> lid = new List<ident>();
            var pars = fh.parameters;
            if (pars != null)
                foreach (var ps in pars.params_list)
                {
                    if (ps.param_kind != parametr_kind.none)
                        throw new SyntaxError("Parameters of functions with yields must not have 'var', 'const' or 'params' modifier", "", pars.source_context, pars);
                    if (ps.inital_value != null)
                        throw new SyntaxError("Parameters of functions with yields must not have initial values", "", pars.source_context, pars);
                    //var_def_statement vds = new var_def_statement(ps.idents, ps.vars_type);
                    ident_list ids = new ident_list(ps.idents.list.Select(id => new ident(formalParamsMap[id.name])).ToArray());
                    var_def_statement vds = new var_def_statement(ids, ps.vars_type);
                    cm.Add(vds); // все параметры функции делаем полями класса
                    //lid.AddRange(vds.vars.idents);
                    lid.AddRange(ps.idents.list);
                }

            var stels = seqt.elements_type;

            // frninja 08/18/15 - Для захвата self
            if ((object)GetClassName(pd) != null)
                cm.Add(new var_def_statement(Consts.Self, GetClassName(pd).name));

            // Системные поля и методы для реализации интерфейса IEnumerable
            cm.Add(new var_def_statement(Consts.State, "integer"),
                new var_def_statement(Consts.Current, stels),
                procedure_definition.EmptyDefaultConstructor,
                new procedure_definition("Reset"),
                new procedure_definition("MoveNext", "boolean", pd.proc_body),
                new procedure_definition("get_Current", "object", new assign("Result", Consts.Current)),
                new procedure_definition("GetEnumerator", "System.Collections.IEnumerator", new assign("Result", "Self"))
                );

            var className = newClassName();
            var classNameHelper = className + "Helper";

            var interfaces = new named_type_reference_list("System.Collections.IEnumerator", "System.Collections.IEnumerable");
            var td = new type_declaration(classNameHelper, SyntaxTreeBuilder.BuildClassDefinition(interfaces, cm));

            // Изменение тела процедуры

            var stl = new statement_list(new var_statement("res", new new_expr(className)));
            //stl.AddMany(lid.Select(id => new assign(new dot_node("res", id), id)));
            stl.AddMany(lid.Select(id => new assign(new dot_node("res", new ident(formalParamsMap[id.name])), id)));

            // frninja 08/12/15 - захват self
            if ((object)GetClassName(pd) != null)
                stl.Add(new assign(new dot_node("res", Consts.Self), new ident("self")));

            stl.Add(new assign("Result", "res"));

            // New body
            pd.proc_body = new block(stl);

            if ((object)GetClassName(pd) != null)
            {
                // frninja 10/12/15 - заменить на function_header и перенести описание тела в declarations
                Replace(pd, fh);
                var decls = UpperTo<declarations>();
                if ((object)decls != null)
                {
                    function_header nfh = new function_header();
                    nfh.name = new method_name(fh.name.meth_name.name);
                    // Set name
                    nfh.name.class_name = GetClassName(pd);
                    nfh.parameters = fh.parameters;
                    nfh.proc_attributes = fh.proc_attributes;

                    procedure_definition npd = new procedure_definition(nfh, new block(stl));

                    // Update header
                    //pd.proc_header.name.class_name = GetClassName(pd);
                    // Add to decls
                    decls.Add(npd);
                }
            }

            // Второй класс

            var tpl = new template_param_list(stels);

            var IEnumeratorT = new template_type_reference("System.Collections.Generic.IEnumerator", tpl);

            var cm1 = class_members.Public.Add(
                procedure_definition.EmptyDefaultConstructor,
                new procedure_definition(new function_header("get_Current", stels), new assign("Result", Consts.Current)),
                new procedure_definition(new function_header("GetEnumerator", IEnumeratorT), new assign("Result", "Self")),
                new procedure_definition("Dispose")
            );

            var interfaces1 = new named_type_reference_list(classNameHelper);
            var IEnumerableT = new template_type_reference("System.Collections.Generic.IEnumerable", tpl);

            interfaces1.Add(IEnumerableT).Add(IEnumeratorT);

            var td1 = new type_declaration(className, SyntaxTreeBuilder.BuildClassDefinition(interfaces1, cm1));

            var cct = new type_declarations(td);
            cct.Add(td1);

            return cct;
        }
예제 #30
0
 public override void visit(type_declaration _type_declaration)
 {
     if (_type_declaration.attributes != null)
         _type_declaration.attributes.visit(this);
     _type_declaration.type_name.visit(this);
     _type_declaration.type_def.visit(this);
 }