Example #1
0
        internal ScriptLogic(ScopeTable ti)
        {
            string type;
            string length;
            var primaryScopeColumn = from ScopeColumn ci in ti.Columns where ci.Primary select ci;
            var nonPrimaryScopeColumn = from ScopeColumn ci in ti.Columns where (ci.Primary == false) select ci;
            _tableName = ti.Name;
            foreach (var ci in primaryScopeColumn)
            {
                type = Runtime.GetSqlType(ci.Type);
                length = Runtime.GetLength(ci.Type.ToString(), ci.Length);

                if (string.IsNullOrEmpty(_clusterKeys))
                {
                    _clusterKeys = "[" + ci.Name + "]";
                }
                else
                {
                    _clusterKeys += ",[" + ci.Name + "]";
                }
                _selectFields += "t.[" + ci.Name + "],";
                if (string.IsNullOrEmpty(_allColumnsParamWithType))
                    _allColumnsParamWithType = "@" + ci.Name + " " + type + length;
                else
                    _allColumnsParamWithType += ",@" + ci.Name + " " + type + length;
                if (string.IsNullOrEmpty(_allColumnsParam))
                    _allColumnsParam = "@" + ci.Name;
                else
                    _allColumnsParam += ",@" + ci.Name;
            }

            foreach (var ci in nonPrimaryScopeColumn)
            {
                type = Runtime.GetSqlType(ci.Type);
                length = Runtime.GetLength(ci.Type.ToString(), ci.Length);
                _selectFields += "c.[" + ci.Name + "],";
                if (string.IsNullOrEmpty(_allColumnsParamWithType))
                    _allColumnsParamWithType = "@" + ci.Name + " " + type + length;
                else
                    _allColumnsParamWithType += ",@" + ci.Name + " " + type + length;
                if (string.IsNullOrEmpty(_allColumnsParam))
                    _allColumnsParam = "@" + ci.Name;
                else
                    _allColumnsParam += ",@" + ci.Name;
            }
            _selectFields = _selectFields.TrimEnd(char.Parse(","));
        }
        /// <summary>
        /// 节点转字符串
        /// </summary>
        /// <param name="node">待转化节点</param>
        /// <returns>返回该节点之下的所有叶子节点组成的字符串</returns>
        private static string nodeToString(ParseTreeNode node)
        {
            String str = "";

            if (node.IsLeaf)
            {
                if (node.TSymbol == TerminalType.ID)
                {
                    ScopeTable scope = Constant.check(node.StringValue);
                    if (scope == null)
                    {
                        ErrorInfo error = new ErrorInfo(node.LineNum, "符号表中没有" + node.StringValue + "!");
                        Constant.outputAppend(error.ToString());
                        //计算出错
                        return("<>");
                    }
                    else if (scope.type != "int" && scope.type != "real")
                    {
                        string[] arr1 = scope.value.Split(',');
                        str += "[";
                        for (int i = 0; i < arr1.Length; i++)
                        {
                            str += arr1[i] + ",";
                        }
                        str += "]";
                        return(str);
                    }
                    return(scope.value);
                }
                else if (node.StringValue == "<>")
                {
                    return("!=");
                }
                return(node.StringValue);
            }

            else
            {
                for (int i = 0; i < node.Childs.Count; i++)
                {
                    str += nodeToString(node.Childs[i]);
                }
            }
            return(str);
        }
