Example #1
0
        public static procedure_definition BuildToStringFuncForAutoClass(List <ident> names)
        {
            var pal = new procedure_attributes_list(proc_attribute.attr_override);
            var fp  = new formal_parameters();
            var ff  = new function_header("ToString", "string", fp, pal);

            var      cleft  = new char_const('(');
            var      cright = new char_const(')');
            var      ccomma = new char_const(',');
            bin_expr ex     = new bin_expr(cleft, cright, Operators.Plus);

            for (var i = 0; i < names.Count; i++)
            {
                var dn     = new dot_node(names[i], new ident("ToString"));
                var asnode = new typecast_node(names[i], new named_type_reference("object"), op_typecast.as_op);
                var eqnode = new bin_expr(asnode, new nil_const(), Operators.Equal);
                var expr   = new question_colon_expression(eqnode, new string_const("nil"), dn);
                ex.left = new bin_expr(ex.left, expr, Operators.Plus);
                if (i < names.Count - 1)
                {
                    ex.left = new bin_expr(ex.left, ccomma, Operators.Plus);
                }
            }
            var ass = new assign("Result", ex);

            return(BuildShortProcFuncDefinitionNoSC(ff, ass));
        }
        expression_list construct_expression_list_for_slice_expr_multi(slice_expr sl)
        {
            if (sl.slices == null)
            {
                return(null);               // упадёт - это ошибка компилятора
            }
            var el = new expression_list(); // будем наполнять кортежами - самое простое
            var sc = sl.source_context;

            foreach (var slice in sl.slices)
            {
                var tup = new dot_node(new dot_node(new ident("?System", sc), new ident("Tuple", sc), sc), new ident("Create", sc), sc);
                var eel = new expression_list();
                // пытаемся разобраться с ^1

                var sl1 = slice.Item1;
                eel.Add(sl1);
                IndexVisitor.New.ProcessNode(sl1); // индексный визитор сам не вызывается поскольку в многомерных срезах хранится List кортежей троек expression, который сам не обходится
                var sl2 = slice.Item2;
                eel.Add(sl2);
                IndexVisitor.New.ProcessNode(sl2);
                var sl3 = slice.Item3; // и step тоже надо обходить!!!
                eel.Add(sl3);
                IndexVisitor.New.ProcessNode(sl3);

                var mc = new method_call(tup, eel, sc); // sc - не очень хорошо - ошибка будет в общем месте
                el.Add(mc);
                // по идее все параметры готовы. Надо только проверить, что они целые
            }
            return(el);
        }
 public override void visit(dot_node dn)
 {
     ProcessNode(dn.left);
     if (dn.right.GetType() != typeof(ident))
     {
         ProcessNode(dn.right);
     }
 }
Example #4
0
        public override void visit(dot_node dn)
        {
            ProcessNode(dn.left);

            if (!(dn.right is ident))
            {
                ProcessNode(dn.right);
            }
        }
Example #5
0
 public addressed_value Into(addressed_value x, addressed_value v) // При возникновении новой конструкции в грамматике variable добавить обработку сюда
 {
     if (v.GetType() == typeof(dot_question_node))
     {
         var vv  = v as dot_question_node;
         var res = new dot_question_node(Into(x, vv.left), vv.right, x.source_context);
         return(res);
     }
     else if (v.GetType() == typeof(dot_node))
     {
         var vv  = v as dot_node;
         var res = new dot_node(Into(x, vv.left), vv.right, x.source_context);
         return(res);
     }
     else if (v.GetType() == typeof(indexer))
     {
         var vv  = v as indexer;
         var res = new indexer(Into(x, vv.dereferencing_value), vv.indexes, x.source_context);
         return(res);
     }
     else if (v.GetType() == typeof(slice_expr))
     {
         var vv  = v as slice_expr;
         var res = new slice_expr(Into(x, vv.dereferencing_value), vv.from, vv.to, vv.step, x.source_context);
         return(res);
     }
     else if (v.GetType() == typeof(slice_expr_question))
     {
         var vv  = v as slice_expr_question;
         var res = new slice_expr_question(Into(x, vv.dereferencing_value), vv.from, vv.to, vv.step, x.source_context);
         return(res);
     }
     else if (v.GetType() == typeof(method_call))
     {
         var vv  = v as method_call;
         var res = new method_call(Into(x, vv.dereferencing_value), vv.parameters, x.source_context);
         return(res);
     }
     else if (v.GetType() == typeof(roof_dereference))
     {
         var vv  = v as roof_dereference;
         var res = new roof_dereference(Into(x, vv.dereferencing_value), x.source_context);
         return(res);
     }
     else if (v.GetType() == typeof(ident_with_templateparams))
     {
         var vv  = v as ident_with_templateparams;
         var res = new ident_with_templateparams(Into(x, vv.name), vv.template_params, x.source_context);
         return(res);
     }
     else
     {
         var res = new dot_node(x, v, x.source_context);
         return(res);
     }
 }
Example #6
0
        public override void visit(tuple_node tup)
        {
            var dn = new dot_node(new dot_node(new ident("?System"), new ident("Tuple")), new ident("Create", tup.source_context));
            var mc = new method_call(dn, tup.el, tup.source_context);

            //var sug = new sugared_expression(tup, mc, tup.source_context); - нет никакой семантической проверки - всё - на уровне синтаксиса!

            ReplaceUsingParent(tup, mc);
            visit(mc);
        }
Example #7
0
        public override void visit(tuple_node tup)
        {
            var dn = new dot_node(new dot_node(new ident("?System"), new ident("Tuple")), new ident("Create", tup.source_context));
            var mc = new method_call(dn, tup.el, tup.source_context);

            //var sug = new sugared_expression(tup, mc, tup.source_context); - нет никакой семантической проверки - всё - на уровне синтаксиса!

            //ReplaceUsingParent(tup, mc); - исправление #1199. Оказывается, ReplaceUsingParent и Replace не эквивалентны - у копии Parent на старого родителя
            Replace(tup, mc);
            visit(mc);
        }
Example #8
0
        private TupleDesugaringResult DesugarTuplePattern(tuple_pattern pattern, expression matchingExpression)
        {
            Debug.Assert(!pattern.IsRecursive, "All recursive patterns should be desugared into simple patterns at this point");
            var desugaringResult = new TupleDesugaringResult();
            var tupleItems       = pattern.parameters;

            for (int i = 0; i < tupleItems.Count; ++i)
            {
                var tupleItemCall = new dot_node(
                    matchingExpression as addressed_value,
                    new ident("Item" + (i + 1).ToString()),
                    matchingExpression.source_context);
                if (tupleItems[i] is tuple_pattern_var_parameter varParam)
                {
                    desugaringResult.VarParametersDeclarations.Add(
                        new var_statement(
                            varParam.identifier,
                            tupleItemCall,
                            matchingExpression.source_context
                            )
                        );
                }

                if (tupleItems[i] is const_pattern_parameter constParam)
                {
                    var eqParams = new expression_list(
                        new List <expression>()
                    {
                        tupleItemCall,
                        constParam.const_param
                    }
                        );
                    var equalCall = new method_call(
                        new dot_node(new ident("object"), new ident("Equals")),
                        eqParams,
                        pattern.source_context
                        );

                    desugaringResult.SuccessMatchingCheck = desugaringResult.SuccessMatchingCheck == null ?
                                                            (expression)equalCall :
                                                            bin_expr.LogicalAnd(desugaringResult.SuccessMatchingCheck, equalCall);
                    desugaringResult.ElemTypeChecks.Add(GetTypeCompatibilityCheck(tupleItemCall, constParam.const_param));
                }
            }

            desugaringResult.TupleLengthCheck = GetTypeCompatibilityCheck(matchingExpression, new int32_const(tupleItems.Count));

            if (desugaringResult.SuccessMatchingCheck == null)
            {
                desugaringResult.SuccessMatchingCheck = new bool_const(true);
            }
            return(desugaringResult);
        }
 public override void visit(dot_node dn)
 {
     if (dn.left is ident id)
     {
         TryToRename(id);
     }
     else
     {
         ProcessNode(dn.left);
     }
     ProcessNode(dn.right);
 }
