Exemplo n.º 1
0
        public override void visit(assign_tuple asstup)
        {
            // тут возможно ошибка более глубокая - в semantic_check_sugared_statement_node(asstup) возможно остаются во вложенных лямбдах другие assign_tuple
            var sl = new statement_list();

            sl.Add(new semantic_check_sugared_statement_node(typeof(assign_tuple), new List <syntax_tree_node> {
                asstup.vars, asstup.expr
            }, asstup.source_context));                                                                                                                              // Это нужно для проверок на этапе преобразования в семантику

            var tname = "#temp_var" + UniqueNumStr();
            var tt    = new var_statement(new ident(tname), asstup.expr);

            sl.Add(tt);

            var n = asstup.vars.variables.Count();

            for (var i = 0; i < n; i++)
            {
                var a = new assign(asstup.vars.variables[i], new dot_node(new ident(tname),
                                                                          new ident("Item" + (i + 1).ToString())), Operators.Assignment,
                                   asstup.vars.variables[i].source_context);
                sl.Add(a);
            }
            // Замена 1 оператор на 1 оператор - всё OK
            ReplaceUsingParent(asstup, sl);

            visit(asstup.expr);
        }
        public override void visit(assign_tuple asstup)
        {
            var sl = new statement_list();

            sl.Add(new semantic_check_sugared_statement_node(asstup)); // Это нужно для проверок на этапе преобразования в семантику

            var tname = "#temp_var" + UniqueNumStr();
            var tt    = new var_statement(new ident(tname), asstup.expr);

            sl.Add(tt);

            var n = asstup.vars.variables.Count();

            for (var i = 0; i < n; i++)
            {
                var a = new assign(asstup.vars.variables[i], new dot_node(new ident(tname),
                                                                          new ident("Item" + (i + 1).ToString())), Operators.Assignment,
                                   asstup.vars.variables[i].source_context);
                sl.Add(a);
            }
            // Замена 1 оператор на 1 оператор - всё OK
            ReplaceUsingParent(asstup, sl);

            visit(asstup.expr);
        }
        public statement MyStmt(expression ex, statement st)
        {
            // Проверить, что в ex - целый тип
            // Сделать специальный узел для проверки new semantic_check("Тип проверки",params syntax_node[] ob)
            // Включать этот узел первым для "сахарных" узлов синтаксического дерева
            var sc = new semantic_check("ExprIsInteger", ex);

            var id     = new ident("#my");
            var idlist = new ident_list(id);
            var typ    = new named_type_reference("integer");
            var one    = new int32_const(1);
            var vdef   = new var_def_statement(idlist, typ, one, definition_attribute.None, false, null);
            var vstat  = new var_statement(vdef, null);

            var ass         = new assign(new ident("#my"), one, Operators.AssignmentAddition);
            var stlistwhile = new statement_list(st);

            stlistwhile.Add(ass);

            var bin = new bin_expr(id, ex, Operators.LessEqual);

            var wh = new while_node(bin, stlistwhile, WhileCycleType.While);

            var stlist = new statement_list(sc);

            stlist.Add(vstat);
            stlist.Add(wh);
            return(stlist);
        }
Exemplo n.º 4
0
        public void Process(statement st)
        {
            if (!(st is yield_node || st is labeled_statement))
            {
                curStatList.Add(st);
            }
            if (st is yield_node)
            {
                var yn = st as yield_node;
                curState += 1;
                curStatList.AddMany(
                    new assign(Consts.Current, yn.ex),
                    new assign(Consts.State, curState),
                    new assign("Result", true),
                    new procedure_call("exit")
                    );

                curStatList = new statement_list();
                case_variant cv = new case_variant(new expression_list(new int32_const(curState)), curStatList);
                cas.conditions.variants.Add(cv);
            }
            if (st is labeled_statement)
            {
                var ls = st as labeled_statement;
                curStatList = StatListAfterCase;
                curStatList.Add(new labeled_statement(ls.label_name));
                Process(ls.to_statement);
            }
        }