Example #3
0
 /// <summary>
 /// 增||改
 /// </summary>
 /// <param name="scopeTable">层数表</param>
 public static void update(ScopeTable scopeTable)
 {
     if (check(scopeTable.name) == null)
     {
         // 增
         scopeTables.Add(scopeTable);
     }
     else
     //改
     {
         for (int i = 0; i < Constant.scopeTables.Count; i++)
         {
             if (Constant.scopeTables[i].name == scopeTable.name)
             {
                 Constant.scopeTables[i].type  = scopeTable.type;
                 Constant.scopeTables[i].value = scopeTable.value;
             }
         }
     }
 }
        /// <summary>
        ///Statement节点分析函数
        /// </summary>
        /// <param name="node">Statement节点</param>
        public static void StatementAnalysis(ParseTreeNode node)
        {
            //判断是不是断点
            if (node.Childs[0].TSymbol == TerminalType.BREAKPOINT)
            {
                string debugString;
                debugString = "-------\n";
                foreach (ScopeTable scope in Constant.scopeTables)
                {
                    if (String.IsNullOrEmpty(scope.value))
                    {
                        debugString += "符号表中名为" + scope.name + "的表项值为空\n";
                        //Constant.deBugAppend("符号表中名为" + scope.name + "的表项值为空");
                    }
                    else
                    {
                        debugString += "符号表中名为" + scope.name + "的表项值为" + scope.value + "\n";
                        //Constant.deBugAppend("符号表中名为" + scope.name + "的表项值为" + scope.value);
                    }
                }
                debugString += "-------\n";
                Constant.deBugAppend(debugString);

                //Constant.deBugAppend("-------");
                //foreach (ScopeTable scope in Constant.scopeTables) {

                //    if (String.IsNullOrEmpty(scope.value))
                //    {
                //        Constant.deBugAppend("符号表中名为" + scope.name + "的表项值为空");
                //    }
                //    else {
                //        Constant.deBugAppend("符号表中名为" + scope.name + "的表项值为" + scope.value);
                //    }
                //}
                //Constant.deBugAppend("-------");
                //如果是断点则阻塞线程
                Constant.mreReset();
                return;
            }
            //判断是否能运行
            Constant._mre.WaitOne();
            if (node.IsLeaf)
            {
                //是叶子节点直接退出
                return;
            }
            else if (node.Childs[0].NSymbol == NEnum.if_stmt)
            //  if-stmt-> if-stmt - block else -stmt - block   //i f语句
            {
                ParseTreeNode ifStmt = node.Childs[0];

                ParseTreeNode ifStmtBlock = ifStmt.Childs[0];

                //if-stmt-block -> if (exp) stmt-block   // if语句子块
                ParseTreeNode exp = ifStmtBlock.Childs[2];

                //if条件为真
                if (expJudge(exp))
                {
                    //遇到stmtBlock
                    ParseTreeNode stmtBlock = ifStmtBlock.Childs[4];
                    //stmt - block->{statement} | { stmt - sequence }   // 语句块
                    if (stmtBlock.Childs.Count == 4)
                    {
                        Constant.currentScopeIncrease();
                        StatementAnalysis(stmtBlock.Childs[1]);
                        //判断是否能运行
                        Constant._mre.WaitOne();
                        Constant.currentScopeDecrease();
                        stmtBlock.Childs.RemoveAt(1);
                    }
                    if (stmtBlock.Childs[1].NSymbol == NEnum.statement)
                    {
                        Constant.currentScopeIncrease();
                        StatementAnalysis(stmtBlock.Childs[1]);
                        //判断是否能运行
                        Constant._mre.WaitOne();
                        Constant.currentScopeDecrease();
                    }

                    else if (!stmtBlock.Childs[1].IsLeaf)
                    {
                        Constant.currentScopeIncrease();
                        ParseTreeNode stmtSequence = stmtBlock.Childs[1];
                        //stmt-sequence -> statement stmt-sequence | ε  // 语句序列
                        while (stmtSequence.Childs.Count >= 2)
                        {
                            for (int j = 0; j < stmtSequence.Childs.Count - 1; j++)
                            {
                                StatementAnalysis(stmtSequence.Childs[j]);
                                //判断是否能运行
                                Constant._mre.WaitOne();
                            }
                            stmtSequence = stmtSequence.Childs[stmtSequence.Childs.Count - 1];
                        }
                        if (stmtSequence.NSymbol == NEnum.statement)
                        {
                            StatementAnalysis(stmtSequence);
                            //判断是否能运行
                            Constant._mre.WaitOne();
                        }
                        else
                        {
                            StatementAnalysis(stmtSequence.Childs[0]);
                            //判断是否能运行
                            Constant._mre.WaitOne();
                        }
                        Constant.currentScopeDecrease();
                    }
                }
                //if条件未假
                else if (ifStmt.Childs.Count == 2)
                //else-stmt-block -> else stmt-block | ε
                {
                    if (ifStmt.Childs[1].Childs[0].TSymbol == TerminalType.EMPTY)
                    {
                        //是空直接退出
                        return;
                    }
                    //遇到stmtBlock
                    ParseTreeNode elseStmtBlock = ifStmt.Childs[1];
                    ParseTreeNode stmtBlock     = elseStmtBlock.Childs[1];
                    //stmt - block->{statement }| { stmt - sequence }   // 语句块
                    if (stmtBlock.Childs.Count == 4)
                    {
                        Constant.currentScopeIncrease();
                        StatementAnalysis(stmtBlock.Childs[1]);
                        //判断是否能运行
                        Constant._mre.WaitOne();
                        Constant.currentScopeDecrease();
                        stmtBlock.Childs.RemoveAt(1);
                    }
                    if (stmtBlock.Childs[1].NSymbol == NEnum.statement)
                    {
                        Constant.currentScopeIncrease();
                        StatementAnalysis(stmtBlock.Childs[1]);
                        //判断是否能运行
                        Constant._mre.WaitOne();
                        Constant.currentScopeDecrease();
                    }
                    else if (!stmtBlock.Childs[1].IsLeaf)
                    {
                        Constant.currentScopeIncrease();
                        ParseTreeNode stmtSequence = stmtBlock.Childs[1];
                        //stmt-sequence -> statement stmt-sequence | ε  // 语句序列
                        while (stmtSequence.Childs.Count >= 2)
                        {
                            for (int j = 0; j < stmtSequence.Childs.Count - 1; j++)
                            {
                                StatementAnalysis(stmtSequence.Childs[j]);
                                //判断是否能运行
                                Constant._mre.WaitOne();
                            }
                            stmtSequence = stmtSequence.Childs[stmtSequence.Childs.Count - 1];
                        }
                        if (stmtSequence.NSymbol == NEnum.statement)
                        {
                            StatementAnalysis(stmtSequence);
                            //判断是否能运行
                            Constant._mre.WaitOne();
                        }
                        else
                        {
                            StatementAnalysis(stmtSequence.Childs[0]);
                            //判断是否能运行
                            Constant._mre.WaitOne();
                        }
                        Constant.currentScopeDecrease();
                    }
                }
            }
            else if (node.Childs[0].NSymbol == NEnum.while_stmt)
            {
                //while-stmt -> while ( exp ) stmt-block   // while语句子快
                ParseTreeNode whileStmt = node.Childs[0];
                while (expJudge(whileStmt.Childs[2]))
                {
                    //遇到stmtBlock
                    ParseTreeNode stmtBlock = whileStmt.Childs[4];
                    //stmt - block->{statement} | { stmt - sequence }   // 语句块
                    if (stmtBlock.Childs.Count == 4)
                    {
                        Constant.currentScopeIncrease();
                        StatementAnalysis(stmtBlock.Childs[1]);
                        //判断是否能运行
                        Constant._mre.WaitOne();
                        Constant.currentScopeDecrease();
                        stmtBlock.Childs.RemoveAt(1);
                    }
                    if (stmtBlock.Childs[1].NSymbol == NEnum.statement)
                    {
                        Constant.currentScopeIncrease();
                        StatementAnalysis(stmtBlock.Childs[1]);
                        Constant._mre.WaitOne();
                        Constant.currentScopeDecrease();
                    }

                    else if (!stmtBlock.Childs[1].IsLeaf)
                    {
                        Constant.currentScopeIncrease();
                        ParseTreeNode stmtSequence = stmtBlock.Childs[1];
                        //stmt-sequence -> statement stmt-sequence | ε  // 语句序列
                        while (stmtSequence.Childs.Count >= 2)
                        {
                            for (int j = 0; j < stmtSequence.Childs.Count - 1; j++)
                            {
                                StatementAnalysis(stmtSequence.Childs[j]);
                                //判断是否能运行
                                Constant._mre.WaitOne();
                            }
                            stmtSequence = stmtSequence.Childs[stmtSequence.Childs.Count - 1];
                        }
                        if (stmtSequence.NSymbol == NEnum.statement)
                        {
                            StatementAnalysis(stmtSequence);
                            Constant._mre.WaitOne();
                        }
                        else
                        {
                            StatementAnalysis(stmtSequence.Childs[0]);
                            Constant._mre.WaitOne();
                        }
                        Constant.currentScopeDecrease();
                    }
                }
            }
            else if (node.Childs[0].NSymbol == NEnum.assign_stmt)
            //赋值语句 assign-stmt -> variable = exp ; variable -> identifier [ [ exp ] ]
            {
                ParseTreeNode assignStmt = node.Childs[0];
                ParseTreeNode variable   = assignStmt.Childs[0];
                if (variable.Childs.Count == 1)
                //一般变量赋值
                {
                    string name = variable.Childs[0].StringValue;
                    //查找并赋值
                    ScopeTable scopeTable = Constant.check(name);
                    if (scopeTable == null)
                    {
                        ErrorInfo error = new ErrorInfo(assignStmt.Childs[1].LineNum, "符号表中没有" + name + "!");
                        Constant.outputAppend(error.ToString());
                        return;
                    }

                    if (IsNumberic(expToValue(assignStmt.Childs[2])))
                    {
                        //声明的为整数时,还需将非整数转化成整数
                        if (scopeTable.type == "int")
                        {
                            string num = expToValue(assignStmt.Childs[2]);
                            if (Regex.IsMatch(num, @"^[+-]?[0-9]+$"))
                            {
                                string value = int.Parse(num).ToString();
                                scopeTable.value = value;
                                Constant.update(scopeTable);
                            }
                            else
                            {
                                ErrorInfo error = new ErrorInfo(assignStmt.Childs[1].LineNum, "赋值类型错误!");
                                Constant.outputAppend(error.ToString());
                                return;
                            }
                        }
                        else //real类型可以直接存入
                        {
                            scopeTable.value = expToValue(assignStmt.Childs[2]);
                            Constant.update(scopeTable);
                        }
                    }
                    else
                    //返回错误
                    {
                        ErrorInfo error = new ErrorInfo(assignStmt.Childs[1].LineNum, "赋值类型错误!");
                        Constant.outputAppend(error.ToString());
                        return;
                    }
                }
                else
                //数组赋值   没有考虑一维数组以外的情况
                {
                    //数组名
                    string name = variable.Childs[0].StringValue;
                    //插入数组位置
                    int leng = int.Parse(variable.Childs[2].StringValue);

                    //查找
                    ScopeTable scopeTable = Constant.check(name);
                    if (scopeTable == null)
                    {
                        ErrorInfo error = new ErrorInfo(assignStmt.Childs[1].LineNum, "符号表中没有" + name + "!");
                        Constant.outputAppend(error.ToString());
                        return;
                    }
                    //判断是否越界
                    string type   = scopeTable.type;
                    string a      = type.Substring(type.IndexOf('[') + 1, type.IndexOf(']') - type.IndexOf('[') - 1);
                    int    length = int.Parse(a);
                    if (leng >= length)
                    {
                        ErrorInfo error = new ErrorInfo(variable.Childs[0].LineNum, "数组越界错误!");
                        Constant.outputAppend(error.ToString());
                        return;
                    }

                    else
                    {
                        //value= 0,0,0
                        string   value = scopeTable.value;
                        string[] arr1  = value.Split(','); // 以','字符对字符串进行分割,返回字符串数组

                        if (IsNumberic(expToValue(assignStmt.Childs[2])))
                        {
                            //声明的为整数时,还需将非整数转化成整数
                            if (scopeTable.type.IndexOf("int") != -1)
                            {
                                string num = expToValue(assignStmt.Childs[2]);
                                if (Regex.IsMatch(num, @"^[+-]?[0-9]+$"))
                                {
                                    string value2 = int.Parse(num).ToString();
                                    arr1[leng]       = value2;
                                    scopeTable.value = String.Join(",", arr1);
                                    Constant.update(scopeTable);
                                }
                                else
                                {
                                    ErrorInfo error = new ErrorInfo(assignStmt.Childs[1].LineNum, "赋值类型错误!");
                                    Constant.outputAppend(error.ToString());
                                    return;
                                }
                            }
                            else //real类型可以直接存入
                            {
                                arr1[leng]       = expToValue(assignStmt.Childs[2]);
                                scopeTable.value = String.Join(",", arr1);
                                Constant.update(scopeTable);
                            }
                        }
                        else
                        //返回错误
                        {
                            ErrorInfo error = new ErrorInfo(assignStmt.Childs[1].LineNum, "赋值类型错误!");
                            Constant.outputAppend(error.ToString());
                            return;
                        }
                    }
                }
            }
            else if (node.Childs[0].NSymbol == NEnum.read_stmt)
            //read-stmt -> read variable ;   // read语句
            {
                Constant.mreReset();
                Constant._mre.WaitOne();
                string        num        = Constant.readstr;
                ParseTreeNode readStmt   = node.Childs[0];
                ScopeTable    scopeTable = Constant.check(readStmt.Childs[1].Childs[0].StringValue);
                if (scopeTable.type == "int")
                {
                    if (Regex.IsMatch(num, @"^[+-]?[0-9]+$"))
                    {
                        scopeTable.value = num;
                    }
                    else
                    {
                        ErrorInfo error = new ErrorInfo(readStmt.Childs[1].Childs[0].LineNum, "赋值类型错误!");
                        Constant.outputAppend(error.ToString());
                        return;
                    }
                }
                else
                {
                    scopeTable.value = num;
                }

                Constant.update(scopeTable);
            }
            else if (node.Childs[0].NSymbol == NEnum.write_stmt)
            //write-stmt -> write exp ;   // write语句
            {
                ParseTreeNode writeStmt = node.Childs[0];
                ParseTreeNode exp       = writeStmt.Childs[1];
                Constant.outputAppend(expToValue(exp));
            }
            else if (node.Childs[0].NSymbol == NEnum.declare_stmt)
            //declare-stmt语句 (int | real) ( (identifier [= exp ]) | (identifier [ exp ]) ) ;
            {
                ParseTreeNode declareStmt = node.Childs[0];

                //声明,且赋值  int a=3;
                //作废
                if (declareStmt.Childs.Count > 3)
                {
                    if (IsNumberic(expToValue(declareStmt.Childs[3])))
                    {
                        //声明的为整数时,还需将非整数转化成整数
                        if (declareStmt.Childs[0].StringValue == "int")
                        {
                            string num = expToValue(declareStmt.Childs[3]);
                            if (Regex.IsMatch(num, @"^[+-]?[0-9]+$"))
                            {
                                string     value      = int.Parse(num).ToString();
                                ScopeTable scopeTable = new ScopeTable(declareStmt.Childs[1].StringValue, declareStmt.Childs[0].StringValue, value, Constant.currentScope);
                                Constant.scopeTables.Add(scopeTable);
                            }
                            else
                            {
                                ErrorInfo error = new ErrorInfo(0, "声明类型错误!");
                            }
                        }
                        else //real类型可以直接存入
                        {
                            ScopeTable scopeTable = new ScopeTable(declareStmt.Childs[1].StringValue, declareStmt.Childs[0].StringValue, expToValue(declareStmt.Childs[3]), Constant.currentScope);
                            Constant.scopeTables.Add(scopeTable);
                        }
                    }
                    else
                    //返回错误
                    {
                        ErrorInfo error = new ErrorInfo(0, "声明类型错误!");
                    }
                }
                else if ((declareStmt.Childs[1].Childs.Count < 2))
                //只申明,未赋值 int a ;
                {
                    ScopeTable scopeTable = new ScopeTable(declareStmt.Childs[1].Childs[0].StringValue, declareStmt.Childs[0].StringValue, null, Constant.currentScope);
                    Constant.scopeTables.Add(scopeTable);
                }
                else if (declareStmt.Childs[1].Childs.Count > 2)
                //申明一个数组 int a[2];  a  int[3]   0,0,0  Constant.currentScope);

                {
                    int length = 0;
                    try
                    {
                        length = int.Parse(declareStmt.Childs[1].Childs[2].StringValue);
                    }
                    catch {
                        ErrorInfo error = new ErrorInfo(declareStmt.Childs[0].LineNum, "数组索引必须为整数!");
                        Constant.outputAppend(error.ToString());
                        return;
                    }
                    if (length == 1)
                    {
                        ErrorInfo error = new ErrorInfo(declareStmt.Childs[0].LineNum, "不能声明大小为1的数组!");
                        Constant.outputAppend(error.ToString());
                        return;
                    }
                    string value = "";
                    for (int i = 1; i < length; i++)
                    {
                        value += "0,";
                    }
                    value += "0";
                    string     n          = declareStmt.Childs[1].Childs[0].StringValue;
                    string     t          = declareStmt.Childs[0].StringValue + declareStmt.Childs[1].Childs[1].StringValue + declareStmt.Childs[1].Childs[2].StringValue + declareStmt.Childs[1].Childs[3].StringValue;
                    ScopeTable scopeTable = new ScopeTable(n, t, value, Constant.currentScope);
                    Constant.scopeTables.Add(scopeTable);
                }
            }
        }
