Merge remote-tracking branch 'origin/main' into multiline-fn

This commit is contained in:
Corey Johnson 2025-10-27 12:36:12 -07:00
commit 2fcd840493
6 changed files with 52 additions and 10 deletions

View File

@ -303,7 +303,8 @@ export class Compiler {
return instructions return instructions
} }
case terms.ThenBlock: { case terms.ThenBlock:
case terms.SingleLineThenBlock: {
const instructions = getAllChildren(node) const instructions = getAllChildren(node)
.map((child) => this.#compileNode(child, input)) .map((child) => this.#compileNode(child, input))
.flat() .flat()
@ -468,7 +469,11 @@ export class Compiler {
} }
default: 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
)
} }
} }
} }

View File

@ -154,6 +154,10 @@ describe('compiler', () => {
scattered scattered
end`).toEvaluateTo('dwarf') end`).toEvaluateTo('dwarf')
}) })
test('single line if', () => {
expect(`if 3 < 9: shire end`).toEvaluateTo('shire')
})
}) })
describe('errors', () => { describe('errors', () => {

View File

@ -2,7 +2,7 @@
@context trackScope from "./scopeTracker" @context trackScope from "./scopeTracker"
@skip { space } @skip { space | comment }
@top Program { item* } @top Program { item* }
@ -18,6 +18,7 @@
newlineOrSemicolon { "\n" | ";" } newlineOrSemicolon { "\n" | ";" }
eof { @eof } eof { @eof }
space { " " | "\t" } space { " " | "\t" }
comment { "#" ![\n]* }
leftParen { "(" } leftParen { "(" }
rightParen { ")" } rightParen { ")" }
colon[closedBy="end", @name="colon"] { ":" } colon[closedBy="end", @name="colon"] { ":" }
@ -104,7 +105,7 @@ IfExpr {
} }
singleLineIf { singleLineIf {
@specialize[@name=keyword]<Identifier, "if"> (ConditionalOp | expression) colon ThenBlock { consumeToTerminator } @specialize[@name=keyword]<Identifier, "if"> (ConditionalOp | expression) colon SingleLineThenBlock @specialize[@name=keyword]<Identifier, "end">
} }
multilineIf { multilineIf {
@ -123,6 +124,10 @@ ThenBlock {
block block
} }
SingleLineThenBlock {
consumeToTerminator
}
ConditionalOp { ConditionalOp {
expression Eq expression | expression Eq expression |
expression Neq expression | expression Neq expression |

View File

@ -41,6 +41,7 @@ export const
NamedArg = 40, NamedArg = 40,
NamedArgPrefix = 41, NamedArgPrefix = 41,
IfExpr = 43, IfExpr = 43,
SingleLineThenBlock = 45,
ThenBlock = 46, ThenBlock = 46,
ElseIfExpr = 47, ElseIfExpr = 47,
ElseExpr = 49, ElseExpr = 49,

View File

@ -348,3 +348,27 @@ describe('DotGet whitespace sensitivity', () => {
expect('readme.txt').toMatchTree(`Word readme.txt`) expect('readme.txt').toMatchTree(`Word readme.txt`)
}) })
}) })
describe('Comments', () => {
test('are barely there', () => {
expect(`x = 5 # one banana\ny = 2 # two bananas`).toMatchTree(`
Assign
AssignableIdentifier x
Eq =
Number 5
Assign
AssignableIdentifier y
Eq =
Number 2`)
expect('# some comment\nbasename = 5 # very astute\n basename / prop\n# good info').toMatchTree(`
Assign
AssignableIdentifier basename
Eq =
Number 5
BinOp
Identifier basename
Slash /
Identifier prop`)
})
})

View File

@ -4,7 +4,7 @@ import '../shrimp.grammar' // Importing this so changes cause it to retest!
describe('if/elseif/else', () => { describe('if/elseif/else', () => {
test('parses single line if', () => { test('parses single line if', () => {
expect(`if y = 1: 'cool'`).toMatchTree(` expect(`if y = 1: 'cool' end`).toMatchTree(`
IfExpr IfExpr
keyword if keyword if
ConditionalOp ConditionalOp
@ -12,12 +12,13 @@ describe('if/elseif/else', () => {
Eq = Eq =
Number 1 Number 1
colon : colon :
ThenBlock SingleLineThenBlock
String String
StringFragment cool StringFragment cool
keyword end
`) `)
expect('a = if x: 2').toMatchTree(` expect('a = if x: 2 end').toMatchTree(`
Assign Assign
AssignableIdentifier a AssignableIdentifier a
Eq = Eq =
@ -25,8 +26,9 @@ describe('if/elseif/else', () => {
keyword if keyword if
Identifier x Identifier x
colon : colon :
ThenBlock SingleLineThenBlock
Number 2 Number 2
keyword end
`) `)
}) })
@ -138,7 +140,7 @@ describe('if/elseif/else', () => {
}) })
test('does not parse identifiers that start with if', () => { test('does not parse identifiers that start with if', () => {
expect('iffy = if true: 2').toMatchTree(` expect('iffy = if true: 2 end').toMatchTree(`
Assign Assign
AssignableIdentifier iffy AssignableIdentifier iffy
Eq = Eq =
@ -146,8 +148,9 @@ describe('if/elseif/else', () => {
keyword if keyword if
Boolean true Boolean true
colon : colon :
ThenBlock SingleLineThenBlock
Number 2 Number 2
keyword end
`) `)
}) })
}) })