Example #10
0
        public override void visit(ident id)
        {
            int?paramNameLevel = null;

            var paramName = id.name;

            // Ищем с какого уровня имя
            for (int level = formalParametersStack.Count - 1; level >= 0; --level)
            {
                if (formalParametersStack[level].ContainsKey(paramName))
                {
                    // Нашли!
                    paramNameLevel = level;
                    break;
                }
            }

            bool isField = false;

            // Локальные параметры обрабатываются в другом визиторе

            // Параметр функции
            if ((object)paramNameLevel != null)
            {
                var upper = UpperNode();
                // Подозреваем обращение к параметру метода
                if ((object)upper == null || (object)upper != null && (upper as dot_node) == null)
                {
                    // Это не self.paramName - поле класса и не что-то другое?
                    // Нашли обращение к параметру?

                    var self = new ident("self", id.source_context);

                    // Заменяем paramName -> self.hoistedParamName: <>num__paramName

                    var hoistedParamName = new ident(formalParametersStack[(int)paramNameLevel][paramName], id.source_context);

                    var selfId = new dot_node(self, hoistedParamName);

                    Replace(id, selfId);
                }
                // Иначе проверить что это поле класса! self.paramName или какой-то другой очень извращенный вариант вроде (someMethod: self).paramName
            }

            // Поле класса

            // Параметр внешней функции (если наша - вложенная)

            // Глобальная переменная
        }
Example #11
0
        public question_colon_expression ConvertToQCE(dot_question_node dqn)
        {
            addressed_value left  = dqn.left;
            addressed_value right = dqn.right;

            var             eq     = new bin_expr(left, new nil_const(), Operators.Equal, left.source_context);
            addressed_value dn     = null;
            var             dnleft = right; // Левая часть dn
            addressed_value rdqn   = null;
            addressed_value ldqn   = null;

            // Если right - это dot_question_node, то протащить внутрь него left. В силу ассоциирования слева направо достаточно на первый уровень.
            if (right.GetType() == typeof(dot_question_node))
            {
                var dqn_int = right as dot_question_node;
                ldqn   = dqn_int.left;
                dnleft = ldqn;
                rdqn   = dqn_int.right;
                // необходимо left протащить внутрь в ldqn
            }

            // Пока right - это dot_node, то необходимо протаскивать left чтобы присоединить его к первому не dot_node
            while (dnleft.GetType() == typeof(dot_node))
            {
                dn     = dnleft;
                dnleft = (dnleft as dot_node).left;
            }
            // В итоге в dnleft - самый внутренний left, который уже не является dot_node
            dnleft = new dot_node(left, dnleft, left.source_context); // Прикрепили right к самому внутреннему левому узлу в нотации a.b.c.d
            if (dn != null)
            {
                (dn as dot_node).left = dnleft;
            }
            else if (rdqn == null)
            {
                right = dnleft;
            }
            else
            {
                right = new dot_question_node(dnleft, (right as dot_question_node).right, dnleft.source_context);
            }

            var q = new question_colon_expression(eq, new nil_const(), right, dqn.source_context);

            right.Parent = q;
            return(q);
        }
 public expression ConvertNamedTypeReferenceToDotNodeOrIdent(named_type_reference ntr) // либо ident либо dot_node
 {
     if (ntr.names.Count == 1)
     {
         return(ntr.names[0]);
     }
     else
     {
         var dn = new dot_node(ntr.names[0], ntr.names[1], ntr.names[0].source_context.Merge(ntr.names[1].source_context));
         for (var i = 2; i < ntr.names.Count; i++)
         {
             dn = new dot_node(dn, ntr.names[i], dn.source_context.Merge(ntr.names[i].source_context));
         }
         dn.source_context = ntr.source_context;
         return(dn);
     }
 }
        /*public override void visit(procedure_call pc)
         * {
         *  ProcessNode(pc.func_name);
         *  var methCall = pc.func_name as method_call;
         *  if ((object)methCall != null)
         *  {
         *      foreach (var param in methCall.parameters.expressions)
         *      {
         *          param.visit(this);
         *      }
         *  }
         * }*/

        public override void visit(dot_node dn)
        {
            var rid = dn.right as ident;

            if ((object)rid != null && rid.name != YieldConsts.Self)
            {
                ProcessNode(dn.left);
            }

            // Most nested
            // DotNode (DLeft, DRight) -> DotNode(DotNode("self", "<>__self"), DRight)


            // LEFT self -> captured self (self.captured_self)

            /*var id = dn.left as ident;
             * if ((object)id != null && (id.className == "self" || CollectedClassFields.Contains(id.className)))
             * {
             *  // Some magic for blocking back-traverse from BaseChangeVisitor redoin' work
             *  //var rid = dn.right as ident;
             *  //if ((object)rid != null && rid.className != Consts.Self)
             *  {
             *      var newDotNode = new dot_node(new dot_node(new ident("self"), new ident(Consts.Self)), dn.right);
             *      // Change right?
             *      //var capturedRight = new dot_node(new ident(Consts.Self), dn.right);
             *      //var newDotNode = new dot_node(dn.left, capturedRight);
             *      Replace(dn, newDotNode);
             *  }
             *
             *
             *  // Some magic for blocking back-traverse from BaseChangeVisitor redoin' work
             *  //var rid = dn.right as ident;
             *  //if ((object)rid != null && rid.className != Consts.Self)
             * // {
             *  //    var capturedSelf = new dot_node(new ident("self"), new ident(Consts.Self));
             *  //    Replace(dn.left, capturedSelf);
             * // }
             * }
             * else
             * {
             *  ProcessNode(dn.left);
             * }*/

            //if (dn.right.GetType() != typeof(ident))
            //    ProcessNode(dn.right);
        }
		public virtual void visit(dot_node _dot_node)
		{
			DefaultVisit(_dot_node);
		}
        private void AddReferencesToIdentInLambda(type_declaration upperScopeWhereVarsAreCapturedClass, CapturedVariablesTreeNode scope, string varName, syntax_tree_node syntaxTreeNodeWithVarDeclaration, dot_node substDotNode, bool nestedLambda)
        {
/*#if DEBUG
 *          var pp = scope.ToString().IndexOf("TreeNode");
 *          var ss = scope.ToString().Remove(0, pp + 8).Replace("Scope"," ");
 *          var cn = "";
 *          if (scope.ChildNodes.Count>0)
 *              cn = "Childs: "+ scope.ChildNodes.Aggregate("",(s, x) => s + x.ScopeIndex.ToString() + " ");
 *          System.IO.File.AppendAllText("d:\\w.txt", "AddR enter: " + ss + scope.ScopeIndex + " " + cn + "" +scope.CorrespondingSyntaxTreeNode + "\n");
 #endif*/
            for (var i = 0; i < scope.ChildNodes.Count; i++)
            {
                if (!(scope.ChildNodes[i] is CapturedVariablesTreeNodeLambdaScope))
                {
                    var substKey = new SubstitutionKey(varName, syntaxTreeNodeWithVarDeclaration,
                                                       scope.ChildNodes[i].CorrespondingSyntaxTreeNode);

                    if (_capturedVarsClassDefs.ContainsKey(scope.ChildNodes[i].ScopeIndex))
                    {
                        var cl = _capturedVarsClassDefs[scope.ChildNodes[i].ScopeIndex];
                        if (cl.AssignNodeForUpperClassFieldInitialization == null)
                        {
                            var fieldType =
                                SyntaxTreeBuilder.BuildSimpleType(upperScopeWhereVarsAreCapturedClass.type_name.name);
                            var field =
                                SyntaxTreeBuilder.BuildClassFieldsSection(
                                    new List <ident>
                            {
                                new ident(cl.GeneratedUpperClassFieldName)
                            },
                                    new List <type_definition> {
                                fieldType
                            });

                            var clClass = (class_definition)cl.ClassDeclaration.type_def;
                            clClass.body.Add(field);

                            cl.AssignNodeForUpperClassFieldInitialization =
                                new assign(
                                    new dot_node(new ident(cl.GeneratedSubstitutingFieldName), new ident(cl.GeneratedUpperClassFieldName)),
                                    new ident(compiler_string_consts.self_word));
                        }
                    }

                    if (!_substitutions.ContainsKey(substKey))
                    {
/*#if DEBUG
 *                      System.IO.File.AppendAllText("d:\\w.txt", "1 substitutions.Add: " + substKey + " " + substDotNode + "\n");
 #endif*/

                        _substitutions.Add(substKey, substDotNode);
                    }

                    AddReferencesToIdentInLambda(upperScopeWhereVarsAreCapturedClass, scope.ChildNodes[i], varName, syntaxTreeNodeWithVarDeclaration, substDotNode, nestedLambda);
                }
                else
                {
                    var scopeAsLambda = scope.ChildNodes[i] as CapturedVariablesTreeNodeLambdaScope;
                    if (scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.HasValue)
                    {
                        dot_node substDotNode1;
                        if (!nestedLambda)
                        {
                            var parts = new Stack <ident>();
                            var dn    = substDotNode;
                            parts.Push((ident)dn.right);

                            while (!(dn.left is ident && dn.right is ident))
                            {
                                dn = (dot_node)dn.left;
                                parts.Push((ident)dn.right);
                            }

                            substDotNode1 = new dot_node(new ident(_capturedVarsClassDefs[scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.Value].GeneratedUpperClassFieldName), parts.Pop());
                            while (parts.Count > 0)
                            {
                                substDotNode1 = new dot_node(substDotNode1, parts.Pop());
                            }
                        }
                        else
                        {
                            var parts = new Stack <ident>();
                            var dn    = substDotNode;
                            parts.Push((ident)dn.right);

                            while (!(dn.left is ident && dn.right is ident))
                            {
                                dn = (dot_node)dn.left;
                                parts.Push((ident)dn.right);
                            }

                            parts.Push((ident)dn.left);

                            substDotNode1 = new dot_node(new ident(_capturedVarsClassDefs[scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.Value].GeneratedUpperClassFieldName), parts.Pop());

                            while (parts.Count > 0)
                            {
                                substDotNode1 = new dot_node(substDotNode1, parts.Pop());
                            }
                        }

                        var substKey = new SubstitutionKey(varName, syntaxTreeNodeWithVarDeclaration,
                                                           scope.ChildNodes[0].CorrespondingSyntaxTreeNode);
                        if (!_substitutions.ContainsKey(substKey))
                        {
/*#if DEBUG
 *                          System.IO.File.AppendAllText("d:\\w.txt", "2 substitutions.Add: " + substKey + " " + substDotNode + "\n");
 #endif*/

                            _substitutions.Add(substKey, substDotNode1);
                        }
                        AddReferencesToIdentInLambda(_capturedVarsClassDefs[scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.Value].ClassDeclaration, scopeAsLambda.ChildNodes[0], varName, syntaxTreeNodeWithVarDeclaration, substDotNode1, true);
                    }
                    else
                    {
                        // SSM 25.06.19 fix #1988 - заменил ошибочное scope.ChildNodes[0] на scope.ChildNodes[i]
                        AddReferencesToIdentInLambda(upperScopeWhereVarsAreCapturedClass, scope.ChildNodes[i], varName, syntaxTreeNodeWithVarDeclaration, substDotNode, nestedLambda);
                    }
                }
            }

/*#if DEBUG
 *          System.IO.File.AppendAllText("d:\\w.txt", "AddR exit: " + scope.ScopeIndex+"\n");
 #endif*/
        }
