Пример #1
0
 public static Session Load (FileSystemDatabase fsd, int key)
 {
     var toLoad = fsd.Read (key);
     if (toLoad == null) {
         return null;
     }
     var result = new Session ();
     result.Id = key;
     if (toLoad.ContainsKey (ShovelVmStateName)) {
         result.ShovelVmState = toLoad [ShovelVmStateName];
     }
     if (toLoad.ContainsKey (ShovelVmBytecodeName)) {
         result.ShovelVmBytecode = toLoad [ShovelVmBytecodeName];
     }
     if (toLoad.ContainsKey (ShovelVmSourcesName)) {
         result.ShovelVmSources = Encoding.UTF8.GetString (toLoad [ShovelVmSourcesName]);
     }
     if (toLoad.ContainsKey (PageContentName)) {
         result.PageContent.Append (Encoding.UTF8.GetString (toLoad [PageContentName]));
     }
     if (toLoad.ContainsKey (ReadStateName)) {
         result.ReadState = (ReadStates)BitConverter.ToInt32 (toLoad [ReadStateName], 0);
     }
     return result;
 }
Пример #2
0
 static Session FreshSession(FileSystemDatabase fsd, Shovel.Instruction[] bytecode, string program)
 {
     var session = new Session ();
     session.Id = fsd.GetFreshId ();
     session.ShovelVmSources = program;
     session.ShovelVmBytecode = Shovel.Api.SerializeBytecode (bytecode);
     return session;
 }
Пример #3
0
 static IEnumerable<Shovel.Callable> Udps(Session session, string userInput)
 {
     var rng = new Random ();
     Action<Shovel.VmApi, Shovel.Value[], Shovel.UdpResult> print = (api, args, result) =>
     {
         if (args.Length > 0 && args [0].Kind == Shovel.Value.Kinds.String) {
             session.PageContent.Append ("<span>");
             session.PageContent.Append (HttpUtility.HtmlEncode (args [0].StringValue));
             session.PageContent.Append ("</span>");
         } else {
             session.PageContent.Append ("PRINT call failed!");
         }
     };
     Action<Shovel.VmApi, Shovel.Value[], Shovel.UdpResult> printLn = (api, args, result) =>
     {
         if (args.Length > 0 && args [0].Kind == Shovel.Value.Kinds.String) {
             session.PageContent.Append ("<span>");
             session.PageContent.Append (HttpUtility.HtmlEncode (args [0].StringValue));
             session.PageContent.Append ("</span><br/>");
         } else {
             session.PageContent.Append ("PRINT call failed!");
         }
     };
     Action<Shovel.VmApi, Shovel.Value[], Shovel.UdpResult> readLine = (api, args, result) =>
     {
         if (session.ReadState == Session.ReadStates.None) {
             result.After = Shovel.UdpResult.AfterCall.NapAndRetryOnWakeUp;
             session.ReadState = Session.ReadStates.ReadLine;
         } else if (session.ReadState == Session.ReadStates.ReadLine) {
             result.Result = Shovel.Value.Make (userInput);
             session.ReadState = Session.ReadStates.None;
             session.PageContent.Append (HttpUtility.HtmlEncode (userInput));
             session.PageContent.Append ("<br/>");
         } else {
             throw new InvalidOperationException ();
         }
     };
     Action<Shovel.VmApi, Shovel.Value[], Shovel.UdpResult> readInt = (api, args, result) =>
     {
         if (session.ReadState == Session.ReadStates.None) {
             result.After = Shovel.UdpResult.AfterCall.NapAndRetryOnWakeUp;
             session.ReadState = Session.ReadStates.ReadInteger;
         } else if (session.ReadState == Session.ReadStates.ReadInteger) {
             int dummy;
             if (!int.TryParse (userInput, out dummy)) {
                 dummy = 0;
             }
             result.Result = Shovel.Value.MakeInt (dummy);
             session.ReadState = Session.ReadStates.None;
             session.PageContent.Append (HttpUtility.HtmlEncode (userInput));
             session.PageContent.Append ("<br/>");
         } else {
             throw new InvalidOperationException ();
         }
     };
     Action<Shovel.VmApi, Shovel.Value[], Shovel.UdpResult> readChar = (api, args, result) =>
     {
         if (session.ReadState == Session.ReadStates.None) {
             result.After = Shovel.UdpResult.AfterCall.NapAndRetryOnWakeUp;
             session.ReadState = Session.ReadStates.ReadChar;
         } else if (session.ReadState == Session.ReadStates.ReadChar) {
             var line = userInput;
             if (line.Length > 0) {
                 result.Result = Shovel.Value.Make (line.Substring (0, 1));
             } else {
                 result.Result = Shovel.Value.Make ("");
             }
             session.ReadState = Session.ReadStates.None;
             session.PageContent.Append (HttpUtility.HtmlEncode (userInput));
             session.PageContent.Append ("<br/>");
         } else {
             throw new InvalidOperationException ();
         }
     };
     Action<Shovel.VmApi, Shovel.Value[], Shovel.UdpResult> random = (api, args, result) =>
     {
         result.Result = Shovel.Value.MakeFloat (rng.NextDouble ());
     };
     return new Shovel.Callable[] {
         Shovel.Callable.MakeUdp ("print", print, 1),
         Shovel.Callable.MakeUdp ("printLn", printLn, 1),
         Shovel.Callable.MakeUdp ("readLine", readLine, 0),
         Shovel.Callable.MakeUdp ("readInt", readInt, 0),
         Shovel.Callable.MakeUdp ("readChar", readChar, 0),
         Shovel.Callable.MakeUdp ("random", random, 0),
     };
 }
