Пример #1
0
        public override void Visit(Cond cond)
        {
            _state.ConsolidateVariables();

            var expr = new ExpressionSimplifierVisitor().Visit(cond.Expr);

            if (expr is Bool b)
            {
                if (b.Value)
                {
                    Visit(cond.Block);
                }
                return;
            }

            var exprResult = new ExpressionGeneratorVisitor(_state).Visit(expr);

            _state.ConsolidateVariables();

            _state.GoToNextLabel(out var trueLabel);
            var falseLabel = _state.NewLabel;

            _llvmGenerator.Emit($"br i1 {exprResult.Register}, label %{trueLabel}, label %{falseLabel}");

            _llvmGenerator.Emit($"{trueLabel}:");
            VisitBlockWithoutRestore(cond.Block);

            _state.ConsolidateVariables();
            _state.RestorePreviousVarEnvWithMerge();

            _llvmGenerator.Emit($"br label %{falseLabel}");

            _state.CurrentLabel = falseLabel;
            _llvmGenerator.Emit($"{falseLabel}:");
        }
        public override void Visit(While @while)
        {
            var expr = new ExpressionSimplifierVisitor().Visit(@while.Expr);

            if (expr is Bool b && b.Value == false)
            {
                return;
            }

            _state.GoToNextLabel(out var startWhileLabel);
            _llvmGenerator.Emit($"br label %{startWhileLabel}");
            _llvmGenerator.Emit($"{startWhileLabel}:");

            var exprResult = new ExpressionGeneratorVisitor(_state).Visit(expr);

            _state.GoToNextLabel(out var whileLabel);
            var endWhileLabel = _state.NewLabel;

            _llvmGenerator.Emit($"br i1 {exprResult.Register}, label %{whileLabel}, label %{endWhileLabel}");

            _llvmGenerator.Emit($"{whileLabel}:");
            Visit(@while.Block);
            _llvmGenerator.Emit($"br label %{startWhileLabel}");

            _state.CurrentLabel = endWhileLabel;
            _llvmGenerator.Emit($"{endWhileLabel}:");
            _llvmGenerator.Emit($"br label %{endWhileLabel}");
        }
        public override void Visit(CondElse condElse)
        {
            var expr = new ExpressionSimplifierVisitor().Visit(condElse.Expr);

            if (expr is Bool b)
            {
                Visit(b.Value ? condElse.TBlock : condElse.FBlock);
                return;
            }

            var exprResult = new ExpressionGeneratorVisitor(_state).Visit(expr);

            _state.GoToNextLabel(out var trueLabel);
            string falseLabel = _state.NewLabel, endIfLabel = _state.NewLabel;

            _llvmGenerator.Emit($"br i1 {exprResult.Register}, label %{trueLabel}, label %{falseLabel}");

            _llvmGenerator.Emit($"{trueLabel}:");
            Visit(condElse.TBlock);
            _llvmGenerator.Emit($"br label %{endIfLabel}");

            _state.CurrentLabel = falseLabel;
            _llvmGenerator.Emit($"{falseLabel}:");
            Visit(condElse.FBlock);
            _llvmGenerator.Emit($"br label %{endIfLabel}");

            _state.CurrentLabel = endIfLabel;
            _llvmGenerator.Emit($"{endIfLabel}:");
        }
        public override void Visit(Ass ass)
        {
            var expr       = new ExpressionSimplifierVisitor().Visit(ass.Expr);
            var exprResult = new ExpressionGeneratorVisitor(_state).Visit(expr);

            _state.VarToLabelToRegister[ass.Id] =
                new Dictionary <string, RegisterLabelContext> {
                { exprResult.Label, exprResult }
            };
        }
Пример #5
0
        public override void Visit(While @while)
        {
            var expr = new ExpressionSimplifierVisitor().Visit(@while.Expr);

            if (expr is Bool b && b.Value == false)
            {
                return;
            }
            _state.ConsolidateVariables();

            _state.GoToNextLabel(out var startWhileLabel);
            _llvmGenerator.Emit($"br label %{startWhileLabel}");

            _state.DetachVarEnv();
            _state.DetachVarEnv();
            var reservedRegisters = _state.ReserveRegisterForCurrentVars(startWhileLabel);

            _state.GoToNextLabel(out var whileLabel);
            _llvmGenerator.Emit($"{whileLabel}:");
            var startLength = _llvmGenerator.GetCurrentLength();

            VisitBlock(@while.Block);

            _state.ConsolidateVariables();
            _state.RestorePreviousVarEnvWithMerge();
            _llvmGenerator.Emit($"br label %{startWhileLabel}");

            _state.CurrentLabel = startWhileLabel;
            _llvmGenerator.Emit($"{startWhileLabel}:");
            _state.RestorePreviousVarEnvWithMerge();

            _state.RemoveReservedRegisters(reservedRegisters, out var removedRegisters);
            _state.ConsolidateVariables(reservedRegisters);

            var removedRegs       = removedRegisters.ToHashSet();
            var reservedToReplace = reservedRegisters.ToList().Where(reg => removedRegs.Contains(reg.Value.Register)).ToList();

            _llvmGenerator.ReplaceRegisters(startLength, reservedToReplace.Select(res =>
                                                                                  (res.Value.Register, _state.VarToLabelToRegister[res.Key][_state.CurrentLabel].Register)).ToList());

            var exprResult    = new ExpressionGeneratorVisitor(_state).Visit(expr);
            var endWhileLabel = _state.NewLabel;

            _llvmGenerator.Emit($"br i1 {exprResult.Register}, label %{whileLabel}, label %{endWhileLabel}");

            _state.CurrentLabel = endWhileLabel;
            _llvmGenerator.Emit($"{endWhileLabel}:");
        }
        public override void Visit(Ret ret)
        {
            var toEmit = "ret ";

            if (ret.Expr == null)
            {
                toEmit += "void";
            }
            else
            {
                var expr       = new ExpressionSimplifierVisitor().Visit(ret.Expr);
                var exprResult = new ExpressionGeneratorVisitor(_state).Visit(expr);
                toEmit += $"{AstToLlvmString.Type(exprResult.Type)} {exprResult.Register}";
            }

            _llvmGenerator.Emit(toEmit);
        }