Example #16
0
 public override void visit(dot_node _dot_node)
 {
 }
        public override void visit(ident id)
        {
            // Check dot node
            var upper = UpperNode(1);
            //if (upper is dot_node)
            //    return;

            var idName          = id.name;
            var idSourceContext = id.source_context;

            // frninja 31/03/16 - фикс селфа для extensionmethod
            if (idName.ToLower() == "self" && !CollectedFormalParams.Contains(idName))
            {
                var newSelf = new dot_node(new ident("self"), new ident(YieldConsts.Self));
                Replace(id, newSelf);
                return;
            }

            // Detect where is id from
            if (CollectedLocals.Contains(idName))
            {
                Replace(id, new ident(CapturedLocalsMap[idName], idSourceContext));
            }
            else if (CollectedFormalParams.Contains(idName))
            {
                Replace(id, new ident(CapturedFormalParamsMap[idName], idSourceContext));
            }
            else if (IsInClassMethod)
            {
                // In class -> check fields
                //if (CollectedClassFields.Contains(idName))
                {
                    // Good
                    // Name in class fields -> capture as class field


                    //var capturedId = new dot_node(new dot_node(new ident("self"), new ident(YieldConsts.Self)), id);
                    //Replace(id, capturedId);
                }
                //else
                {
                    // Bad
                    // At syntax we don't know if the className is class field or not coz of e.g. base .NET classes
                    // HERE WE SHOULD REPLACE TO yield_unknown_reference -> so decision is passed to semantic
                    // Check for globals will be processed at semantic, too

                    if (!id.name.StartsWith("<")) // Check for already captured
                    {
                        Replace(id, new yield_unknown_ident(id, ClassName, this.IsStaticMethod));
                    }
                }
            }
            else
            {
                // Not in class -> check globals
                if (CollectedUnitGlobals.Contains(idName))
                {
                    // Global -> just do nothing
                }
                else
                {
                    // What about static classes - search at semantic
                    // HERE WE SHOULD REPLACE TO yield_unknown_reference -> so decision is passed to semantic
                }
            }
        }
Example #18
0
 public override void visit(dot_node _dot_node)
 {
     _dot_node.left.visit(this);
     _dot_node.right.visit(this);
 }