Exemplo n.º 5
0
        public override void visit(loop_stmt loop)
        {
            // тут возможно ошибка более глубокая - в semantic_check_sugared_statement_node(asstup) возможно остаются во вложенных лямбдах другие assign_tuple
            var sl = new statement_list();

            sl.Add(new semantic_check_sugared_statement_node(typeof(loop_stmt), new List <syntax_tree_node> {
                loop.count
            }, loop.source_context));

            var tname = "#loop_var" + UniqueNumStr();
            var fn    = new for_node(new ident(tname), new int32_const(1), loop.count, loop.stmt, loop.source_context);

            sl.Add(fn);

            ReplaceUsingParent(loop, sl);

            visit(fn);
        }
Exemplo n.º 6
0
        public static statement_list CreateStatementList(params statement[] stmts)
        {
            statement_list res = new statement_list();

            foreach (statement x in stmts)
            {
                res.Add(x);
            }
            return(res);
        }
Exemplo n.º 7
0
        public static statement_list BuildSimpleAssignList(List <ident> lnames, List <ident> rnames)
        {
            var sl = new statement_list();

            for (int i = 0; i < lnames.Count; i++)
            {
                sl.Add(new assign(lnames[i], rnames[i]));
            }
            return(sl);
        }
Exemplo n.º 8
0
        private static SyntaxTree.program_module InternalCreateProgramModule(statement_list statements, declarations defs)
        {
            block block = new block();

            if (defs != null)
            {
                block.defs = defs;
            }
            statements.Add(new SyntaxTree.empty_statement());
            statements.left_logical_bracket  = new token_info("begin");
            statements.right_logical_bracket = new token_info("end");
            block.program_code = statements;

            program_module res = new program_module();

            res.program_block = block;
            //res.used_units = create_standard_uses_list();
            return(res);
        }
        private statement_list ConvertIfNode(if_node ifNode, List <statement> statementsBeforeIf, out statement elseBody)
        {
            // if e then <then> else <else>
            //
            // переводим в
            //
            // begin
            //   statementsBeforeIf
            //   if e then begin <then>; goto end_if end;
            // end
            // <else>
            // end_if: empty_statement

            // if e then <then>
            //
            // переводим в
            //
            // begin
            //   statementsBeforeIf
            //   if e then <then>
            // end

            // Добавляем, чтобы на конвертировать еще раз, если потребуется
            processedIfNodes.Add(ifNode);

            var statementsBeforeAndIf = new statement_list();

            statementsBeforeAndIf.AddMany(statementsBeforeIf);
            statementsBeforeAndIf.Add(ifNode);

            if (ifNode.else_body == null)
            {
                elseBody = null;
                return(statementsBeforeAndIf);
            }
            else
            {
                var result = new statement_list();
                result.Add(statementsBeforeAndIf);
                var endIfLabel = NewEndIfName();
                // добавляем метку
                if (!(ifNode.then_body is statement_list))
                {
                    ifNode.then_body        = new statement_list(ifNode.then_body, ifNode.then_body.source_context);
                    ifNode.then_body.Parent = ifNode;
                }

                var thenBody = ifNode.then_body as statement_list;
                thenBody.Add(new goto_statement(endIfLabel));
                // добавляем else и метку за ним
                result.Add(ifNode.else_body);
                result.Add(new labeled_statement(endIfLabel));
                // Возвращаем else для обхода, т.к. он уже не входит в if
                elseBody = ifNode.else_body;
                // удаляем else из if
                ifNode.else_body = null;
                // Добавляем метку
                AddLabel(endIfLabel);

                return(result);
            }
        }
Exemplo n.º 10
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
        }
Exemplo n.º 11
0
        type_declarations GenClassesForYield(procedure_definition pd, IEnumerable <var_def_statement> fields)
        {
            var fh = (pd.proc_header as function_header);

            if (fh == null)
            {
                throw new SyntaxError("Only functions can contain yields", "", pd.proc_header.source_context, pd.proc_header);
            }
            var seqt = fh.return_type as sequence_type;

            if (seqt == null)
            {
                throw new SyntaxError("Functions with yields must return sequences", "", fh.return_type.source_context, fh.return_type);
            }

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

            // Захваченные переменные
            var cm = class_members.Public;

            foreach (var m in fields)
            {
                cm.Add(m);
            }

            // Параметры функции
            List <ident> lid  = new List <ident>();
            var          pars = fh.parameters;

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

            var stels = seqt.elements_type;

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

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

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

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

            var stl = new statement_list(new var_statement("res", new new_expr(className)));

            stl.AddMany(lid.Select(id => new assign(new dot_node("res", id), id)));
            stl.Add(new assign("Result", "res"));
            pd.proc_body = new block(stl);

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

            var tpl = new template_param_list(stels);

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

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

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

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

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

            var cct = new type_declarations(td);

            cct.Add(td1);

            return(cct);
        }
