From 686c6f90d7a3c2bc0f8b89619c5d91ee8fb320e4 Mon Sep 17 00:00:00 2001 From: Elizabeth Hunt Date: Sun, 4 Jan 2026 22:15:20 -0800 Subject: Add tabloid language support --- src/index.ts | 51 ++++++++++++++++++++ src/syntax.grammar | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 src/index.ts create mode 100644 src/syntax.grammar (limited to 'src') diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..14b4ffe --- /dev/null +++ b/src/index.ts @@ -0,0 +1,51 @@ +import {parser} from "./syntax.grammar" +import {LRLanguage, LanguageSupport, indentNodeProp, foldNodeProp, foldInside, delimitedIndent} from "@codemirror/language" +import {styleTags, tags as t} from "@lezer/highlight" + +export const tabloidLanguage = LRLanguage.define({ + parser: parser.configure({ + props: [ + indentNodeProp.add({ + Block: delimitedIndent({closing: "endOfStory", align: false}), + ParenBlock: delimitedIndent({closing: ")", align: false}), + FunctionDecl: context => context.baseIndent + context.unit, + IfStatement: context => context.baseIndent + context.unit, + }), + foldNodeProp.add({ + Block: foldInside, + ParenBlock: foldInside, + }), + styleTags({ + Identifier: t.variableName, + NumberLiteral: t.number, + StringLiteral: t.string, + BooleanLiteral: t.bool, + FunctionCall: t.function(t.variableName), + discoverHowTo: t.definitionKeyword, + expertsClaim: t.definitionKeyword, + toBe: t.operatorKeyword, + rumorHasIt: t.keyword, + endOfStory: t.keyword, + whatIf: t.controlKeyword, + liesBang: t.controlKeyword, + shockingDevelopment: t.controlKeyword, + youWontWantToMiss: t.keyword, + latestNewsOn: t.keyword, + pleaseLikeAndSubscribe: t.keyword, + "with of": t.keyword, + "isActually beats smallerThan": t.compareOperator, + "and or": t.logicOperator, + "plus minus times dividedBy modulo": t.arithmeticOperator, + "( )": t.paren, + ",": t.separator + }) + ] + }), + languageData: { + commentTokens: {} + } +}) + +export function tabloid() { + return new LanguageSupport(tabloidLanguage) +} diff --git a/src/syntax.grammar b/src/syntax.grammar new file mode 100644 index 0000000..bffd9c4 --- /dev/null +++ b/src/syntax.grammar @@ -0,0 +1,136 @@ +@top Program { statement* ProgramEnd } + +@precedence { + else, + call, + times @left, + plus @left, + compare @left, + and @left, + or @left +} + +statement { + FunctionDecl | + Assignment | + IfStatement | + ReturnStatement | + Block | + ExprStatement +} + +ExprStatement { expression } + +FunctionDecl { + discoverHowTo Identifier (with ArgumentList)? statement +} + +ArgumentList { Identifier ("," Identifier)* } + +Assignment { + expertsClaim Identifier toBe expression +} + +IfStatement { + whatIf expression statement (!else liesBang statement)? +} + +ReturnStatement { + shockingDevelopment expression +} + +PrintStatement { + youWontWantToMiss expression +} + +InputStatement { + latestNewsOn expression +} + +Block { + rumorHasIt statement* endOfStory +} + +ParenBlock { + "(" statement* ")" +} + +FunctionCall { + Identifier !call of ArgumentExpression ("," ArgumentExpression)* +} + +ArgumentExpression { expression } + +expression { + NumberLiteral | + StringLiteral | + BooleanLiteral | + Identifier | + FunctionCall | + ParenBlock | + PrintStatement | + InputStatement | + BinaryExpression +} + +BinaryExpression { + expression !times (times | dividedBy | modulo) expression | + expression !plus (plus | minus) expression | + expression !compare (isActually | beats | smallerThan) expression | + expression !and and expression | + expression !or or expression +} + +ProgramEnd { + pleaseLikeAndSubscribe +} + +@skip { space | newline } + +@tokens { + space { $[ \t]+ } + newline { $[\n\r] } + + identifierChar { $[A-Z_\-] | $[0-9] | "'" } + + word { ($[A-Z_\-] | "'") identifierChar* } + + @precedence { StringLiteral, NumberLiteral, BooleanLiteral, discoverHowTo, expertsClaim, latestNewsOn, pleaseLikeAndSubscribe, rumorHasIt, shockingDevelopment, whatIf, youWontWantToMiss, toBe, with, of, endOfStory, liesBang, isActually, dividedBy, smallerThan, and, or, plus, minus, times, modulo, beats, Identifier } + + Identifier { word } + + NumberLiteral { $[0-9]+ ("." $[0-9]+)? } + + StringLiteral { '"' (!["\\] | "\\" _)* '"' | "'" (!['\\] | "\\" _)* "'" } + + BooleanLiteral { "TOTALLY" space "RIGHT" | "COMPLETELY" space "WRONG" } + + discoverHowTo { "DISCOVER" space "HOW" space "TO" } + with { "WITH" } + of { "OF" } + expertsClaim { "EXPERTS" space "CLAIM" } + toBe { "TO" space "BE" } + rumorHasIt { "RUMOR" space "HAS" space "IT" } + whatIf { "WHAT" space "IF" } + liesBang { "LIES!" } + endOfStory { "END" space "OF" space "STORY" } + shockingDevelopment { "SHOCKING" space "DEVELOPMENT" } + youWontWantToMiss { "YOU" space "WON'T" space "WANT" space "TO" space "MISS" } + latestNewsOn { "LATEST" space "NEWS" space "ON" } + pleaseLikeAndSubscribe { "PLEASE" space "LIKE" space "AND" space "SUBSCRIBE" } + + isActually { "IS" space "ACTUALLY" } + and { "AND" } + or { "OR" } + plus { "PLUS" } + minus { "MINUS" } + times { "TIMES" } + dividedBy { "DIVIDED" space "BY" } + modulo { "MODULO" } + beats { "BEATS" } + smallerThan { "SMALLER" space "THAN" } + + "(" ")" "," +} + +@detectDelim -- cgit v1.2.3-70-g09d2