{"id":17654655,"url":"https://github.com/ubugeeei/glasper","last_synced_at":"2026-01-20T11:07:00.538Z","repository":{"id":59072926,"uuid":"526972634","full_name":"ubugeeei/Glasper","owner":"ubugeeei","description":"Toy JavaScript Interpreter implementation in Rust","archived":false,"fork":false,"pushed_at":"2023-05-07T13:42:32.000Z","size":372,"stargazers_count":0,"open_issues_count":10,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-19T08:37:34.645Z","etag":null,"topics":["interpreter","javascript","javascript-engine","javascript-interpreter","language-processing","rust","scratch-implementation"],"latest_commit_sha":null,"homepage":"","language":"Rust","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/ubugeeei.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}},"created_at":"2022-08-20T15:57:42.000Z","updated_at":"2023-02-04T04:23:07.000Z","dependencies_parsed_at":"2023-02-18T13:46:07.945Z","dependency_job_id":null,"html_url":"https://github.com/ubugeeei/Glasper","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ubugeeei/Glasper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ubugeeei%2FGlasper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ubugeeei%2FGlasper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ubugeeei%2FGlasper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ubugeeei%2FGlasper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ubugeeei","download_url":"https://codeload.github.com/ubugeeei/Glasper/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ubugeeei%2FGlasper/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28602175,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T10:46:13.255Z","status":"ssl_error","status_checked_at":"2026-01-20T10:42:51.865Z","response_time":117,"last_error":"SSL_read: 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":["interpreter","javascript","javascript-engine","javascript-interpreter","language-processing","rust","scratch-implementation"],"created_at":"2024-10-23T12:35:28.865Z","updated_at":"2026-01-20T11:07:00.522Z","avatar_url":"https://github.com/ubugeeei.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://user-images.githubusercontent.com/71201308/191884187-75417bf0-8d23-4d89-8f8a-ba0d1d5e4ab9.png\" width=\"200\"\u003e\n\n[![CI](https://github.com/Ubugeeei/Glasper/actions/workflows/rust.yml/badge.svg)](https://github.com/Ubugeeei/Glasper/actions/workflows/rust.yml)\n\nA toy JavaScript engine and runtime implementation in Rust.\n\n\u003c/div\u003e\n\n# Installation\n\n```sh\n$ make install\n# set path your shell\n$ echo 'export PATH=/usr/local/bin/gls:$PATH' \u003e\u003e ~/.hogerc\n```\n\n# Usage\n\n## Run source code\n\n```sh\n$ gls example/main.js\n```\n\n## Run interactive\n\n```sh\n$ gls\nWelcome to Glasper v0.1.0\nexit using ctrl+c or ctrl+d or exit()\n\u003e # input your source\n```\n\nyou can get more info by help command.\n\n```sh\n$ gls --help\n```\n\n## Use as library (JavaScript engine)\n\n### Basic Execution\n\n```rs\nuse glasper::engine::*;\n\nlet handle_scope = HandleScope::new();\nlet mut context = Context::new(handle_scope);\nlet mut isolate = Isolate::new(context);\nlet mut script = Script::compile(String::from(\"let a = 1;\"),  \u0026mut isolate.context);\nscript.run()\n```\n\n### Binding Objects\n\n```rs\nuse glasper::engine::*;\n\nlet handle_scope = HandleScope::new();\nlet mut context = Context::new(handle_scope);\n\nlet global = context.global();\nlet console_builder = ConsoleBuilder::new();\nlet console = console_builder.build();\nglobal.set(\"console\", console);\n\nlet mut isolate = Isolate::new(context);\nlet mut script = Script::compile(String::from(\"console.log(1, 2, 3);\"),  \u0026mut isolate.context);\nscript.run()\n```\n\n\u003cdetails\u003e\n\u003csummary\u003ebuiltin console sample\u003c/summary\u003e\n\n```rs\nuse glasper::engine::*;\n\npub struct ConsoleBuilder;\nimpl Default for ConsoleBuilder {\n    fn default() -\u003e Self {\n        Self::new()\n    }\n}\nimpl ConsoleBuilder {\n    pub fn new() -\u003e Self {\n        Self\n    }\n    pub fn build(self) -\u003e RuntimeObject {\n        let mut properties = HashMap::new();\n        properties.insert(\n            String::from(\"log\"),\n            RuntimeObject::BuiltinFunction(JSBuiltinFunction::new(\"log\", log)),\n        );\n        properties.insert(\n            String::from(\"debug\"),\n            RuntimeObject::BuiltinFunction(JSBuiltinFunction::new(\"log\", log)),\n        );\n        properties.insert(\n            String::from(\"warn\"),\n            RuntimeObject::BuiltinFunction(JSBuiltinFunction::new(\"log\", log)),\n        );\n\n        RuntimeObject::Object(JSObject { properties })\n    }\n}\n\nfn log(args: Vec\u003cRuntimeObject\u003e) -\u003e RuntimeObject {\n    for arg in args {\n        print!(\"{}\", arg);\n        print!(\"\\x20\");\n    }\n    println!();\n\n    RuntimeObject::Undefined(JSUndefined)\n}\n```\n\n\u003c/details\u003e\n\n# Syntax\n\n## Console log\n\n```js\nconsole.log(\"Hello World!\");\n```\n\n## Expression\n\n### Primitive literals\n\n```js\n// bool\nconsole.log(true);\nconsole.log(false);\n\n// number\nconsole.log(1);\nconsole.log(0x1111);\nconsole.log(0o1111);\nconsole.log(0b1111);\nconsole.log(1.1);\nconsole.log(1.1e3);\nconsole.log(1.1e-3);\n\n// string\nconsole.log(\"hello string\");\n\n// undefined, null\nconsole.log(undefined);\nconsole.log(null);\n```\n\n### Operators\n\n```js\nconsole.log(2 + 2);\nconsole.log(2 - 2);\nconsole.log(2 * 2);\nconsole.log(2 / 2);\nconsole.log(2 % 2);\nconsole.log(2 ** 2);\nconsole.log(2 + 2 * 2);\n\n// comp\nconsole.log(2 == 2);\nconsole.log(2 != 2);\nconsole.log(2 === 2);\nconsole.log(2 !== 2);\nconsole.log(2 \u003e 2);\nconsole.log(2 \u003c 2);\nconsole.log(2 \u003c= 2);\nconsole.log(2 \u003e= 2);\n\n// bit\nconsole.log(2 \u003c\u003c 2);\nconsole.log(2 \u003e\u003e 2);\nconsole.log(2 \u0026 2);\nconsole.log(2 | 2);\nconsole.log(2 ^ 2);\n\n// bool\nconsole.log(2 \u0026\u0026 2);\nconsole.log(2 || 2);\n\n// nullish\nconsole.log(1 ?? 2); // 1\nconsole.log(null ?? 2); // 2\n\n// typeof\nconsole.log(typeof 1); // \"number\"\n```\n\n## Array and prototype functions\n\n```js\nconst arr = [1, 2, 3, 4, 5];\n\nconsole.log(arr[0]); // 1\nconsole.log(arr[100]); // undefined\nconsole.log(arr.length); // 5\n\nconst last = arr.at(-1);\nconsole.log(last); // 5\n\nconst concat = arr.concat([6, 7, 8]);\nconsole.log(concat[6]); // 6\n\nconst every = arr.every(function (v) {\n  return v \u003c 10;\n});\nconsole.log(every); // true\n\nconst joined = arr.join(\"/\");\nconsole.log(joined); // \"1/2/3/4/5/6/7/8\"\n\nconst mapped = arr.map(function (it) {\n  return it * 2;\n});\nconsole.log(mapped[0]); // 2\n\nconst found = arr.find(function (it) {\n  return it % 2 === 0;\n});\nconsole.log(found); // 2\n```\n\n## Object\n\n```js\nlet o = {\n  message: \"hello object\",\n};\nconsole.log(o.message);\n\no.message = \"hello object again\";\nconsole.log(o.message);\n\nlet o_cp = o;\no_cp.message = \"hello object again by copy\";\nconsole.log(o.message);\n```\n\n## Variable snd scope\n\n### declare \"var\"\n\n```js\na = 1;\nconsole.log(\"variables a:\", a); // 1\na = 5;\nconsole.log(\"variables assigned a:\", a); // 5\n```\n\n### declare \"let\"\n\n```js\nlet a = 2;\nconsole.log(\"variables a:\", a); // 2\na = 6;\nconsole.log(\"variables assigned a:\", a); // 6\n```\n\n### declare \"const\"\n\n```js\nconst c = 3;\nconsole.log(\"variables c:\", c); // 3\nc = 7; // error\nconst c = 7; // error\n```\n\n### scope\n\n```js\nlet v = 1;\nlet global = 100;\n{\n  let v = 2;\n  console.log(\"child scope v:\", v); // 2\n  console.log(\"global in child:\", global); // 100\n}\nconsole.log(\"parent scoped v:\", v); // 1\n```\n\n## Function\n\n```js\nconst add = function (a, b) {\n  return a + b;\n};\n\nconsole.log(\"add(1, 2):\", add(1, 2));\n```\n\n```js\n// recursive\nconst factorial = function (num) {\n  if (num == 0) return 1;\n  return num * factorial(num - 1);\n};\nconsole.log(\"factorial(5):\", factorial(5)); // 120\n```\n\n## \"this\" in Function\n\n```js\nconst inner_f = function () {\n  return this.value;\n};\nconsole.log(inner_f()); // undefined\n\nconst o = {\n  value: 1,\n  f: inner_f,\n};\nconsole.log(o.f()); // { value: 1, f: [Function] }\n\nconst oo = {\n  value: 2,\n  f: inner_f,\n};\nconsole.log(oo.f()); // { value: 2, f: [Function] }\n```\n\n## Prototype\n\n```js\nArray.prototype = {\n  nth: function (n) {\n    return this[n];\n  },\n};\n\nconst arr = [1, 2, 3, 4, 5];\nconsole.log(arr.nth(2)); // 3\n```\n\n## Statements\n\n### If\n\n```js\nlet num = 2;\nif (num % 2 == 0) {\n  console.log(\"even!\");\n} else {\n  console.log(\"odd!\");\n}\n```\n\n### switch\n\n```js\nconst match = function (num) {\n  switch (num) {\n    case 1: {\n      console.log(\"one\");\n      break;\n    }\n    case 2: {\n      console.log(\"two\");\n      break;\n    }\n    default: {\n      console.log(\"other\");\n      break;\n    }\n  }\n};\nmatch(1);\nmatch(2);\nmatch(99);\n```\n\n```js\nconst match_no_break = function (num) {\n  switch (num) {\n    case 1:\n      console.log(\"one\");\n    case 2:\n      console.log(\"two\");\n    default:\n      console.log(\"other\");\n  }\n};\nmatch_no_break(1);\nmatch_no_break(2);\nmatch_no_break(99);\n```\n\n### For\n\n```js\nconst arr = [1, 2, 3, 4];\n\nfor (let i = 0; i \u003c arr.length; i++) {\n  if (i % 2) {\n    continue; // skip odd index\n  }\n\n  console.log(arr[i] * 2);\n}\n```\n\n## FizzBuzz sample\n\n```js\nconst fizzBuzz = function (num) {\n  // comment out\n  if (!num) return 0;\n\n  if (num % 15 == 0) {\n    console.log(\"FizzBuzz\");\n  } else if (num % 5 == 0) {\n    console.log(\"Buzz\");\n  } else if (num % 3 == 0) {\n    console.log(\"Fizz\");\n  } else {\n    console.log(num);\n  }\n\n  fizzBuzz(num - 1);\n};\n\nfizzBuzz(20);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fubugeeei%2Fglasper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fubugeeei%2Fglasper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fubugeeei%2Fglasper/lists"}