protected bool Equals(ResolvableType other) { if (_type != null && other._type != null) return _type.Equals(other._type); return Name.Equals(other.Name); }
public override IRppNode Analyze(SymbolTable scope, Diagnostic diagnostic) { // TODO should be unified with RppFuncCall and rethink how types for closures are figureout. // we should use constraints and type inference only, not this kind of hacks when we check target // closure signature and use types from there // Skip closures because they may have missing types _arguments = NodeUtils.AnalyzeWithPredicate(scope, _arguments, node => !(node is RppClosure), diagnostic); Type.Resolve(scope); RType targetType = Type.Value; if (NeedToInferGenericArguments(targetType)) { RType inferredTargetType; Constructor = FindGenericConstructor(targetType, out inferredTargetType); Type = new ResolvableType(inferredTargetType); } else { Constructor = FindConstructor(targetType); } _arguments = RppFuncCall.ReplaceUndefinedClosureTypesIfNeeded(_arguments, Constructor.Parameters, new List<RType>()); NodeUtils.AnalyzeWithPredicate(scope, _arguments, node => node is RppClosure, diagnostic); return this; }
public override IRppNode Analyze(SymbolTable scope, Diagnostic diagnostic) { RType thisType = scope.GetEnclosingType(); if (thisType == null) { throw new Exception("Can't find enclosing type for this"); } Type = new ResolvableType(thisType); return this; }
public override IRppNode Analyze(SymbolTable scope, Diagnostic diagnostic) { if (TargetType == null) { throw new Exception("TargetType should be specified before anaylyze is called"); } RType classType = TargetType; // TODO It's kinda weird to have resolution here and not in the scope, because similar // lookup is done for methods while (classType != null && Field == null) { Field = classType.Fields.FirstOrDefault(f => f.Name == Name); if (Field != null) { break; } classType = classType.BaseType; } if (Field == null) { var functions = scope.LookupFunction(Name); if (functions.Any(f => f.Parameters.IsEmpty())) { RppFuncCall funcCall = new RppFuncCall(Name, Collections.NoExprs); return funcCall.Analyze(scope, diagnostic); } throw SemanticExceptionFactory.ValueIsNotMember(Token, TargetType.ToString()); } Debug.Assert(classType != null, "obj != null"); Type = new ResolvableType(Field.Type); return this; }
public override IRppNode Analyze(SymbolTable scope, Diagnostic diagnostic) { Value = (IRppExpr) Value.Analyze(scope, diagnostic); RppVar declIn = new RppVar(MutabilityFlag.MfVal, "<in>", Value.Type, Value); declIn.Analyze(scope, diagnostic); CaseClauses = NodeUtils.Analyze(scope, CaseClauses, diagnostic); Type = CheckCommonType(CaseClauses, Token).AsResolvable(); RppVar declOut = new RppVar(MutabilityFlag.MfVar, "<out>", Type, new RppDefaultExpr(Type)); RppId declInId = new RppId("<in>", declIn); declInId.Analyze(scope, diagnostic); RppId declOutId = new RppId("<out>", declOut); RppMatchingContext ctx = new RppMatchingContext(); var ifC = Create(declInId, declOutId, CaseClauses, ctx); var expr = new RppBlockExpr(List<IRppNode>(declIn, ifC)) {Exitable = true}; SymbolTable matchScope = new SymbolTable(scope); RppBlockExpr matchBlock = new RppBlockExpr(List<IRppNode>(declOut, expr, declOutId)); return matchBlock.Analyze(matchScope, diagnostic); }
protected RppPop() { Type = ResolvableType.NothingTy; }
public static IRppExpr ReplaceUndefinedClosureTypesIfNeeded([NotNull] IRppExpr expr, ResolvableType targetType, IList<RType> genericArgs) { if (expr is RppClosure) { RppClosure closure = (RppClosure) expr; var hasUndefinedClosureBinding = closure.Bindings.Any(b => b.Type.IsUndefined()); if (targetType.IsDefined() && hasUndefinedClosureBinding) { RType type = targetType.Value; if (genericArgs.NonEmpty()) { // Substitute generics parameters with specified generic arguments // def func[A,U]()... // func[Int, Float]()... // Function1[!!A, !!U] -> Function1[Int, Float] type = type.MakeGenericType(genericArgs.ToArray()); } IReadOnlyCollection<RType> genericArguments = type.GenericArguments; List<IRppParam> newBindings = genericArguments.Zip(closure.Bindings, (varTypeGenArg, binding) => binding.CloneWithNewType(varTypeGenArg)).ToList(); return new RppClosure(newBindings, closure.Expr); } } return expr; }
public RppAsInstanceOf(IRppExpr value, ResolvableType type) { Value = value; Type = type; }
public RppField(MutabilityFlag mutabilityFlag, string name, HashSet<ObjectModifier> modifiers, ResolvableType type, IRppExpr initExpr) : base(mutabilityFlag, name, type, initExpr) { Modifiers = modifiers; IsLocalSemantic = false; }
public RppField(MutabilityFlag mutabilityFlag, string name, HashSet<ObjectModifier> modifiers, ResolvableType type) : base(mutabilityFlag, name, type, RppEmptyExpr.Instance) { Modifiers = modifiers; IsLocalSemantic = false; }
private RppClass ParseObjectDef(HashSet<ObjectModifier> modifiers) { Expect(RppLexer.Id); string objectName = _lastToken.Text; RTypeName baseClassTypeName; IList<IRppExpr> baseClassArgs; IList<IRppNode> stats = ParseClassTemplateOpt(out baseClassTypeName, out baseClassArgs); ResolvableType baseClass = ResolvableType.AnyTy; if (baseClassTypeName != null) { baseClass = new ResolvableType(baseClassTypeName); } return new RppClass(ClassKind.Object, modifiers, objectName, Collections.NoFields, stats, Collections.NoVariantTypeParams, new RppBaseConstructorCall(baseClass, Collections.NoExprs)); }
private bool ParseBinding(out RppParam binding) { binding = null; if (!Require(RppLexer.Id)) { return false; } string name = _lastToken.Text; ResolvableType type = ResolvableType.UndefinedTy; if (Require(RppLexer.OP_Colon)) { RTypeName typeName; if (!ParseType(out typeName)) { RaiseSyntaxError("Type is expected"); } type = new ResolvableType(typeName); } binding = new RppParam(name, type) {IsClosureBinding = true}; return true; }
// ClassDef ::= id [TypeParamClause] {Annotation} [AccessModifier] ClassParamClauses ClassTemplateOpt public RppClass ParseClassDef(HashSet<ObjectModifier> modifiers) { if (Require(RppLexer.Id)) { string name = _lastToken.Text; IList<RppVariantTypeParam> typeParams = ParseTypeParams(); IList<RppField> classParams = ParseClassParamClause(); IList<IRppExpr> baseClassArgs; RTypeName baseClassTypeName; IList<IRppNode> nodes = ParseClassTemplateOpt(out baseClassTypeName, out baseClassArgs); ResolvableType baseClass = ResolvableType.AnyTy; if (baseClassTypeName != null) { baseClass = new ResolvableType(baseClassTypeName); } return new RppClass(ClassKind.Class, modifiers, name, classParams, nodes, typeParams, new RppBaseConstructorCall(baseClass, baseClassArgs)); } RaiseSyntaxError("Expected identifier but got : "); return null; }
public RppTypedPattern(IToken varid, RTypeName typeName) { Token = varid; Name = varid.Text; _resolvableType = new ResolvableType(typeName); }
public RppConstructorPattern(ResolvableType typeName, IEnumerable<RppMatchPattern> patterns) { _type = typeName; _patterns = patterns.ToArray(); }
public RppThrow(IRppExpr expr) { Expr = expr; Type = ResolvableType.NothingTy; }
public RppWhile(IRppExpr condition, IRppNode body) { Condition = condition; Body = body; Type = ResolvableType.UnitTy; }
public RppClass(ClassKind kind, HashSet<ObjectModifier> modifiers, [NotNull] string name, [NotNull] IList<RppField> classParams, [NotNull] IEnumerable<IRppNode> classBody, [NotNull] IList<RppVariantTypeParam> typeParams, RppBaseConstructorCall baseConstructorCall) : base(name) { Kind = kind; BaseConstructorCall = baseConstructorCall; _classParams = classParams; // TODO all of this can be simplified, we don't need to separate body of class. We can just walk rpp nodes with visitors IEnumerable<IRppNode> rppNodes = classBody as IList<IRppNode> ?? classBody.ToList(); _funcs = rppNodes.OfType<RppFunc>().Where(f => !f.IsConstructor).ToList(); _funcs.ForEach(DefineFunc); var constrExprs = rppNodes.OfType<IRppExpr>().Where(n => !(n is RppField)).ToList(); // TODO for some reason RppField is also IRppExpr, I think it shouldn't be _typeParams = typeParams; Modifiers = modifiers; _constructors = rppNodes.OfType<RppFunc>().Where(f => f.IsConstructor).ToList(); _fields = _classParams.Where(param => param.MutabilityFlag != MutabilityFlag.MfUnspecified || IsCase).ToList(); rppNodes.OfType<RppField>().ForEach(_fields.Add); var primaryConstructor = CreatePrimaryConstructor(constrExprs); _constructors.Add(primaryConstructor); CreateProperties(); if (kind == ClassKind.Object) { string objectName = SymbolTable.GetObjectName(Name); ResolvableType instanceFieldType = new ResolvableType(new RTypeName(objectName)); InstanceField = new RppField(MutabilityFlag.MfVal, "_instance", Collections.NoModifiers, instanceFieldType, new RppNew(instanceFieldType, Collections.NoExprs)); _fields.Add(InstanceField); } _nested = rppNodes.OfType<RppClass>().ToList(); }
public static RppNew New(ResolvableType type, IEnumerable<IRppExpr> args) { return new RppNew(type, args); }