Example #5
0
        internal ScriptLogic(ScopeTable ti)
        {
            string type;
            string length;
            var    primaryScopeColumn    = from ScopeColumn ci in ti.Columns where ci.Primary select ci;
            var    nonPrimaryScopeColumn = from ScopeColumn ci in ti.Columns where (ci.Primary == false) select ci;

            _tableName = ti.Name;
            foreach (var ci in primaryScopeColumn)
            {
                type   = Runtime.GetSqlType(ci.Type);
                length = Runtime.GetLength(ci.Type.ToString(), ci.Length);

                if (string.IsNullOrEmpty(_clusterKeys))
                {
                    _clusterKeys = "[" + ci.Name + "]";
                }
                else
                {
                    _clusterKeys += ",[" + ci.Name + "]";
                }
                _selectFields += "t.[" + ci.Name + "],";
                if (string.IsNullOrEmpty(_allColumnsParamWithType))
                {
                    _allColumnsParamWithType = "@" + ci.Name + " " + type + length;
                }
                else
                {
                    _allColumnsParamWithType += ",@" + ci.Name + " " + type + length;
                }
                if (string.IsNullOrEmpty(_allColumnsParam))
                {
                    _allColumnsParam = "@" + ci.Name;
                }
                else
                {
                    _allColumnsParam += ",@" + ci.Name;
                }
            }

            foreach (var ci in nonPrimaryScopeColumn)
            {
                type           = Runtime.GetSqlType(ci.Type);
                length         = Runtime.GetLength(ci.Type.ToString(), ci.Length);
                _selectFields += "c.[" + ci.Name + "],";
                if (string.IsNullOrEmpty(_allColumnsParamWithType))
                {
                    _allColumnsParamWithType = "@" + ci.Name + " " + type + length;
                }
                else
                {
                    _allColumnsParamWithType += ",@" + ci.Name + " " + type + length;
                }
                if (string.IsNullOrEmpty(_allColumnsParam))
                {
                    _allColumnsParam = "@" + ci.Name;
                }
                else
                {
                    _allColumnsParam += ",@" + ci.Name;
                }
            }
            _selectFields = _selectFields.TrimEnd(char.Parse(","));
        }
