using System; using System.Linq; using System.Collections.Generic; using System.Diagnostics; // TODO: рефакторинг для многоязычности EVA namespace PascalABCCompiler.SyntaxTree { /// /// Тип обхода дерева /// public enum TraversalType { /// /// Обход в ширину /// LevelOrder, /// /// Постфиксный обход /// PostOrder, /// /// Префиксный обход /// PreOrder } public enum Desc { All, DirectDescendants } public enum SemanticCheckType { MatchedExpression, MatchedExpressionAndType, MatchedExpressionAndExpression, MatchedTuple, SliceAssignmentTypeCompatibility } public partial class syntax_tree_node { public syntax_tree_node Parent; public int FindIndex(syntax_tree_node node, Desc d = Desc.All) { int ind = -1; var count = d == Desc.All ? subnodes_count : subnodes_without_list_elements_count; for (var i = 0; i < count; i++) if (node == this[i]) { ind = i; break; } if (ind == -1) throw new Exception(string.Format("У элемента {0} не найден {1} среди дочерних\n", this, node)); return ind; } /*public void ReplaceDescendant(syntax_tree_node from, syntax_tree_node to, Desc d = Desc.All) // есть риск, что типы не совпадут { var ind = FindIndex(from,d); this[ind] = to; }*/ // Безопасная версия Replace - не сработает если менять foreach_node на if_node. Плохо public void ReplaceDescendant(T from, T1 to, Desc d = Desc.All) where T : syntax_tree_node where T1 : T { var ind = FindIndex(from, d); this[ind] = to; to.Parent = from.Parent; } public void ReplaceDescendantUnsafe(syntax_tree_node from, syntax_tree_node to, Desc d = Desc.All) { var ind = FindIndex(from, d); this[ind] = to; to.Parent = from.Parent; } /// /// Находит последнего потомка, удовлетворяющего условию. Возвращает null, если такой не найден. /// /// Условие /// Найденный узел, либо null public syntax_tree_node FindLast(Predicate condition) { for (int i = subnodes_count - 1; i >= 0; i--) { if (condition(this[i])) return this[i]; } return null; } /// /// Получает коллекцию предков текущего узла /// /// Включить в список текущий узел /// Коллекция предков узла public IEnumerable AscendantNodes(bool includeSelf = false) { if (includeSelf) yield return this; var parentNode = Parent; while (parentNode != null) { yield return parentNode; parentNode = parentNode.Parent; } } /// /// Получает коллекцию узлов поддерева, в котором корнем является текущий узел. /// /// Тип обхода дерева. Определяет порядок добавления узлов в коллекцию /// Опциональная функция, позволяющая указать, нужно ли посещать потомков конкретного узла /// Позволяет включить текущий узел в список /// Коллекция узлов поддерева /// Выбрасывается при отсутствии реализации для заданного обхода public IEnumerable DescendantNodes( TraversalType traversalType = TraversalType.PostOrder, Func descendIntoChildren = null, bool includeSelf = false) { switch (traversalType) { case TraversalType.LevelOrder: return DescendantNodesLevelOrder(descendIntoChildren, includeSelf); case TraversalType.PostOrder: return DescendantNodesPostOrder(descendIntoChildren, includeSelf); case TraversalType.PreOrder: return DescendantNodesPreOrder(descendIntoChildren, includeSelf); default: throw new NotImplementedException("Данный вид обхода не поддерживается"); } } /// /// Получает список узлов поддерева, в котором корнем является текущий узел. /// Порядок добавления в список: родитель, затем потомки. /// /// Опциональная функция, позволяющая указать, нужно ли посещать потомков конкретного узла /// Позволяет включить текущий узел в список /// Список узлов поддерева private IEnumerable DescendantNodesPreOrder(Func descendIntoChildren, bool includeSelf) { var stack = new Stack(); if (includeSelf) stack.Push(this); else for (int childIndex = subnodes_count - 1; childIndex >= 0; childIndex--) if (this[childIndex] != null) stack.Push(this[childIndex]); while (stack.Count > 0) { syntax_tree_node node = stack.Pop(); if (descendIntoChildren == null || descendIntoChildren(node)) for (int childIndex = node.subnodes_count - 1; childIndex >= 0; childIndex--) { var child = node[childIndex]; if (child == null) continue; stack.Push(child); } yield return node; } } /// /// Получает список узлов поддерева, в котором корнем является текущий узел. /// Порядок добавления в список: потомки, затем родитель. /// /// Опциональная функция, позволяющая указать, нужно ли посещать потомков конкретного узла /// Позволяет включить текущий узел в список /// Список узлов поддерева private IEnumerable DescendantNodesPostOrder(Func descendIntoChildren, bool includeSelf) { var stack = new Stack(); if (includeSelf) stack.Push(this); else for (int childIndex = subnodes_count - 1; childIndex >= 0; childIndex--) if (this[childIndex] != null) stack.Push(this[childIndex]); syntax_tree_node lastReturnedNode = null; while (stack.Count > 0) { syntax_tree_node node = stack.Peek(); bool isLeafNode = true; // Если мы не должны посещать потомков узла или уже добавили их в список, // то не кладем их на стек if (!ReferenceEquals(lastReturnedNode, node.FindLast(x => x != null))) if (descendIntoChildren == null || descendIntoChildren(node)) for (int childIndex = node.subnodes_count - 1; childIndex >= 0; childIndex--) { var child = node[childIndex]; if (child == null) continue; stack.Push(child); isLeafNode = false; } if (isLeafNode) { stack.Pop(); lastReturnedNode = node; yield return node; } } } /// /// Получает список узлов поддерева, в котором корнем является текущий узел. /// Порядок добавления в список: узлы первого уровня, затем второго и т.д. /// /// Опциональная функция, позволяющая указать, нужно ли посещать потомков конкретного узла /// Позволяет включить текущий узел в список /// Список узлов поддерева private IEnumerable DescendantNodesLevelOrder(Func descendIntoChildren, bool includeSelf) { var queue = new Queue(); if (includeSelf) queue.Enqueue(this); else for (int childIndex = 0; childIndex < subnodes_count; childIndex++) if (this[childIndex] != null) queue.Enqueue(this[childIndex]); while (queue.Count > 0) { syntax_tree_node node = queue.Dequeue(); if (descendIntoChildren == null || descendIntoChildren(node)) for (int childIndex = 0; childIndex < node.subnodes_count; childIndex++) { var child = node[childIndex]; if (child == null) continue; queue.Enqueue(child); } yield return node; } } } //------------------------------ public class SyntaxList where T : syntax_tree_node // операции для работы с вложенными списками синтаксических узлов. Класс пока не используется { public List list; public SyntaxList(List l) { list = l; } public void AddMany(params T[] tt) { list.AddRange(tt); } public bool Remove(T t) { return list.Remove(t); } public void InsertAfter(T st, T newst) { var ind = list.FindIndex(x => x == st); if (ind == -1) throw new Exception(string.Format("У {0} не найден {1} среди дочерних\n", this, st)); list.Insert(ind + 1, newst); } public void InsertBefore(T st, T newst) { var ind = list.FindIndex(x => x == st); if (ind == -1) throw new Exception(string.Format("У {0} не найден {1} среди дочерних\n", this, st)); list.Insert(ind, newst); } public void AddFirst(T st) { list.Insert(0, st); } } //------------------------------ public partial class statement_list { /// /// IsInternal - statement_list получен на этапе семантики синтаксическим сахаром из одного оператора. /// На первом проходе с лямбдами один оператор заменяется на такой Internal statement list /// На втором и третьем проходе с лямбдами он обходится как один оператор /// public bool IsInternal = false; public statement_list(IEnumerable sts) { AddMany(sts); } public statement_list(params statement[] sts) { AddMany(sts); } //-- List members begin public List list { get { return subnodes; } } public void AddMany(IEnumerable els) { list.AddRange(els); foreach (var elem in els) if (elem != null) elem.Parent = this; } public static statement_list Empty { get { return new statement_list(); } } public override string ToString() { return "begin " + list.Select(st => st is empty_statement ? "" : st.ToString() + "; ").Aggregate((s, x) => s + x) + "end"; } //-- List members end } public partial class ident : addressed_value_funcname { public override string ToString() { return name; } public static implicit operator ident(string s) { return new ident(s); } } public partial class assign { public assign(addressed_value left, expression ex, SourceContext sc = null) : this(left, ex, Operators.Assignment, sc) { } public assign(string name, expression ex, SourceContext sc = null) : this(new ident(name), ex, sc) { } public assign(string name, string id) : this(new ident(name), new ident(id)) { } public assign(string name, int value) : this(new ident(name), new int32_const(value)) { } public assign(string name, double value) : this(new ident(name), new double_const(value)) { } public assign(string name, char value) : this(new ident(name), new char_const(value)) { } public assign(string name, bool value) : this(new ident(name), new bool_const(value)) { } public assign(addressed_value _to, expression _from, Operators _operator_type) : this(_to, _from, _operator_type, false) { } public assign(addressed_value _to, expression _from, Operators _operator_type, SourceContext sc) : this(_to, _from, _operator_type, false, sc) { } public override string ToString() { return string.Format("{0} {1} {2}", to, OperatorServices.ToString(operator_type, StringConstants.pascalLanguageName), from); } } public partial class bin_expr { public static bin_expr Greater(expression left, expression right) { return new bin_expr(left, right, Operators.Greater); } public static bin_expr GreaterEqual(expression left, expression right) { return new bin_expr(left, right, Operators.GreaterEqual); } public static bin_expr Less(expression left, expression right) { return new bin_expr(left, right, Operators.Less); } public static bin_expr LessEqual(expression left, expression right) { return new bin_expr(left, right, Operators.LessEqual); } public static bin_expr LogicalAnd(expression left, expression right) { return new bin_expr(left, right, Operators.LogicalAND); } public static bin_expr LogicalOr(expression left, expression right) { return new bin_expr(left, right, Operators.LogicalOR); } public override string ToString() { return string.Format("{0} {2} {1}", left, right, OperatorServices.ToString(operation_type, StringConstants.pascalLanguageName)); } } public partial class un_expr { public static un_expr Not(expression ex) { return new un_expr(ex, Operators.LogicalNOT); } public override string ToString() { return string.Format("{0} {1}", OperatorServices.ToString(operation_type, StringConstants.pascalLanguageName), this.subnode); } } public partial class bool_const { public override string ToString() { if (val) return "True"; else return "False"; } } public partial class int32_const { public override string ToString() { return val.ToString(); } } public partial class double_const { public override string ToString() { return val.ToString(System.Globalization.CultureInfo.InvariantCulture); } } public partial class roof_dereference { public override string ToString() { return base.ToString() + "^"; } } public partial class named_type_reference { public named_type_reference(string name) { this.names = name.Split('.').Select(s => new ident(s)).ToList(); } public override string ToString() { var sb = new System.Text.StringBuilder(); sb.Append(names[0].ToString()); for (int i = 1; i < names.Count; i++) sb.Append("." + names[i].ToString()); return sb.ToString(); } public ident FirstIdent { get { return names[0]; } } public static named_type_reference Boolean => new named_type_reference("boolean"); } public partial class template_type_reference { public template_type_reference(string name, template_param_list params_list) : this(new named_type_reference(name), params_list) { } public override string ToString() { var sb = new System.Text.StringBuilder(); sb.Append(this.name.ToString()); sb.Append("<"); sb.Append(params_list.params_list[0].ToString()); for (int i = 1; i < params_list.params_list.Count; i++) sb.Append("," + params_list.params_list[i].ToString()); sb.Append(">"); return sb.ToString(); } } public partial class variable_definitions { //-- List members begin public List list { get { return var_definitions; } } //-- List members end } public partial class ident_list { public ident_list(params ident[] idents) { this.idents = idents.ToList(); } public override string ToString() { if (idents.Count == 0) return ""; var sb = new System.Text.StringBuilder(); sb.Append(idents[0].ToString()); for (int i = 1; i < idents.Count; i++) sb.Append("," + idents[i].ToString()); return sb.ToString(); } //-- List members begin public List list { get { return idents; } } //-- List members end } public partial class var_def_statement { public var_def_statement(ident_list vars, type_definition vars_type, SourceContext sc = null) : this(vars, vars_type, null, definition_attribute.None, false, sc) { } public var_def_statement(ident_list vars, type_definition vars_type, expression iv, SourceContext sc = null) : this(vars, vars_type, iv, definition_attribute.None, false, sc) { } public var_def_statement(ident id, type_definition type, SourceContext sc = null) : this(new ident_list(id), type, sc) { } public var_def_statement(ident id, type_definition type, expression iv, SourceContext sc = null) : this(new ident_list(id), type, iv, sc) { } public var_def_statement(ident id, expression iv, SourceContext sc = null) : this(new ident_list(id), null, iv, sc) { } public var_def_statement(ident id, string type) : this(new ident_list(id), new named_type_reference(type)) { } public override string ToString() { var sb = new System.Text.StringBuilder(); sb.Append(vars.ToString()); if (vars_type != null) { sb.Append(": "); sb.Append(vars_type.ToString()); } if (inital_value != null) { sb.Append(" := "); sb.Append(inital_value.ToString()); } //sb.Append("; "); return sb.ToString(); } } public partial class var_tuple_def_statement { public var_tuple_def_statement(ident_list vars, expression iv, SourceContext sc = null) : this(vars, null, iv, definition_attribute.None, false, sc) { } } public partial class declarations { //-- List members begin public List list { get { return defs; } } public static statement_list Empty { get { return new statement_list(); } } //-- List members end } public partial class program_tree { } public partial class program_name { public override string ToString() { return prog_name.ToString(); } } public partial class string_const { public override string ToString() { return "'" + Value + "'"; } public bool IsInterpolated = false; public bool IsMultiline = false; } public partial class expression_list { public static expression_list Empty { get { return new expression_list(); } } public override string ToString() { if (expressions.Count == 0) return ""; var sb = new System.Text.StringBuilder(); sb.Append(expressions[0].ToString()); for (int i = 1; i < expressions.Count; i++) { sb.Append(","); sb.Append(expressions[i].ToString()); } return sb.ToString(); } } public partial class dereference { public override string ToString() { return dereferencing_value.ToString(); } } public partial class indexer { public indexer(addressed_value av, expression ex, SourceContext sc = null) { this.dereferencing_value = av; this.indexes = new expression_list(ex); this.source_context = sc; } public override string ToString() { return base.ToString() + "[" + indexes.ToString() + "]"; } } public partial class indexers_types { } public partial class label_definitions { public label_definitions(params ident[] ids) : this(new ident_list(ids)) { } public override string ToString() { return "label " + labels.ToString() + ";"; } } public partial class procedure_attribute { public override string ToString() { return attribute_type.ToString(); } } public partial class typed_parameters { public typed_parameters(ident_list idents, type_definition type, SourceContext sc = null) : this(idents, type, parametr_kind.none, null) { this.source_context = sc; } public typed_parameters(ident id, type_definition type, SourceContext sc = null) : this(new ident_list(id), type) { this.source_context = sc; } public override string ToString() { var s = this.idents.ToString() + ": " + this.vars_type.ToString(); if (this.inital_value != null) s += " := " + this.inital_value.ToString(); return s; } } public partial class formal_parameters { public override string ToString() { return string.Join(",", params_list.Select(p => p.ToString())); } public static formal_parameters Empty { get { return new formal_parameters(); } } } /// public partial class procedure_attributes_list { public procedure_attributes_list(proc_attribute attr, SourceContext sc = null) : this(new procedure_attribute(attr), sc) { } } public partial class procedure_header { // frninja 20/05/16 - для методов хелперов yield public bool is_yield_helper = false; // end frninja public bool IsAsync { get; set; } = false; public procedure_header(formal_parameters _parameters, procedure_attributes_list _proc_attributes, method_name _name, where_definition_list _where_defs, SourceContext sc) { this._parameters = _parameters; this._proc_attributes = _proc_attributes; this._name = _name; this._of_object = false; this._class_keyword = false; this._template_args = null; this._where_defs = _where_defs; source_context = sc; if (name != null) if (name.meth_name is template_type_name) { var t = name.meth_name as template_type_name; template_args = t.template_args; if (name.meth_name is template_operator_name) { name.meth_name = new operator_name_ident((name.meth_name as template_operator_name).opname.operator_type, name.meth_name.source_context); } else name.meth_name = new ident(name.meth_name.name, name.meth_name.source_context); } } //for sugar public procedure_header(string name, formal_parameters fp, procedure_attributes_list pal) : this(fp, pal, new method_name(name), null, null) { } public procedure_header(string name, formal_parameters fp) : this(name, fp, new procedure_attributes_list()) { } public procedure_header(string name) : this(name, new formal_parameters()) { } public override string ToString() { var sb = new System.Text.StringBuilder(); sb.Append("procedure "); if (name != null) sb.Append(name.ToString()); else sb.Append(""); if (template_args != null) sb.Append("<" + template_args.ToString() + ">"); if (parameters != null) sb.Append("(" + parameters.ToString() + ")"); if (name != null) sb.Append(";"); if (this.proc_attributes != null) foreach (var pa in this.proc_attributes.proc_attributes) sb.Append(" " + pa.ToString() + " "); return sb.ToString(); } public bool is_extension() { if (proc_attributes?.proc_attributes != null) return proc_attributes.proc_attributes.FindIndex(attr => attr.attribute_type == proc_attribute.attr_extension) >= 0; else return false; } } public partial class function_header { public function_header(formal_parameters _parameters, procedure_attributes_list _proc_attributes, method_name _name, where_definition_list _where_defs, type_definition _return_type, SourceContext sc) : base(_parameters, _proc_attributes, _name, _where_defs, sc) { this._return_type = _return_type; } //for sugar public function_header(string name, type_definition returntype, formal_parameters fp) : this(fp, new procedure_attributes_list(), new method_name(name), null, returntype, null) { } public function_header(string name, type_definition returntype) : this(new formal_parameters(), new procedure_attributes_list(), new method_name(name), null, returntype, null) { } public function_header(string name, string returntype, formal_parameters fp, procedure_attributes_list pal) : this(fp, pal, new method_name(name), null, new named_type_reference(returntype), null) { } public function_header(string name, string returntype, formal_parameters fp) : this(fp, new procedure_attributes_list(), new method_name(name), null, new named_type_reference(returntype), null) { } public function_header(string name, string returntype) : this(new formal_parameters(), new procedure_attributes_list(), new method_name(name), null, new named_type_reference(returntype), null) { } public override string ToString() { var sb = new System.Text.StringBuilder(); sb.Append(base.ToString()); sb.Remove(0, 9); sb.Remove(sb.Length - 1, 1); sb.Insert(0, "function"); if (return_type != null) sb.Append(": " + return_type.ToString() + ";"); return sb.ToString(); } } public partial class procedure_definition { public bool has_yield = false; public procedure_definition(procedure_header proc_header, proc_block proc_body, SourceContext sc) { this.proc_header = proc_header; this.proc_body = proc_body; source_context = sc; is_short_definition = false; FillParentsInDirectChilds(); } public procedure_definition(procedure_header proc_header, proc_block proc_body) { this.proc_header = proc_header; this.proc_body = proc_body; source_context = null; is_short_definition = false; FillParentsInDirectChilds(); } public static procedure_definition EmptyDefaultConstructor { get { return new procedure_definition(new constructor(null), block.Empty, null); } } public procedure_definition(string name, formal_parameters fp, declarations defs, statement_list code) : this(new procedure_header(name, fp), new block(defs, code)) { } public procedure_definition(string name, formal_parameters fp, statement_list code) : this(new procedure_header(name, fp), new block(null, code)) { } public procedure_definition(string name, formal_parameters fp, statement st) : this(new procedure_header(name, fp), new block(null, new statement_list(st))) { } public procedure_definition(string name, declarations defs, statement_list code) : this(new procedure_header(name), new block(defs, code)) { } public procedure_definition(string name, statement_list code, proc_block b) : this(new procedure_header(name), b) { } public procedure_definition(string name, statement_list code) : this(new procedure_header(name), new block(null, code)) { } public procedure_definition(procedure_header proc_header, statement_list code) : this(proc_header, new block(null, code)) { } public procedure_definition(string name) : this(new procedure_header(name), new block(null, statement_list.Empty)) { } public procedure_definition(string name, statement st) : this(new procedure_header(name), new block(null, new statement_list(st))) { } public procedure_definition(procedure_header proc_header, statement st) : this(proc_header, new block(null, new statement_list(st))) { } public procedure_definition(string name, string rettype, formal_parameters fp, declarations defs, statement_list code) : this(new function_header(name, rettype, fp), new block(defs, code)) { } public procedure_definition(string name, string rettype, formal_parameters fp, statement_list code) : this(new function_header(name, rettype, fp), new block(null, code)) { } public procedure_definition(string name, string rettype, formal_parameters fp, statement st) : this(new function_header(name, rettype, fp), new block(null, new statement_list(st))) { } public procedure_definition(string name, string rettype, declarations defs, statement_list code) : this(new function_header(name, rettype), new block(defs, code)) { } public procedure_definition(string name, string rettype, proc_block b) : this(new function_header(name, rettype), b) { } public procedure_definition(string name, string rettype, statement_list code) : this(new function_header(name, rettype), new block(null, code)) { } public procedure_definition(string name, string rettype, statement st) : this(new function_header(name, rettype), new block(null, new statement_list(st))) { } public void AssignAttrList(attribute_list al) { if (proc_header != null) proc_header.attributes = al; } } public partial class type_declarations { } public partial class consts_definitions_list { } public partial class unit_or_namespace { public unit_or_namespace(string name, SourceContext sc = null) { this.name = new ident_list(name, sc); } // имя модуля в случае обычного uses // или путь к модулю в случае uses-in public virtual string UsesPath() => name.idents[0].name; } public partial class uses_list { public uses_list(string name, SourceContext sc = null) { Add(new unit_or_namespace(name), sc); } public uses_list AddUsesList(uses_list ul, SourceContext sc = null) { foreach (var un in ul.units) units.Add(un); if (sc != null) source_context = sc; return this; } } public partial class unit_module { public unit_module(string _Language, unit_name _unit_name, interface_node _interface_part, implementation_node _implementation_part, statement_list _initialization_part, statement_list _finalization_part, SourceContext sc) { this._Language = _Language; this._unit_name = _unit_name; this._interface_part = _interface_part; this._implementation_part = _implementation_part; this._initialization_part = _initialization_part; this._finalization_part = _finalization_part; source_context = sc; } } /*public partial class program_module { public static program_module create(ident id, uses_list _used_units, block _program_block, using_list _using_namespaces, SourceContext sc = null) { var r = new program_module(new program_name(id), _used_units, _program_block, _using_namespaces, sc); r.Language = LanguageId.CommonLanguage; return r; } public static program_module create(ident id, uses_list _used_units, block _program_block) { var r = new program_module(new program_name(id), _used_units, _program_block, null); r.Language = LanguageId.CommonLanguage; return r; } public static program_module create(ident id, uses_list _used_units, block _program_block, SourceContext sc = null) { var r = new program_module(new program_name(id), _used_units, _program_block, null, sc); r.Language = LanguageId.CommonLanguage; return r; } }*/ public partial class method_name { public method_name(string name, SourceContext sc = null) : this(null, null, new ident(name), null, sc) { } public override string ToString() { return meth_name.ToString(); } } public partial class dot_node { public dot_node(ident left, ident right, SourceContext sc = null) { this.left = left; this.right = right; this.source_context = sc; } public override string ToString() { return left.ToString() + "." + right.ToString(); } } public partial class goto_statement { public override string ToString() { return "goto " + label; } } public partial class dot_node { public static dot_node NewP(addressed_value avl, addressed_value avr, SourceContext sc) { var dn = new dot_node(avl, avr, sc); if (avl != null) avl.Parent = dn; if (avr != null) avr.Parent = dn; return dn; } } public partial class method_call { public static method_call NewP(addressed_value av, expression_list el, SourceContext sc) { var mc = new method_call(av, el, sc); if (av != null) av.Parent = mc; if (el != null) el.Parent = mc; return mc; } /// /// Простое имя метода. Возвращает null, если не удалось такое получить. /// public string SimpleName { get { var dv = dereferencing_value as ident; if (dv == null) return null; else return dv.name; } } /// /// Количество параметров метода /// public int ParametersCount { get { if (parameters != null) return parameters.subnodes_count; else return 0; } } public override string ToString() { string s = dereferencing_value.ToString(); if (parameters != null) s += "(" + parameters.ToString() + ")"; else s += "()"; return s; } } public partial class pascal_set_constant { //Добавляет во множество элемент public void Add(expression value) { values.Add(value); } } public partial class property_accessors { public property_accessors(ident read_accessor, ident write_accessor, SourceContext sc = null) : this(new read_accessor_name(read_accessor, null, null), new write_accessor_name(write_accessor, null, null), sc) { } } public partial class simple_property { public simple_property(property_ident name, type_definition type, property_accessors accessors, SourceContext sc = null) : this(name, type, null, accessors, null, null, definition_attribute.None, proc_attribute.attr_none, false, null, sc) { } } public partial class class_members { public static class_members Public { get { return new class_members(access_modifer.public_modifer); } } public static class_members Private { get { return new class_members(access_modifer.private_modifer); } } public class_members(access_modifer access) { access_mod = new access_modifer_node(access); } public class_members Add(params declaration[] decls) { foreach (var d in decls) members.Add(d); return this; } } public partial class class_body_list { } public partial class class_definition { public class_definition(named_type_reference_list parents, class_body_list body, SourceContext sc = null) : this(parents, body, class_keyword.Class, null, null, class_attribute.None, false, sc) { is_auto = false; } public class_definition(class_body_list body, SourceContext sc = null) : this(null, body, sc) { is_auto = false; } public bool IsAutoClass() { return (attribute & class_attribute.Auto) == class_attribute.Auto; } } public partial class record_const { } public partial class literal_const_line { } public partial class variant_list { } public partial class variant_types { } public partial class procedure_call { public procedure_call(addressed_value _func_name, SourceContext sc = null) : this(_func_name, false, sc) { } public procedure_call(ident name) { this._func_name = name; } public override string ToString() { return func_name.ToString(); } } public partial class constructor { public constructor(formal_parameters fp, SourceContext sc = null) : this(null, fp, new procedure_attributes_list(), new method_name(StringConstants.default_constructor_name), false, false, null, null, sc) { } public override string ToString() { var sb = new System.Text.StringBuilder(); sb.Append("constructor "); if (parameters != null) sb.Append("(" + parameters.ToString() + ")"); else sb.Append("()"); sb.Append(";"); return sb.ToString(); } } public partial class block { public block(statement_list code) : this(null, code, null) { } public static block Empty { get { return new block(null, new statement_list()); } } } public partial class case_variants { } public partial class var_def_list_for_record { } public partial class property_parameter_list { } public partial class initfinal_part { public initfinal_part(token_info stn1, statement_list init, token_info stn2, statement_list fin, token_info stn3, SourceContext sc) { _initialization_sect = init; _finalization_sect = fin; source_context = sc; init.left_logical_bracket = stn1; init.right_logical_bracket = stn2; if (fin != null) { fin.left_logical_bracket = stn2; fin.right_logical_bracket = stn3; } } } public partial class token_info { public override string ToString() { return text.ToLower(); } } public partial class exception_handler_list { } public partial class named_type_reference_list { public named_type_reference_list(string name) { Add(new named_type_reference(name)); } public named_type_reference_list(string name1, string name2) { Add(new named_type_reference(name1)); Add(new named_type_reference(name2)); } public override string ToString() { return string.Join(",", this.types.Select(x => x.ToString()).ToArray()); } } public partial class template_param_list { public template_param_list(IEnumerable names) { foreach (var s in names) Add(new named_type_reference(s)); } public template_param_list(string names) { foreach (var ntr in names.Split(',').Select(s => new named_type_reference(s))) Add(ntr); } } public partial class int64_const { public override string ToString() { return val.ToString(); } } public partial class uint64_const { public override string ToString() { return val.ToString(); } } public partial class new_expr { public new_expr(type_definition type, expression_list pars, SourceContext sc = null) : this(type, pars, false, null, sc) { } public new_expr(string type, expression_list pars) : this(new named_type_reference(type), pars, false, null) { } public new_expr(string type) : this(new named_type_reference(type), expression_list.Empty, false, null) { } public override string ToString() { return "new " + (this.type != null ? this.type.ToString() : "NOTYPE") + "(" + (this.params_list != null ? this.params_list.ToString() : "NOPARAMS") + ")"; } } public partial class where_type_specificator_list { } public partial class where_definition_list { } public partial class var_statement { public var_statement(ident_list vars, type_definition type, expression iv) : this(new var_def_statement(vars, type, iv)) { } public var_statement(ident_list vars, type_definition type) : this(new var_def_statement(vars, type)) { } public var_statement(ident id, type_definition type, expression iv) : this(new var_def_statement(new ident_list(id, id.source_context), type, iv)) { } public var_statement(ident id, type_definition type) : this(new var_def_statement(new ident_list(id, id.source_context), type)) { } public var_statement(ident id, type_definition type, SourceContext sc) : this(new var_def_statement(new ident_list(id, id.source_context), type, sc),sc) { } public var_statement(ident id, string type) : this(new var_def_statement(new ident_list(id, id.source_context), new named_type_reference(type))) { } public var_statement(ident id, expression iv) : this(new var_def_statement(new ident_list(id,id.source_context), null, iv)) { } public var_statement(ident id, expression iv, SourceContext sc) : this(new var_def_statement(new ident_list(id,id.source_context), null, iv, sc),sc) { } public var_statement(ident id, string type, expression iv, SourceContext sc) : this(new var_def_statement(new ident_list(id, id.source_context), new named_type_reference(type), iv, sc), sc) { } public override string ToString() { return "var " + var_def.ToString(); } } public partial class enumerator_list { } public partial class type_definition_attr_list { } public partial class compiler_directive_list { } public partial class documentation_comment_list { } public partial class documentation_comment_section { } public partial class bracket_expr { public override string ToString() { return "(" + expr.ToString() + ")"; } } public partial class simple_attribute_list { } public partial class attribute_list { } public partial class function_lambda_definition { public object RealSemTypeOfResExpr = null; // Result := ex; - семантический тип ex - нужно для лучшего выбора среди перегруженных методов с параметрами-лямбдами public object RealSemTypeOfResult = null; public List unpacked_params = null; // SSM 04/03/21 - сахарный узел, содержащий параметры, которые необходимо распаковать: (\(x,y,z),\(a,b))) public function_lambda_definition(string name, formal_parameters formalPars, type_definition returnType, statement_list body, int usedkw, SourceContext sc) { statement_list _statement_list = body; expression_list _expression_list = new expression_list(); ident_list identList = new ident_list(); lambda_visit_mode = LambdaVisitMode.None; if (formalPars != null) { for (int i = 0; i < formalPars.params_list.Count; i++) { for (int j = 0; j < formalPars.params_list[i].idents.idents.Count; j++) { identList.idents.Add(formalPars.params_list[i].idents.idents[j]); _expression_list.expressions.Add(formalPars.params_list[i].idents.idents[j]); } } } formal_parameters = formalPars; return_type = returnType; ident_list = identList; parameters = _expression_list; lambda_name = name; proc_body = _statement_list; usedkeyword = usedkw; source_context = sc; } public function_lambda_definition(string name, formal_parameters formalPars, type_definition returnType, statement_list body, SourceContext sc) : this(name, formalPars, returnType, body, 0, sc) { } } public partial class semantic_check { public semantic_check(string name, params syntax_tree_node[] pars) { CheckName = name; param.AddRange(pars); } } public partial class name_assign_expr_list { } public partial class unnamed_type_object { public string name() { return (new_ex.type as SyntaxTree.named_type_reference).names[0].name; } public void set_name(string nm) { var ntr = new_ex.type as SyntaxTree.named_type_reference; ntr.names[0].name = nm; } } public partial class yield_node { public override string ToString() { return "yield " + ex.ToString(); } } public partial class sequence_type { public override string ToString() { return "sequence of " + this.elements_type.ToString(); } } public partial class if_node { public if_node(expression _condition, statement _then_body) { this._condition = _condition; this._then_body = _then_body; this._else_body = null; } } public partial class empty_statement { public static empty_statement New { get { return new empty_statement(); } } } public partial class case_node { public case_node(expression _param, case_variants _conditions) { this._param = _param; this._conditions = _conditions; this._else_statement = null; } public case_node(expression _param) { this._param = _param; this._conditions = new case_variants(); this._else_statement = null; } } public partial class labeled_statement { public labeled_statement(ident label_name) { this._label_name = label_name; this._to_statement = empty_statement.New; } } public partial class uses_closure { } // frninja 12/05/16 - хелперы для yield public partial class yield_unknown_expression_type : type_definition { protected var_def_statement _Vds; public var_def_statement Vds { get { return _Vds; } set { _Vds = value; } } public yield_unknown_expression_type(var_def_statement vds) { this.Vds = vds; } } public partial class yield_unknown_ident : ident { //protected ident _UnknownID; protected ident _ClassName; protected bool _IsYieldInStaticMethod; /*public ident UnknownID { get { return _UnknownID; } set { _UnknownID = value; } }*/ public ident ClassName { get { return _ClassName; } set { _ClassName = value; } } public bool IsYieldInStaticMethod { get { return _IsYieldInStaticMethod; } set { _IsYieldInStaticMethod = value; } } /// ///Конструктор с параметрами. /// public yield_unknown_ident(ident _UnknownID, ident _ClassName, bool isYieldInStaticMethod = false) { this._name = _UnknownID.name; this._UnknownID = _UnknownID; this._ClassName = _ClassName; this._IsYieldInStaticMethod = isYieldInStaticMethod; } /// ///Конструктор с параметрами. /// public yield_unknown_ident(ident _UnknownID, ident _ClassName, bool isYieldInStaticMethod, SourceContext sc) { this._name = _UnknownID.name; this._UnknownID = _UnknownID; this._ClassName = _ClassName; this._IsYieldInStaticMethod = isYieldInStaticMethod; source_context = sc; } public override string ToString() { return "yui(обраб.на сем.)"+this.ClassName+" "+this.UnknownID.ToString(); } } public partial class yield_unknown_foreach_type : type_definition { protected foreach_stmt _unknown_foreach; public foreach_stmt unknown_foreach { get { return _unknown_foreach; } set { _unknown_foreach = value; } } /// ///Конструктор с параметрами. /// public yield_unknown_foreach_type(foreach_stmt _unknown_foreach) { this._unknown_foreach = _unknown_foreach; } /// ///Конструктор с параметрами. /// public yield_unknown_foreach_type(foreach_stmt _unknown_foreach, SourceContext sc) { this._unknown_foreach = _unknown_foreach; source_context = sc; } } public partial class yield_unknown_foreach_type_ident : ident { protected foreach_stmt _unknown_foreach; public foreach_stmt unknown_foreach { get { return _unknown_foreach; } set { _unknown_foreach = value; } } /// ///Конструктор с параметрами. /// public yield_unknown_foreach_type_ident(foreach_stmt _unknown_foreach) { this._unknown_foreach = _unknown_foreach; } /// ///Конструктор с параметрами. /// public yield_unknown_foreach_type_ident(foreach_stmt _unknown_foreach, SourceContext sc) { this._unknown_foreach = _unknown_foreach; source_context = sc; } } public partial class array_type { public override string ToString() { return "array of " + this.elements_type.ToString(); } } public partial class function_lambda_definition { public override string ToString() { var s = this._ident_list.ToString(); if (_ident_list.Count != 1) s = "(" + s + ")"; var b = this.proc_body.ToString(); return "" + s + " -> " + b; } } public partial class nil_const { public override string ToString() { return "nil"; } } public partial class access_modifer_node { public override string ToString() { return this.access_level.ToString().Replace("_modifier", ""); } } public partial class statement { public statement_list ToStatementList() { var stl = this as statement_list; if (stl != null) return stl; else return new statement_list(this); } } public partial class addressed_value { public indexer indexer(expression ex, SourceContext sc = null) { return new SyntaxTree.indexer(this, ex, sc); } public dot_node dot_node(ident id, SourceContext sc = null) { return new SyntaxTree.dot_node(this, id, sc); } /// /// Сервисное поле для реализации механизма ?. Оно - типа question_colon_expression /// public object ExprToQCE = null; } public partial class expression { //public object semantic_ex; public expression Plus(expression e) { return new bin_expr(this, e, Operators.Plus); } public expression Minus(expression e) { return new bin_expr(this, e, Operators.Minus); } public static implicit operator expression(int i) { return new int32_const(i); } } public partial class slice_expr { public List> slices; // = new List>(); public override string ToString() => this.v + "[" + this.from + ":" + this.to + ":" + this.step + "]"; } public partial class slice_expr_question { public slice_expr_question(addressed_value v, expression from, expression to, expression step) : base(v, from, to, step) { } public slice_expr_question(addressed_value v, expression from, expression to, expression step, SourceContext sc) : base(v, from, to, step, sc) { } } public partial class sugared_addressed_value { public static sugared_addressed_value NewP(object sug, addressed_value av, SourceContext sc) { var res = new sugared_addressed_value(sug, av, sc); av.Parent = res; return res; } public override string ToString() { return "{sug}" + this.new_addr_value; } } public partial class question_colon_expression { public override string ToString() => this.condition + "?" + this.ret_if_true + ":" + this.ret_if_false; } public partial class dot_question_node { public override string ToString() => left.ToString() + "?." + right.ToString(); } public partial class for_node { public for_node(ident loop_variable, expression init_value, expression finish_value, statement stmt, SourceContext sc) : this(loop_variable, init_value, finish_value, stmt, for_cycle_type.to, null, null, true) { } public override string ToString() => "for var " + this.loop_variable.ToString() + " := " + this.initial_value.ToString() + " to " + this.finish_value.ToString() + " do \n" + this.statements.ToString(); } public partial class loop_stmt { public override string ToString() => "loop " + this.count.ToString() + " do \n" + this.stmt.ToString(); } public partial class lambda_inferred_type { public override string ToString() => "lam_inferred"; } public partial class desugared_deconstruction { public bool HasAllExplicitTypes => variables.definitions.All(x => x.vars_type != null); public desugared_deconstruction(List variables, expression target, SourceContext context = null) : this(new deconstruction_variables_definition(variables), target, context) { } public var_statement[] WithTypes(type_definition[] types) { var_statement[] result = new var_statement[types.Length]; Debug.Assert(types.Length == variables.definitions.Count, "Inconsistent types count"); for (int i = 0; i < variables.definitions.Count; i++) { variables.definitions[i].vars_type = types[i]; result[i] = new var_statement(variables.definitions[i]); } return result; } public override string ToString() => $"var {string.Join(", ", variables.definitions)}"; } public partial class is_pattern_expr { public override string ToString() => $"{left} is {right}"; } public partial class deconstructor_pattern { public override string ToString() => $"{type}({string.Join(", ", parameters.Select(x => x.ToString()))})"; } public partial class pattern_node { public bool IsRecursive => parameters.Any(x => x is recursive_pattern_parameter); } public partial class typecast_node { public override string ToString() { return "" + this.expr + " " + this.cast_op + " " + this.type_def; } } public partial class semantic_check_sugared_statement_node { public bool visited = false; public override string ToString() => "semantic_check_sugared(" + string.Join(", ",lst) + ")"; } public partial class var_deconstructor_parameter { public override string ToString() => identifier.ToString() + (type == null ? "" : $": {type}"); } public partial class recursive_deconstructor_parameter { public override string ToString() => pattern.ToString(); } public partial class tuple_pattern_wild_card { /// ///Конструктор c параметрами /// public tuple_pattern_wild_card(SourceContext sc) { this.source_context = sc; } } public partial class collection_pattern_wild_card { /// ///Конструктор c параметрами /// public collection_pattern_wild_card(SourceContext sc) { this.source_context = sc; } } public partial class collection_pattern_gap_parameter { /// ///Конструктор c параметрами /// public collection_pattern_gap_parameter(SourceContext sc) { this.source_context = sc; } } public partial class wild_card_deconstructor_parameter { /// ///Конструктор c параметрами /// public wild_card_deconstructor_parameter(SourceContext sc) { this.source_context = sc; } } public partial class const_pattern { /// ///Конструктор c параметрами /// public const_pattern(List pattern_nodes, SourceContext sc) { source_context = sc; pattern_expressions = new expression_list(); pattern_expressions.source_context = sc; foreach (var elem in pattern_nodes) { if (elem is named_type_reference type) { expression pattern_expr = null; if (type.names.Count == 1) { pattern_expr = type.names[0]; } else { pattern_expr = new dot_node(null, type.names[type.names.Count - 1], sc); var curr_dot_node = pattern_expr as dot_node; for (var i = type.names.Count - 2; i >= 1; --i) { curr_dot_node.left = new dot_node(null, type.names[i], sc); curr_dot_node = curr_dot_node.left as dot_node; } curr_dot_node.left = type.names[0]; } pattern_expressions.Add(pattern_expr, type.source_context); } else if (elem is expression expr) { pattern_expressions.Add(expr, elem.source_context); } } } } public partial class empty_statement { public override string ToString() => "<>"; } public partial class modern_proc_type { public override string ToString() => ""; } public partial class ident_with_templateparams { public override string ToString() => $"{this.name}{this.template_params}"; } public partial class template_param_list { public override string ToString() => "<"+string.Join(",",this.params_list.Select(td=>td.ToString()))+">"; } /* public partial class slice_expr : dereference { /// ///Конструктор с параметрами. /// public slice_expr(addressed_value _v, expression _from, expression _to, expression _step) : this(_v, _from, _to, _step, false, false) { } /// ///Конструктор с параметрами. /// public slice_expr(addressed_value _v, expression _from, expression _to, expression _step, SourceContext sc) : this(_v, _from, _to, _step, false, false, sc) { } /// ///Конструктор с параметрами. /// public slice_expr(addressed_value _dereferencing_value, addressed_value _v, expression _from, expression _to, expression _step) : this(_dereferencing_value, _v, _from, _to, _step, false, false) { } /// ///Конструктор с параметрами. /// public slice_expr(addressed_value _dereferencing_value, addressed_value _v, expression _from, expression _to, expression _step, SourceContext sc) : this(_dereferencing_value, _v, _from, _to, _step, false, false, sc) { } }*/ public partial class assign_var_tuple { public object sl = null; } public partial class foreach_stmt { public object ext = null; } public partial class uses_unit_in { public override string UsesPath() => in_file.Value; } public class ident_or_list : expression // Это для распаковки параметров в лямбдах \(x,y) { // только одно поле - ненулевое! public ident id; public unpacked_list_of_ident_or_list lst; public ident_or_list(ident id) { this.id = id; this.source_context = id.source_context; } public ident_or_list(unpacked_list_of_ident_or_list lst) { this.lst = lst; this.source_context = lst.source_context; } } public class unpacked_list_of_ident_or_list: expression // это для самого верхнего уровня { public List lst; public unpacked_list_of_ident_or_list(List lst) { this.lst = lst; if (lst != null && lst.Count > 0) this.source_context = lst[0].source_context; } public unpacked_list_of_ident_or_list() { lst = new List(); } public void Add(ident_or_list il) { lst.Add(il); if (source_context == null) source_context = il.source_context; else source_context = source_context.Merge(il.source_context); } } public partial class class_definition { public bool IsDataClass { get ; set; } } public partial class procedure_definition { /*public procedure_definition(procedure_header _proc_header, proc_block _proc_body, bool _is_short_definition) { this._proc_header = _proc_header; this._proc_body = _proc_body; this._is_short_definition = _is_short_definition; FillParentsInDirectChilds(); }*/ } public class semantic_check_delegates_pointers_in_cached_function // класс - маркер семантической проверки { } public partial class let_var_expr { public bool visit_var = true; } }