From e4100c7d89bd8928d74b63bfb9101def7cdf3b91 Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Sat, 25 Oct 2025 19:51:57 -0700 Subject: [PATCH 1/2] failing single line if test --- src/compiler/tests/compiler.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/compiler/tests/compiler.test.ts b/src/compiler/tests/compiler.test.ts index 35da324..603a9eb 100644 --- a/src/compiler/tests/compiler.test.ts +++ b/src/compiler/tests/compiler.test.ts @@ -139,6 +139,10 @@ describe('compiler', () => { scattered end`).toEvaluateTo('dwarf') }) + + test('single line if', () => { + expect(`if 3 < 9: shire`).toEvaluateTo('shire') + }) }) describe('errors', () => { -- 2.50.1 From 6e432dd7a1d75c3aa407fbdc30bfba9999db3f4e Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Mon, 27 Oct 2025 11:30:49 -0700 Subject: [PATCH 2/2] Made it work --- src/compiler/compiler.ts | 9 +++++++-- src/compiler/tests/compiler.test.ts | 2 +- src/parser/shrimp.grammar | 6 +++++- src/parser/shrimp.terms.ts | 1 + src/parser/shrimp.ts | 10 +++++----- src/parser/tests/control-flow.test.ts | 15 +++++++++------ 6 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/compiler/compiler.ts b/src/compiler/compiler.ts index 212da55..b7e6274 100644 --- a/src/compiler/compiler.ts +++ b/src/compiler/compiler.ts @@ -303,7 +303,8 @@ export class Compiler { return instructions } - case terms.ThenBlock: { + case terms.ThenBlock: + case terms.SingleLineThenBlock: { const instructions = getAllChildren(node) .map((child) => this.#compileNode(child, input)) .flat() @@ -468,7 +469,11 @@ export class Compiler { } default: - throw new CompilerError(`Unsupported syntax node: ${node.type.name}`, node.from, node.to) + throw new CompilerError( + `Compiler doesn't know how to handle a "${node.type.name}" node.`, + node.from, + node.to + ) } } } diff --git a/src/compiler/tests/compiler.test.ts b/src/compiler/tests/compiler.test.ts index 603a9eb..40b2271 100644 --- a/src/compiler/tests/compiler.test.ts +++ b/src/compiler/tests/compiler.test.ts @@ -141,7 +141,7 @@ describe('compiler', () => { }) test('single line if', () => { - expect(`if 3 < 9: shire`).toEvaluateTo('shire') + expect(`if 3 < 9: shire end`).toEvaluateTo('shire') }) }) diff --git a/src/parser/shrimp.grammar b/src/parser/shrimp.grammar index c608994..d1ceb9b 100644 --- a/src/parser/shrimp.grammar +++ b/src/parser/shrimp.grammar @@ -105,7 +105,7 @@ IfExpr { } singleLineIf { - @specialize[@name=keyword] (ConditionalOp | expression) colon ThenBlock { consumeToTerminator } + @specialize[@name=keyword] (ConditionalOp | expression) colon SingleLineThenBlock @specialize[@name=keyword] } multilineIf { @@ -124,6 +124,10 @@ ThenBlock { block } +SingleLineThenBlock { + consumeToTerminator +} + ConditionalOp { expression Eq expression | expression Neq expression | diff --git a/src/parser/shrimp.terms.ts b/src/parser/shrimp.terms.ts index 75f88be..2b65bbc 100644 --- a/src/parser/shrimp.terms.ts +++ b/src/parser/shrimp.terms.ts @@ -41,6 +41,7 @@ export const NamedArg = 40, NamedArgPrefix = 41, IfExpr = 43, + SingleLineThenBlock = 45, ThenBlock = 46, ElseIfExpr = 47, ElseExpr = 49, diff --git a/src/parser/shrimp.ts b/src/parser/shrimp.ts index dfcbbe4..10dc75f 100644 --- a/src/parser/shrimp.ts +++ b/src/parser/shrimp.ts @@ -7,10 +7,10 @@ import {highlighting} from "./highlight" const spec_Identifier = {__proto__:null,do:52, end:58, null:74, if:88, elseif:96, else:100} export const parser = LRParser.deserialize({ version: 14, - states: ".jQYQbOOO#[QcO'#CrO$UQRO'#CsO$dQcO'#DnO${QbO'#DtOOQ`'#Cu'#CuO%TQbO'#CqO%uOSO'#CzOOQa'#Dr'#DrO&TOpO'#DSO&YQcO'#DqOOQ`'#Do'#DoO&qQbO'#DnO'PQbO'#EROOQ`'#DX'#DXO'nQRO'#DaOOQ`'#Dn'#DnO'sQQO'#DmOOQ`'#Dm'#DmOOQ`'#Db'#DbQYQbOOOOQa'#Dq'#DqOOQ`'#Cp'#CpO'{QbO'#DUOOQ`'#Dp'#DpOOQ`'#Dc'#DcO(VQbO,59ZO'PQbO,59_O'PQbO,59_OOQ`'#Dd'#DdO(sQbO'#CwO({QQO,5:`O)lQRO'#CsO)|QRO,59]O*_QRO,59]O*YQQO,59]O+YQQO,59]O+bQbO'#C|O+jQWO'#C}OOOO'#Dz'#DzOOOO'#Df'#DfO,OOSO,59fOOQa,59f,59fO,^O`O,59nO,cQbO'#DgO,hQbO,59YO,yQRO,5:mO-QQQO,5:mO-VQbO,59{OOQ`,5:X,5:XOOQ`-E7`-E7`OOQ`,59p,59pOOQ`-E7a-E7aOOQa1G.y1G.yO-aQcO1G.yOOQ`-E7b-E7bO-{QbO1G/zO'PQbO,59`O'PQbO,59`OOQa1G.w1G.wOOOO,59h,59hOOOO,59i,59iOOOO-E7d-E7dOOQa1G/Q1G/QOOQa1G/Y1G/YO!TQbO'#CrOOQ`,5:R,5:ROOQ`-E7e-E7eO.YQbO1G0XOOQ`1G/g1G/gO.gQbO7+%fO.lQbO7+%gOOQO1G.z1G.zO.yQRO1G.zOOQ`'#DZ'#DZOOQ`7+%s7+%sO/TQbO7+%tOOQ`<mAN>mO'PQbO'#D]OOQ`'#Dh'#DhO0bQbOAN>zO0mQQO'#D_OOQ`AN>zAN>zO0rQbOAN>zO0wQRO,59wO1OQQO,59wOOQ`-E7f-E7fOOQ`G24fG24fO1TQbOG24fO1YQQO,59yO1_QQO1G/cOOQ`LD*QLD*QO.lQbO1G/eO/TQbO7+$}OOQ`7+%P7+%POOQ`<mAN>mO'PQbO'#D]OOQ`'#Dh'#DhO0gQbOAN>zO0rQQO'#D_OOQ`AN>zAN>zO0wQbOAN>zO0|QRO,59wO1TQQO,59wOOQ`-E7f-E7fOOQ`G24fG24fO1YQbOG24fO1_QQO,59yO1dQQO1G/cOOQ`LD*QLD*QO.lQbO1G/eO/YQbO7+$}OOQ`7+%P7+%POOQ`< spec_Identifier[value] || -1}], - tokenPrec: 756 + tokenPrec: 761 }) diff --git a/src/parser/tests/control-flow.test.ts b/src/parser/tests/control-flow.test.ts index df1bc3c..11c81d0 100644 --- a/src/parser/tests/control-flow.test.ts +++ b/src/parser/tests/control-flow.test.ts @@ -4,7 +4,7 @@ import '../shrimp.grammar' // Importing this so changes cause it to retest! describe('if/elseif/else', () => { test('parses single line if', () => { - expect(`if y = 1: 'cool'`).toMatchTree(` + expect(`if y = 1: 'cool' end`).toMatchTree(` IfExpr keyword if ConditionalOp @@ -12,12 +12,13 @@ describe('if/elseif/else', () => { Eq = Number 1 colon : - ThenBlock + SingleLineThenBlock String StringFragment cool + keyword end `) - expect('a = if x: 2').toMatchTree(` + expect('a = if x: 2 end').toMatchTree(` Assign AssignableIdentifier a Eq = @@ -25,8 +26,9 @@ describe('if/elseif/else', () => { keyword if Identifier x colon : - ThenBlock + SingleLineThenBlock Number 2 + keyword end `) }) @@ -138,7 +140,7 @@ describe('if/elseif/else', () => { }) test('does not parse identifiers that start with if', () => { - expect('iffy = if true: 2').toMatchTree(` + expect('iffy = if true: 2 end').toMatchTree(` Assign AssignableIdentifier iffy Eq = @@ -146,8 +148,9 @@ describe('if/elseif/else', () => { keyword if Boolean true colon : - ThenBlock + SingleLineThenBlock Number 2 + keyword end `) }) }) -- 2.50.1