public override IRppExpr RewriteCaseClause(RppMember inVar, RppMember outOut, IRppExpr thenExpr, RppMatchingContext ctx) { if (Name == "_") { return Block(Assign(outOut, thenExpr), Break); } throw new NotImplementedException(); }
public override IRppNode Analyze(SymbolTable scope, Diagnostic diagnostic) { Condition = (IRppExpr) Condition.Analyze(scope, diagnostic); ThenExpr = (IRppExpr) ThenExpr.Analyze(scope, diagnostic); ElseExpr = (IRppExpr) ElseExpr.Analyze(scope, diagnostic); Type = ThenExpr.Type; return this; }
/// <summary> /// So we have pattern like this: /// case [Pattern] => [Expr] /// we need to figure out type of [Expr] but it can depend on variables spawned in /// [Pattern], so we need to get thise variables (see RppMatchPattern.DeclareVariables()) /// and add them to the scope and then anaylize [Expr] /// </summary> public override IRppNode Analyze(SymbolTable scope, Diagnostic diagnostic) { Pattern = (RppMatchPattern) Pattern.Analyze(scope, diagnostic); SymbolTable localScope = new SymbolTable(scope); RType inputType = GetInputType(localScope); IEnumerable<IRppExpr> locals = Pattern.DeclareVariables(inputType); NodeUtils.Analyze(localScope, locals, diagnostic); Expr = (IRppExpr) Expr.Analyze(localScope, diagnostic); return this; }
private IRppExpr ProcessCases(RppMember inVar, RppMember outOut, IRppExpr thenExpr, RppMatchingContext ctx, string localOptionVar, int patternIndex) { if (patternIndex >= _patterns.Length) { List<IRppNode> nodes = new List<IRppNode>(); // Binding to a variable if it exists varid@Foo... if (BindedVariableToken != null) { var varId = Val(BindedVariableToken, _type.Value, inVar); nodes.Add(varId); } nodes.Add(thenExpr); nodes.Add(Break); return Block(nodes); } IRppExpr classParamValue = GetClassParam(localOptionVar, patternIndex, _patterns.Length); RppMatchPattern pattern = _patterns[patternIndex]; int nextPatternIndex = patternIndex + 1; if (pattern is RppLiteralPattern) { RppLiteralPattern literalPattern = (RppLiteralPattern) pattern; return If(BinOp("==", literalPattern.Literal, classParamValue), ProcessCases(inVar, outOut, thenExpr, ctx, localOptionVar, nextPatternIndex)); } RType classParamType = _classParamTypes[patternIndex]; if (pattern is RppVariablePattern) { RType patternType = classParamType; RppVar var = Val(pattern.Token.Text, patternType, classParamValue); var.Token = pattern.Token; return Block(var, ProcessCases(inVar, outOut, thenExpr, ctx, localOptionVar, nextPatternIndex)); } if (pattern is RppConstructorPattern) { RppConstructorPattern constructorPattern = (RppConstructorPattern) pattern; string classParamArg = ctx.CreateLocal(classParamType.Name); RppVar classParamArgVar = Val(classParamArg, classParamType, classParamValue); RppId classParamInput = StaticId(classParamArgVar); IRppExpr nextPattern = ProcessCases(inVar, outOut, thenExpr, ctx, localOptionVar, nextPatternIndex); return Block(classParamArgVar, constructorPattern.MatchInstance(classParamInput, outOut, nextPattern, ctx)); } return ProcessCases(inVar, outOut, thenExpr, ctx, localOptionVar, nextPatternIndex); }
private IRppExpr MatchInstance(RppMember inVar, RppMember outOut, IRppExpr thenExpr, RppMatchingContext ctx) { // If type of input variable do not match pattern type, we need to cast it if (!inVar.Type.Equals(_type)) { string localVar = ctx.CreateLocal(_type.Name.Name); var castedVariable = Val(localVar, _type.Value, new RppAsInstanceOf(inVar, _type)); return If(BinOp("!=", new RppAsInstanceOf(inVar, _type), NullTy), Block(castedVariable, ProcessMatchExpr(Id(localVar), outOut, thenExpr, ctx))); } return ProcessMatchExpr(inVar, outOut, thenExpr, ctx); }
public static IRppExpr CastIfNeeded(IRppExpr sourceExpr, RType targetType) { RType sourceType = sourceExpr.Type.Value; if (sourceType.Equals(targetType)) { return sourceExpr; } if (sourceType.IsPrimitive && targetType == RppTypeSystem.AnyTy) { return new RppBox(sourceExpr); } /* if (sourceType.IsValueType && targetType == typeof (object)) { return new RppBox(sourceExpr); } if (IsAssignable(sourceExpr.Type.Runtime, targetType)) { return sourceExpr; } if (sourceExpr.Type.Runtime.IsSubclassOf(targetType)) { return sourceExpr; } */ if (sourceType.IsSubclassOf(targetType)) { return sourceExpr; } if (targetType.IsClass && sourceType == RppTypeSystem.NullTy) { return sourceExpr; } if (sourceType == RppTypeSystem.NothingTy) { return sourceExpr; } throw new Exception("Can't cast expression to a specific type"); }
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); }
public RppAsInstanceOf(IRppExpr value, ResolvableType type) { Value = value; Type = type; }
private static RType ResolveType(IRppExpr param) { return param.Type.Value; }
public RppCaseClause([NotNull] RppMatchPattern pattern, [NotNull] IRppExpr expr) { Pattern = pattern; Expr = expr; }
public abstract IRppExpr RewriteCaseClause(RppMember inVar, RppMember outOut, IRppExpr thenExpr, RppMatchingContext ctx);
private static RppSelector CallSetter(IRppExpr target, RppFieldInfo field, IRppExpr value) { return new RppSelector(target, new RppFuncCall(field.SetterName, List(value))); }
public RppIf([NotNull] IRppExpr condition, [NotNull] IRppExpr thenExpr, [NotNull] IRppExpr elseExpr) { Condition = condition; ThenExpr = thenExpr; ElseExpr = elseExpr; }
private static RppBinOp Eq(IRppExpr left, IRppExpr right) { return RppBinOp.Create("==", left, right); }
private static RppBinOp Sub(IRppExpr left, IRppExpr right) { return RppBinOp.Create("-", left, right); }
public RppLiteralPattern([NotNull] IRppExpr literal) { Literal = literal; }
private static RppBinOp LogicalOr(IRppExpr left, IRppExpr right) { return RppBinOp.Create("||", left, right); }
public override IRppExpr RewriteCaseClause(RppMember inVar, RppMember outOut, IRppExpr thenExpr, RppMatchingContext ctx) { return If(BinOp("==", inVar, Literal), Block(Assign(outOut, thenExpr), Break)); }
public RppWhile(IRppExpr condition, IRppNode body) { Condition = condition; Body = body; Type = ResolvableType.UnitTy; }
private IRppExpr ProcessMatchExpr(RppMember inVar, RppMember outOut, IRppExpr thenExpr, RppMatchingContext ctx) { string localOptionVar = ctx.CreateLocalOption(); RppVar localOption = Val(localOptionVar, _unapplyMethod.ReturnType, CallMethod(_type.Value.Name, _unapplyMethod.Name, inVar)); return Block(localOption, If(GetIsValidExpression(localOption), ProcessCases(inVar, outOut, thenExpr, ctx, localOptionVar, 0))); }
private static void TestExpr(string code, IRppExpr expected) { var parser = ParserTest.CreateParser(code); IRppExpr expr = parser.ParseExpr(); Assert.AreEqual(expected, expr); }
public static RppIf If(IRppExpr condition, IRppExpr thenExpr, IRppExpr elseExpr) { return new RppIf(condition, thenExpr, elseExpr); }
private static RppBinOp Add(IRppExpr left, IRppExpr right) { return RppBinOp.Create("+", left, right); }
public RppField(MutabilityFlag mutabilityFlag, string name, HashSet<ObjectModifier> modifiers, ResolvableType type, IRppExpr initExpr) : base(mutabilityFlag, name, type, initExpr) { Modifiers = modifiers; IsLocalSemantic = false; }
private static RppBinOp Mult(IRppExpr left, IRppExpr right) { return RppBinOp.Create("*", left, right); }
public override IRppExpr RewriteCaseClause(RppMember inVar, RppMember outOut, IRppExpr thenExpr, RppMatchingContext ctx) { return MatchInstance(inVar, outOut, Assign(outOut, thenExpr), ctx); }
private static RppUnary Not(IRppExpr expr) { return new RppUnary("!", expr); }
public RppMatch(IRppExpr value, [NotNull] IEnumerable<RppCaseClause> caseClauses) { Value = value; CaseClauses = caseClauses; }
private static RppSelector Selector(IRppExpr expr, RppMember member) { return new RppSelector(expr, member); }
public static RppIf If(IRppExpr condition, IRppExpr thenExpr) { return If(condition, thenExpr, RppEmptyExpr.Instance); }