Example #19
0
        // frninja 21/05/16
        public override void visit(foreach_stmt frch)
        {
            // Полный код Loweringа c yield_unknown_foreach_type = integer
            //  var a: System.Collections.Generic.IEnumerable<integer>;
            //  a := l;
            //  var en := a.GetEnumerator();
            //  while en.MoveNext do
            //  begin
            //    var curr := en.Current; // var не нужно ставить если curr была описана раньше
            //    Print(curr);
            //  end;
            ///

            // var a: System.Collections.Generic.IEnumerable<yield_unknown_foreach_type> := l;
            var foreachCollIdent = this.NewForeachCollectionName();
            var foreachCollType  = new template_type_reference(new named_type_reference("System.Collections.Generic.IEnumerable"),
                                                               new template_param_list(new yield_unknown_foreach_type(frch)));
            var foreachCollVarDef = new var_statement(foreachCollIdent, foreachCollType);

            var ass = new assign(foreachCollIdent, frch.in_what);

            //  var en := a.GetEnumerator();
            var enumeratorIdent  = this.NewEnumeratorName();
            var enumeratorVarDef = new var_statement(enumeratorIdent, new method_call(new dot_node(foreachCollIdent, new ident("GetEnumerator")), new expression_list()));

            //var curr := en.Current;
            // Переменная цикла foreach. Есть три варианта:
            // 1. foreach x in l do           ->    curr := en.Current;
            // 2. foreach var x in l do       ->    var curr := en.Current;
            // 3. foreach var x: T in l do    ->    var curr: T := en.Current;
            var       currentIdent = frch.identifier;
            statement st           = null;

            var curExpr = new dot_node(enumeratorIdent, "Current");

            // С типом
            if (frch.type_name == null) // 1. foreach x in l do   ->   curr := en.Current;
            {
                st = new assign(currentIdent, curExpr);
            }
            else if (frch.type_name is no_type_foreach) // 2. foreach var x in l do    ->    var curr := en.Current;
            {
                // Получаем служебное имя с $ и заменяем его в теле цикла
                currentIdent = this.NewVarNames(frch.identifier).VarName;
                var replacerVis = new ReplaceVariableNameVisitor(frch.identifier, currentIdent);
                frch.visit(replacerVis);

                st = new var_statement(currentIdent, curExpr);
            }
            else // 3. foreach var x: T in l do    ->    var curr: T := en.Current;
            {
                // Получаем служебное имя с $ и заменяем его в теле цикла
                currentIdent = this.NewVarNames(frch.identifier).VarName;
                var replacerVis = new ReplaceVariableNameVisitor(frch.identifier, currentIdent);
                frch.visit(replacerVis);

                st = new var_statement(currentIdent, frch.type_name, curExpr);
            }

            // Добавляем тело цикла в stl
            var stl = new statement_list(st);

            ProcessNode(frch.stmt); // для обработки вложенных конструкций
            stl.Add(frch.stmt);

            var whileNode = new while_node(new method_call(new dot_node(enumeratorIdent, "MoveNext"), new expression_list()),
                                           stl,
                                           WhileCycleType.While);

            var sq = SeqStatements(foreachCollVarDef, ass, enumeratorVarDef, whileNode);

            ReplaceStatement(frch, sq);

            visit(whileNode); // Lowering оставшегося whileNode
        }
        public override void visit(ident id)
        {
            var idName = id.name.ToLower();

            SymbolInfo si = _visitor.context.find_first(idName);

            //var q = si.GetHashCode();

            if (si == null)
            {
                /*if (InLambdaContext)
                 * {
                 *  _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id)));
                 *  return;
                 * }*/
                return;
            }

            if (si.sym_info.semantic_node_type == semantic_node_type.namespace_variable ||
                si.sym_info.semantic_node_type == semantic_node_type.common_namespace_function_node ||
                si.sym_info.semantic_node_type == semantic_node_type.namespace_constant_definition ||
                si.sym_info.semantic_node_type == semantic_node_type.compiled_function_node ||
                //si.sym_info.semantic_node_type == semantic_node_type.common_method_node || // SSM bug fix  #1991 11.06.19  конкурирует с #891
                si.sym_info.semantic_node_type == semantic_node_type.compiled_namespace_node ||
                si.sym_info.semantic_node_type == semantic_node_type.compiled_variable_definition ||
                si.sym_info.semantic_node_type == semantic_node_type.common_type_node ||
                si.sym_info.semantic_node_type == semantic_node_type.compiled_type_node ||
                si.sym_info.semantic_node_type == semantic_node_type.basic_interface_node ||
                si.sym_info.semantic_node_type == semantic_node_type.common_unit_node ||
                si.sym_info.semantic_node_type == semantic_node_type.common_namespace_node ||
                si.sym_info.semantic_node_type == semantic_node_type.compiled_unit_node ||
                si.sym_info.semantic_node_type == semantic_node_type.template_type ||
                si.sym_info.semantic_node_type == semantic_node_type.ref_type_node ||
                si.sym_info.semantic_node_type == semantic_node_type.generic_indicator ||
                si.sym_info.semantic_node_type == semantic_node_type.class_constant_definition ||
                si.sym_info.semantic_node_type == semantic_node_type.function_constant_definition || // SSM 03.11.18 bug fix #1449
                si.sym_info.semantic_node_type == semantic_node_type.basic_function_node && (idName == "exit" || idName == "continue" || idName == "break"))
            {
                return;
            }

            var acceptableVarType = si.sym_info.semantic_node_type == semantic_node_type.local_variable ||
                                    si.sym_info.semantic_node_type == semantic_node_type.local_block_variable ||
                                    si.sym_info.semantic_node_type == semantic_node_type.common_parameter ||
                                    si.sym_info.semantic_node_type == semantic_node_type.class_field ||
                                    si.sym_info.semantic_node_type == semantic_node_type.basic_property_node
            ;

            //trjuk, chtoby ne perelopachivat ves kod. zamenjaem ident na self.ident
            // Использую этот трюк для нестатических полей предков - они не захватываются из-за плохого алгоритма захвата
            // aab 12.06.19 begin
            // Добавил такое же переименование для статичесских полей класса. Теперь захват работает
            if ((si.sym_info.semantic_node_type == semantic_node_type.class_field || si.sym_info.semantic_node_type == semantic_node_type.common_method_node ||
                 si.sym_info.semantic_node_type == semantic_node_type.common_event || si.sym_info.semantic_node_type == semantic_node_type.common_property_node ||
                 si.sym_info.semantic_node_type == semantic_node_type.basic_property_node) && InLambdaContext)
            {
                dot_node dn = null;
                // Поменял принцип добавления имени класса для статических полей и функций
                Func <common_type_node, addressed_value> getClassIdent = classNode =>
                {
                    if (classNode.name.Contains("<"))
                    {
                        var classIdent     = new ident(classNode.name.Remove(classNode.name.IndexOf("<")));
                        var templateParams = new template_param_list(classNode.instance_params.Select(x => x.name) /*.Aggregate("", (acc, elem) => acc += elem)*/);
                        return(new ident_with_templateparams(classIdent, templateParams));
                    }
                    else
                    {
                        return(new ident(classNode.name));
                    }
                };
                if (si.sym_info is class_field classField && classField.IsStatic)
                {
                    dn = new dot_node(getClassIdent(classField.cont_type),
                                      new ident(id.name, id.source_context), id.source_context);
                }
                else if (si.sym_info is common_method_node commonMethodNode && commonMethodNode.IsStatic)
                {
                    dn = new dot_node(getClassIdent(commonMethodNode.cont_type),
                                      new ident(id.name, id.source_context), id.source_context);
                }
Example #21
0
 public virtual void visit(dot_node _dot_node)
 {
     DefaultVisit(_dot_node);
 }
Example #22
0
		public override void visit(dot_node _dot_node)
		{
			DefaultVisit(_dot_node);
			pre_do_visit(_dot_node);
			visit(dot_node.left);
			visit(dot_node.right);
			post_do_visit(_dot_node);
		}
Example #23
0
		public virtual void post_do_visit(dot_node _dot_node)
		{
		}
Example #24
0
		public virtual void visit(dot_node _dot_node)
		{
		}
Example #25
0
        private void VisitCapturedVar(CapturedVariablesTreeNode scope, CapturedVariablesTreeNode.CapturedSymbolInfo symbolInfo)
        {
            var varName           = ((IVAriableDefinitionNode)symbolInfo.SymbolInfo.sym_info).name.ToLower();
            var isSelfWordInClass = scope is CapturedVariablesTreeNodeClassScope && varName == compiler_string_consts.self_word;

            foreach (var referencingLambda in symbolInfo.ReferencingLambdas.OrderByDescending(rl => rl.ScopeIndex))
            {
                if (scope != referencingLambda.ParentNode)
                {
                    var upperScopesStack        = new Stack <CapturedVariablesTreeNode>();
                    var crawlUpScope            = referencingLambda.ParentNode;
                    var anotherLambdaIsOnTheWay = crawlUpScope is CapturedVariablesTreeNodeLambdaScope;

                    while (crawlUpScope != null && crawlUpScope != scope && !anotherLambdaIsOnTheWay)
                    {
                        upperScopesStack.Push(crawlUpScope);
                        crawlUpScope            = crawlUpScope.ParentNode;
                        anotherLambdaIsOnTheWay = crawlUpScope is CapturedVariablesTreeNodeLambdaScope;
                    }

                    if (anotherLambdaIsOnTheWay || crawlUpScope == null)
                    {
                        continue;
                    }

                    var upperScopeWhereVarsAreCaptured      = scope;
                    var upperScopeWhereVarsAreCapturedClass =
                        _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex].ClassDeclaration;

                    var substKey = new SubstitutionKey(varName, symbolInfo.SyntaxTreeNodeWithVarDeclaration,
                                                       scope.CorrespondingSyntaxTreeNode);
                    if (!_substitutions.ContainsKey(substKey))
                    {
                        _substitutions.Add(substKey,
                                           new dot_node(
                                               new ident(
                                                   _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex]
                                                   .GeneratedSubstitutingFieldName), new ident(varName)));
                    }

                    while (upperScopesStack.Count != 0)
                    {
                        var foundScopeWhereVarsWereCaptured = false;
                        while (upperScopesStack.Count != 0 && !foundScopeWhereVarsWereCaptured)
                        {
                            if (
                                upperScopesStack.Peek()
                                .VariablesDefinedInScope.Exists(var => var.ReferencingLambdas.Count > 0))
                            {
                                foundScopeWhereVarsWereCaptured = true;
                            }
                            else
                            {
                                var curScope = upperScopesStack.Pop();

                                if (upperScopeWhereVarsAreCaptured == scope &&
                                    upperScopeWhereVarsAreCaptured is CapturedVariablesTreeNodeClassScope)
                                {
                                    continue;
                                }

                                substKey = new SubstitutionKey(varName, symbolInfo.SyntaxTreeNodeWithVarDeclaration,
                                                               curScope.CorrespondingSyntaxTreeNode);

                                dot_node dotnode;

                                if (upperScopeWhereVarsAreCaptured != scope)
                                {
                                    dotnode =
                                        new dot_node(
                                            new ident(
                                                _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex]
                                                .GeneratedSubstitutingFieldName),
                                            new ident(
                                                _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex]
                                                .GeneratedUpperClassFieldName));

                                    var nodeForDotNodeCalc = upperScopeWhereVarsAreCaptured.ParentNode;
                                    while (nodeForDotNodeCalc != scope)
                                    {
                                        if (_capturedVarsClassDefs.ContainsKey(nodeForDotNodeCalc.ScopeIndex) &&
                                            _capturedVarsClassDefs[nodeForDotNodeCalc.ScopeIndex]
                                            .AssignNodeForUpperClassFieldInitialization != null)
                                        {
                                            dotnode = new dot_node(dotnode,
                                                                   new ident(
                                                                       _capturedVarsClassDefs[
                                                                           nodeForDotNodeCalc.ScopeIndex]
                                                                       .GeneratedUpperClassFieldName));
                                        }

                                        nodeForDotNodeCalc = nodeForDotNodeCalc.ParentNode;
                                    }
                                    if (!isSelfWordInClass)
                                    {
                                        dotnode = new dot_node(dotnode, new ident(varName));
                                    }
                                }
                                else
                                {
                                    dotnode = new dot_node(new ident(
                                                               _capturedVarsClassDefs[
                                                                   upperScopeWhereVarsAreCaptured.ScopeIndex]
                                                               .GeneratedSubstitutingFieldName),
                                                           new ident(varName));
                                }

                                if (!_substitutions.ContainsKey(substKey))
                                {
                                    _substitutions.Add(substKey, dotnode);
                                }
                            }
                        }

                        if (foundScopeWhereVarsWereCaptured)
                        {
                            var nextNodeWhereVarsAreCaptured = upperScopesStack.Pop();
                            if (!_capturedVarsClassDefs.ContainsKey(nextNodeWhereVarsAreCaptured.ScopeIndex))
                            {
                                var classDef        = SyntaxTreeBuilder.BuildClassDefinition();
                                var typeDeclaration = new type_declaration(GeneratedClassName, classDef);
                                _capturedVarsClassDefs.Add(nextNodeWhereVarsAreCaptured.ScopeIndex,
                                                           new ScopeClassDefinition(
                                                               nextNodeWhereVarsAreCaptured.CorrespondingSyntaxTreeNode,
                                                               typeDeclaration,
                                                               nextNodeWhereVarsAreCaptured));
                            }

                            var nextNodeWhereVarsAreCapturedClass =
                                (class_definition)
                                _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex].ClassDeclaration
                                .type_def;

                            if (
                                _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex]
                                .AssignNodeForUpperClassFieldInitialization == null)
                            {
                                var fieldType =
                                    SyntaxTreeBuilder.BuildSimpleType(upperScopeWhereVarsAreCapturedClass.type_name.name);
                                var field =
                                    SyntaxTreeBuilder.BuildClassFieldsSection(
                                        new List <ident>
                                {
                                    new ident(
                                        _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex]
                                        .GeneratedUpperClassFieldName)
                                },
                                        new List <type_definition> {
                                    fieldType
                                });

                                nextNodeWhereVarsAreCapturedClass.body.Add(field);

                                _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex]
                                .AssignNodeForUpperClassFieldInitialization =
                                    new assign(
                                        new dot_node(
                                            new ident(
                                                _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex]
                                                .GeneratedSubstitutingFieldName),
                                            new ident(
                                                _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex]
                                                .GeneratedUpperClassFieldName)),
                                        new ident(
                                            _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex]
                                            .GeneratedSubstitutingFieldName));
                            }

                            substKey = new SubstitutionKey(varName, symbolInfo.SyntaxTreeNodeWithVarDeclaration,
                                                           nextNodeWhereVarsAreCaptured.CorrespondingSyntaxTreeNode);

                            var dot =
                                new dot_node(
                                    new ident(
                                        _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex]
                                        .GeneratedSubstitutingFieldName),
                                    new ident(
                                        _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex]
                                        .GeneratedUpperClassFieldName));

                            var nodeForDotNodeCalculation = nextNodeWhereVarsAreCaptured.ParentNode;
                            while (nodeForDotNodeCalculation != scope)
                            {
                                if (_capturedVarsClassDefs.ContainsKey(nodeForDotNodeCalculation.ScopeIndex) &&
                                    _capturedVarsClassDefs[nodeForDotNodeCalculation.ScopeIndex]
                                    .AssignNodeForUpperClassFieldInitialization != null)
                                {
                                    dot = new dot_node(dot,
                                                       new ident(
                                                           _capturedVarsClassDefs[nodeForDotNodeCalculation.ScopeIndex]
                                                           .GeneratedUpperClassFieldName));
                                }

                                nodeForDotNodeCalculation = nodeForDotNodeCalculation.ParentNode;
                            }

                            if (!isSelfWordInClass)
                            {
                                dot = new dot_node(dot, new ident(varName));
                            }

                            if (!_substitutions.ContainsKey(substKey))
                            {
                                _substitutions.Add(substKey, dot);
                            }

                            upperScopeWhereVarsAreCaptured      = nextNodeWhereVarsAreCaptured;
                            upperScopeWhereVarsAreCapturedClass =
                                _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex].ClassDeclaration;
                        }
                    }

                    if (!(upperScopeWhereVarsAreCaptured == scope &&
                          upperScopeWhereVarsAreCaptured is CapturedVariablesTreeNodeClassScope))
                    {
                        if (upperScopeWhereVarsAreCaptured != scope)
                        {
                            var dotnode1 = new dot_node(
                                new ident(compiler_string_consts.self_word),
                                new ident(
                                    _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex]
                                    .GeneratedUpperClassFieldName));

                            if (upperScopeWhereVarsAreCaptured != scope)
                            {
                                var nodeForDotNodeCalc = upperScopeWhereVarsAreCaptured.ParentNode;
                                while (nodeForDotNodeCalc != scope)
                                {
                                    if (_capturedVarsClassDefs.ContainsKey(nodeForDotNodeCalc.ScopeIndex) &&
                                        _capturedVarsClassDefs[nodeForDotNodeCalc.ScopeIndex]
                                        .AssignNodeForUpperClassFieldInitialization != null)
                                    {
                                        dotnode1 = new dot_node(dotnode1,
                                                                new ident(
                                                                    _capturedVarsClassDefs[nodeForDotNodeCalc.ScopeIndex]
                                                                    .GeneratedUpperClassFieldName));
                                    }

                                    nodeForDotNodeCalc = nodeForDotNodeCalc.ParentNode;
                                }
                            }

                            if (!isSelfWordInClass)
                            {
                                var classScope = scope as CapturedVariablesTreeNodeClassScope;
                                if (classScope != null)
                                {
                                    Tuple <string, class_field, semantic_node> publicProperty;
                                    if (classScope.NonPublicMembersNamesMapping.TryGetValue(varName, out publicProperty))
                                    {
                                        dotnode1 = new dot_node(dotnode1, new ident(publicProperty.Item1));
                                    }
                                    else
                                    {
                                        dotnode1 = new dot_node(dotnode1, new ident(varName));
                                    }
                                }
                                else
                                {
                                    dotnode1 = new dot_node(dotnode1, new ident(varName));
                                }
                            }
                            _lambdaIdReferences.Add(new LambdaReferencesSubstitutionInfo
                            {
                                LambdaScope = referencingLambda,
                                VarName     = varName,
                                SyntaxTreeNodeWithVarDeclaration = symbolInfo.SyntaxTreeNodeWithVarDeclaration,
                                DotNode = dotnode1
                            });
                        }
                        else
                        {
                            var dotnode1 = new dot_node(
                                new ident(compiler_string_consts.self_word),
                                new ident(varName));

                            _lambdaIdReferences.Add(new LambdaReferencesSubstitutionInfo
                            {
                                LambdaScope = referencingLambda,
                                VarName     = varName,
                                SyntaxTreeNodeWithVarDeclaration = symbolInfo.SyntaxTreeNodeWithVarDeclaration,
                                DotNode = dotnode1
                            });
                        }
                    }
                    if (!referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.HasValue ||
                        upperScopeWhereVarsAreCaptured.ScopeIndex >
                        referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod)
                    {
                        referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod =
                            upperScopeWhereVarsAreCaptured.ScopeIndex;
                    }
                }
                else
                {
                    if (!_capturedVarsClassDefs.ContainsKey(scope.ScopeIndex))
                    {
                        var classDef        = SyntaxTreeBuilder.BuildClassDefinition();
                        var typeDeclaration = new type_declaration(GeneratedClassName, classDef);
                        _capturedVarsClassDefs.Add(scope.ScopeIndex,
                                                   new ScopeClassDefinition(
                                                       scope.CorrespondingSyntaxTreeNode,
                                                       typeDeclaration,
                                                       scope));
                    }

                    var substKey = new SubstitutionKey(varName, symbolInfo.SyntaxTreeNodeWithVarDeclaration,
                                                       scope.CorrespondingSyntaxTreeNode);
                    if (!_substitutions.ContainsKey(substKey))
                    {
                        if (!isSelfWordInClass)
                        {
                            string propertyName = null;

                            var classScope = scope as CapturedVariablesTreeNodeClassScope;
                            if (classScope != null)
                            {
                                Tuple <string, class_field, semantic_node> publicProperty;
                                if (classScope.NonPublicMembersNamesMapping.TryGetValue(varName, out publicProperty))
                                {
                                    propertyName = publicProperty.Item1;
                                }
                            }

                            _substitutions.Add(substKey,
                                               new dot_node(
                                                   new ident(
                                                       _capturedVarsClassDefs[scope.ScopeIndex]
                                                       .GeneratedSubstitutingFieldName), new ident(propertyName ?? varName)));
                        }
                    }

                    var dotnode1 = new dot_node(
                        new ident(compiler_string_consts.self_word),
                        new ident(varName));

                    _lambdaIdReferences.Add(new LambdaReferencesSubstitutionInfo
                    {
                        LambdaScope = referencingLambda,
                        VarName     = varName,
                        SyntaxTreeNodeWithVarDeclaration = symbolInfo.SyntaxTreeNodeWithVarDeclaration,
                        DotNode = dotnode1
                    });

                    if (!referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.HasValue ||
                        scope.ScopeIndex > referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod)
                    {
                        referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod = scope.ScopeIndex;
                    }
                }

                if (!_lambdasToBeAddedAsMethods.Contains(referencingLambda))
                {
                    _lambdasToBeAddedAsMethods.Add(referencingLambda);
                }
            }
        }
