{"id":19533318,"url":"https://github.com/andreainfufsm/testing-liascript-coderunner","last_synced_at":"2026-02-14T20:36:04.570Z","repository":{"id":102723951,"uuid":"594146879","full_name":"AndreaInfUFSM/testing-liascript-coderunner","owner":"AndreaInfUFSM","description":null,"archived":false,"fork":false,"pushed_at":"2023-02-04T14:53:12.000Z","size":5,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-08T11:50:04.433Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AndreaInfUFSM.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-01-27T17:57:08.000Z","updated_at":"2023-01-27T17:57:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"d7691645-fd04-4032-a946-8e8a5fd8d602","html_url":"https://github.com/AndreaInfUFSM/testing-liascript-coderunner","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/AndreaInfUFSM/testing-liascript-coderunner","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndreaInfUFSM%2Ftesting-liascript-coderunner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndreaInfUFSM%2Ftesting-liascript-coderunner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndreaInfUFSM%2Ftesting-liascript-coderunner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndreaInfUFSM%2Ftesting-liascript-coderunner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AndreaInfUFSM","download_url":"https://codeload.github.com/AndreaInfUFSM/testing-liascript-coderunner/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndreaInfUFSM%2Ftesting-liascript-coderunner/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29455360,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-14T15:52:44.973Z","status":"ssl_error","status_checked_at":"2026-02-14T15:52:11.208Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T02:06:52.694Z","updated_at":"2026-02-14T20:36:04.565Z","avatar_url":"https://github.com/AndreaInfUFSM.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!--\nauthor:   Andrea Charão\n\nemail:    andrea@inf.ufsm.br\n\nversion:  0.0.1\n\nlanguage: en\n\nnarrator: US English Female\n\nonload\nwindow.CodeRunner = {\n    ws: undefined,\n    handler: {},\n\n    init(url) {\n        this.ws = new WebSocket(url);\n        const self = this\n        this.ws.onopen = function () {\n            self.log(\"connections established\");\n            setInterval(function() {\n                self.ws.send(\"ping\")\n            }, 15000);\n        }\n        this.ws.onmessage = function (e) {\n            // e.data contains received string.\n\n            let data\n            try {\n                data = JSON.parse(e.data)\n            } catch (e) {\n                self.warn(\"received message could not be handled =\u003e\", e.data)\n            }\n            if (data) {\n                self.handler[data.uid](data)\n            }\n        }\n        this.ws.onclose = function () {\n            self.warn(\"connection closed\")\n        }\n        this.ws.onerror = function (e) {\n            self.warn(\"an error has occurred =\u003e \", e)\n        }\n    },\n    log(...args) {\n        console.log(\"CodeRunner:\", ...args)\n    },\n    warn(...args) {\n        console.warn(\"CodeRunner:\", ...args)\n    },\n    handle(uid, callback) {\n        this.handler[uid] = callback\n    },\n    send(uid, message) {\n        message.uid = uid\n        this.ws.send(JSON.stringify(message))\n    }\n}\n\n//window.CodeRunner.init(\"wss://coderunner.informatik.tu-freiberg.de/\")\n//window.CodeRunner.init(\"wss://testing-coderunner.andreaschwertne.repl.co/\")\nwindow.CodeRunner.init(\"wss://ancient-hollows-41316.herokuapp.com/\")\n//window.CodeRunner.init(\"ws://127.0.0.1:8000/\")\n\n@end\n\n\n@LIA.c:       @LIA.eval(`[\"main.c\"]`, `gcc -Wall main.c -o a.out`, `./a.out`)\n@LIA.clojure: @LIA.eval(`[\"main.clj\"]`, `none`, `clojure -M main.clj`)\n@LIA.cpp:     @LIA.eval(`[\"main.cpp\"]`, `g++ main.cpp -o a.out`, `./a.out`)\n@LIA.go:      @LIA.eval(`[\"main.go\"]`, `go build main.go`, `./main`)\n@LIA.haskell: @LIA.eval(`[\"main.hs\"]`, `ghc main.hs -o main`, `./main`)\n@LIA.java:    @LIA.eval(`[\"@0.java\"]`, `javac @0.java`, `java @0`)\n@LIA.julia:   @LIA.eval(`[\"main.jl\"]`, `none`, `julia main.jl`)\n@LIA.mono:    @LIA.eval(`[\"main.cs\"]`, `mcs main.cs`, `mono main.exe`)\n@LIA.nasm:    @LIA.eval(`[\"main.asm\"]`, `nasm -felf64 main.asm \u0026\u0026 ld main.o`, `./a.out`)\n@LIA.python:  @LIA.python3\n@LIA.python2: @LIA.eval(`[\"main.py\"]`, `python2.7 -m compileall .`, `python2.7 main.pyc`)\n@LIA.python3: @LIA.eval(`[\"main.py\"]`, `none`, `python3 main.py`)\n@LIA.r:       @LIA.eval(`[\"main.R\"]`, `none`, `Rscript main.R`)\n@LIA.rust:    @LIA.eval(`[\"main.rs\"]`, `rustc main.rs`, `./main`)\n@LIA.v:       @LIA.eval(`[\"main.v\"]`, `v main.v`, `./main`)\n@LIA.zig:     @LIA.eval(`[\"main.zig\"]`, `zig build-exe ./main.zig -O ReleaseSmall`, `./main`)\n\n@LIA.dotnet\n```xml    -project.csproj\n\u003cProject Sdk=\"Microsoft.NET.Sdk\"\u003e\n  \u003cPropertyGroup\u003e\n    \u003cOutputType\u003eExe\u003c/OutputType\u003e\n    \u003cTargetFramework\u003enet6.0\u003c/TargetFramework\u003e\n    \u003cImplicitUsings\u003eenable\u003c/ImplicitUsings\u003e\n    \u003cNullable\u003eenable\u003c/Nullable\u003e\n  \u003c/PropertyGroup\u003e\n\u003c/Project\u003e\n```\n@LIA.eval(`[\"Program.cs\",\"project.csproj\"]`, `dotnet build -nologo`, `dotnet run`)\n@end\n\n@LIA.dotnetFsharp\n```xml    -project.csproj\n\u003cProject Sdk=\"Microsoft.NET.Sdk\"\u003e\n  \u003cPropertyGroup\u003e\n    \u003cOutputType\u003eExe\u003c/OutputType\u003e\n    \u003cTargetFramework\u003enet6.0\u003c/TargetFramework\u003e\n  \u003c/PropertyGroup\u003e\n  \u003cItemGroup\u003e\n    \u003cCompile Include=\"Program.fs\" /\u003e\n  \u003c/ItemGroup\u003e\n\u003c/Project\u003e\n```\n@LIA.eval(`[\"Program.fs\", \"project.fsproj\"]`, `dotnet build -nologo`, `dotnet run`)\n@end\n\n@LIA.eval:  @LIA.eval_(false,`@0`,@1,@2)\n\n@LIA.evalWithDebug: @LIA.eval_(true,`@0`,@1,@2)\n\n@LIA.eval_\n\u003cscript\u003e\nfunction random(len=16) {\n    let chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n    let str = '';\n    for (let i = 0; i \u003c len; i++) {\n        str += chars.charAt(Math.floor(Math.random() * chars.length));\n    }\n    return str;\n}\n\nconst uid = random()\nvar order = @1\nvar files = []\n\nif (order[0])\n  files.push([order[0], `@'input(0)`])\nif (order[1])\n  files.push([order[1], `@'input(1)`])\nif (order[2])\n  files.push([order[2], `@'input(2)`])\nif (order[3])\n  files.push([order[3], `@'input(3)`])\nif (order[4])\n  files.push([order[4], `@'input(4)`])\nif (order[5])\n  files.push([order[5], `@'input(5)`])\nif (order[6])\n  files.push([order[6], `@'input(6)`])\nif (order[7])\n  files.push([order[7], `@'input(7)`])\nif (order[8])\n  files.push([order[8], `@'input(8)`])\nif (order[9])\n  files.push([order[9], `@'input(9)`])\n\n\nsend.handle(\"input\", (e) =\u003e {\n    CodeRunner.send(uid, {stdin: e})\n})\nsend.handle(\"stop\",  (e) =\u003e {\n    CodeRunner.send(uid, {stop: true})\n});\n\n\nCodeRunner.handle(uid, function (msg) {\n    switch (msg.service) {\n        case 'data': {\n            if (msg.ok) {\n                CodeRunner.send(uid, {compile: @2})\n            }\n            else {\n                send.lia(\"LIA: stop\")\n            }\n            break;\n        }\n        case 'compile': {\n            if (msg.ok) {\n                if (msg.message) {\n                    if (msg.problems.length)\n                        console.warn(msg.message);\n                    else\n                        console.log(msg.message);\n                }\n\n                send.lia(\"LIA: terminal\")\n                CodeRunner.send(uid, {exec: @3})\n\n                if(!@0) {\n                  console.clear()\n                }\n            } else {\n                send.lia(msg.message, msg.problems, false)\n                send.lia(\"LIA: stop\")\n            }\n            break;\n        }\n        case 'stdout': {\n            if (msg.ok)\n                console.stream(msg.data)\n            else\n                console.error(msg.data);\n            break;\n        }\n\n        case 'stop': {\n            if (msg.error) {\n                console.error(msg.error);\n            }\n\n            if (msg.images) {\n                for(let i = 0; i \u003c msg.images.length; i++) {\n                    console.html(\"\u003chr/\u003e\", msg.images[i].file)\n                    console.html(\"\u003cimg title='\" + msg.images[i].file + \"' src='\" + msg.images[i].data + \"' onclick='window.LIA.img.click(\\\"\" + msg.images[i].data + \"\\\")'\u003e\")\n                }\n\n            }\n\n            send.lia(\"LIA: stop\")\n            break;\n        }\n\n        default:\n            console.log(msg)\n            break;\n    }\n})\n\n\nCodeRunner.send(\n    uid, { \"data\": files }\n);\n\n\"LIA: wait\"\n\u003c/script\u003e\n@end\n--\u003e\n\n\n# Testing LiaScript's CodeRunner\n\n\n\u003e This is a playground to test some use cases with [LiaScript](https://github.com/LiaScript/LiaScript) and [CodeRunner](https://github.com/liascript/CodeRunner)\n\n\nIt all started with `git clone https://github.com/liascript/CodeRunner` \n\n\nCodeRunner is a *\"code-running server, based on Python, that can compile and execute code and communicate via websockets\"*.  It is not to be confused with these other CodeRunners: https://github.com/trampgeek/moodle-qtype_coderunner, https://github.com/codeclassroom/CodeRunner. \n\nCodeRunner's clients are LiaScript documents, so we have a single document and multiple ways to view it:\n\n- LiaScript server on GitHub:\n  https://liascript.github.io/course/?https://github.com/andreainfufsm/testing-liascript-coderunner\n\n- GitHub-rendered Markdown:\n  https://github.com/andreainfufsm/testing-liascript-coderunner\n\n- Raw Markdown on GitHub:\n  https://raw.githubusercontent.com/AndreaInfUFSM/testing-liascript-coderunner/master/README.md\n\n- Local LiaScript development server: `liascript-devserver --input README.md --port 3001 --live`\n\n\n## Where does the code run?\n\nThe code runs on a WebSocket server specified in the header of this document. The server can be deployed anywhere:\n\n```\n//window.CodeRunner.init(\"wss://coderunner.informatik.tu-freiberg.de/\")\nwindow.CodeRunner.init(\"wss://ancient-hollows-41316.herokuapp.com/\")\n//window.CodeRunner.init(\"ws://127.0.0.1:8000/\")\n//window.CodeRunner.init(\"wss://testing-coderunner.andreaschwertne.repl.co/\")\n```\n\n## Running C code with GCC\n\nUsing `@LIA.eval` macro:\n\n```\n@LIA.eval(`[\"main.c\"]`, `gcc -Wall main.c -o a.out`, `./a.out`)\n```\n\nClick the tiny button below the code to see the magic happen:\n\n```c\n#include \u003cstdio.h\u003e\n\nint main (void){\n  printf (\"It works!\\n\");\n\treturn 0;\n}\n```\n@LIA.eval(`[\"main.c\"]`, `gcc -Wall main.c -o a.out`, `./a.out`)\n\n## Running Haskell code with GHC\n\nNow we'll be exploring two approaches to run Haskell example codes: using CodeRunner or embedding a Repl.it project.\n\nChoose one from the menu or just click next to continue.\n\n\n\n### CodeRunner via LiaScript Macros\n\nAbout the macros:\n\n- Implementation described in: https://github.com/LiaScript/CodeRunner/blob/master/README.md#implementation\n\n- We've pasted the code into the header of our MarkDown document. Check the raw view of the document: \nhttps://raw.githubusercontent.com/AndreaInfUFSM/testing-liascript-coderunner/master/README.md\n\n\n\u003e The `@LIA.eval` macro gives us more flexibility, but `@LIA.haskell` is shorter and should be enough for most use cases.\n\nUsing `@LIA.eval` macro: we just have to copy this line right below the Haskell code\n\n```\n@LIA.eval(`[\"main.hs\"]`, `ghc main.hs -o main`, `./main`)\n```\n\n\n``` haskell\nmain = do\n  print \"Hello\"\n```\n@LIA.eval(`[\"main.hs\"]`, `ghc main.hs -o main`, `./main`)\n\n\nUsing the `@LIA.haskell` macro: same result as above, but a shorter line to copy below the Haskell code\n\n\n```\n@LIA.haskell()\n```\n\n``` haskell\nmain = do\n  print \"Hello\"\n```\n@LIA.haskell()\n\n\n\n### Problem with backticks (solved)\n\nHaskell infix operator uses backticks around a function: https://wiki.haskell.org/Infix_operator\n\nFor example, consider the function `mod`.\n\nIn prefix notation:\n\n```\nmod 9 2\n```\n\nIn infix notation:\n\n```\n9 `mod` 2\n```\n\n\nThat seems to be a problem for LiaScript to run such Haskell code.\n\nThis works:\n\n``` haskell\nmain = do\n  putStrLn $ show $ mod 9 2\n```\n@LIA.haskell()\n\n\n\n\n\nBut this didn't work with a CodeRunner script using `@input(` :\n\n``` haskell\nmain = do\n  putStrLn $ show $ 9 `mod` 2\n```\n\n\n\n**Update:** This is now solved with a new macro `@'input(` replacing `@input(` in the CodeRunner script located in the header of this document.\n\n``` haskell\nmain = do\n  putStrLn $ show $ 9 `mod` 2\n```\n@LIA.eval(`[\"main.hs\"]`, `ghc main.hs -o main`, `./main`)\n\n### Embedded Repl.it\n\nRepl.it online integrated development environment is another alternative to run code inside a LiaScript document. It can be embedded in a document using `iframe` or LiaScript's oEmbed service (see below).\n\n\u003e It is a powerful alternative because Repl.it supports any language/library using Nix. However, it takes longer to run/show and even its simple public interface may be confusing to some students. Also, the browser may prevent the embed to show and force the user to open the site in another window.\n\nThis Repl.it project runs a simple `main` function and keeps GHCi running so we can try Haskell functions in the interactive environment: https://replit.com/@AndreaSchwertne/2022haskell-console\n\nEmbedding using `iframe`:\n\n```\n\u003ciframe frameborder=\"0\" width=\"100%\" height=\"500px\" src=\"https://replit.com/@AndreaSchwertne/2022haskell-console?embed=true\"\u003e\u003c/iframe\u003e\n```\n\u003ciframe frameborder=\"0\" width=\"100%\" height=\"500px\" src=\"https://replit.com/@AndreaSchwertne/2022haskell-console?embed=true\"\u003e\u003c/iframe\u003e\n\n\nEmbedding using `oEmbed`:\n\n```\n??[replit](https://replit.com/@AndreaSchwertne/2022haskell-console)\n```\n\n??[replit](https://replit.com/@AndreaSchwertne/2022haskell-console)\n\n\n\n## Deploying CodeRunner on Repl.it\n\nRepl.it allows users to easily deploy HTTP servers: https://docs.replit.com/hosting/deploying-http-servers\n\nWebSockets are also supported, so we could try to deploy CodeRunner on Repl.it.\n\nAfter some tweaking with Nix packages and Repl.it ports, here goes a proof of concept!\n\nhttps://replit.com/@AndreaSchwertne/testing-coderunner\n\nNotes:\n\n- This project install Nix Python packages required by CodeRunner and starts the server on port 80 (otherwise it would not work)\n\n- Click `Show files`  then click the three dots and `Show hidden files` to see Nix and Repl.it configuration files\n\n- In the LiaScript document, change the hostname: `window.CodeRunner.init(\"wss://testing-coderunner.andreaschwertne.repl.co/\")`\n\n- Only C and Python included in this proof of concept, but we could add more packages (compilers, libraries) in the `replit.nix` (although this can slow the repl to start).\n\n\n\n## More to test...\n\n__More languages__\n\nThe original CodeRunner template has a lot more examples on many popular programming languages: https://github.com/liascript/CodeRunner\n\n__Deploying on Repl.it__\n\n- CodeRunner server.py uses [python-websocket-server](https://github.com/Pithikos/python-websocket-server), which is not found as a Nix package, so we had to install it on user space. There is a WebSocket server library for Python called [simple-websocket-server](https://github.com/dpallot/simple-websocket-server) which is distributed as a Nix package, so it would be worth trying to replace the websocket library to avoid reinstallation every time the repl restarts.\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreainfufsm%2Ftesting-liascript-coderunner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandreainfufsm%2Ftesting-liascript-coderunner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreainfufsm%2Ftesting-liascript-coderunner/lists"}