public override string VisitVariableDecl(AstVariableDecl variable, int indentLevel = 0) { StringBuilder sb = new StringBuilder(); if (variable.Directives != null) { var dirs = ""; foreach (var d in variable.Directives) { dirs += "#" + d.Name.Name; foreach (var arg in d.Arguments) { dirs += " " + arg.Accept(this); } dirs += "\n"; } sb.Append(dirs); } if (variable.GetFlag(StmtFlags.IsLocal)) { sb.Append("local "); } sb.Append(variable.Name.Accept(this)); sb.Append($" : {variable.Type}"); if (variable.Initializer != null) { sb.Append(" = "); sb.Append(variable.Initializer.Accept(this)); } return(sb.ToString()); }
public override NodeFinderResult VisitVariableDecl(AstVariableDecl variable, int index = 0) { if (GetRelativeLocation(variable.Initializer?.Location, index) == RelativeLocation.Same) { return(variable.Initializer.Accept(this, index)); } if (GetRelativeLocation(variable.TypeExpr.Location, index) == RelativeLocation.Same) { return(new NodeFinderResult(variable.Scope, type: variable.Type)); } return(new NodeFinderResult(variable.Scope, stmt: variable)); }
private void GenerateVariableDecl(AstVariableDecl decl) { if (decl.Type.IsComptimeOnly) { return; } var varPtr = CreateLocalVariable(decl.Type, decl.Name.Name); valueMap[decl] = varPtr; if (decl.Initializer != null) { var x = GenerateExpression(decl.Initializer, true); builder.CreateStore(x, varPtr); } }
private IEnumerable <AstVariableDecl> AnalyseVariableDecl(AstVariableDecl decl) { foreach (var sub in SplitVariableDeclaration(decl)) { yield return(sub); } decl.ContainingFunction = currentFunction; ResolveVariableDecl(decl); var(ok, other) = decl.GetFlag(StmtFlags.IsLocal) ? decl.Scope.DefineLocalSymbol(decl) : decl.Scope.DefineSymbol(decl); if (!ok) { ReportError(decl, $"A symbol with name '{decl.Name.Name}' already exists in this scope", ("Other declaration here:", other)); } }
public override string VisitVariableDecl(AstVariableDecl variable, int indentLevel = 0) { StringBuilder sb = new StringBuilder(); sb.Append(variable.Pattern.Accept(this)); if (variable.TypeExpr != null) { sb.Append($" : {variable.TypeExpr.Accept(this)} "); } else { sb.Append(" :"); } if (variable.Initializer != null) { sb.Append("= "); sb.Append(variable.Initializer.Accept(this)); } return(sb.ToString()); }
private void ResolveVariableDecl(AstVariableDecl v) { Debug.Assert(v.Name != null); if (v.Directives != null) { foreach (var d in v.Directives) { foreach (var arg in d.Arguments) { arg.Scope = v.Scope; InferType(arg, null); } } } if (v.HasDirective("local")) { v.SetFlag(StmtFlags.IsLocal, true); } if (v.TypeExpr != null) { v.TypeExpr.AttachTo(v); v.TypeExpr.SetFlag(ExprFlags.ValueRequired, true); v.TypeExpr = ResolveTypeNow(v.TypeExpr, out var t); v.Type = t; } // initializer stuff if (v.Initializer == null) { if (v.GetFlag(StmtFlags.GlobalScope) && !v.HasDirective("extern")) { ReportError(v, $"Global variables must have an initializer"); } } else { v.Initializer.AttachTo(v); v.Initializer.SetFlag(ExprFlags.ValueRequired, true); v.Initializer = InferType(v.Initializer, v.Type); ConvertLiteralTypeToDefaultType(v.Initializer, v.Type); if (v.TypeExpr != null) { //v.Initializer = HandleReference(v.Initializer, v.Type, null); v.Initializer = CheckType(v.Initializer, v.Type); } } if (v.TypeExpr == null) { v.Type = v.Initializer.Type; } switch (v.Type) { case IntType _: case FloatType _: case BoolType _: case CharType _: case SliceType _: case StringType _: case ArrayType _: case StructType _: case EnumType _: case PointerType _: case ReferenceType _: case FunctionType _: case TupleType _: case RangeType _: break; case CheezType t when t.IsErrorType: break; default: ReportError(v, $"Variable can't have type {v.Type}"); break; } //if (vardecl.Type is SumType) //{ // ReportError(vardecl.Pattern, $"Invalid type for variable declaration: {vardecl.Type}"); //} }
private IEnumerable <AstVariableDecl> SplitVariableDeclaration(AstVariableDecl v) { v.Pattern.SetFlag(ExprFlags.IsDeclarationPattern, true); switch (v.Pattern) { case AstCompCallExpr cc when cc.Name.Name == "id": cc.AttachTo(v); v.Name = InferType(cc, null) as AstIdExpr; break; case AstIdExpr name: // ok, do nothing v.Name = name; break; case AstTupleExpr t: { v.Name = new AstIdExpr(GetUniqueName(t.ToString()), false, t); v.Pattern = v.Name; //var initClone = v.Initializer.Clone(); //initClone.AttachTo(v); //initClone.SetFlag(ExprFlags.ValueRequired, true); //initClone = InferType(initClone, null); //AstVariableDecl CreateSub(int index, string name) //{ // var init = mCompiler.ParseExpression( // $"@{name}(§init)", // new Dictionary<string, AstExpression> // { // { "init", new AstVariableRef(v, v.Initializer) } // }); // var sub = new AstVariableDecl(t.Values[index], null, init, Location: v); // sub.Scope = v.Scope; // sub.SetFlags(v.GetFlags()); // return sub; //} //if (initClone.Type is PointerType pt1 && pt1.TargetType is AnyType) //{ // // create new declarations for sub patterns // yield return CreateSub(0, "ptr_of_any"); // yield return CreateSub(1, "type_info_of_any"); // break; //} //else if (initClone.Type is PointerType pt2 && pt2.TargetType is TraitType) //{ // // create new declarations for sub patterns // yield return CreateSub(0, "ptr_of_trait"); // yield return CreateSub(1, "vtable_of_trait"); // break; //} //else //{ // create new declarations for sub patterns var index = 0; foreach (var subPattern in t.Values) { var init = new AstArrayAccessExpr( new AstVariableRef(v, v.Initializer), new AstNumberExpr(NumberData.FromBigInt(index), Location: v.Initializer)); var sub = new AstVariableDecl(subPattern, null, init, v.Mutable, v.Documentation, Location: v); sub.Scope = v.Scope; sub.SetFlags(v.GetFlags()); yield return(sub); index += 1; } break; //} } default: ReportError(v.Pattern, $"Invalid pattern in variable declaration"); break; } }
public virtual ReturnType VisitVariableDecl(AstVariableDecl decl, DataType data = default) => default;
public AstVariableRef(AstVariableDecl let, ILocation Location = null) : base(Location) { Declaration = let; Type = let.Type; }
public VarDeclType(AstVariableDecl decl) { Declaration = decl; }
private void InitGlobalVariable(AstVariableDecl decl, HashSet <AstVariableDecl> visited) { if (visited.Contains(decl)) { return; } if (decl.Dependencies != null) { foreach (var dep in decl.Dependencies) { if (dep is AstVariableDecl v) { InitGlobalVariable(v, visited); } } } visited.Add(decl); // Don't emit global variables that aren't even used if (dontEmitUnusedDeclarations && !decl.IsUsed) { return; } // create vars var type = CheezTypeToLLVMType(decl.Type); var name = decl.Name.Name; if (decl.TryGetDirective("linkname", out var linkname)) { name = linkname.Arguments[0].Value as string; } var varPtr = module.AddGlobal(type, name); varPtr.SetLinkage(LLVMLinkage.LLVMInternalLinkage); if (decl.HasDirective("thread_local")) { varPtr.SetThreadLocal(true); } //varPtr.SetLinkage(LLVMLinkage.LLVMExternalLinkage);// TODO? if (decl.HasDirective("extern")) { varPtr.SetLinkage(LLVMLinkage.LLVMExternalLinkage); } else { LLVMValueRef initializer = LLVM.ConstNull(CheezTypeToLLVMType(decl.Type)); varPtr.SetInitializer(initializer); } valueMap[decl] = varPtr; // do initialization TODO: other patterns if (decl.Initializer != null) { var x = GenerateExpression(decl.Initializer, true); builder.CreateStore(x, varPtr); } }
private AstStatement AnalyseForStatement(AstForStmt fo) { fo.SubScope = new Scope("for", fo.Scope); fo.Collection.SetFlag(ExprFlags.ValueRequired, true); fo.Collection.AttachTo(fo); fo.Collection = InferType(fo.Collection, null); ConvertLiteralTypeToDefaultType(fo.Collection, null); if (fo.Collection.Type.IsErrorType) { return(fo); } fo.Body.AttachTo(fo); fo.Body.Scope = fo.SubScope; fo.Body = InferType(fo.Body, CheezType.Code); var fors = fo.Scope.GetForExtensions(fo.Collection.Type); var matches = fors.Select(func => { var args = new List <AstArgument> { new AstArgument(fo.Collection, Location: fo.Collection), new AstArgument(fo.Body, Location: fo.Body) }; if (fo.Arguments != null) { args.AddRange(fo.Arguments); } var par = func.Parameters.Select(p => (p.Name?.Name, p.Type, p.DefaultValue)).ToArray(); if (CheckAndMatchArgsToParams(args, par, false)) { return(func, args); } return(null, null); }).Where(a => a.func != null).ToList(); if (matches.Count == 0) { var candidates = fors.Select(f => ("Tried this candidate:", f.ParameterLocation)); ReportError(fo.Collection, $"No for extension matches type '{fo.Collection.Type}'", candidates); return(fo); } else if (matches.Count > 1) { var candidates = matches.Select(f => ("This matches:", f.func.ParameterLocation)); ReportError(fo.Collection, $"Multiple for extensions match type '{fo.Collection.Type}'", candidates); return(fo); } else { AstVariableDecl CreateLink(AstIdExpr name, AstExpression expr, ILocation location) { var link = new AstCompCallExpr( new AstIdExpr("link", false, location), new List <AstArgument> { new AstArgument(expr, Location: expr.Location) }, location); var type = mCompiler.ParseExpression($"@typeof(@link({expr}))", new Dictionary <string, AstExpression> { { "it", name } }); var varDecl = new AstVariableDecl(name, type, link, true, Location: location); return(varDecl); } var(func, args) = matches[0]; var code = args[1].Expr; var links = new List <AstStatement>(); var it = new AstIdExpr("it", false, fo.Location); var it_index = new AstIdExpr("it_index", false, fo.Location); // create links for it and it_index if (fo.VarName != null) { links.Add(CreateLink(fo.VarName, it, fo.VarName.Location)); } else { links.Add(CreateLink(it, it.Clone(), it.Location)); } if (fo.IndexName != null) { links.Add(CreateLink(fo.IndexName, it_index, fo.IndexName.Location)); } else { links.Add(CreateLink(it_index, it_index.Clone(), it_index.Location)); } // set break and continue if (fo.Label != null) { var setBreakAndContinue = mCompiler.ParseStatement($"@set_break_and_continue({fo.Label.Name})"); links.Add(setBreakAndContinue); } // set value to null because it is not a code anymore code.TypeInferred = false; code.Value = null; links.Add(new AstExprStmt(code, code.Location)); args[1].Expr = new AstBlockExpr(links, Location: fo.Body.Location); var call = new AstCallExpr(new AstFunctionRef(func, null, fo.Location), args, fo.Location); var exprStmt = new AstExprStmt(call, fo.Body.Location); exprStmt.Parent = fo.Parent; exprStmt.Scope = fo.SubScope; var result = AnalyseStatement(exprStmt, out var ns); Debug.Assert(ns == null); return(result); } }