{"id":18994838,"url":"https://github.com/jweinst1/oblivion","last_synced_at":"2025-04-05T12:09:23.884Z","repository":{"id":57313050,"uuid":"81268256","full_name":"jweinst1/Oblivion","owner":"jweinst1","description":"The language of Art","archived":false,"fork":false,"pushed_at":"2018-05-06T06:54:29.000Z","size":522,"stargazers_count":413,"open_issues_count":2,"forks_count":16,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-29T11:11:18.505Z","etag":null,"topics":["art","compiler","graphics","languages","svg"],"latest_commit_sha":null,"homepage":"https://jweinst1.github.io/OblivionWebsite/","language":"JavaScript","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/jweinst1.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-08T00:08:11.000Z","updated_at":"2024-06-17T12:54:51.000Z","dependencies_parsed_at":"2022-09-20T23:20:14.078Z","dependency_job_id":null,"html_url":"https://github.com/jweinst1/Oblivion","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jweinst1%2FOblivion","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jweinst1%2FOblivion/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jweinst1%2FOblivion/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jweinst1%2FOblivion/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jweinst1","download_url":"https://codeload.github.com/jweinst1/Oblivion/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247332611,"owners_count":20921853,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["art","compiler","graphics","languages","svg"],"created_at":"2024-11-08T17:27:15.954Z","updated_at":"2025-04-05T12:09:23.864Z","avatar_url":"https://github.com/jweinst1.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Oblivion\n\n[Website](https://jweinst1.github.io/OblivionWebsite/)\n\nThe language of art and graphics!\n\nOblivion is a programming language that produces SVG files. It's a domain specific language dedicated to producing graphics and\ngiving programmers as well as artists the tools to create art with code.\n\nIt's a language designed to visualize code and create incredible illustrations!\n\n#### `Features:`\n* SVG-specific data structures and operators\n* Simple, Ruby/Python like syntax\n* Runs in the browser, or in NodeJS\n* Recursion and functional programming support\n* Immutable Python-style lists\n\n`Oblivion` is the perfect programming language for artists, researchers, programmers, and anyone who wants to use a functional approach to visualize their code.\n\nTry out Oblivion on the playground, or read the guide to see how it all works!\n\n## Contents\n\n- [Installation](#installation)\n- [Language Guide](#language-guide)\n- [Output](#output)\n    - [Whitespace](#whitespace)\n    - [Runtime](#runtime)\n- [Types](#types)\n    - [Numbers](#numbers)\n    - [Bools](#bools)\n    - [Lists](#lists)\n    - [Points](#points)\n    - [Lines](#lines)\n    - [Shapes](#shapes)\n    - [Colors](#colors)\n- [Operators](#operators)\n    - [Left Associativity](#left-associativity)\n    - [Arithmetic Operators](#arithmetic-operators)\n    - [Random Number Operator](#random-number-operator)\n    - [Logical Operators](#logical-operators) \n    - [List Operators](#list-operators)\n    - [Color Operator](#color-operator)\n- [If-Else Statements](#if-else-statements)\n- [Functions](#functions)\n- [Processes](#processes)\n- [List Functions](#list-functions)\n- [License](#license)\n\n## Installation\n\nTo Install Oblivion, use the following shell command\n\n`$ npm install -g oblivion-js`\n\nTo compile an `.obl` file, use the following `oblivion` command\n\n`$ oblivion yourfilename.obl`\n\nThe stdout will be logged to your console and the svg output will be written to a file.\n\n## `Language Guide`:\n\n## Output\n\nOblivion is a programming language that outputs a string representing an svg format graphic. This is called the `SVGOut`. We can think of this output as a buffer. Similarly, the language can also \"print\" statements to another output called `StdOut`. Both of these are accessed with the `draw` keyword and `print()` function respectively.\n\n### WhiteSpace\n\nIn Oblivion, newlines, spaces, tabs and commas are treated as whitespace. This means you can put as many commas, spaces or newlines as you like, to allow for a customized spacing of code.\n\n```\n\nprint(3, 4)\nprint(3,,,,,,,,,\n,,,,,,,,,,,,4)\n\n3\n4\n3\n```\n\n### Runtime\n\nOblivion's compiler is implemented in TypeScript, with its parser generated from JavaScript. Unlike most web-based languages, Oblivion does not transcompile to JavaScript. It also does not run on a virtual machine.\n\nOblivion uses a self-evaluating abstract syntax tree with a pre-defined set of *rules*. A program is compiled by traversing the abstract syntax tree in a depth-first fashion, and using a node's rule to evaluate its child arguments. The state of evaluation never changes as rules are the same.\n\n## Types\n\nOblivion has a relatively small number of types, allowing for a small variety of data to yield many combinations of uses and functionality.\n\n### Numbers\n\nNumbers in Oblivion represent both Integers and Floats. They are very similar to JavaScript numbers.\n\n```\nprint(7 /6)\nprint(4 + 6)\n\n1.1666666666666667\n10\n```\n\n### Bools\n\nBools or booleans represent true and false in Oblivion. They are the results of using logical operators. `true` and `false` can also be used in lists or returned from functions\n\n```\nd = true || false\nprint(d)\nprint(d \u0026\u0026 false)\n\ntrue\nfalse\n```\n\n### Lists\n\nLists are a special type in Oblivion and are denoted with square brackets `[]`. They can contain any value, and are not statically typed. They are also immutable, you can only use operators to create new lists, you can never edit a list once it's created.\n\n```\nprint([1,2,3])\nprint([1 2 3])\ng = [1] \u0026 [2, 3]\nprint(g)\nprint(g \u0026 [2, 3 + 3])\n\n[1,2,3]\n[1,2,3]\n[1,2,3]\n[1,2,3,2,6]\n```\n\n### Points\n\nPoints are two member structs that contain two numbers, one that applies to the x and y coordinate of a point on a grid. SVG graphics are always arranged on a x-y grid system, thus points are an easy way to manage places on a grid.\n\nYou can access the x and y properties of a point, but points are always immutable\n\n```\nf = (3, 2)\nprint(f.x)\n\n3\n```\n\n### Lines\n\nIn Oblivion, a line is a data structure that represent a series of points connected by a line. It is immutable, like the rest of Oblivion's types. A line has both a printable form and a drawable form. They are connected via the `-\u003e` operator.\n\n```\ng = (1,8) -\u003e (44, 9) -\u003e (44,44)\n print(g)\ng = #red |= g\ndraw g\n\n1,8 -\u003e 44,9 -\u003e 44,44\n```\n\nThis gives the SVG\n\n```xml\n\u003csvg width=\"100%\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\n\u003cstyle\u003e\u003c/style\u003e\n\u003cpolyline points=\"1,8 44,9 44,44\" fill=\"transparent\" stroke=\"red\" stroke-width=\"1\"\u003e\u003c/polyline\u003e\n\u003c/svg\u003e\n```\n\n### Shapes\n\nShapes, also called polygons, are very similar to lines, but they are always `filled`. This means that the shape is always colored. Shapes are connected via the `*\u003e` operator.\n\n```\ng = (1,8) *\u003e (44, 9) *\u003e (44,44) *\u003e (0, 90)\n print(g)\ng = #tan |= g\ndraw g\n\n1,8 *\u003e 44,9 *\u003e 44,44 *\u003e 0,90\n```\n\n```xml\n\u003csvg width=\"100%\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\n\u003cstyle\u003e\u003c/style\u003e\n\u003cpolygon points=\"1,8 44,9 44,44 0,90\" fill=\"tan\" stroke=\"transparent\" stroke-width=\"1\"\u003e\u003c/polygon\u003e\n\u003c/svg\u003e\n```\n\n### Colors\n\nColors are special types in Oblivion that allow you to color your lines and shapes. For now, you can use a small range of named colors, like `red` or `orange`, or a hex color, such as `#fff`.\n\n## Operators\n\nUnlike most functional languages, Oblivion uses a wide array of operators (*and a minimal amount of parenthesis*).\n\n### Left Associativity\n\nIt is important to note all operators in Oblivion associate toward the left. There is no other operator precedence.\n\n### Arithmetic Operators\n\nOblivion has five arithmetic operators, `+, -, *, /, %`. They are used like so:\n\n```\nprint(3 + 3)\nprint(44 / 5 - 4)\nprint(6 % 2)\n\n6\n44\n0\n```\n\n#### Random Number Operator\n\nThe `!!` operator returns a random number between the left and right numbers argued with it respectively. Such as `3 !! 10`.\n\n### Logical Operators\n\nOblivion makes use of several different logical operators. These can be used to compare values, and check if values are the same.\n\n```\nprint(3 == 4)\nprint([4] ~= [4])\nprint(true == 3 == 3)\nprint(3 != 4)\nprint(5 \u003c= 5 + 7 - 3 * 4)\n\nfalse\ntrue\ntrue\ntrue\n```\n\nThe `~=` checks for absolute equality, and can compare lists against each other. The `==` operator will not work properly for lists.\n\n### List Operators\n\nOblivion has two operators specifically for lists! The first is the extension operator, `\u0026`. It returns a new list that is extended by the right hand list or other element. If the right side is not a list, it acts as an appending operator.\n\nSecond is the set, `=\u003e` operator. It allows you to reference an index of a list and returns a new copy of the list that gets reassigned.\n\n```\na = [1, 2, 3]\nprint(a \u0026 [4])\nprint(a.1 =\u003e [3])\n\n[1,2,3,4]\n[1,[3],3,4]\n```\n\n### Color Operator\n\nThe `|=` operator takes one color and a line shape or combo and colors it.\n\n## If-Else Statements\n\nOblivion's only conditional element is the if statement. It's constructed similarly to Ruby's if..else syntax. Like with all body statements, if statements end with a _, and can be nested.\n\n```\nd = (3,4) -\u003e (5,6)\ne = (3,4) -\u003e (5,6)\nif d ~= e\n    print(true)\nelse\n   print(false)\n_\n\ntrue\n```\n\nThey can also be used with the `draw` keyword\n\n```\ng = (88, 1) *\u003e (5, 5)\n\nif 3 == 3\n   draw (30, 30) *\u003e g\n_\n\nif 3 == 4\n   draw (30, 30) *\u003e g\nelse\n    draw #green |= (60, 30) *\u003e g\n_\n```\n\n```xml\n\u003csvg width=\"100%\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\n\u003cstyle\u003e\u003c/style\u003e\n\u003cpolygon points=\"30,30 88,1 5,5\" fill=\"black\" stroke=\"transparent\" stroke-width=\"1\"\u003e\u003c/polygon\u003e\n\u003cpolygon points=\"60,30 88,1 5,5\" fill=\"green\" stroke=\"transparent\" stroke-width=\"1\"\u003e\u003c/polygon\u003e\n\u003c/svg\u003e\n\n```\n\n## Functions\n\nFunctions are the central feature in Oblivion used for computation. They work much like functions in languages like Ruby and Python. They even use the all so familiar `def` keyword!\n\n```\ndef fact(i)\n   if i == 0\n      return i\n   else\n      return i + fact(i - 1)\n   _\n_\n\nprint(fact(8))\n\n36\n```\n\nFunctions can also be used with drawing!\n\n```\ndef diagonal(n)\n     if n == 0\n         return (0, 0)\n     else\n        return (n, n) -\u003e diagonal(n - 1)\n    _\n_\n\ndraw diagonal(99)\n```\n\n```xml\n\n\u003csvg width=\"100%\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\n\u003cstyle\u003e\u003c/style\u003e\n\u003cpolyline points=\"99,99 98,98 97,97 96,96 95,95 94,94 93,93 92,92 91,91 90,90 89,89 88,88 87,87 86,86 85,85 84,84 83,83 82,82 81,81 80,80 79,79 78,78 77,77 76,76 75,75 74,74 73,73 72,72 71,71 70,70 69,69 68,68 67,67 66,66 65,65 64,64 63,63 62,62 61,61 60,60 59,59 58,58 57,57 56,56 55,55 54,54 53,53 52,52 51,51 50,50 49,49 48,48 47,47 46,46 45,45 44,44 43,43 42,42 41,41 40,40 39,39 38,38 37,37 36,36 35,35 34,34 33,33 32,32 31,31 30,30 29,29 28,28 27,27 26,26 25,25 24,24 23,23 22,22 21,21 20,20 19,19 18,18 17,17 16,16 15,15 14,14 13,13 12,12 11,11 10,10 9,9 8,8 7,7 6,6 5,5 4,4 3,3 2,2 1,1 0,0\" fill=\"transparent\" stroke=\"black\" stroke-width=\"1\"\u003e\u003c/polyline\u003e\n\u003c/svg\u003e\n```\n\nBecause Oblivion uses trampoline recursion, the limit for a recursive call is much deeper than with most other languages.\n\n## Processes\n\nA Process in oblivion is a no parameter function denoted by `{}`. It's meant to serve as a currying tool to aid in functional programming. It's also very useful for drawing.\n\n```\nf = [1]\nf = f.0 =\u003e {return [2]}\nprint(f.0())\n\n[2]\n```\n\nYou can also use processes with the `repeat` built-in function\n\n```\nf = [1]\nf = f.0 =\u003e {print(3)}\nrepeat(4, f.0)\n\n3\n3\n3\n3\n```\n\nHere's an example that uses two processes together to draw with random numbers!\n\n```\ngetnum = {return 1 !! 70}\n\nrandline = {\n    draw #cyan |= (getnum(), getnum()) -\u003e (getnum(), getnum())\n}\n\nrepeat(10, randline)\n```\n\n```\n\u003csvg width=\"100%\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\n\u003cstyle\u003e\u003c/style\u003e\n\u003cpolyline points=\"54,15 37,49\" fill=\"transparent\" stroke=\"cyan\" stroke-width=\"1\"\u003e\u003c/polyline\u003e\n\u003cpolyline points=\"17,14 59,48\" fill=\"transparent\" stroke=\"cyan\" stroke-width=\"1\"\u003e\u003c/polyline\u003e\n\u003cpolyline points=\"51,32 35,9\" fill=\"transparent\" stroke=\"cyan\" stroke-width=\"1\"\u003e\u003c/polyline\u003e\n\u003cpolyline points=\"39,21 16,14\" fill=\"transparent\" stroke=\"cyan\" stroke-width=\"1\"\u003e\u003c/polyline\u003e\n\u003cpolyline points=\"43,59 19,55\" fill=\"transparent\" stroke=\"cyan\" stroke-width=\"1\"\u003e\u003c/polyline\u003e\n\u003cpolyline points=\"25,68 23,19\" fill=\"transparent\" stroke=\"cyan\" stroke-width=\"1\"\u003e\u003c/polyline\u003e\n\u003cpolyline points=\"38,12 43,9\" fill=\"transparent\" stroke=\"cyan\" stroke-width=\"1\"\u003e\u003c/polyline\u003e\n\u003cpolyline points=\"58,35 38,50\" fill=\"transparent\" stroke=\"cyan\" stroke-width=\"1\"\u003e\u003c/polyline\u003e\n\u003cpolyline points=\"48,23 34,66\" fill=\"transparent\" stroke=\"cyan\" stroke-width=\"1\"\u003e\u003c/polyline\u003e\n\u003cpolyline points=\"56,47 56,29\" fill=\"transparent\" stroke=\"cyan\" stroke-width=\"1\"\u003e\u003c/polyline\u003e\n\u003c/svg\u003e\n```\n\n## List Functions\n\nOblivion also has a variety of built in List functions that can slice, search, and insert items into a newly returned list.\n\n```\nprint(range(8))\nprint(insert(range(7), 3, 88))\nprint(find(range(5), 77))\nprint(len(range(8)))\n\nprint(slice([1, 2, 3, 4], 2))\nprint(in([1, 2], 3))\n\n[0,1,2,3,4,5,6,7]\n[0,1,2,88,3,4,5,6]\nfalse\n[3,4]\n8\nfalse\n```\n\n* `in()` Checks if a list contains a value\n* `range()` Creates a list from 0 to some integer, or from some start integer to some end integer\n* `len()` Takes the length of a list\n* `insert()` Return a new list with some item inserted at an index in the list.\n* `slice()` Return a new list between, or starting at the index in the arguments.\n\n## License\n\n[MIT License](LICENSE.md)\n\nCopyright (c) 2017 Josh Weinstein\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjweinst1%2Foblivion","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjweinst1%2Foblivion","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjweinst1%2Foblivion/lists"}