{"_id":"@codincod/codemirror-lang-rockstar","_rev":"2-767b93a5d3d5fa381e35f9f38eaaf1e3","name":"@codincod/codemirror-lang-rockstar","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@codincod/codemirror-lang-rockstar","version":"0.1.0","keywords":["code","codemirror","editor","esoteric","rockstar"],"author":{"name":"CodinCod","email":"hello@codincod.com"},"license":"MIT","_id":"@codincod/codemirror-lang-rockstar@0.1.0","maintainers":[{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"}],"homepage":"https://codincod.com/","dist":{"shasum":"86cfa0e05b989ef95a8e41691930d8ce6c9d6490","tarball":"https://registry.npmjs.org/@codincod/codemirror-lang-rockstar/-/codemirror-lang-rockstar-0.1.0.tgz","fileCount":14,"integrity":"sha512-FXm+TfvVTPsbSDEwueEHNQTbxLC+rJkhqFgIm9XjqIag+lD2spPYEJUPMBRLdh7AF4P19SmzfVNVi6i3nOKEPg==","signatures":[{"sig":"MEUCIQDWArR1N+HlSg37Ec1sJGSXUo52F647m62m5zUwJ/YWwgIgLztfY+DSrVokhUmybX/TYm3oRbWfJORVcgRpsdn0AY4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":151532},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{"import":"./dist/index.js","require":"./dist/index.cjs"},"gitHead":"76cacd84e54133c7828e8924e0d84e8dd8798002","scripts":{"fuzz":"npm run build && node ../lezer-survey/src/cli.ts fuzz","gaps":"npm run build && node ../lezer-survey/src/cli.ts gaps --group parent","test":"npm run build && node --test \"test/*.test.ts\"","build":"rm -rf dist && lezer-generator src/rockstar.grammar -o src/parser.js && cm-buildhelper src/rockstar.ts","corpus":"npm run build && node ../lezer-survey/src/cli.ts measure --group parent","harvest":"node ../lezer-survey/src/cli.ts harvest --ext rock,rockstar --history --max-repo-kb 120000 --words \"shout,whisper,scream,listen,takes,taking,knock,build,mysterious,nothing,gone,silence,giving,back,burn,cast,unite,dump,continue,exactly,nowhere,nobody,ain't,says,holds,without,turn,round,roll,rock,split,join,let,put,into,while,until,else,yeah,baby,plus,minus,times,over,stronger,weaker,bigger,smaller,tommy\" --oracle \"rockstar -p {}\" --reject \"Unexpected|expected|Failed to parse|^Error at\"","prepare":"npm run build","build-debug":"lezer-generator src/rockstar.grammar --names -o src/parser.js && cm-buildhelper src/rockstar.ts"},"_npmUser":{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"},"repository":{"url":"https://codeberg.org/reeven/codemirror-lang-rockstar","type":"git"},"_npmVersion":"11.6.2","description":"Rockstar language support for the CodeMirror code editor","directories":{},"sideEffects":false,"_nodeVersion":"25.0.0","dependencies":{"@lezer/lr":"^1.0.0","@lezer/highlight":"^1.0.0","@codemirror/language":"^6.0.0","@codemirror/autocomplete":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@lezer/generator":"^1.7.0","@codemirror/state":"^6.7.1","@codemirror/buildhelper":"^1.0.2"},"_npmOperationalInternal":{"tmp":"tmp/codemirror-lang-rockstar_0.1.0_1786557203137_0.8185610462852873","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@codincod/codemirror-lang-rockstar","version":"0.2.0","description":"Rockstar language support for the CodeMirror code editor","keywords":["code","codemirror","editor","esoteric","rockstar"],"author":{"name":"CodinCod","email":"hello@codincod.com"},"license":"MIT","type":"module","main":"dist/index.cjs","exports":{"import":"./dist/index.js","require":"./dist/index.cjs"},"module":"dist/index.js","types":"dist/index.d.ts","sideEffects":false,"dependencies":{"@codemirror/autocomplete":"^6.0.0","@codemirror/language":"^6.0.0","@lezer/highlight":"^1.0.0","@lezer/lr":"^1.0.0"},"devDependencies":{"@codemirror/buildhelper":"^1.0.2","@codemirror/state":"^6.7.1","@lezer/generator":"^1.7.0","typescript":"^5.6.0"},"homepage":"https://codincod.com/","repository":{"type":"git","url":"https://codeberg.org/reeven/codemirror-lang-rockstar"},"scripts":{"build":"rm -rf dist && lezer-generator src/rockstar.grammar -o src/parser.js && cm-buildhelper src/rockstar.ts","build-debug":"lezer-generator src/rockstar.grammar --names -o src/parser.js && cm-buildhelper src/rockstar.ts","test":"npm run build && node --test \"test/*.test.ts\"","measure":"npm run build && node ../lezer-survey/src/cli.ts measure --group parent","fuzz":"npm run build && node ../lezer-survey/src/cli.ts fuzz","gaps":"npm run build && node ../lezer-survey/src/cli.ts gaps --group parent","harvest":"node ../lezer-survey/src/cli.ts harvest --ext rock,rockstar --history --max-repo-kb 120000 --words \"shout,whisper,scream,listen,takes,taking,knock,build,mysterious,nothing,gone,silence,giving,back,burn,cast,unite,dump,continue,exactly,nowhere,nobody,ain't,says,holds,without,turn,round,roll,rock,split,join,let,put,into,while,until,else,yeah,baby,plus,minus,times,over,stronger,weaker,bigger,smaller,tommy\" --oracle \"rockstar -p {}\" --reject \"Unexpected|expected|Failed to parse|^Error at\""},"_id":"@codincod/codemirror-lang-rockstar@0.2.0","_integrity":"sha512-tVi6JbyfvLyaEiUI0lUKKQ3a9bgPk3ya7yfX8Nhh7PI/PSYsPIjoPBrN1MkQ7urAWLs9xg5w/e/5jLvxXDJK8Q==","_resolved":"/tmp/f3336dc1037083e2dac528bba8c74573/codincod-codemirror-lang-rockstar-0.2.0.tgz","_from":"file:codincod-codemirror-lang-rockstar-0.2.0.tgz","_nodeVersion":"25.0.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-tVi6JbyfvLyaEiUI0lUKKQ3a9bgPk3ya7yfX8Nhh7PI/PSYsPIjoPBrN1MkQ7urAWLs9xg5w/e/5jLvxXDJK8Q==","shasum":"64e91c86cef6681e55b2db07a7e331ef3ed250c9","tarball":"https://registry.npmjs.org/@codincod/codemirror-lang-rockstar/-/codemirror-lang-rockstar-0.2.0.tgz","fileCount":14,"unpackedSize":161928,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCMEPo+PzDjrkDqsbbubn1ZDVwbV8flwJ2TSFWyWnIcxgIhAK+uh0r/ZVS0bQd3KMtlcPI5WESAYD8OpWBy9rtFul8/"}]},"_npmUser":{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"},"directories":{},"maintainers":[{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/codemirror-lang-rockstar_0.2.0_1786831878301_0.2967703461001543"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-12T17:53:23.024Z","modified":"2026-08-15T22:11:18.661Z","0.1.0":"2026-08-12T17:53:23.287Z","0.2.0":"2026-08-15T22:11:18.475Z"},"author":{"name":"CodinCod","email":"hello@codincod.com"},"license":"MIT","homepage":"https://codincod.com/","keywords":["code","codemirror","editor","esoteric","rockstar"],"repository":{"type":"git","url":"https://codeberg.org/reeven/codemirror-lang-rockstar"},"description":"Rockstar language support for the CodeMirror code editor","maintainers":[{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"}],"readme":"# @codincod/codemirror-lang-rockstar [![NPM version](https://img.shields.io/npm/v/@codincod/codemirror-lang-rockstar.svg)](https://www.npmjs.org/package/@codincod/codemirror-lang-rockstar)\n\n[ [**CHANGELOG**](https://codeberg.org/reeven/codemirror-lang-rockstar/src/branch/master/CHANGELOG.md) ]\n\nThis package implements [Rockstar](https://codewithrockstar.com/) language\nsupport for the [CodeMirror](https://codemirror.net/) code editor, using a\n[Lezer](https://lezer.codemirror.net/) grammar ported from the reference\nimplementation's own grammar.\n\nRockstar is a language whose programs are power ballads. It is designed so that\na program can be sung, which means most of its syntax is English: a keyword is\na set of words, a variable name can hold a space, and a line of lyrics can be a\nnumber.\n\nWritten in part for [CodinCod](https://codincod.com/), a competitive coding\nplatform, where it colours the editor people solve puzzles in.\n\nThis code is released under an\n[MIT license](https://codeberg.org/reeven/codemirror-lang-rockstar/src/branch/master/LICENSE).\n\n## Usage\n\n```javascript\nimport {EditorView, basicSetup} from \"codemirror\"\nimport {rockstar} from \"@codincod/codemirror-lang-rockstar\"\n\nconst view = new EditorView({\n  parent: document.body,\n  doc: `Tommy was a lovestruck ladykiller\\nShout Tommy`,\n  extensions: [basicSetup, rockstar()]\n})\n```\n\n## What was there before\n\nThe Rockstar repository carries a `cm-lang-rockstar` directory holding a Lezer\ngrammar of its own, which was never published to npm. Most of its statement\nrules are commented out: functions, conditionals, increments, mutations and\nrounding are all absent, and a program using any of them does not parse. This\ngrammar is a fresh one, ported from `Starship/Rockstar.Engine/rockstar.peg`,\nthe Pegasus grammar the reference implementation actually parses with, and it\ncovers the language as of Rockstar 2.0.30.\n\n## What a PEG can say and an LR parser cannot\n\nThe reference grammar is a PEG, with ordered choice and unbounded lookahead.\nLezer is LR, so four things move out of the grammar and into an external\ntokenizer, and a fifth is there because a token made of a regular expression\ncannot count: a comment in parentheses nests to any depth, and the reference\nsays so in its own test suite.\n\n**A keyword is a set of words, not a word.** `is`, `was`, `are`, `were` and\n`am` are one token, and so are `print`, `say`, `shout`, `scream` and `whisper`.\nEvery one of them is case insensitive, which a Lezer token cannot be, so the\ntokenizer lowercases what it reads and looks the result up. Which token a word\nbecomes then depends on the parser state: `with` is the argument list of a\ncall, the modifier of a cast, and addition, and only one of the three is legal\nat any point.\n\n**A variable name can hold a space.** `the night`, `my heart` and\n`Johnny B Goode` are each one name. Whether a word begins a name is decided by\nthe word after it, so a name is read whole rather than assembled from parts.\n\n**Most of a poetic literal is not syntax.** `My heart is on fire` assigns 24,\nbecause the words are digits and their lengths are the number, and everything\nto the end of the line belongs to the literal, full stops and all. Whether a\nline holds one is decided by its first word: the reference grammar refuses a\npoetic number that starts with a word that could start an expression, and so\ndoes this.\n\n**A block ends at a blank line, at `end`, or in front of `else`.** Only the\nfirst two consume anything, so the token that closes a block in front of an\n`else` is empty, the way `@lezer/python`'s dedent is. One blank line closes one\nblock, which is the reference behaviour and is worth knowing when reading a\ndeeply nested program.\n\n## What it was measured on\n\n**781 published Rockstar programs, of which 777 parse with no error node:\n99.49%.**\n\nThat is not a sample. Rockstar is not a language GitHub Linguist knows, so\nthere is no `language:` search to build a corpus from; the corpus was found by\nsearching code for the language's own vocabulary instead, one query per word,\nunioned by repository. Every word converged on the same handful of\nrepositories, which is what the whole of the language's public record turned\nout to be, and 121 of them had a program in. The great majority of what the\nextension gathers is not Rockstar at all: `.rock` is LuaRocks' package archive\nextension as well, so most of the harvest is binary archives, and the rest is\npadded with empty files and with copies of one file.\n\nWhat was left went one at a time to Rockstar itself, through `rockstar -p`,\nwhich parses without running. It refused the files in some other language that\nalso uses the extension, the songs that were never programs, and the ones\nwritten for Rockstar 1. The repositories that survived that and are still not\nRockstar were found by reading the failures: an oracle written for a language\nwhose every unknown word is a variable name is a floor and not a filter.\n\nThe four that still fail are each their own: two put a statement after the word\nthat closes a block, which the reference reaches by trying the line again and\nan LR parser has no second attempt at, and two are lines the reference reads by\nbacktracking out of a reading this grammar has already committed to.\n\n`npm run harvest -- <corpus>` rebuilds all of it. The command is\n[lezer-survey](https://codeberg.org/reeven/lezer-survey)'s, the corpus harness\nthese grammars share, and the words and the oracle are the arguments in\n`package.json`.\n\n## Deliberately looser than the reference\n\nA few readings are wider here than in the PEG, each because the narrower one\ncosts a rule and buys nothing a colour can show:\n\n- `X is minus 5` is read as a sign in front of a list rather than as a compound\n  assignment. Both colour the same.\n- A word that the parser state has no use for as a keyword becomes a name.\n  `Now is nothing` names a variable `Now`, which every implementation accepts\n  and the written grammar does not quite say.\n- An index is arithmetic at most, never a comparison, so\n  `Absolution at 1 is \"Apocalypse Please\"` assigns to a slot rather than\n  comparing one.\n- The clauses a mutation or a push takes may repeat and may come in any order.\n  The reference decides between them by backtracking: `Cast X with Y using Z`\n  reads `with` as addition only because the `using` further along has taken the\n  role it would otherwise have had, and an LR parser has no way to see that\n  coming.\n- A comma may sit between a block's header and the rest of its line, which is\n  what `While gamma ain't nothing, write it` and `Otherwise, if X` are written\n  with.\n\nAnd one place it is narrower. The reference is a PEG, so a line it reads the\nwrong way round is given back and tried as something else. `tokens.ts` buys a\nlittle of that with lookahead, which is how `Rock is electric heaven` assigns\nto a variable called Rock and `Print takes Message` defines a function called\nPrint, but it is lookahead and not a second attempt. Where the reference needs\nthe whole of the rest of the line to decide, this grammar has already\ncommitted.\n","readmeFilename":"README.md"}