Skip to content

Commit

Permalink
add s expression getter for teaching purposes
Browse files Browse the repository at this point in the history
  • Loading branch information
breck7 committed Dec 16, 2024
1 parent 1c507e8 commit 5cb77d6
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 16 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "scrollsdk",
"version": "100.0.1",
"version": "100.1.0",
"description": "This npm package includes the Particles class, the Parsers compiler-compiler, a Parsers IDE, and more, all implemented in Particles, Parsers, and TypeScript.",
"types": "./built/scrollsdk.node.d.ts",
"main": "./products/Particle.js",
Expand Down
43 changes: 43 additions & 0 deletions particle/Particle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4019,6 +4019,49 @@ testParticles.asyncUndoRedo = async equal => {
equal(particle.get("hello"), "earth")
}

testParticles.asSExpression = equal => {
// Test basic nodes with just cue and content
equal(new Particle("foo 1").asSExpression, "((foo 1))", "basic node conversion")

// Test nodes with single child
equal(new Particle("foo 1\n bar 2").asSExpression, "((foo 1 (bar 2)))", "node with single child")

// Test nodes with multiple children
equal(new Particle("foo\n bar 1\n baz 2").asSExpression, "((foo (bar 1) (baz 2)))", "node with multiple children")

// Test deep nesting
equal(new Particle("foo\n bar\n baz 3").asSExpression, "((foo (bar (baz 3))))", "deeply nested nodes")

// Test nodes without content
equal(new Particle("foo\n bar").asSExpression, "((foo (bar)))", "nodes without content")

// Test complex mixed case
equal(new Particle("root 1\n first 2\n inner 3\n other 4\n second 5").asSExpression, "((root 1 (first 2 (inner 3) (other 4)) (second 5)))", "complex mixed nesting")

// Test empty particle
equal(new Particle("").asSExpression, "()", "empty particle")

// Test node with content containing spaces
equal(new Particle("title Hello World").asSExpression, "((title Hello World))", "content with spaces")

// Test realistic example with mixed content types
const webpage = new Particle(`html
head
title My Page
body
div
class main
content Hello world`)

equal(webpage.asSExpression, "((html (head (title My Page)) (body (div (class main) (content Hello world)))))", "realistic webpage example")

// Test a node with blank/empty children
equal(new Particle("parent\n child1\n child2 \n child3").asSExpression, "((parent (child1) (child2 ) (child3)))", "handling empty/blank child nodes")

// Test numbers and special characters in content
equal(new Particle("math\n sum 2+2=4\n pi 3.14159").asSExpression, "((math (sum 2+2=4) (pi 3.14159)))", "handling numbers and special characters")
}

testParticles.trim = equal => {
// Arrange/Act/Assert
const particle = new Particle("\n\n\n")
Expand Down
17 changes: 16 additions & 1 deletion particle/Particle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,21 @@ class Particle extends AbstractParticle {
}
}

get asSExpression(): string {
return this._toSExpression()
}

protected _toSExpression(): string {
const thisAtoms = this.atoms.join(" ")
if (!this.length)
// For leaf nodes, just return (cue content) or (cue) if no content
return `(${thisAtoms})`

// For nodes with children, recursively process each child
const children = this.map(particle => particle._toSExpression()).join(" ")
return thisAtoms ? `(${thisAtoms} ${children})` : `(${children})`
}

get asJson(): string {
return JSON.stringify({ subparticles: this.map(subparticle => subparticle._toObjectForSerialization()) }, null, " ")
}
Expand Down Expand Up @@ -3094,7 +3109,7 @@ class Particle extends AbstractParticle {
return str ? indent + str.replace(/\n/g, indent) : ""
}

static getVersion = () => "100.0.1"
static getVersion = () => "100.1.0"