Example #6
0
        private void compute(ComputationContext ctx)
        {
            foreach (TypeDefinition trait in this.AssociatedTraits)
            {
                trait.computeAncestors(ctx, new HashSet <TypeDefinition>());
            }
            computeAncestors(ctx, new HashSet <TypeDefinition>());

            IEnumerable <INode> owned_nodes = this.ChildrenNodes.Concat(this.AssociatedTraits.SelectMany(it => it.ChildrenNodes));

            owned_nodes.WhereType <ISurfable>().ForEach(it => it.Surfed(ctx));

            // --

            if (this.Modifier.HasMutable &&
                (!this.Modifier.HasHeapOnly || this.NestedFunctions.Any(it => it.IsCopyInitConstructor(ctx))))
            {
                // creating counterparts of mutable methods

                // todo: this should be implemented differently -- instead of creating methods, creating expressions
                // copy-cons, mutable call, return obj
                // on demand, in-place, when const non-existing method is called

                HashSet <string> const_functions = this.NestedFunctions.Where(f => !f.Modifier.HasMutable).Concat(
                    this.Inheritance.OrderedAncestorsIncludingObject.SelectMany(it => it.TargetType.NestedFunctions
                                                                                .Where(f => !f.Modifier.HasMutable && !f.Modifier.HasPrivate)))
                                                   .Select(it => it.Name.Name)
                                                   .ToHashSet();

                foreach (FunctionDefinition func in this.NestedFunctions.Where(it => it.Modifier.HasMutable).StoreReadOnly())
                {
                    string const_name = NameFactory.UnmutableName(func.Name.Name);
                    if (const_functions.Contains(const_name))
                    {
                        continue;
                    }

                    if (!ctx.Env.IsOfUnitType(func.ResultTypeName))
                    {
                        continue;
                    }

                    INameReference result_typename = NameFactory.ItNameReference();
                    if (this.Modifier.HasHeapOnly)
                    {
                        result_typename = NameFactory.PointerNameReference(result_typename);
                    }

                    var instructions = new List <IExpression>();
                    if (this.Modifier.HasHeapOnly)
                    {
                        instructions.Add(VariableDeclaration.CreateStatement("cp", null,
                                                                             ExpressionFactory.HeapConstructor(NameFactory.ItNameReference(), NameReference.CreateThised())));
                    }
                    else
                    {
                        // explicit typename is needed, because otherwise we would get a reference to this, not value (copy)
                        instructions.Add(VariableDeclaration.CreateStatement("cp", NameFactory.ItNameReference(),
                                                                             NameReference.CreateThised()));
                    }

                    instructions.Add(FunctionCall.Create(NameReference.Create("cp", func.Name.Name),
                                                         func.Parameters.Select(it => NameReference.Create(it.Name.Name)).ToArray()));
                    instructions.Add(Return.Create(NameReference.Create("cp")));

                    FunctionDefinition const_func = FunctionBuilder.Create(const_name, func.Name.Parameters,
                                                                           result_typename,
                                                                           Block.CreateStatement(instructions))
                                                    .SetModifier(EntityModifier.AutoGenerated)
                                                    // native methods have parameters with forbidden read
                                                    .Parameters(func.Parameters.Select(it => it.CloneAsReadable()));

                    this.AddNode(const_func);
                    const_func.Surfed(ctx);
                }
            }



            if (this.Modifier.HasEnum)
            {
                // finally we are at point when we know from which offset we can start setting ids for enum cases

                FunctionDefinition zero_constructor = this.NestedFunctions.Single(it => it.IsZeroConstructor() && it.Modifier.HasStatic);
                if (zero_constructor.IsComputed)
                {
                    throw new System.Exception("Internal error -- we cannot alter the body after the function was already computed");
                }

                int enum_ord = this.InstanceOf.PrimaryAncestors(ctx).Select(it => it.TargetType)
                               .Sum(it => it.NestedFields.Count(f => f.Modifier.HasEnum));

                foreach (VariableDeclaration decl in this.NestedFields.Where(it => it.Modifier.HasEnum))
                {
                    zero_constructor.UserBody.Append(decl.CreateFieldInitCall(NatLiteral.Create($"{enum_ord++}")));
                }
            }

            // base method -> derived (here) method
            var virtual_mapping = new VirtualTable(isPartial: false);

            foreach (EntityInstance parent_instance in this.Inheritance.MinimalParentsIncludingObject
                     .Concat(this.AssociatedTraits.SelectMany(it => it.Inheritance.MinimalParentsIncludingObject))
                     .Distinct(EntityInstance.Comparer)
                     .Reverse())
            {
                virtual_mapping.OverrideWith(parent_instance.TargetType.InheritanceVirtualTable);
            }

            IEnumerable <FunctionDefinition> all_nested_functions = this.AllNestedFunctions
                                                                    .Concat(this.AssociatedTraits.SelectMany(it => it.AllNestedFunctions));

            // derived (here) method -> base methods
            Dictionary <FunctionDefinition, List <FunctionDefinition> > derivation_mapping = all_nested_functions
                                                                                             .Where(it => it.Modifier.HasOverride)
                                                                                             .ToDictionary(it => it, it => new List <FunctionDefinition>());

            var inherited_member_instances = new HashSet <EntityInstance>(EntityInstance.Comparer);

            var missing_func_implementations = new List <FunctionDefinition>();

            foreach (EntityInstance ancestor in this.Inheritance.OrderedAncestorsIncludingObject
                     .Concat(this.AssociatedTraits.SelectMany(it => it.Inheritance.OrderedAncestorsIncludingObject))
                     .Distinct(EntityInstance.Comparer))
            {
                // special case are properties -- properties are in fact not inherited, their accessors are
                // however user sees properties, so we get members here (including properties), but when we compute
                // what function overrode which, we use really functions, and only having them in hand we check if
                // they are property accessors
                IEnumerable <EntityInstance> members = (ancestor.TargetType.AvailableEntities ?? Enumerable.Empty <EntityInstance>())
                                                       .Where(it => it.Target is IMember);

                foreach (EntityInstance entity_instance in members
                         .Where(it => it.Target.Modifier.HasPublic || it.Target.Modifier.HasProtected)
                         .Where(it => !(it.Target is FunctionDefinition func) || !func.IsAnyConstructor()))
                {
                    EntityInstance translated = entity_instance.TranslateThrough(ancestor);
                    inherited_member_instances.Add(translated);
                }

                foreach (FunctionDerivation deriv_info in TypeDefinitionExtension.PairDerivations(ctx, ancestor, all_nested_functions))
                {
                    if (deriv_info.Derived == null)
                    {
                        // we can skip implementation or abstract signature of the function in the abstract type
                        if (deriv_info.Base.Modifier.RequiresOverride && !this.Modifier.IsAbstract)
                        {
                            missing_func_implementations.Add(deriv_info.Base);
                        }
                    }
                    else
                    {
                        {
                            if (deriv_info.Base.IsPropertyAccessor(out Property base_property))
                            {
                                EntityInstance base_prop_instance = base_property.InstanceOf.TranslateThrough(ancestor);
                                inherited_member_instances.Remove(base_prop_instance);
                            }

                            EntityInstance base_instance = deriv_info.Base.InstanceOf.TranslateThrough(ancestor);
                            inherited_member_instances.Remove(base_instance);
                        }

                        if (deriv_info.Derived.Modifier.HasOverride)
                        {
                            derivation_mapping[deriv_info.Derived].Add(deriv_info.Base);
                            // user does not have to repeat "pinned" all the time, but for easier tracking of pinned methods
                            // we add it automatically
                            if (deriv_info.Base.Modifier.HasPinned)
                            {
                                deriv_info.Derived.SetModifier(deriv_info.Derived.Modifier | EntityModifier.Pinned);
                            }

                            if (deriv_info.Base.Modifier.HasHeapOnly != deriv_info.Derived.Modifier.HasHeapOnly)
                            {
                                ctx.AddError(ErrorCode.HeapRequirementChangedOnOverride, deriv_info.Derived);
                            }
                        }
                        else if (!deriv_info.Base.Modifier.IsSealed)
                        {
                            ctx.AddError(ErrorCode.MissingOverrideModifier, deriv_info.Derived);
                        }

                        if (!deriv_info.Base.Modifier.IsSealed)
                        {
                            virtual_mapping.Update(deriv_info.Base, deriv_info.Derived);

                            // the rationale for keeping the same access level is this
                            // narrowing is pretty easy to skip by downcasting
                            // expanding looks like a good idea, but... -- the author of original type
                            // maybe had better understanding why given function is private/protected and not protected/public
                            // it is better to keep it safe, despite little annoyance (additional wrapper), than finding out
                            // how painful is violating that "good reason" because it was too easy to type "public"
                            if (!deriv_info.Base.Modifier.SameAccess(deriv_info.Derived.Modifier))
                            {
                                ctx.AddError(ErrorCode.AlteredAccessLevel, deriv_info.Derived.Modifier);
                            }
                        }
                        else if (deriv_info.Derived.Modifier.HasOverride)
                        {
                            ctx.AddError(ErrorCode.CannotOverrideSealedMethod, deriv_info.Derived);
                        }
                    }
                }
            }

            foreach (FunctionDefinition missing_impl in missing_func_implementations)
            {
                if (!isDerivedByAncestors(missing_impl))
                {
                    ctx.AddError(ErrorCode.BaseFunctionMissingImplementation, this, missing_impl);
                }
            }

            // here we eliminate "duplicate" entries -- if we have some method in ancestor A
            // and this method is overridden in ancestor B, then we would like to have
            // only method B listed, not both
            foreach (EntityInstance inherited in inherited_member_instances.ToArray())
            {
                IEntity target = inherited.Target;
                if (target is Property prop)
                {
                    target = prop.Getter;
                }
                if (target is FunctionDefinition func && isDerivedByAncestors(func))
                {
                    inherited_member_instances.Remove(inherited);
                }
            }

            this.InheritanceVirtualTable = virtual_mapping;
            this.DerivationTable         = new DerivationTable(ctx, this, derivation_mapping);
            this.availableEntities       = ScopeTable.Combine(this.AvailableEntities, inherited_member_instances);

            foreach (FunctionDefinition func in derivation_mapping.Where(it => !it.Value.Any()).Select(it => it.Key))
            {
                ctx.AddError(ErrorCode.NothingToOverride, func);
            }

            this.isEvaluated = true;
        }