Example #26
0
 public override void visit(dot_node _dot_node)
 {
     prepare_node(_dot_node.left, "left");
     prepare_node(_dot_node.right, "right");
 }
        bool VisitTypeclassDeclaration(type_declaration typeclassDeclaration)
        {
            var typeclassDefinition = typeclassDeclaration.type_def as typeclass_definition;

            if (typeclassDefinition == null)
            {
                return(false);
            }

            var typeclassName = typeclassDeclaration.type_name as typeclass_restriction;

            // TODO: typeclassDefinition.additional_restrictions - translate to usual classes

            // Creating interface

            // Get members for typeclass interface
            var interfaceMembers = new List <class_members>();

            foreach (var cm in typeclassDefinition.body.class_def_blocks)
            {
                var cmNew = (class_members)cm.Clone();

                for (int i = 0; i < cmNew.members.Count; i++)
                {
                    var member = cmNew.members[i];
                    if (member is function_header || member is procedure_header)
                    {
                        cmNew.members[i] = member;
                    }
                    else if (member is procedure_definition procDef)
                    {
                        cmNew.members[i] = procDef.proc_header;
                    }
                    AddAttribute(cmNew.members[i], "__TypeclassMemberAttribute");
                    if (cmNew.members[i] is procedure_header ph)
                    {
                        ConvertOperatorNameIdent(ph);
                    }
                }

                interfaceMembers.Add(cmNew);
            }
            var interfaceInheritance = (named_type_reference_list)typeclassDefinition.additional_restrictions?.Clone();

            if (interfaceInheritance != null)
            {
                interfaceInheritance.source_context = null;
                for (int i = 0; i < interfaceInheritance.types.Count; i++)
                {
                    if (interfaceInheritance.types[i] is typeclass_reference tr)
                    {
                        interfaceInheritance.types[i] = TypeclassReferenceToInterfaceName(tr.names[0].name, tr.restriction_args);
                    }
                    else
                    {
                        throw new NotImplementedException("Syntactic Error");
                    }
                }
            }
            var typeclassInterfaceDef =
                SyntaxTreeBuilder.BuildClassDefinition(
                    interfaceInheritance,
                    null, interfaceMembers.ToArray());

            typeclassInterfaceDef.keyword = class_keyword.Interface;
            var typeclassInterfaceName = new template_type_name("I" + typeclassName.name, RestrictionsToIdentList(typeclassName.restriction_args));
            var typeclassInterfaceDecl = new type_declaration(typeclassInterfaceName, typeclassInterfaceDef);

            typeclassInterfaceDecl.attributes = typeclassDeclaration.attributes;
            AddAttribute(
                typeclassInterfaceDecl, "__TypeclassAttribute",
                new expression_list(new string_const(TypeclassRestrictionToString(typeclassName))));


            // Creating class

            var typeclassDefTranslated =
                SyntaxTreeBuilder.BuildClassDefinition(
                    new named_type_reference_list(new template_type_reference(typeclassInterfaceName.name, typeclassName.restriction_args)),
                    null, typeclassDefinition.body.class_def_blocks.ToArray());

            typeclassDefTranslated.attribute = class_attribute.Abstract;
            for (int i = 0; i < typeclassDefTranslated.body.class_def_blocks.Count; i++)
            {
                var cm = typeclassDefTranslated.body.class_def_blocks[i].members;

                for (int j = 0; j < cm.Count; j++)
                {
                    procedure_header header = null;
                    if (cm[j] is procedure_header ph)
                    {
                        header = ph;
                        header.proc_attributes.Add(new procedure_attribute("abstract", proc_attribute.attr_abstract));
                    }
                    else if (cm[j] is procedure_definition pd)
                    {
                        header = pd.proc_header;
                        header.proc_attributes.Add(new procedure_attribute("virtual", proc_attribute.attr_virtual));
                    }

                    ConvertOperatorNameIdent(header);
                }
            }

            /*
             * {
             *  // Add constructor
             *  var cm = typeclassDefTranslated.body.class_def_blocks[0];
             *  var def = new procedure_definition(
             *      new constructor(),
             *      new statement_list(new empty_statement()));
             *  def.proc_body.Parent = def;
             *  def.proc_header.proc_attributes = new procedure_attributes_list();
             *
             *  cm.Add(def);
             * }
             */
            // Add template parameters for typeclass class(derived typeclasses)
            ident_list templates = RestrictionsToIdentList(typeclassName.restriction_args);

            if (typeclassDefinition.additional_restrictions != null)
            {
                for (int i = 0; i < typeclassDefinition.additional_restrictions.types.Count; i++)
                {
                    string name;
                    string templateName;
                    if (typeclassDefinition.additional_restrictions.types[i] is typeclass_reference tr)
                    {
                        name         = tr.names[0].name;
                        templateName = TypeclassRestrctionToTemplateName(name, tr.restriction_args).name;
                    }
                    else
                    {
                        throw new NotImplementedException("SyntaxError");
                    }

                    // Add template parameter
                    templates.Add(templateName);

                    // Add where restriction
                    if (typeclassDefTranslated.where_section == null)
                    {
                        typeclassDefTranslated.where_section = new where_definition_list();
                    }
                    typeclassDefTranslated.where_section.Add(GetWhereRestriction(
                                                                 interfaceInheritance.types[i],
                                                                 templateName));

                    // Add methods from derived typeclasses
                    var body = (instancesAndRestrictedFunctions.typeclasses[name].type_def as typeclass_definition).body;
                    foreach (var cdb in body.class_def_blocks)
                    {
                        var cdbNew = new class_members(cdb.access_mod == null ? access_modifer.none : cdb.access_mod.access_level);
                        foreach (var member in cdb.members)
                        {
                            procedure_header memberHeaderNew;

                            if (member is procedure_header || member is function_header)
                            {
                                memberHeaderNew = (procedure_header)member.Clone();
                                memberHeaderNew.source_context = null;
                            }
                            else if (member is procedure_definition procDefinition)
                            {
                                memberHeaderNew                = (procedure_header)procDefinition.proc_header.Clone();
                                memberHeaderNew.Parent         = null;
                                memberHeaderNew.source_context = null;
                            }
                            else
                            {
                                continue;
                            }

                            var variableName = templateName + "Instance";
                            var parameters   = memberHeaderNew.parameters.params_list.Aggregate(new expression_list(), (x, y) => new expression_list(x.expressions.Concat(y.idents.idents).ToList()));

                            expression methodCall = null;
                            if (memberHeaderNew.name.meth_name is operator_name_ident oni)
                            {
                                ConvertOperatorNameIdent(memberHeaderNew);
                                Debug.Assert(parameters.expressions.Count == 2, "Parameters count for operation should be equal to 2");
                                //methodCall = new bin_expr(parameters.expressions[0], parameters.expressions[1], oni.operator_type);
                            }
                            var callName = new dot_node(variableName, memberHeaderNew.name.meth_name.name);
                            methodCall = new method_call(callName, parameters);
                            statement exec = null;
                            if (memberHeaderNew is function_header)
                            {
                                exec = new assign("Result", methodCall);
                            }
                            else if (memberHeaderNew is procedure_header)
                            {
                                exec = new procedure_call(methodCall as method_call);
                            }
                            var procDef = new procedure_definition(
                                memberHeaderNew,
                                new statement_list(
                                    GetInstanceSingletonVarStatement(templateName),
                                    exec));
                            cdbNew.Add(procDef);
                        }
                        typeclassDefTranslated.body.class_def_blocks.Add(cdbNew);
                    }
                }
            }

            var typeclassNameTanslated = new template_type_name(typeclassName.name, templates, typeclassName.source_context);

            var typeclassDeclTranslated = new type_declaration(typeclassNameTanslated, typeclassDefTranslated, typeclassDeclaration.source_context);

            typeclassDeclTranslated.attributes = typeclassDeclaration.attributes;
            AddAttribute(
                typeclassDeclTranslated, "__TypeclassAttribute",
                new expression_list(new string_const(TypeclassRestrictionToString(typeclassName))));

            Replace(typeclassDeclaration, typeclassDeclTranslated);
            UpperNodeAs <type_declarations>().InsertBefore(typeclassDeclTranslated, typeclassInterfaceDecl);
            visit(typeclassInterfaceDecl);
            visit(typeclassDeclTranslated);

            return(true);
        }