Пример #4
0
 static void ServeSession(HttpListenerContext ctx, FileSystemDatabase fsd, Session session, string userInput)
 {
     var vm = Shovel.Api.RunVm (
         Shovel.Api.DeserializeBytecode (session.ShovelVmBytecode),
         ProgramSources (session.ShovelVmSources),
         Udps (session, userInput),
         session.ShovelVmState,
         totalTicksQuota: null,
         ticksUntilNextNapQuota: null,
         usedCellsQuota: null);
     if (Shovel.Api.VmProgrammingError (vm) != null) {
         ServeError (ctx, session, Shovel.Api.VmProgrammingError (vm).Message);
     } else if (Shovel.Api.VmUserDefinedPrimitiveError (vm) != null) {
         ServeError (ctx, session, Shovel.Api.VmUserDefinedPrimitiveError (vm).Message);
     } else if (Shovel.Api.VmExecutionComplete (vm)) {
         using (var sw = new StreamWriter(ctx.Response.OutputStream)) {
             sw.Write ("<!DOCTYPE html>\n");
             sw.Write (session.PageContent.ToString ());
             sw.Write ("<p>Program execution completed.</p>");
             sw.Write ("<a href='/' id='restart-link'>Enter another program.</p>");
             sw.Write ("<script>\n");
             sw.Write ("document.getElementById('restart-link').focus()\n");
             sw.Write ("</script>\n");
         }
     } else {
         session.ShovelVmState = Shovel.Api.SerializeVmState (vm);
         session.Id = fsd.GetFreshId ();
         session.Save (fsd);
         using (var sw = new StreamWriter(ctx.Response.OutputStream)) {
             sw.Write ("<!DOCTYPE html>\n");
             sw.Write (session.PageContent.ToString ());
             sw.Write ("<form action='/' method='get'>");
             sw.Write ("<input type='text' name='input' id='shovel-input'/>");
             sw.Write ("<input type='submit' value='Submit'/>");
             sw.Write (String.Format (
                 "<input type='hidden' name='sessionid' value='{0}' id='shovel-input'/>",
                 session.Id)
             );
             sw.Write ("</form>");
             sw.Write ("<script>\n");
             sw.Write ("document.getElementById('shovel-input').focus()\n");
             sw.Write ("</script>\n");
         }
     }
     ctx.Response.OutputStream.Close ();
 }
Пример #5
0
 static void ServeError(HttpListenerContext ctx, Session session, string error)
 {
     using (var sw = new StreamWriter(ctx.Response.OutputStream)) {
         sw.Write ("<!DOCTYPE html>\n");
         sw.Write (session.PageContent.ToString ());
         sw.Write ("<p>Program execution failed.</p>");
         sw.Write ("<pre>");
         sw.Write (HttpUtility.HtmlEncode (error));
         sw.Write ("</pre>");
         sw.Write ("<a href='/' id='restart-link'>Enter another program.</p>");
         sw.Write ("<script>\n");
         sw.Write ("document.getElementById('restart-link').focus()\n");
         sw.Write ("</script>\n");
     }
 }