/// <summary> /// Создать var-выражение /// </summary> /// <param name="name">Имя переменной</param> /// <param name="initialValue">Начальное значение</param> /// <returns></returns> public var_def_statement CreateVarDef(string name, expression initialValue) { ident_list list = new ident_list(); list.idents.Add(new ident(name)); var res = new var_def_statement(); res.inital_value = initialValue; res.vars = list; return res; }
///<summary> ///Конструктор с параметрами. ///</summary> public variant(ident_list _vars,type_definition _vars_type,SourceContext sc) { this._vars=_vars; this._vars_type=_vars_type; source_context = sc; }
public void write_ident_list(ident_list _ident_list) { write_syntax_tree_node(_ident_list); if (_ident_list.idents == null) { bw.Write((byte)0); } else { bw.Write((byte)1); bw.Write(_ident_list.idents.Count); for(Int32 ssyy_i = 0; ssyy_i < _ident_list.idents.Count; ssyy_i++) { if (_ident_list.idents[ssyy_i] == null) { bw.Write((byte)0); } else { bw.Write((byte)1); _ident_list.idents[ssyy_i].visit(this); } } } }
/*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; }
///<summary> ///Конструктор с параметрами. ///</summary> public uses_unit_in(ident_list _name,string_const _in_file,SourceContext sc) { this._name=_name; this._in_file=_in_file; source_context = sc; }
///<summary> ///Конструктор с параметрами. ///</summary> public unit_or_namespace(ident_list _name,SourceContext sc) { this._name=_name; source_context = sc; }
///<summary> ///Конструктор с параметрами. ///</summary> public function_header(type_definition_attr_list _attr_list,formal_parameters _parameters,procedure_attributes_list _proc_attributes,method_name _name,bool _of_object,bool _class_keyword,ident_list _template_args,where_definition_list _where_defs,type_definition _return_type,SourceContext sc) { this._attr_list=_attr_list; this._parameters=_parameters; this._proc_attributes=_proc_attributes; this._name=_name; this._of_object=_of_object; this._class_keyword=_class_keyword; this._template_args=_template_args; this._where_defs=_where_defs; this._return_type=_return_type; source_context = sc; }
///<summary> ///Конструктор с параметрами. ///</summary> public typed_parameters(ident_list _idents,type_definition _vars_type,parametr_kind _param_kind,expression _inital_value,SourceContext sc) { this._idents=_idents; this._vars_type=_vars_type; this._param_kind=_param_kind; this._inital_value=_inital_value; source_context = sc; }
///<summary> ///Конструктор с параметрами. ///</summary> public template_type_name(ident_list _template_args) { this._template_args=_template_args; }
///<summary> ///Конструктор с параметрами. ///</summary> public var_def_statement(ident_list _vars,type_definition _vars_type,expression _inital_value,definition_attribute _var_attr,bool _is_event,SourceContext sc) { this._vars=_vars; this._vars_type=_vars_type; this._inital_value=_inital_value; this._var_attr=_var_attr; this._is_event=_is_event; source_context = sc; }
///<summary> ///Конструктор с параметрами. ///</summary> public var_def_statement(ident_list _vars,type_definition _vars_type,expression _inital_value,definition_attribute _var_attr,bool _is_event) { this._vars=_vars; this._vars_type=_vars_type; this._inital_value=_inital_value; this._var_attr=_var_attr; this._is_event=_is_event; }
///<summary> ///Конструктор с параметрами. ///</summary> public where_definition(ident_list _names,where_type_specificator_list _types,SourceContext sc) { this._names=_names; this._types=_types; source_context = sc; }
///<summary> ///Конструктор с параметрами. ///</summary> public where_definition(ident_list _names,where_type_specificator_list _types) { this._names=_names; this._types=_types; }
///<summary> ///Конструктор с параметрами. ///</summary> public property_parameter(ident_list _names,type_definition _type,SourceContext sc) { this._names=_names; this._type=_type; source_context = sc; }
///<summary> ///Конструктор с параметрами. ///</summary> public property_parameter(ident_list _names,type_definition _type) { this._names=_names; this._type=_type; }
///<summary> ///Конструктор с параметрами. ///</summary> public label_definitions(ident_list _labels,SourceContext sc) { this._labels=_labels; source_context = sc; }
///<summary> ///Конструктор с параметрами. ///</summary> public typed_parameters(ident_list _idents,type_definition _vars_type,parametr_kind _param_kind,expression _inital_value) { this._idents=_idents; this._vars_type=_vars_type; this._param_kind=_param_kind; this._inital_value=_inital_value; }
///<summary> ///Конструктор с параметрами. ///</summary> public template_type_name(ident_list _template_args,SourceContext sc) { this._template_args=_template_args; source_context = sc; }
///<summary> ///Конструктор с параметрами. ///</summary> public procedure_header(type_definition_attr_list _attr_list,formal_parameters _parameters,procedure_attributes_list _proc_attributes,method_name _name,bool _of_object,bool _class_keyword,ident_list _template_args,where_definition_list _where_defs) { this._attr_list=_attr_list; this._parameters=_parameters; this._proc_attributes=_proc_attributes; this._name=_name; this._of_object=_of_object; this._class_keyword=_class_keyword; this._template_args=_template_args; this._where_defs=_where_defs; }
///<summary> ///Конструктор с параметрами. ///</summary> public template_type_name(string _name,ident_list _template_args) { this._name=_name; this._template_args=_template_args; }
///<summary> ///Конструктор с параметрами. ///</summary> public unit_or_namespace(ident_list _name) { this._name=_name; }
///<summary> ///Конструктор с параметрами. ///</summary> public template_type_name(string _name,ident_list _template_args,SourceContext sc) { this._name=_name; this._template_args=_template_args; source_context = sc; }
///<summary> ///Конструктор с параметрами. ///</summary> public uses_unit_in(ident_list _name,string_const _in_file) { this._name=_name; this._in_file=_in_file; }
///<summary> ///Конструктор с параметрами. ///</summary> public function_lambda_definition(ident_list _ident_list,type_definition _return_type,formal_parameters _formal_parameters,statement _proc_body,procedure_definition _proc_definition,expression_list _parameters,string _lambda_name,List<declaration> _defs,LambdaVisitMode _lambda_visit_mode,syntax_tree_node _substituting_node,SourceContext sc) { this._ident_list=_ident_list; this._return_type=_return_type; this._formal_parameters=_formal_parameters; this._proc_body=_proc_body; this._proc_definition=_proc_definition; this._parameters=_parameters; this._lambda_name=_lambda_name; this._defs=_defs; this._lambda_visit_mode=_lambda_visit_mode; this._substituting_node=_substituting_node; source_context = sc; }
public void Transform() { res.Add(new labeled_statement(YieldConsts.LabelStatePrefix+curState.ToString())); foreach (var st in stl.subnodes) Process(st); // добавим метки состояний var idseq = Enumerable.Range(0, curState + 1).Select(i => new ident("lbstate#" + i.ToString())); var idl = new ident_list(idseq.ToList()); defs.Add(new label_definitions(idl)); statement ifgoto = new goto_statement(YieldConsts.LabelStatePrefix + curState.ToString()); for (var i = curState - 1; i >= 0; i--) ifgoto = new if_node(new bin_expr(new ident(YieldConsts.State), new int32_const(i), Operators.Equal), new goto_statement(YieldConsts.LabelStatePrefix + i.ToString()), ifgoto ); res.AddFirst(ifgoto); res.AddFirst(new assign("Result", false)); }
///<summary> ///Конструктор с параметрами. ///</summary> public template_operator_name(string _name,ident_list _template_args,operator_name_ident _opname) { this._name=_name; this._template_args=_template_args; this._opname=_opname; }
public void visit(ident_list _ident_list) { bw.Write((Int16)18); write_ident_list(_ident_list); }
///<summary> ///Конструктор с параметрами. ///</summary> public template_operator_name(string _name,ident_list _template_args,operator_name_ident _opname,SourceContext sc) { this._name=_name; this._template_args=_template_args; this._opname=_opname; source_context = sc; }
/*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; }
///<summary> ///Конструктор с параметрами. ///</summary> public label_definitions(ident_list _labels) { this._labels=_labels; }