public IInterpreter IfBranches() { var interpreter = new Interpreter.Interpreter(); foreach (var mutability in Options.AllMutabilityModes) { var env = Language.Environment.Create(new Options() { AllowInvalidMainResult = true }.SetMutability(mutability)); var root_ns = env.Root; var main_func = root_ns.AddBuilder(FunctionBuilder.Create( "main", ExpressionReadMode.OptionalUse, NameFactory.Int64NameReference(), Block.CreateStatement(new IExpression[] { IfBranch.CreateIf(BoolLiteral.CreateFalse(), new[] { Return.Create(Int64Literal.Create("5")) }, IfBranch.CreateElse(new[] { Return.Create(Int64Literal.Create("2")) })) }))); ExecValue result = interpreter.TestRun(env); Assert.AreEqual(2L, result.RetValue.PlainValue); } return(interpreter); }
public IErrorReporter ScopeShadowing() { NameResolver resolver = null; foreach (var mutability in Options.AllMutabilityModes) { var env = Environment.Create(new Options() { ScopeShadowing = true, DiscardingAnyExpressionDuringTests = true }.SetMutability(mutability)); var root_ns = env.Root; root_ns.AddBuilder(FunctionBuilder.Create( "anything", null, ExpressionReadMode.OptionalUse, NameFactory.UnitNameReference(), Block.CreateStatement(new IExpression[] { VariableDeclaration.CreateStatement("x",null,Int64Literal.Create("2")), Block.CreateStatement(new IExpression[]{ // shadowing VariableDeclaration.CreateStatement("x", null, BoolLiteral.CreateFalse()), VariableDeclaration.CreateStatement("a",NameFactory.BoolNameReference(),NameReference.Create("x")), ExpressionFactory.Readout("a"), }), VariableDeclaration.CreateStatement("b",NameFactory.Int64NameReference(),NameReference.Create("x")), ExpressionFactory.Readout("b"), }))); resolver = NameResolver.Create(env); Assert.AreEqual(0, resolver.ErrorManager.Errors.Count); } return resolver; }
public IErrorReporter ErrorCannotInferResultType() { NameResolver resolver = null; foreach (var mutability in Options.AllMutabilityModes) { var env = Environment.Create(new Options() { DiscardingAnyExpressionDuringTests = true }.SetMutability(mutability)); var root_ns = env.Root; IExpression lambda = FunctionBuilder.CreateLambda(null, Block.CreateStatement(new IExpression[] { IfBranch.CreateIf(BoolLiteral.CreateFalse(), new[] { Return.Create(BoolLiteral.CreateTrue()) }), Return.Create(Int64Literal.Create("2")) })).Build(); root_ns.AddBuilder(FunctionBuilder.Create("me", ExpressionReadMode.OptionalUse, NameFactory.UnitNameReference(), Block.CreateStatement(new IExpression[] { // f = () => x VariableDeclaration.CreateStatement("f", null, lambda), ExpressionFactory.Readout("f") }))); resolver = NameResolver.Create(env); Assert.AreEqual(1, resolver.ErrorManager.Errors.Count); Assert.IsTrue(resolver.ErrorManager.HasError(ErrorCode.CannotInferResultType, lambda)); } return(resolver); }
public IInterpreter ShortcutComputationInOptionalDeclaration() { var interpreter = new Interpreter.Interpreter(); foreach (var mutability in Options.AllMutabilityModes) { // purpose: check if RHS of the optional declaration is computed only when it is needed // here we count RHS computations and since we declare two variables // let (x,y) =? (None,Some) // Some should not be executed, because `x` assigment fails first var env = Language.Environment.Create(new Options() { DebugThrowOnError = true, DiscardingAnyExpressionDuringTests = true, }.SetMutability(mutability)); var root_ns = env.Root; root_ns.AddBuilder(TypeBuilder.Create("Mutator") .SetModifier(EntityModifier.Mutable) .With(VariableDeclaration.CreateStatement("c", NameFactory.IntNameReference(), null, env.Options.ReassignableModifier() | EntityModifier.Public))); // return Some or None depending on the `f` parameter, and also increments the count of option evaluations root_ns.AddBuilder(FunctionBuilder.Create("give", NameFactory.OptionNameReference(NameFactory.Nat8NameReference()), Block.CreateStatement( ExpressionFactory.Inc(() => NameReference.Create("m", "c")), Return.Create(ExpressionFactory.Ternary(NameReference.Create("f"), ExpressionFactory.OptionOf(NameFactory.Nat8NameReference(), Nat8Literal.Create("11")), ExpressionFactory.OptionEmpty(NameFactory.Nat8NameReference()))) )) .Parameters(FunctionParameter.Create("f", NameFactory.BoolNameReference()), FunctionParameter.Create("m", NameFactory.ReferenceNameReference(NameReference.Create("Mutator"))))); IExpression opt_declaration = ExpressionFactory.OptionalDeclaration(new[] { VariablePrototype.Create("x", NameFactory.Nat8NameReference()), VariablePrototype.Create("y", NameFactory.Nat8NameReference()) }, new[] { FunctionCall.Create("give", BoolLiteral.CreateFalse(), NameReference.Create("mut")), FunctionCall.Create("give", BoolLiteral.CreateTrue(), NameReference.Create("mut")), }); root_ns.AddBuilder(FunctionBuilder.Create("main", ExpressionReadMode.OptionalUse, NameFactory.Nat8NameReference(), Block.CreateStatement( VariableDeclaration.CreateStatement("mut", null, ExpressionFactory.StackConstructor(NameReference.Create("Mutator"))), IfBranch.CreateIf(opt_declaration, new[] { ExpressionFactory.Readout("x"), ExpressionFactory.Readout("y"), ExpressionFactory.GenericThrow(), }, IfBranch.CreateElse( // crucial check -- we should not evaluate the second option ExpressionFactory.AssertEqual(IntLiteral.Create("1"), NameReference.Create("mut", "c")) )), Return.Create(Nat8Literal.Create("0")) ))); ExecValue result = interpreter.TestRun(env); Assert.AreEqual((byte)0, result.RetValue.PlainValue); } return(interpreter); }
public static IExpression OptionalAssignment(IEnumerable <IExpression> lhsExpressions, IEnumerable <IExpression> rhsExpressions) { // todo: add support for spread if (lhsExpressions.Count() != rhsExpressions.Count()) { throw new NotImplementedException(); } // please note we could have dummy assignments in form // _ ?= x // in such case we are not interested in the assigment but the fact it was sucessful or not lhsExpressions = lhsExpressions.Select(lhs => lhs is NameReference lhs_name && lhs_name.IsSink ? null : lhs); var temp_names = new List <string>(); IExpression condition = null; foreach (Tuple <IExpression, IExpression> pair in rhsExpressions.SyncZip(lhsExpressions)) { IExpression rhs = pair.Item1; IExpression lhs = pair.Item2; IExpression opt; if (lhs == null) { temp_names.Add(null); opt = rhs; } else { string temp = AutoName.Instance.CreateNew("optassign"); temp_names.Add(temp); opt = VariableDeclaration.CreateExpression(temp, null, rhs); } IExpression curr = NameReference.Create(opt, BrowseMode.Decompose, NameFactory.OptionHasValue); if (condition == null) { condition = curr; } else { condition = And(condition, curr); } } var success_body = new List <IExpression>(); { foreach (Tuple <IExpression, string> pair in lhsExpressions.SyncZip(temp_names)) { IExpression lhs = pair.Item1; string temp = pair.Item2; if (lhs != null) { success_body.Add(Assignment.CreateStatement(lhs, NameReference.Create(NameReference.Create(temp), BrowseMode.Decompose, NameFactory.OptionValue))); } } success_body.Add(BoolLiteral.CreateTrue()); } IfBranch result = IfBranch.CreateIf(condition, success_body, IfBranch.CreateElse(BoolLiteral.CreateFalse())); return(result); }