Ejemplo n.º 1
0
        public void GenerateType(ClassDef @class)
        {
            _llvmGenerator.Emit($"%{@class.Id} = type " + "{");

            _llvmGenerator.Emit($"%{@class.Id}_vtable*");

            @class.Fields.ToList().ForEach(field =>
            {
                _llvmGenerator.Emit($",{AstToLlvmString.Type(field.Value.Type)}");
            });

            _llvmGenerator.Emit("}");
        }
Ejemplo n.º 2
0
        public override RegisterLabelContext Visit(ObjectField objectField)
        {
            string nextRegister1 = _state.NewRegister, nextRegister2 = _state.NewRegister;
            var    objectExpr = Visit(objectField.IdExpr);
            var    field      = _globalState.NameToClass[objectExpr.Type.GetText()].Fields[objectField.FieldId];

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

            _llvmGenerator.Emit($"{nextRegister2} = load {AstToLlvmString.Type(field.Type)}, " +
                                $"{AstToLlvmString.Type(field.Type)}* {nextRegister1}");

            return(new RegisterLabelContext(nextRegister2, _state.CurrentLabel, field.Type));
        }
        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);
        }
Ejemplo n.º 4
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}");
        }
Ejemplo n.º 5
0
        public override RegisterLabelContext Visit(MethodCall methodCall)
        {
            var objectExpr  = Visit(methodCall.IdExpr);
            var objectClass = _globalState.NameToClass[objectExpr.Type.GetText()];

            var(method, methodNum) = objectClass.Methods[methodCall.Id];
            var selfType = method.Args.Last().Type;

            if (objectClass.Id != selfType.GetText())
            {
                var nextRegister = _state.NewRegister;
                _llvmGenerator.Emit(
                    $"{nextRegister} = bitcast %{objectClass.Id}* {objectExpr.Register} to %{selfType.GetText()}*");
                objectExpr.Register = nextRegister;
                objectExpr.Type     = selfType;
            }

            string newRegister1 = _state.NewRegister, newRegister2 = _state.NewRegister,
                   newRegister3 = _state.NewRegister, newRegister4 = _state.NewRegister;

            _llvmGenerator.Emit($"{newRegister1} = getelementptr %{selfType.GetText()}, %{selfType.GetText()}* " +
                                $"{objectExpr.Register}, i32 0, i32 0");
            _llvmGenerator.Emit(
                $"{newRegister2} = load %{selfType.GetText()}_vtable*, %{selfType.GetText()}_vtable** {newRegister1}");
            _llvmGenerator.Emit($"{newRegister3} = getelementptr %{selfType.GetText()}_vtable, %{selfType.GetText()}_vtable*" +
                                $" {newRegister2}, i32 0, i32 {methodNum}");
            _llvmGenerator.Emit($"{newRegister4} = load {AstToLlvmString.FunctionalType(method)}, " +
                                $"{AstToLlvmString.FunctionalType(method)}* {newRegister3}");

            return(VisitFunctionCall(
                       new FunCall
            {
                Id = "",
                Exprs = methodCall.Exprs
            },
                       objectExpr,
                       new FunctionDef
            {
                Id = newRegister4,
                Type = method.Type,
                Args = method.Args
            }));
        }
Ejemplo n.º 6
0
        public void GenerateVTable(ClassDef @class)
        {
            _llvmGenerator.Emit($"%{@class.Id}_vtable = type " + "{");

            var isFirst = true;

            @class.Methods.Values.ToList().ForEach(method =>
            {
                var toEmit = "";
                if (!isFirst)
                {
                    toEmit = ",";
                }

                toEmit += AstToLlvmString.FunctionalType(method.Item1);
                _llvmGenerator.Emit(toEmit);

                isFirst = false;
            });

            _llvmGenerator.Emit("}");

            _llvmGenerator.Emit($"@{@class.Id}_vtable_ptrs = global %{@class.Id}_vtable " + "{");

            isFirst = true;
            @class.Methods.Values.ToList().ForEach(method =>
            {
                var toEmit = "";
                if (!isFirst)
                {
                    toEmit = ",";
                }

                toEmit += AstToLlvmString.FunctionalType(method.Item1);
                toEmit += $" @{method.Item1.Id}";
                _llvmGenerator.Emit(toEmit);

                isFirst = false;
            });

            _llvmGenerator.Emit("}");
        }
Ejemplo n.º 7
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);
        }
Ejemplo n.º 8
0
        public void GenerateConstructor(ClassDef @classDef)
        {
            _llvmGenerator.Emit($"define void @g_{@classDef.Id}_construct(%{@classDef.Id}* %this) " + "{");

            if (!_globalState.LiteralToStringConstId.ContainsKey(""))
            {
                _globalState.LiteralToStringConstId[""] = _globalState.NewString;
            }
            var emptyStr = _globalState.LiteralToStringConstId[""];

            int register = 1, counter = @classDef.OwnFieldsStartIndex;

            if (counter > 0)
            {
                _llvmGenerator.Emit($"%r{register} = bitcast %{@classDef.Id}* %this to %{@classDef.ParentId}*");
                _llvmGenerator.Emit($"call void @g_{@classDef.ParentId}_construct(%{@classDef.ParentId}* %r{register})");
                register++;
            }

            _llvmGenerator.Emit($"%r0 = getelementptr %{@classDef.Id}, %{@classDef.Id}* %this, i32 0, i32 0");
            _llvmGenerator.Emit($"store %{@classDef.Id}_vtable* @{@classDef.Id}_vtable_ptrs, %{@classDef.Id}_vtable** %r0");

            @classDef.Fields.Skip(counter).ToList().ForEach(field =>
            {
                _llvmGenerator.Emit($"%r{register} = getelementptr %{@classDef.Id}, %{@classDef.Id}* %this, i32 0, i32 {counter + 1}");
                _llvmGenerator.Emit(
                    $"store {AstToLlvmString.Type(field.Value.Type)} " +
                    $@"{(field.Value.Type switch
                    {
                        LatteParser.TStringContext _ => emptyStr,
                        LatteParser.TTypeNameContext _ => "null",
                        _ => "0"
                        
                    })}, " +
                    $"{AstToLlvmString.Type(field.Value.Type)}* %r{register}");

                register++;
                counter++;
            });
Ejemplo n.º 9
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}");
            }
        }