Example #28
0
 public virtual void visit(dot_node _dot_node)
 {
 }
Example #29
0
 public override void visit(dot_node _dot_node)
 {
     ProcessNode(_dot_node.left);
     //правую часть не обходим
 }
        public override void visit(ident id)
        {
            var idName = id.name.ToLower();

            SymbolInfo si = _visitor.context.find_first(idName);

            if (si == null)
            {
                if (InLambdaContext)
                {
                    _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id)));
                    return;
                }
                return;
            }

            if (si.sym_info.semantic_node_type == semantic_node_type.namespace_variable ||
                si.sym_info.semantic_node_type == semantic_node_type.common_namespace_function_node ||
                si.sym_info.semantic_node_type == semantic_node_type.namespace_constant_definition ||
                si.sym_info.semantic_node_type == semantic_node_type.compiled_function_node ||
                si.sym_info.semantic_node_type == semantic_node_type.common_method_node || // SSM bug fix  #167
                si.sym_info.semantic_node_type == semantic_node_type.compiled_namespace_node ||
                si.sym_info.semantic_node_type == semantic_node_type.compiled_variable_definition ||
                si.sym_info.semantic_node_type == semantic_node_type.common_type_node ||
                si.sym_info.semantic_node_type == semantic_node_type.compiled_type_node ||
                si.sym_info.semantic_node_type == semantic_node_type.basic_interface_node ||
                si.sym_info.semantic_node_type == semantic_node_type.common_unit_node ||
                si.sym_info.semantic_node_type == semantic_node_type.common_namespace_node ||
                si.sym_info.semantic_node_type == semantic_node_type.compiled_unit_node ||
                si.sym_info.semantic_node_type == semantic_node_type.template_type ||
                si.sym_info.semantic_node_type == semantic_node_type.generic_indicator ||
                si.sym_info.semantic_node_type == semantic_node_type.class_constant_definition ||
                si.sym_info.semantic_node_type == semantic_node_type.basic_function_node && (idName == "exit" || idName == "continue" || idName == "break"))
            {
                return;
            }

            var acceptableVarType = si.sym_info.semantic_node_type == semantic_node_type.local_variable ||
                                    si.sym_info.semantic_node_type == semantic_node_type.local_block_variable ||
                                    si.sym_info.semantic_node_type == semantic_node_type.common_parameter ||
                                    si.sym_info.semantic_node_type == semantic_node_type.class_field
            ;

            //trjuk, chtoby ne perelopachivat ves kod. zamenjaem ident na self.ident
            // Использую этот трюк для нестатических полей предков - они не захватываются из-за плохого алгоритма захвата
            if ((si.sym_info.semantic_node_type == semantic_node_type.class_field && !(si.sym_info as class_field).IsStatic || si.sym_info.semantic_node_type == semantic_node_type.common_event || si.sym_info.semantic_node_type == semantic_node_type.common_property_node) && InLambdaContext)
            {
                dot_node dn = new dot_node(new ident("self", id.source_context), new ident(id.name, id.source_context), id.source_context);
                bool     ok = true;
                try
                {
                    id.Parent.ReplaceDescendantUnsafe(id, dn);
                }
                catch
                {
                    ok = false;
                }
                if (ok)
                {
                    ProcessNode(id.Parent);
                    return;
                }
            }
            if (!(acceptableVarType) && InLambdaContext)
            {
                _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id)));
                return;
            }

            /*if (si.sym_info.semantic_node_type == semantic_node_type.class_field && InLambdaContext)
             * {
             *  var semClassField = (class_field)si.sym_info;
             *  if (semClassField.polymorphic_state != polymorphic_state.ps_common)
             *  {
             *      _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id)));
             *      return;
             *  }
             * }*/

            if (si.scope == null)
            {
                return;
            }

            var scopeIndex      = si.scope.ScopeNum;
            var selfWordInClass = false;

            CapturedVariablesTreeNode scope;

            if (_scopesCapturedVarsNodesDictionary.TryGetValue(scopeIndex, out scope))
            {
                var prScope = scope as CapturedVariablesTreeNodeProcedureScope;
                if (prScope != null && acceptableVarType)
                {
                    if (si.sym_info.semantic_node_type == semantic_node_type.local_variable)
                    {
                        if (!(idName == compiler_string_consts.self_word && si.scope is SymbolTable.ClassMethodScope && _classScope != null) && InLambdaContext)
                        {
                            _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id)));
                        }
                    }
                    if (si.sym_info.semantic_node_type == semantic_node_type.common_parameter && prScope.FunctionNode.parameters.First(v => v.name.ToLower() == idName).parameter_type != parameter_type.value && InLambdaContext)
                    {
                        _visitor.AddError(new CannotCaptureNonValueParameters(_visitor.get_location(id)));
                    }

                    if (idName == compiler_string_consts.self_word && si.scope is SymbolTable.ClassMethodScope &&
                        _classScope != null)
                    {
                        var selfField = _classScope.VariablesDefinedInScope.Find(var => var.SymbolInfo == si);

                        if (selfField == null)
                        {
                            _classScope.VariablesDefinedInScope.Add(
                                new CapturedVariablesTreeNode.CapturedSymbolInfo(null, si));
                        }

                        selfWordInClass = true;
                    }
                    else
                    {
                        var field = prScope.VariablesDefinedInScope.Find(var => var.SymbolInfo == si);

                        if (field == null)
                        {
                            prScope.VariablesDefinedInScope.Add(new CapturedVariablesTreeNode.CapturedSymbolInfo(null,
                                                                                                                 si));
                        }
                    }
                }

                var clScope = scope as CapturedVariablesTreeNodeClassScope;
                if (clScope != null && acceptableVarType)
                {
                    var field = clScope.VariablesDefinedInScope.Find(var => var.SymbolInfo == si);

                    if (field == null)
                    {
                        clScope.VariablesDefinedInScope.Add(new CapturedVariablesTreeNode.CapturedSymbolInfo(null, si));
                    }

                    if (si.access_level != access_level.al_public)
                    {
                        if (!clScope.NonPublicMembersNamesMapping.ContainsKey(idName))
                        {
                            var name          = LambdaHelper.GetNameForNonPublicMember(idName);
                            var semClassField = (class_field)si.sym_info;
                            var pn            = new common_property_node(name, _visitor.context._ctn, null, field_access_level.fal_public, semClassField.polymorphic_state);
                            pn.internal_property_type = _visitor.convert_strong(id).type;
                            clScope.NonPublicMembersNamesMapping.Add(idName, new Tuple <string, class_field, semantic_node>(name, semClassField, pn));
                        }
                    }
                }

                var idRef = (selfWordInClass ? _classScope : scope)
                            .VariablesDefinedInScope
                            .Find(var => var.SymbolInfo == si);

                if (idRef == null)                                     //TODO: Осторожнее переделать
                {
                    {
                        return;
                    }
                }

                if (_currentTreeNode.CorrespondingSyntaxTreeNode != null)
                {
                    var varName  = ((IVAriableDefinitionNode)idRef.SymbolInfo.sym_info).name;                     //TODO: случай параметров и полей класса!!!!!!!!!!!!!!!!!!
                    var substKey = new SubstitutionKey(varName, idRef.SyntaxTreeNodeWithVarDeclaration, _currentTreeNode.CorrespondingSyntaxTreeNode);

                    if (!_identsReferences.ContainsKey(substKey))
                    {
                        _identsReferences.Add(substKey, new List <ident>());
                    }

                    _identsReferences[substKey].Add(id);
                }

                if (InLambdaContext && scope is CapturedVariablesTreeNodeLambdaScope &&
                    scopeIndex < _currentLambdaScopeNodeStack.Peek().ScopeIndex) //TODO: Захват параметров лямбды в другой лямбде
                {
                    _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id)));
                    return;
                }

                if (!InLambdaContext ||
                    scopeIndex >= _currentLambdaScopeNodeStack.Peek().ScopeIndex)
                {
                    return;
                }

                var stackAsList = _currentLambdaScopeNodeStack.ToList();
                stackAsList.RemoveAt(0);

                if (!_currentLambdaScopeNodeStack.Peek().CapturedVarsSymbolInfo.Contains(si))
                {
                    _currentLambdaScopeNodeStack.Peek().CapturedVarsSymbolInfo.Add(si);
                    foreach (var capturedVariablesTreeNodeLambdaScope in stackAsList)
                    {
                        if (!capturedVariablesTreeNodeLambdaScope.CapturedVarsSymbolInfo.Contains(si))
                        {
                            capturedVariablesTreeNodeLambdaScope.CapturedVarsSymbolInfo.Add(si);
                        }
                    }
                }
                if (!idRef.ReferencingLambdas.Contains(_currentLambdaScopeNodeStack.Peek()))
                {
                    idRef.ReferencingLambdas.Add(_currentLambdaScopeNodeStack.Peek());
                    foreach (var capturedVariablesTreeNodeLambdaScope in stackAsList)
                    {
                        if (!idRef.ReferencingLambdas.Contains(capturedVariablesTreeNodeLambdaScope))
                        {
                            idRef.ReferencingLambdas.Add(capturedVariablesTreeNodeLambdaScope);
                        }
                    }
                }
            }
        }