static fromDisk(path: string): Particle {
const format = this._getFileFormat(path)
Expand Down
1 change: 0 additions & 1 deletion products/Parsers.js
Original file line number Diff line number Diff line change
Expand Up @@ -1819,7 +1819,6 @@ ${captures}
}
return this._cache_parserDefinitionParsers
}
get extendedDef() {}
get hasParserDefinitions() {
return !!this.getSubparticlesByParser(parserDefinitionParser).length
}
Expand Down
1 change: 0 additions & 1 deletion products/Parsers.ts.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -1817,7 +1817,6 @@ ${captures}
}
return this._cache_parserDefinitionParsers
}
get extendedDef() {}
get hasParserDefinitions() {
return !!this.getSubparticlesByParser(parserDefinitionParser).length
}
Expand Down
14 changes: 13 additions & 1 deletion products/Particle.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,18 @@ class Particle extends AbstractParticle {
atoms: this.atoms
}
}
get asSExpression() {
return this._toSExpression()
}
_toSExpression() {
const thisAtoms = this.atoms.join(" ")
if (!this.length)
// For leaf nodes, just return (cue content) or (cue) if no content
return `(${thisAtoms})`
// For nodes with children, recursively process each child
const children = this.map(particle => particle._toSExpression()).join(" ")
return thisAtoms ? `(${thisAtoms} ${children})` : `(${children})`
}
get asJson() {
return JSON.stringify({ subparticles: this.map(subparticle => subparticle._toObjectForSerialization()) }, null, " ")
}
Expand Down Expand Up @@ -2598,7 +2610,7 @@ Particle.iris = `sepal_length,sepal_width,petal_length,petal_width,species
4.9,2.5,4.5,1.7,virginica
5.1,3.5,1.4,0.2,setosa
5,3.4,1.5,0.2,setosa`
Particle.getVersion = () => "100.0.1"
Particle.getVersion = () => "100.1.0"
class AbstractExtendibleParticle extends Particle {
_getFromExtended(cuePath) {
const hit = this._getParticleFromExtended(cuePath)
Expand Down
14 changes: 13 additions & 1 deletion products/Particle.js
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,18 @@ class Particle extends AbstractParticle {
atoms: this.atoms
}
}
get asSExpression() {
return this._toSExpression()
}
_toSExpression() {
const thisAtoms = this.atoms.join(" ")
if (!this.length)
// For leaf nodes, just return (cue content) or (cue) if no content
return `(${thisAtoms})`
// For nodes with children, recursively process each child
const children = this.map(particle => particle._toSExpression()).join(" ")
return thisAtoms ? `(${thisAtoms} ${children})` : `(${children})`
}
get asJson() {
return JSON.stringify({ subparticles: this.map(subparticle => subparticle._toObjectForSerialization()) }, null, " ")
}
Expand Down Expand Up @@ -2588,7 +2600,7 @@ Particle.iris = `sepal_length,sepal_width,petal_length,petal_width,species
4.9,2.5,4.5,1.7,virginica
5.1,3.5,1.4,0.2,setosa
5,3.4,1.5,0.2,setosa`
Particle.getVersion = () => "100.0.1"
Particle.getVersion = () => "100.1.0"
class AbstractExtendibleParticle extends Particle {
_getFromExtended(cuePath) {
const hit = this._getParticleFromExtended(cuePath)
Expand Down
31 changes: 31 additions & 0 deletions products/Particle.test.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -3317,6 +3317,37 @@ testParticles.asyncUndoRedo = async equal => {
// Assert
equal(particle.get("hello"), "earth")
}
testParticles.asSExpression = equal => {
// Test basic nodes with just cue and content
equal(new Particle("foo 1").asSExpression, "((foo 1))", "basic node conversion")
// Test nodes with single child
equal(new Particle("foo 1\n bar 2").asSExpression, "((foo 1 (bar 2)))", "node with single child")
// Test nodes with multiple children
equal(new Particle("foo\n bar 1\n baz 2").asSExpression, "((foo (bar 1) (baz 2)))", "node with multiple children")
// Test deep nesting
equal(new Particle("foo\n bar\n baz 3").asSExpression, "((foo (bar (baz 3))))", "deeply nested nodes")
// Test nodes without content
equal(new Particle("foo\n bar").asSExpression, "((foo (bar)))", "nodes without content")
// Test complex mixed case
equal(new Particle("root 1\n first 2\n inner 3\n other 4\n second 5").asSExpression, "((root 1 (first 2 (inner 3) (other 4)) (second 5)))", "complex mixed nesting")
// Test empty particle
equal(new Particle("").asSExpression, "()", "empty particle")
// Test node with content containing spaces
equal(new Particle("title Hello World").asSExpression, "((title Hello World))", "content with spaces")
// Test realistic example with mixed content types
const webpage = new Particle(`html
head
title My Page
body
div
class main
content Hello world`)
equal(webpage.asSExpression, "((html (head (title My Page)) (body (div (class main) (content Hello world)))))", "realistic webpage example")
// Test a node with blank/empty children
equal(new Particle("parent\n child1\n child2 \n child3").asSExpression, "((parent (child1) (child2 ) (child3)))", "handling empty/blank child nodes")
// Test numbers and special characters in content
equal(new Particle("math\n sum 2+2=4\n pi 3.14159").asSExpression, "((math (sum 2+2=4) (pi 3.14159)))", "handling numbers and special characters")
}
testParticles.trim = equal => {
// Arrange/Act/Assert
const particle = new Particle("\n\n\n")
Expand Down
16 changes: 11 additions & 5 deletions products/SandboxApp.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class SandboxApp extends AbstractParticleComponentParser {
if (eventSource !== "outlineConsole") willowBrowser.setHtmlOfElementWithIdHack("outlineConsole", particle.asOutline)
if (eventSource !== "htmlConsole") willowBrowser.setHtmlOfElementWithIdHack("htmlConsole", particle.asHtml)
if (eventSource !== "tableConsole") willowBrowser.setHtmlOfElementWithIdHack("tableConsole", particle.asTable)
if (eventSource !== "sExpressionConsole") willowBrowser.setValueOfElementWithIdHack("sExpressionConsole", particle.asSExpression)
if (eventSource !== "htmlCubeConsole") willowBrowser.setHtmlOfElementWithIdHack("htmlCubeConsole", particle.asHtmlCube)
if (eventSource !== "fusionConsole") this.updateFusion(particle)
if (eventSource !== "yamlConsole") willowBrowser.setHtmlOfElementWithIdHack("yamlConsole", particle.asYaml)
Expand Down Expand Up @@ -288,17 +289,22 @@ class tableComponent extends AbstractParticleComponentParser {
div asYaml
pre
id yamlConsole
tr
td
div asSExpression
textarea
id sExpressionConsole
td
div Fusion
pre
id fusionConsole
tr
td
div asHtmlCube
title Experimental. This is a very specific kind of Language.
div
id htmlCubeConsole
style position:relative;
td
div Fusion
pre
id fusionConsole`
style position:relative;`
}
}
window.SandboxApp = SandboxApp
3 changes: 3 additions & 0 deletions releaseNotes.scroll
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ node_modules/scroll-cli/microlangs/changes.parsers

thinColumns 4

📦 100.1.0 2024-12-16
🎉 add `asSExpression` getter

📦 100.0.1 2024-12-07
🏥 fixed bug in Parsers where inline Parsers were not in scope in child Parsers

Expand Down
16 changes: 11 additions & 5 deletions sandbox/SandboxApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class SandboxApp extends AbstractParticleComponentParser {
if (eventSource !== "outlineConsole") willowBrowser.setHtmlOfElementWithIdHack("outlineConsole", particle.asOutline)
if (eventSource !== "htmlConsole") willowBrowser.setHtmlOfElementWithIdHack("htmlConsole", particle.asHtml)
if (eventSource !== "tableConsole") willowBrowser.setHtmlOfElementWithIdHack("tableConsole", particle.asTable)
if (eventSource !== "sExpressionConsole") willowBrowser.setValueOfElementWithIdHack("sExpressionConsole", particle.asSExpression)
if (eventSource !== "htmlCubeConsole") willowBrowser.setHtmlOfElementWithIdHack("htmlCubeConsole", particle.asHtmlCube)
if (eventSource !== "fusionConsole") this.updateFusion(particle)
if (eventSource !== "yamlConsole") willowBrowser.setHtmlOfElementWithIdHack("yamlConsole", particle.asYaml)
Expand Down Expand Up @@ -319,17 +320,22 @@ class tableComponent extends AbstractParticleComponentParser {
div asYaml
pre
id yamlConsole
tr
td
div asSExpression
textarea
id sExpressionConsole
td
div Fusion
pre
id fusionConsole
tr
td
div asHtmlCube
title Experimental. This is a very specific kind of Language.
div
id htmlCubeConsole
style position:relative;
td
div Fusion
pre
id fusionConsole`
style position:relative;`
}
}

Expand Down

0 comments on commit 5cb77d6

Please sign in to comment.