Пример #7
0
        public override void Visit(StructAss structAss)
        {
            var objectExpr       = new ExpressionSimplifierVisitor().Visit(structAss.IdExpr);
            var objectExprResult = new ExpressionGeneratorVisitor(_state).Visit(objectExpr);

            var expr       = new ExpressionSimplifierVisitor().Visit(structAss.Expr);
            var exprResult = new ExpressionGeneratorVisitor(_state).Visit(expr);

            var nextRegister1   = _state.NewRegister;
            var field           = _globalState.NameToClass[objectExprResult.Type.GetText()].Fields[structAss.Id];
            var fieldTypeString = objectExprResult.Type.GetText();

            _llvmGenerator.Emit($"{nextRegister1} = getelementptr %{fieldTypeString}, " +
                                $"%{fieldTypeString}* {objectExprResult.Register}, i32 0, i32 {field.Number + 1}");

            _llvmGenerator.Emit($"store {AstToLlvmString.Type(exprResult.Type)} {exprResult.Register}, " +
                                $"{AstToLlvmString.Type(field.Type)}* {nextRegister1}");
        }
Пример #8
0
        public override void Visit(Ret ret)
        {
            var toEmit = "ret ";

            if (ret.Expr == null)
            {
                toEmit += "void";
            }
            else
            {
                var expr       = new ExpressionSimplifierVisitor().Visit(ret.Expr);
                var exprResult = new ExpressionGeneratorVisitor(_state).Visit(expr);
                toEmit += exprResult.Type is LatteParser.TVoidContext
                    ? AstToLlvmString.Type(_globalState.NameToFunction[_state.CurrentFunction].Type)
                    : AstToLlvmString.Type(exprResult.Type);
                toEmit += $" {exprResult.Register}";
            }

            _llvmGenerator.Emit(toEmit);
        }
        public override void Visit(Decl decl)
        {
            decl.Items.ToList().ForEach(item =>
            {
                var expr = item.Expr != null
                    ? new ExpressionSimplifierVisitor().Visit(item.Expr)
                    : Common.AST.Exprs.Utils.DefaultValueForType(decl.Type);
                var exprResult = new ExpressionGeneratorVisitor(_state).Visit(expr);

                _state.VarToLabelToRegister[item.Id] =
                    new Dictionary <string, RegisterLabelContext> {
                    { exprResult.Label, exprResult }
                };

                if (_state.VarToLabelToRegister.ContainsKey(item.Id))
                {
                    _state.RedefinedVars.Add(item.Id);
                }
            });
        }
Пример #10
0
        public override void Visit(Ass ass)
        {
            var expr       = new ExpressionSimplifierVisitor().Visit(ass.Expr);
            var exprResult = new ExpressionGeneratorVisitor(_state).Visit(expr);

            if (_state.VarToLabelToRegister.ContainsKey(ass.Id))
            {
                var varType = _state.VarToLabelToRegister[ass.Id].ToList()[0].Value.Type;
                if (varType.GetText() != exprResult.Type.GetText())
                {
                    var nextRegister = _state.NewRegister;
                    _llvmGenerator.Emit($"{nextRegister} = bitcast {AstToLlvmString.Type(exprResult.Type)} " +
                                        $"{exprResult.Register} to {AstToLlvmString.Type(varType)}");
                    exprResult.Register = nextRegister;
                    exprResult.Type     = varType;
                }

                _state.VarToLabelToRegister[ass.Id] =
                    new Dictionary <string, RegisterLabelContext> {
                    { exprResult.Label, exprResult }
                };
            }
            else
            {
                var classDef     = _globalState.CurrentClass;
                var field        = classDef.Fields[ass.Id];
                var selfRegister = _state.VarToLabelToRegister["self"].Values.ToList()[0].Register;

                var nextRegister = _state.NewRegister;

                _llvmGenerator.Emit(
                    $"{nextRegister} = getelementptr %{classDef.Id}, %{classDef.Id}* {selfRegister}, i32 0, i32 {field.Number + 1}");
                _llvmGenerator.Emit($"store {AstToLlvmString.Type(field.Type)} {exprResult.Register}, " +
                                    $"{AstToLlvmString.Type(field.Type)}* {nextRegister}");
            }
        }