Example #31
0
        private void AddReferencesToIdentInLambda(type_declaration upperScopeWhereVarsAreCapturedClass, CapturedVariablesTreeNode scope, string varName, syntax_tree_node syntaxTreeNodeWithVarDeclaration, dot_node substDotNode, bool nestedLambda)
        {
            for (var i = 0; i < scope.ChildNodes.Count; i++)
            {
                if (!(scope.ChildNodes[i] is CapturedVariablesTreeNodeLambdaScope))
                {
                    var substKey = new SubstitutionKey(varName, syntaxTreeNodeWithVarDeclaration,
                                                       scope.ChildNodes[i].CorrespondingSyntaxTreeNode);

                    if (_capturedVarsClassDefs.ContainsKey(scope.ChildNodes[i].ScopeIndex))
                    {
                        var cl = _capturedVarsClassDefs[scope.ChildNodes[i].ScopeIndex];
                        if (cl.AssignNodeForUpperClassFieldInitialization == null)
                        {
                            var fieldType =
                                SyntaxTreeBuilder.BuildSimpleType(upperScopeWhereVarsAreCapturedClass.type_name.name);
                            var field =
                                SyntaxTreeBuilder.BuildClassFieldsSection(
                                    new List <ident>
                            {
                                new ident(cl.GeneratedUpperClassFieldName)
                            },
                                    new List <type_definition> {
                                fieldType
                            });

                            var clClass = (class_definition)cl.ClassDeclaration.type_def;
                            clClass.body.Add(field);

                            cl.AssignNodeForUpperClassFieldInitialization =
                                new assign(
                                    new dot_node(new ident(cl.GeneratedSubstitutingFieldName), new ident(cl.GeneratedUpperClassFieldName)),
                                    new ident(compiler_string_consts.self_word));
                        }
                    }

                    if (!_substitutions.ContainsKey(substKey))
                    {
                        _substitutions.Add(substKey, substDotNode);
                    }

                    AddReferencesToIdentInLambda(upperScopeWhereVarsAreCapturedClass, scope.ChildNodes[i], varName, syntaxTreeNodeWithVarDeclaration, substDotNode, nestedLambda);
                }
                else
                {
                    var scopeAsLambda = scope.ChildNodes[i] as CapturedVariablesTreeNodeLambdaScope;
                    if (scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.HasValue)
                    {
                        dot_node substDotNode1;
                        if (!nestedLambda)
                        {
                            var parts = new Stack <ident>();
                            var dn    = substDotNode;
                            parts.Push((ident)dn.right);

                            while (!(dn.left is ident && dn.right is ident))
                            {
                                dn = (dot_node)dn.left;
                                parts.Push((ident)dn.right);
                            }

                            substDotNode1 = new dot_node(new ident(_capturedVarsClassDefs[scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.Value].GeneratedUpperClassFieldName), parts.Pop());
                            while (parts.Count > 0)
                            {
                                substDotNode1 = new dot_node(substDotNode1, parts.Pop());
                            }
                        }
                        else
                        {
                            var parts = new Stack <ident>();
                            var dn    = substDotNode;
                            parts.Push((ident)dn.right);

                            while (!(dn.left is ident && dn.right is ident))
                            {
                                dn = (dot_node)dn.left;
                                parts.Push((ident)dn.right);
                            }

                            parts.Push((ident)dn.left);

                            substDotNode1 = new dot_node(new ident(_capturedVarsClassDefs[scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.Value].GeneratedUpperClassFieldName), parts.Pop());

                            while (parts.Count > 0)
                            {
                                substDotNode1 = new dot_node(substDotNode1, parts.Pop());
                            }
                        }

                        var substKey = new SubstitutionKey(varName, syntaxTreeNodeWithVarDeclaration,
                                                           scope.ChildNodes[0].CorrespondingSyntaxTreeNode);
                        if (!_substitutions.ContainsKey(substKey))
                        {
                            _substitutions.Add(substKey, substDotNode1);
                        }

                        AddReferencesToIdentInLambda(_capturedVarsClassDefs[scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.Value].ClassDeclaration, scopeAsLambda.ChildNodes[0], varName, syntaxTreeNodeWithVarDeclaration, substDotNode1, true);
                    }
                    else
                    {
                        AddReferencesToIdentInLambda(upperScopeWhereVarsAreCapturedClass, scope.ChildNodes[0], varName, syntaxTreeNodeWithVarDeclaration, substDotNode, nestedLambda);
                    }
                }
            }
        }
Example #32
0
		public override void visit(dot_node _dot_node)
		{
			executer.visit(_dot_node);
			if (_dot_node.left != null)
				this.visit((dynamic)_dot_node.left);
			if (_dot_node.right != null)
				this.visit((dynamic)_dot_node.right);
			if (_dot_node.attributes != null)
				this.visit((dynamic)_dot_node.attributes);
		}