コード例 #1
0
ファイル: RppProgram.cs プロジェクト: dubik/csharprpp
 private static RppFunc CreateApply(RTypeName className, IEnumerable<ResolvableType> classParams)
 {
     int paramIndex = 0;
     IEnumerable<IRppParam> funcParams = classParams.Select(t => new RppParam($"_{paramIndex++}", t)).ToList();
     RppNew newExpr = new RppNew(new ResolvableType(className), funcParams.Select(p => new RppId(p.Name, p)));
     return new RppFunc("apply", funcParams, new ResolvableType(className), newExpr);
 }
コード例 #2
0
ファイル: RppProgram.cs プロジェクト: dubik/csharprpp
        private static RppClass CreateCompanion(string name, IEnumerable<RppField> classParamsCollection)
        {
            RTypeName typeName = new RTypeName(name);
            IEnumerable<RppField> classParams = classParamsCollection as IList<RppField> ?? classParamsCollection.ToList();
            var classParamsTypes = classParams.Select(p => p.Type).ToList();
            RppFunc apply = CreateApply(typeName, classParamsTypes);
            RppFunc unapply = CreateUnapply(typeName, classParams);
            var exprs = List(apply, unapply);
            RppClass clazz = new RppClass(ClassKind.Object, new HashSet<ObjectModifier>(), name, Collections.NoFields, exprs,
                Collections.NoVariantTypeParams,
                RppBaseConstructorCall.Object);

            return clazz;
        }
コード例 #3
0
ファイル: RppProgram.cs プロジェクト: dubik/csharprpp
 private static RTypeName CreateTupleType(IEnumerable<string> names)
 {
     IEnumerable<string> typeNames = names as IList<string> ?? names.ToList();
     string tupleTypeNameString = "Tuple" + typeNames.Count();
     RTypeName tuppleType = new RTypeName(tupleTypeNameString);
     typeNames.Select(n => new RTypeName(n)).ForEach(tuppleType.AddGenericArgument);
     return tuppleType;
 }
コード例 #4
0
ファイル: RppProgram.cs プロジェクト: dubik/csharprpp
        private static ResolvableType CreateUnapplyReturnType(IEnumerable<string> typeNames)
        {
            IEnumerable<string> names = typeNames as IList<string> ?? typeNames.ToList();
            if (!names.Any())
            {
                return ResolvableType.BooleanTy;
            }

            if (names.Count() == 1)
            {
                RTypeName optionType = new RTypeName("Option");
                optionType.AddGenericArgument(new RTypeName(names.First()));
                return new ResolvableType(optionType);
            }
            else
            {
                RTypeName optionType = new RTypeName("Option");
                RTypeName tuppleType = CreateTupleType(names);
                optionType.AddGenericArgument(tuppleType);
                return new ResolvableType(optionType);
            }
        }
コード例 #5
0
ファイル: RppParser.cs プロジェクト: dubik/csharprpp
 private static RTypeName CreateTupleTypeName(ICollection<RTypeName> paramTypes)
 {
     RTypeName tupleType = new RTypeName(CreateTupleClassName(paramTypes.Count));
     paramTypes.ForEach(tupleType.AddGenericArgument);
     return tupleType;
 }
コード例 #6
0
ファイル: RppParser.cs プロジェクト: dubik/csharprpp
 private static bool IsAction(RTypeName returnType)
 {
     return returnType.Name.Equals("Unit");
 }
コード例 #7
0
ファイル: RppParser.cs プロジェクト: dubik/csharprpp
 /// <summary>
 /// Creates Function[paramCount] type name if return type is not Unit.
 /// If it's Unit then it creates Action[paramCount].
 /// </summary>
 private static RTypeName CreateClosureTypeName(ICollection<RTypeName> paramTypes, RTypeName returnType)
 {
     bool isAction = IsAction(returnType);
     string baseTypeName = isAction ? "Action" : "Function";
     RTypeName closureType = new RTypeName(baseTypeName + paramTypes.Count);
     paramTypes.ForEach(closureType.AddGenericArgument);
     if (!isAction)
     {
         closureType.AddGenericArgument(returnType);
     }
     return closureType;
 }