Exemplo n.º 12
0
        private statement_list ConvertIfNode(if_node ifNode, List <statement> statementsBeforeIf, out statement elseBody)
        {
            // if e then <then> else <else>
            //
            // переводим в
            //
            // begin
            // var <>visitElseBranch := true;
            //   begin
            //     <>visitElseBranch := true;
            //     statementsBeforeIf
            //     if e then begin <then>; <>visitElseBranch := false; end;
            //   end
            //   if <>visitElseBranch then <else>
            // end

            // if e then <then>
            //
            // переводим в
            //
            // begin
            //   statementsBeforeIf
            //   if e then <then>
            // end

            // Добавляем объявление <>visitElseBranch если мы находимся в первом в цепочке if, который не является вложенным
            List <statement> visitElseStatList = null;

            if (ifNode.else_body != null &&
                !(ifNode.Parent is if_node ifParentNode &&
                  ifParentNode.condition is ident ifParentNodeIdent &&
                  ifParentNodeIdent.name.Equals(GeneratedVisitElseBranchVariableName)) &&
                !IsNestedIfWithExtendedIs(ifNode))
            {
                visitElseStatList = new List <statement>();
                visitElseStatList.Add(
                    new var_statement(
                        new ident(GeneratedVisitElseBranchVariableName, ifNode.source_context),
                        new bool_const(true, ifNode.source_context),
                        ifNode.source_context)
                    );
            }

            // Добавляем, чтобы на конвертировать еще раз, если потребуется
            processedIfNodes.Add(ifNode);

            if (ifNode.else_body != null)
            {
                statementsBeforeIf.Add(new assign(
                                           new ident(GeneratedVisitElseBranchVariableName, ifNode.source_context),
                                           new bool_const(true, ifNode.source_context),
                                           Operators.Assignment,
                                           ifNode.source_context));
            }
            var statementsBeforeAndIf = new statement_list();

            statementsBeforeAndIf.AddMany(statementsBeforeIf);
            statementsBeforeAndIf.Add(ifNode);

            if (ifNode.else_body == null)
            {
                elseBody = null;
                if (visitElseStatList != null)
                {
                    visitElseStatList.Add(statementsBeforeAndIf);
                    statementsBeforeAndIf = new statement_list(visitElseStatList);
                }
                return(statementsBeforeAndIf);
            }
            else
            {
                var result = new statement_list();
                result.Add(statementsBeforeAndIf);
                var endIfLabel = NewEndIfName();

                if (!(ifNode.then_body is statement_list))
                {
                    ifNode.then_body        = new statement_list(ifNode.then_body, ifNode.then_body.source_context);
                    ifNode.then_body.Parent = ifNode;
                }

                var thenBody = ifNode.then_body as statement_list;

                thenBody.Add(new assign(
                                 new ident(GeneratedVisitElseBranchVariableName, thenBody.source_context),
                                 new bool_const(false, thenBody.source_context),
                                 Operators.Assignment,
                                 thenBody.source_context));

                // добавляем else
                result.Add(
                    new if_node(
                        new ident(GeneratedVisitElseBranchVariableName, ifNode.else_body.source_context),
                        ifNode.else_body,
                        null,
                        ifNode.else_body.source_context));

                // Возвращаем else для обхода, т.к. он уже не входит в if
                elseBody = ifNode.else_body;
                // удаляем else из if
                ifNode.else_body = null;

                if (visitElseStatList != null)
                {
                    visitElseStatList.Add(result);
                    result = new statement_list(visitElseStatList);
                }

                return(result);
            }
        }