コード例 #1
0
ファイル: AstDeclaration.cs プロジェクト: CheezLang/CheezLang
 public AstParameter(AstIdExpr name, AstExpression typeExpr, AstExpression defaultValue, bool mutable, ILocation Location = null)
 {
     this.Location     = Location;
     this.Name         = name;
     this.TypeExpr     = typeExpr;
     this.DefaultValue = defaultValue;
     this.Mutable      = mutable;
 }
コード例 #2
0
ファイル: RawAstPrinter.cs プロジェクト: CheezLang/CheezLang
 public override string VisitIdExpr(AstIdExpr ident, int indentLevel = 0)
 {
     if (ident.IsPolymorphic)
     {
         return('$' + ident.Name);
     }
     return(ident.Name);
 }
コード例 #3
0
 public AstForStmt(
     AstIdExpr varName,
     AstIdExpr indexName,
     AstExpression collection,
     AstExpression body,
     List <AstArgument> arguments,
     AstIdExpr label,
     ILocation Location = null)
     : base(Location: Location)
 {
     this.VarName    = varName;
     this.IndexName  = indexName;
     this.Collection = collection;
     this.Body       = body;
     this.Arguments  = arguments;
     this.Label      = label;
 }
コード例 #4
0
 public override NodeFinderResult VisitIdExpr(AstIdExpr ident, int data = 0)
 {
     return(new NodeFinderResult(ident.Scope, expr: ident));
 }
コード例 #5
0
 public virtual ReturnType VisitIdExpr(AstIdExpr expr, DataType data                   = default) => default;
コード例 #6
0
ファイル: AstDirective.cs プロジェクト: CheezLang/CheezLang
 public AstDirective(AstIdExpr name, List <AstExpression> args, ILocation Location = null)
 {
     this.Location  = Location;
     this.Name      = name;
     this.Arguments = args;
 }
コード例 #7
0
ファイル: AstDeclaration.cs プロジェクト: CheezLang/CheezLang
 public AstDecl(AstIdExpr name, string doc, List <AstDirective> Directives = null, ILocation Location = null) : base(Directives, Location)
 {
     this.Name          = name;
     this.Documentation = doc;
 }
コード例 #8
0
 public AstWhileStmt(AstBlockExpr body, AstIdExpr label, ILocation Location = null)
     : base(Location: Location)
 {
     this.Body  = body;
     this.Label = label;
 }
コード例 #9
0
        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);
            }
        }