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("}"); }
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); }
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}"); }
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 })); }
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("}"); }
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 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++; });
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}"); } }