Ejemplo n.º 1
0
        public static IUnboundExpr Match(BindingContext context, MatchExpr expr, IBoundExpr boundValue)
        {
            // validate the patterns
            ShapeChecker.Validate(expr, boundValue.Type);
            Coverage.Validate(expr, boundValue.Type);

            // convert the cases to vanilla if/then blocks
            var valueName       = context.NameGenerator.Generate();
            var defineValueExpr = new DefineExpr(expr.Value.Position, valueName, expr.Value, false);
            var valueExpr       = new NameExpr(expr.Value.Position, valueName);

            var conditions = new List <DesugaredMatchCase>();

            foreach (var matchCase in expr.Cases)
            {
                var result = new DesugaredMatchCase();

                result.Condition = Match(context, boundValue.Type,
                                         matchCase.Pattern, valueExpr, result.Variables);

                conditions.Add(result);
            }

            // build a single compound "if" expression
            var ifExpr = (IUnboundExpr)null;

            if (expr.Cases.Count == 0)
            {
                throw new CompileException(expr.Position, "Match expression has no cases.");
            }
            else if (expr.Cases.Count == 1)
            {
                // if there is only a since case, and we've ensured exhaustivity already,
                // then it must match all values, so just use the body directly
                ifExpr = CreateCaseBody(conditions[0].Variables, expr.Cases[0].Body);
            }
            else
            {
                // go in reverse order so that we start with the trailing else and build
                // forward
                for (int i = expr.Cases.Count - 1; i >= 0; i--)
                {
                    if (ifExpr == null)
                    {
                        // for the first popped (i.e. last appearing) case, we know it must
                        // match because the match expression is exhaustive, so just use its
                        // body directly
                        ifExpr = CreateCaseBody(conditions[i].Variables, expr.Cases[i].Body);
                    }
                    else
                    {
                        var body = CreateCaseBody(conditions[i].Variables, expr.Cases[i].Body);
                        ifExpr = new IfExpr(expr.Cases[i].Position, conditions[i].Condition,
                                            body, ifExpr);
                    }
                }
            }

            return(new BlockExpr(new IUnboundExpr[] { defineValueExpr, ifExpr }));
        }
Ejemplo n.º 2
0
        // <-- Name
        //   | FN Name TupleType
        //   | BOOL_LITERAL
        //   | INT_LITERAL
        //   | STRING_LITERAL
        //   | LPAREN (Expression)? RPAREN
        private IUnboundExpr PrimaryExpr()
        {
            IUnboundExpr expression;

            if (CurrentIs(TokenType.Name))
            {
                var name = Consume();
                expression = new NameExpr(name.Position, name.StringValue, TypeArgs());
            }
            else if (CurrentIs(TokenType.Fn))
            {
                expression = FuncExpr();
            }
            else if (CurrentIs(TokenType.Bool))
            {
                expression = new BoolExpr(Consume(TokenType.Bool));
            }
            else if (CurrentIs(TokenType.Int))
            {
                expression = new IntExpr(Consume(TokenType.Int));
            }
            else if (CurrentIs(TokenType.String))
            {
                expression = new StringExpr(Consume(TokenType.String));
            }
            else if (CurrentIs(TokenType.LeftParen))
            {
                Token leftParen = Consume(TokenType.LeftParen);

                if (CurrentIs(TokenType.RightParen))
                {
                    // () -> unit
                    expression = new UnitExpr(leftParen.Position);
                }
                else if (CurrentIs(TokenType.Operator))
                {
                    // ( OPERATOR ) -> an operator in prefix form
                    Token op = Consume(TokenType.Operator);
                    expression = new NameExpr(op.Position, op.StringValue);
                }
                else
                {
                    // anything else is a regular parenthesized expression
                    expression = Expression();
                }

                Consume(TokenType.RightParen);
            }
            else
            {
                expression = null;
            }

            return(expression);
        }
Ejemplo n.º 3
0
        IBoundExpr IUnboundExprVisitor<IBoundExpr>.Visit(NameExpr expr)
        {
            //### bob: handle array constructors. hack! should be intrinsic
            if (expr.Name == "ArrayOf")
            {
                // handle ArrayOf[Int]
                if (expr.TypeArgs.Count == 1)
                {
                    return new ArrayExpr(expr.Position, expr.TypeArgs[0]).Accept(this);
                }
            }

            return mContext.ResolveName(mFunction, Scope,
                expr.Position, expr.Name, expr.TypeArgs, null);
        }
Ejemplo n.º 4
0
        // <-- FN ((Name | Operator) TupleType)
        //      | (LPAREN ParamDecl RPAREN)
        private IUnboundExpr FuncExpr()
        {
            Position position = Consume(TokenType.Fn).Position;

            if (CurrentIs(TokenType.LeftParen))
            {
                // local function
                var paramNames = new List <string>();
                var funcType   = FnArgsDecl(paramNames);
                var body       = Block();

                return(new LocalFuncExpr(position, paramNames, funcType, body));
            }
            else
            {
                // function reference
                NameExpr name;
                if (CurrentIs(TokenType.Operator))
                {
                    Token op = Consume(TokenType.Operator);
                    name = new NameExpr(op.Position, op.StringValue);
                }
                else
                {
                    var token = Consume(TokenType.Name);
                    name = new NameExpr(token.Position, token.StringValue, TypeArgs());
                }

                var          parameters = TupleType().ToArray();
                IUnboundDecl parameter;
                if (parameters.Length == 0)
                {
                    parameter = Decl.Unit;
                }
                else if (parameters.Length == 1)
                {
                    parameter = parameters[0];
                }
                else
                {
                    parameter = new TupleType(parameters);
                }

                return(new FuncRefExpr(position, name, parameter));
            }
        }
Ejemplo n.º 5
0
 public FuncRefExpr(Position position, NameExpr name, IUnboundDecl paramType)
 {
     Position  = position;
     Name      = name;
     ParamType = paramType;
 }
 public virtual IUnboundExpr Transform(NameExpr expr)
 {
     return(expr);
 }
Ejemplo n.º 7
0
 IUnboundExpr IUnboundExprVisitor <IUnboundExpr> .Visit(NameExpr expr)
 {
     return(Call("NameExpr", String(expr.Name)));
 }