コード例 #8
0
ファイル: RppParser.cs プロジェクト: dubik/csharprpp
        // Consume follow is needed to handle pattern matching case:
        // case x: Foo => x.length
        // without consumeFollow false it will parse and closure type (Foo => x) which is incorrect
        public bool ParseType(out RTypeName type, bool consumeFollow = true)
        {
            if (Require(RppLexer.Id))
            {
                IToken typeNameToken = _lastToken;
                if (Require(RppLexer.OP_LBracket))
                {
                    RTypeName genericType = new RTypeName(typeNameToken);
                    type = genericType;

                    RTypeName subType;
                    if (!ParseType(out subType))
                    {
                        RaiseSyntaxError("Type is expected");
                    }

                    genericType.AddGenericArgument(subType);

                    while (true)
                    {
                        if (Require(RppLexer.OP_RBracket))
                        {
                            break;
                        }

                        if (Require(RppLexer.OP_Comma))
                        {
                            if (!ParseType(out subType))
                            {
                                RaiseSyntaxError("Type is expected");
                            }

                            genericType.AddGenericArgument(subType);
                        }
                        else
                        {
                            RaiseSyntaxError("Expected comma");
                        }
                    }

                    return true;
                }

                // A => B
                if (consumeFollow && Require(RppLexer.OP_Follow))
                {
                    RTypeName returnType;
                    if (!ParseType(out returnType))
                    {
                        RaiseSyntaxError("Type is expected");
                    }

                    type = CreateClosureTypeName(new List<RTypeName> {new RTypeName(typeNameToken)}, returnType);
                    return true;
                }

                type = new RTypeName(typeNameToken);
                return true;
            }

            // (A, B) => C
            // (A => B)
            if (Require(RppLexer.OP_LParen))
            {
                bool closingParenRequired = true;
                RTypeName returnType;
                IList<RTypeName> paramTypes = new List<RTypeName>();
                while (true)
                {
                    if (Require(RppLexer.OP_RParen))
                    {
                        closingParenRequired = false;
                        break;
                    }

                    if (Peek(RppLexer.OP_Follow))
                    {
                        break;
                    }

                    if (paramTypes.Count > 0)
                    {
                        Expect(RppLexer.OP_Comma);
                    }

                    RTypeName paramType;
                    if (ParseType(out paramType))
                    {
                        paramTypes.Add(paramType);
                    }
                    else
                    {
                        RaiseSyntaxError("Type is expected");
                    }
                }

                if (!Require(RppLexer.OP_Follow))
                {
                    // (A => A)
                    if (paramTypes.Count == 1)
                    {
                        type = paramTypes[0];
                        return true;
                    }

                    // (A, B, C)
                    type = CreateTupleTypeName(paramTypes);
                    return true;
                }

                if (!ParseType(out returnType))
                {
                    RaiseSyntaxError("Type is expected");
                }

                if (closingParenRequired)
                {
                    Expect(RppLexer.OP_RParen);
                }

                type = CreateClosureTypeName(paramTypes, returnType);
                return true;
            }

            type = null;
            return false;
        }
コード例 #9
0
 public RppVariantTypeParam([NotNull] string name, TypeVariant variant, [CanBeNull] RTypeName constraintTypeName) : base(name)
 {
     Variant = variant;
     _constraint = constraintTypeName;
 }
コード例 #10
0
ファイル: RppParser.cs プロジェクト: dubik/csharprpp
        private bool ParseVariantTypeParam(out RppVariantTypeParam typeParam)
        {
            TypeVariant variant = TypeVariant.Invariant; // "A"
            bool requireId = false;
            if (Require(RppLexer.OP_Unary))
            {
                if (_lastToken.Text == "+") // "+A"
                {
                    variant = TypeVariant.Covariant;
                }
                else if (_lastToken.Text == "-") // "-A"
                {
                    variant = TypeVariant.Contravariant;
                }
                else
                {
                    RaiseSyntaxError("Expected '+' or '-'");
                }

                requireId = true;
            }

            if (Require(RppLexer.Id))
            {
                string typeParamName = _lastToken.Text;
                RTypeName constraint = null;
                if (Require(RppLexer.OP_Upper))
                {
                    Expect(RppLexer.Id);
                    constraint = new RTypeName(_lastToken);
                }

                typeParam = new RppVariantTypeParam(typeParamName, variant, constraint);
                return true;
            }

            if (requireId)
            {
                RaiseSyntaxError("Expected identifier");
            }

            typeParam = null;
            return false;
        }
コード例 #11
0
ファイル: ResolvableType.cs プロジェクト: dubik/csharprpp
 private static RTypeName Reconstruct(RType type)
 {
     RTypeName typeName = new RTypeName(type.Name);
     type.GenericArguments.ForEach(ga => typeName.AddGenericArgument(Reconstruct(ga)));
     return typeName;
 }
コード例 #12
0
ファイル: ResolvableType.cs プロジェクト: dubik/csharprpp
 public ResolvableType([NotNull] RType type)
 {
     _type = type;
     Name = new RTypeName(type.Name); // TODO this doesn't work for generics
 }
コード例 #13
0
ファイル: RTypeName.cs プロジェクト: dubik/csharprpp
 protected bool Equals(RTypeName other)
 {
     // TODO need to Equals also generic params
     return string.Equals(Name, other.Name);
 }
コード例 #14
0
ファイル: RTypeName.cs プロジェクト: dubik/csharprpp
 public void AddGenericArgument(RTypeName genericArgument)
 {
     _params.Add(genericArgument);
 }
コード例 #15
0
ファイル: AstHelper.cs プロジェクト: dubik/csharprpp
 public static RppParam Param(string name, RTypeName typeName)
 {
     return new RppParam(name, new ResolvableType(typeName));
 }
コード例 #16
0
ファイル: RppParser.cs プロジェクト: dubik/csharprpp
        public IList<IRppNode> ParseClassTemplateOpt(out RTypeName baseClassType, out IList<IRppExpr> constrArgs)
        {
            baseClassType = null;
            constrArgs = Collections.NoExprs;
            if (Require(RppLexer.KW_Extends))
            {
                if (Require(RppLexer.Id))
                {
                    baseClassType = new RTypeName(_lastToken);
                }
                else
                {
                    RaiseSyntaxError("Expected identifier");
                }

                IList<RTypeName> typeArgs = ParseTypeParamClause();
                typeArgs.ForEach(baseClassType.AddGenericArgument);
                var args = ParseArgsOpt();
                constrArgs = args;
            }

            return ParseTemplateBody();
        }
コード例 #17
0
ファイル: RppTypedPattern.cs プロジェクト: dubik/csharprpp
 public RppTypedPattern(IToken varid, RTypeName typeName)
 {
     Token = varid;
     Name = varid.Text;
     _resolvableType = new ResolvableType(typeName);
 }