Exemple #1
0
        public (Value success, Value cost, Value result) CompileMatchCase(Value matchWith, MatchCase matchCase)
        {
            LabelTarget failLabel   = Expression.Label("fail");
            LabelTarget finishLabel = Expression.Label("finish");
            var         successVar  = Expression.Parameter(typeof(bool), "success");
            var         costVar     = Expression.Parameter(typeof(int), "cost");

            var compiler = new FunctionCompiler(scope);
            var matcher  = new Matcher(
                compiler,
                implicitVariables: matchCase.ImplicitVariables
                );
            var instr = new List <Expression>();

            instr.Add(matcher.CompileMatch(matchWith, matchCase.MatchedValue, failLabel, MatchKind.exact));

            foreach (var variable in matchCase.ImplicitVariables)
            {
                if (matcher.implicitVars[variable.name] == null)
                {
                    throw new Exception($"{variable.name} was not instantiated at {matchCase.Location}");
                }
                var value = matcher.implicitVars[variable.name];
                if (variable.type.IsSome())
                {
                    var coerceResult = compiler.CompileCoerce(value, CompileExpr(variable.type.Get()));
                    // TODO: this should always succeed due to type constraints

                    instr.Add(Expression.IfThenElse(
                                  coerceResult.success.Expression,
                                  Expression.Block(
                                      Expression.AddAssign(costVar, coerceResult.cost.Expression),
                                      scope.CreateVariable(variable.name, coerceResult.value)),
                                  Expression.Goto(failLabel)));
                }
                else
                {
                    instr.Add(scope.CreateVariable(variable.name, value));
                }
            }

            instr.Add(Expression.Assign(successVar, Expression.Constant(true)));
            instr.Add(Expression.Goto(finishLabel));

            instr.Add(Expression.Label(failLabel));
            instr.Add(Expression.Assign(successVar, Expression.Constant(false)));

            instr.Add(Expression.Label(finishLabel));

            return(Value.Seq(instr, Value.Dynamic(successVar)), Value.Dynamic(costVar), compiler.CompileExpr(matchCase.Body));
        }
 public Matcher(FunctionCompiler compiler, List <(string name, Optional <Expr> type)> implicitVariables)