{"id":51229697,"url":"https://github.com/marekvospel/pebble","last_synced_at":"2026-06-28T15:01:38.402Z","repository":{"id":355853040,"uuid":"1081824704","full_name":"marekvospel/pebble","owner":"marekvospel","description":"A very simple interpreted language written in Haskell","archived":false,"fork":false,"pushed_at":"2026-02-04T00:52:13.000Z","size":61,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-05T15:51:57.082Z","etag":null,"topics":["haskell","interpreter","programming-language"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marekvospel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2025-10-23T10:44:04.000Z","updated_at":"2026-02-16T12:18:23.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/marekvospel/pebble","commit_stats":null,"previous_names":["marekvospel/pebble"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/marekvospel/pebble","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marekvospel%2Fpebble","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marekvospel%2Fpebble/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marekvospel%2Fpebble/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marekvospel%2Fpebble/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marekvospel","download_url":"https://codeload.github.com/marekvospel/pebble/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marekvospel%2Fpebble/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34892547,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-28T02:00:05.809Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["haskell","interpreter","programming-language"],"created_at":"2026-06-28T15:01:37.770Z","updated_at":"2026-06-28T15:01:38.394Z","avatar_url":"https://github.com/marekvospel.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pebble\nA tiny interpreted language made to learn haskell.\n\n## Features\n- [X] Everything is an expression. *`let x = if (something) 42 else 100;` works!*\n- [X] Calling functions. *You can do while loops using recursion!*\n- [X] Very simple AST. *Arithmetic operations are just function calls!*\n- [X] STD that can interact with IO. *Soon, even reading from stdin!*\n- [X] Clean implementation. *Using State+Except Monads!*\n- [X] Scoped variables. *Your variables aren't polluted from previous calls!*\n- [ ] Stack traces. *Required internals for this are in place...*\n- [ ] Parser, REPL. *Needs more than a bit of work...*\n\n## Examples\nSince I haven't implemented the parser yet, pebble is written using it's AST.\nLuckily thanks to Haskell's data type definitions, this feels much closer to\nactual programming language than other ASTs.\n\nThere is an example program inside `app/Main.hs` (Factorial calculation).\n`Main.hs` includes the logic to start evaluating any AST. You can execute\nany other example. (see [#AST](#ast) section)\n\n## Compiling / running project\nThis project is using the **stack** toolchain to manage ghc versions,\ninstall dependencies, build modules and/or run tests. To install stack, visit\nhttps://docs.haskellstack.org/en/stable/\n\nRunning tests:\n```sh\nstack test\n```\n\nRunning main example (`app/Main.hs`):\n```sh\nstack run\n```\n\n## AST\nThe AST types are described inside `src/AST.hs`. As mentioned, since everything\nis an expression, almost everything is part of the `data Expression` type.\n\nHere is an example of fibonacci's number calculation using pebble. (Uses all\nAST nodes that pebble has)\n```haskell\nprogram :: AST.Root\nprogram = [\n    FunctionDecl \"main\" [] [\n      VariableAssign \"result\" (FunctionCall \"fib\" [ExprLiteral (LitInt 10)]),\n      FunctionCall \"print\" [ExprLiteral (LitString \"Fib 10: \"), ExprIdent \"result\"]\n    ],\n    FunctionDecl \"fib\" [\"target\"] [\n      FunctionCall \"fib_impl\" [ExprLiteral (LitInt 0), ExprLiteral (LitInt 1), ExprLiteral (LitInt 1), ExprIdent \"target\"]\n    ],\n    FunctionDecl \"fib_impl\" [\"x\", \"y\", \"i\", \"target\"] [\n      If (FunctionCall \"eq\" [ExprIdent \"i\", ExprIdent \"target\"]) (ExprIdent \"y\")\n        (Just (BlockStatement [\n          VariableAssign \"temp\" (FunctionCall \"add\" [ExprIdent \"x\", ExprIdent \"y\"]),\n          FunctionCall \"fib_impl\" [ExprIdent \"y\", ExprIdent \"temp\", FunctionCall \"add\" [ExprIdent \"i\", ExprLiteral (LitInt 1)], ExprIdent \"target\"]\n        ]))\n    ]\n  ]\n```\n\n## Review notes\n- I haven't implemented many of the bonus point exercies in favor of learning\n  more about Haskell (namely Monads) and writing clean code, I hope this gets\n  taken into account when reviewing.\n- I didn't have much time because of other exams, however I'd like to finish\n  at least all features in the [#features](#features) section sometime in the\n  future (and release this project to github when the semester is done)\n- I haven't implemented while loops, since I didn't like the idea for this\n  project (and they can be done using functions \u0026 ifs) Here is how a while loop\n  could be implemented (Additions to `AST.hs` \u0026 `Eval.hs`)\n\n```haskell\n-- AST\ndata Expr = ... | While Expression [Expression]\n--\n\neval_expr :: Expression -\u003e EvalM Value\neval_expr (While predicate block) = do\n  cond \u003c- eval_expr predicate\n\n  case cond of\n    VBool True -\u003e do \n      modify $ \\st -\u003e st { callStack = (StackFrame {}:(callStack st)) }\n      val \u003c- eval_while predicate block\n      cleanup_frame\n      pure val\n    _ -\u003e do\n      pure (VVoid ())\n\neval_while :: Expression -\u003e [Expression] -\u003e EvalM Value\neval_while predicate block = do\n  res \u003c- eval_block block\n  cond \u003c- eval_expr predicate\n  case cond of\n    VBool True -\u003e eval_while predicate block\n    _ -\u003e do\n      pure (case res of\n          (val:_) -\u003e val\n          _ -\u003e VVoid ())\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarekvospel%2Fpebble","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarekvospel%2Fpebble","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarekvospel%2Fpebble/lists"}