public async Task RunYolol([Remainder] string input) { var code = input.ExtractYololCodeBlock(); if (code == null) { await ReplyAsync(@"Failed to parse a yolol program from message - ensure you have enclosed your solution in triple backticks \`\`\`like this\`\`\`"); return; } var result = Yolol.Grammar.Parser.ParseProgram(code); if (!result.IsOk) { await ReplyAsync(result.Err.ToString()); return; } var network = new DefaultValueDeviceNetwork(); var state = new MachineState(network); var done = state.GetVariable(":done"); // Run lines until completion indicator is set or execution time limit is exceeded var limit = 0; var pc = 0; while (!done.Value.ToBool() && limit++ < 2000) { try { // If line if blank, just move to the next line if (pc >= result.Ok.Lines.Count) { pc++; } else { pc = result.Ok.Lines[pc].Evaluate(pc, state); } } catch (ExecutionException) { pc++; } // loop around if program counter goes over max if (pc >= 20) { pc = 0; } } // Print out the final machine state var embed = state.ToEmbed(network, limit, pc + 1).Build(); await ReplyAsync(embed : embed); }
public override ExecutionResult Evaluate(MachineState state) { var var = state.GetVariable(Left.Name); var.Value = Right.Evaluate(state); return(new ExecutionResult()); }
public void ExternalVariable() { var n = new ConstantNetwork(); n.Get("name").Value = new Value(13); var s = new MachineState(n, new DefaultIntrinsics()); Assert.AreEqual(13, s.GetVariable(":name").Value.Number); }
public void ExternalVariable() { var n = new ConstantNetwork(); n.Get("name").Value = new Value((Number)13); var s = new MachineState(n); Assert.AreEqual((Number)13, s.GetVariable(":name").Value.Number); }
public void Enumerate() { var s = new MachineState(new ConstantNetwork(), new DefaultIntrinsics()); s.GetVariable("name"); var arr = s.ToArray(); Assert.AreEqual(1, arr.Length); }
public override Value Evaluate(MachineState state) { var variable = state.GetVariable(Name); var original = variable.Value; var modified = Evaluate(original, state.MaxStringLength); variable.Value = modified; return(PreOp ? modified : original); }
public override Value Evaluate(MachineState state) { var variable = state.GetVariable(Name); var original = variable.Value; var modified = Modify(original); variable.Value = modified; return(Return(original, modified)); }
public void ZijkhalBoolDivision() { const string code = "a=-9223372036854775.808 c=a/1"; var ast = TestHelpers.Parse(code); var st = new MachineState(new NullDeviceNetwork(), 20); ast.Lines[0].Evaluate(1, st); var ms = TestHelpers.Test(code); Assert.AreEqual(st.GetVariable("c").Value, ms.GetVariable("c")); }
public override Failure?CheckCase(IReadOnlyDictionary <string, Value> inputs, IReadOnlyDictionary <string, Value> expectedOutputs, MachineState state) { // Check that the machine state is exactly correct for every expected output foreach (var(key, expected) in expectedOutputs) { var actual = state.GetVariable($":{key}").Value; // Add bonus points averaged across all cases AddBonusAveragedPoints((expected.Type, actual.Type) switch { (Type.Number, Type.Number) => AccuracyScore(expected.Number, actual.Number), (Type.String, Type.String) => AccuracyScore(expected.String, actual.String), _ => 0, });
public virtual Failure?CheckCase(IReadOnlyDictionary <string, Value> inputs, IReadOnlyDictionary <string, Value> expectedOutputs, MachineState state) { // Check that the machine state is exactly correct for every expected output foreach (var(key, value) in expectedOutputs) { var v = state.GetVariable($":{key}"); if ((v.Value != value).ToBool()) { var ii = string.Join(",", inputs.Select(b => $"`:{b.Key}={b.Value.ToHumanString()}`")); var oo = string.Join(",", expectedOutputs.Select(b => $"`:{b.Key}={b.Value.ToHumanString()}`")); return(new Failure(FailureType.IncorrectResult, $"For inputs {ii} expected outputs {oo}, got `{v.Value.ToHumanString()}` for `:{key}`")); } } // All variables ok, return null to indicate no failure return(null); }
public override Value Evaluate(MachineState state) { return(state.GetVariable(_var.Name).Value); }
public async Task <(Success?, Failure?)> Verify(Challenge.Challenge challenge, string yolol) { await Task.CompletedTask; IScore scoreMode = challenge.ScoreMode switch { ScoreMode.BasicScoring => new BasicScoring(), ScoreMode.Approximate => new ApproximateScoring(), ScoreMode.Unknown => throw new InvalidOperationException("Cannot use `Unknown` score mode (challenge is broken - contact Martin#2468)"), _ => throw new NotImplementedException($"Score mode `{challenge.ScoreMode}` is not implemented") }; // Retrieve the test cases for the challenge var(inputs, outputs) = GetTests(challenge); // Check input program fits within 20x70 var lines = yolol.Split("\n"); if (lines.Length > 20 || lines.Any(l => l.Length > 70)) { return(null, new Failure(FailureType.ProgramTooLarge, null)); } // parse the program var result = Parser.ParseProgram(yolol); if (!result.IsOk) { return(null, new Failure(FailureType.ParseFailed, result.Err.ToString())); } var entry = result.Ok; // Get the variable which the program uses to indicate it is ready to move to the next round var state = new MachineState(new DefaultValueDeviceNetwork()); var done = state.GetVariable($":{challenge.CheckIndicator}"); // Begin counting how long it takes to verify (for profiling purposes) var timer = new Stopwatch(); timer.Start(); // Run through test cases one by one var overflowIters = _config.MaxItersOverflow; var totalRuntime = 0u; var pc = 0; for (var i = 0; i < Math.Min(inputs.Count, outputs.Count); i++) { // Set inputs var input = inputs[i]; foreach (var(key, value) in input) { state.GetVariable($":{key}").Value = value; } // Clear completion indicator done.Value = 0; // Run lines until completion indicator is set or execution time limit is exceeded var limit = 0; while (!done.Value.ToBool()) { // Check if this test has exceed it's time limit if (limit++ > _config.MaxTestIters) { //If so use iterations from the overflow pool overflowIters--; //Once the overflow pool is empty too, fail if (overflowIters <= 0) { return(null, new Failure(FailureType.RuntimeTooLong, null)); } } totalRuntime++; try { // If line if blank, just move to the next line if (pc >= entry.Lines.Count) { pc++; } else { pc = entry.Lines[pc].Evaluate(pc, state); } } catch (ExecutionException) { pc++; } // loop around if program counter goes over max if (pc >= 20) { pc = 0; } } // Check this test case with the current scoring mode var scoreFailure = scoreMode.CheckCase(input, outputs[i], state); if (scoreFailure != null) { return(null, scoreFailure); } } Console.WriteLine($"Verified {totalRuntime} ticks, {timer.ElapsedMilliseconds}ms runtime"); // Calculate score var codeLength = yolol.Replace("\n", "").Length; var score = scoreMode.FinalizeScore( (uint)inputs.Count, totalRuntime, codeLength ); return(new Success((uint)score, (uint)totalRuntime, (uint)codeLength), null); }
public Value GetVariable(string v) { return(_machineState.GetVariable(v).Value); }
public static void Compare(Program ast, int ticks) { // Compile setup var ext = new ExternalsMap(); var lines = Math.Max(20, ast.Lines.Count); var compiled = ast.Compile(ext, lines); var internals = new Value[compiled.InternalsMap.Count]; Array.Fill(internals, new Value((Number)0)); var externals = new Value[ext.Count]; Array.Fill(externals, new Value((Number)0)); // Interpret setup var maxLines = Math.Max(20, ast.Lines.Count); int CheckPc(int pc) { if (pc >= maxLines) { return(0); } if (pc < 0) { return(0); } return(pc); } var pc = 0; var nt = new DeviceNetwork(); var st = new MachineState(nt, (ushort)maxLines); for (var i = 0; i < ticks; i++) { if (pc >= ast.Lines.Count) { pc++; } else { try { pc = ast.Lines[pc].Evaluate(pc, st); } catch (ExecutionException) { pc++; } } pc = CheckPc(pc); compiled.Tick(internals, externals); foreach (var item in compiled.InternalsMap) { var interpretedVal = st.GetVariable(item.Key.Name).Value; var compiledVal = internals[item.Value]; Assert.AreEqual(interpretedVal, compiledVal, $"varname:{item.Key} ticks:{i}"); } foreach (var item in ext) { var interpretedVal = st.GetVariable(item.Key.Name).Value; var compiledVal = externals[item.Value]; Assert.AreEqual(interpretedVal, compiledVal, $"varname:{item.Key} ticks:{i}"); } } }
public async Task <(Success?, Failure?)> Verify(Challenge.Challenge challenge, string yolol) { await Task.CompletedTask; if (challenge.ScoreMode != Challenge.ScoreMode.BasicScoring) { throw new NotImplementedException($"Score mode `{challenge.ScoreMode}` is not implemented"); } // Retrieve the test cases for the challenge var(inputs, outputs) = GetTests(challenge); // Check input program is 20x70 var lines = yolol.Split("\n"); if (lines.Length > 20 || lines.Any(l => l.Length > 70)) { return(null, new Failure(FailureType.ProgramTooLarge, null)); } // parse the entry program var result = Parser.ParseProgram(yolol); if (!result.IsOk) { return(null, new Failure(FailureType.ParseFailed, result.Err.ToString())); } var entry = result.Ok; // Get the variable which the program uses to indicate it is ready to move to the next round var state = new MachineState(new DefaultValueDeviceNetwork()); var done = state.GetVariable($":{challenge.CheckIndicator}"); // Begin counting how long it takes to verify var timer = new Stopwatch(); timer.Start(); // Run through test cases one by one var overflowIters = _config.MaxItersOverflow; var totalRuntime = 0u; var pc = 0; for (var i = 0; i < Math.Min(inputs.Count, outputs.Count); i++) { // Set inputs var input = inputs[i]; foreach (var(key, value) in input) { state.GetVariable($":{key}").Value = value; } // Clear completion indicator done.Value = 0; // Run lines until completion indicator is set or execution time limit is exceeded var limit = 0; while (!done.Value.ToBool()) { // Check if this test has exceed it's time limit if (limit++ > _config.MaxTestIters) { //If so use iterations from the overflow pool overflowIters--; //Once the overflow pool is empty too, fail if (overflowIters <= 0) { return(null, new Failure(FailureType.RuntimeTooLong, null)); } } totalRuntime++; try { // If line if blank, just move to the next line if (pc >= entry.Lines.Count) { pc++; } else { pc = entry.Lines[pc].Evaluate(pc, state); } } catch (ExecutionException) { pc++; } // loop around if program counter goes over max if (pc >= 20) { pc = 0; } } // Check outputs foreach (var(key, value) in outputs[i]) { var v = state.GetVariable($":{key}"); if ((v.Value != value).ToBool()) { var ii = string.Join(",", input.Select(b => $"`:{b.Key}={b.Value.ToHumanString()}`")); var oo = string.Join(",", outputs[i].Select(b => $"`:{b.Key}={b.Value.ToHumanString()}`")); return(null, new Failure(FailureType.IncorrectResult, $"For inputs {ii} expected outputs {oo}, got `{v.Value.ToHumanString()}` for `:{key}`")); } } } Console.WriteLine($"Verified {totalRuntime} ticks, {timer.ElapsedMilliseconds}ms runtime"); // Calculate score var codeLength = yolol.Replace("\n", "").Length; var score = _score.Score( (uint)inputs.Count, totalRuntime, codeLength ); return(new Success((uint)score, (uint)totalRuntime, (uint)codeLength), null); }