Skip to content

Commit

Permalink
bitsRequired method
Browse files Browse the repository at this point in the history
  • Loading branch information
breck7 committed Dec 1, 2024
1 parent 0ab30bf commit 18124ae
Show file tree
Hide file tree
Showing 12 changed files with 169 additions and 4 deletions.
2 changes: 2 additions & 0 deletions langs/jibberish/jibberish.parsers
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ integerAtom
onoffAtom
enum on off
atomAtom
keywordAtom
topLevelPropertyAtom
paint constant.language
extends keywordAtom
opSymbolAtom
paint keyword.operator.arithmetic

Expand Down
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": "99.0.0",
"version": "99.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
10 changes: 10 additions & 0 deletions parsers/Parsers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,16 @@ anyAtom`
}
}

testParticles.informationContent = equal => {
// Test bit atom
const bitProgram = makeJibberishProgram("lightbulbState on")
const bitParticle = bitProgram.particleAt(0)
const atom = bitParticle.parsedAtoms[1]
equal(atom.bitsRequired, 1, "bit atom should have 1 bit of information")
equal(bitParticle.parsedAtoms[0].bitsRequired, 0, "cue word should have 0 bits of information. particle is fixed.")
equal(bitParticle.bitsRequired, 1, "bit particle should have 1 bit of information")
}

testParticles.duplicateParsers = equal => {
// Arrange/Act
const anyProgram = makeJibberishProgram(`type foo
Expand Down
55 changes: 55 additions & 0 deletions parsers/Parsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,22 @@ abstract class ParserBackedParticle extends Particle {
return newIndex
}

/**
* Returns the total information bits required to represent this particle and all its subparticles.
* This is calculated as the sum of:
* 1. Information bits of all atoms in this particle
* 2. Information bits of all subparticles (recursive)
*/
get bitsRequired(): number {
// Get information bits for all atoms in this particle
const atomBits = this.parsedAtoms.map(atom => atom.bitsRequired).reduce((sum, bits) => sum + bits, 0)

// Recursively get information bits from all subparticles
const subparticleBits = this.map(child => (<ParserBackedParticle>child).bitsRequired).reduce((sum, bits) => sum + bits, 0)

return atomBits + subparticleBits
}

getSubparticleInstancesOfParserId(parserId: particlesTypes.parserId): ParserBackedParticle[] {
return this.particleIndex[parserId] || []
}
Expand Down Expand Up @@ -773,6 +789,13 @@ abstract class AbstractParsersBackedAtom<T> {
this._parserDefinitionParser = parserDefinitionParser
}

get optionCount() {
return this._typeDef.optionCount
}
get bitsRequired() {
return Math.log2(this.optionCount)
}

getAtom() {
return this._particle.getAtom(this._index)
}
Expand Down Expand Up @@ -909,6 +932,10 @@ class ParsersBitAtom extends AbstractParsersBackedAtom<boolean> {
return atom === "0" || atom === "1"
}

get optionCount() {
return 2
}

static defaultPaint = "constant.numeric"

_synthesizeAtom() {
Expand Down Expand Up @@ -944,6 +971,12 @@ class ParsersIntegerAtom extends ParsersNumberAtom {
return num.toString() === atom
}

get optionCount() {
const minVal = parseInt(this.min) || -Infinity
const maxVal = parseInt(this.max) || Infinity
return maxVal - minVal + 1
}

static defaultPaint = "constant.numeric.integer"

_synthesizeAtom(seed: number) {
Expand All @@ -969,6 +1002,14 @@ class ParsersFloatAtom extends ParsersNumberAtom {
return !isNaN(num) && /^-?\d*(\.\d+)?([eE][+-]?\d+)?$/.test(atom)
}

get optionCount() {
// For floats, we'll estimate based on typical float32 precision
// ~7 decimal digits of precision
const minVal = parseInt(this.min) || -Infinity
const maxVal = parseInt(this.max) || Infinity
return (maxVal - minVal) * Math.pow(10, 7)
}

static defaultPaint = "constant.numeric.float"

_synthesizeAtom(seed: number) {
Expand Down Expand Up @@ -999,6 +1040,10 @@ class ParsersBooleanAtom extends AbstractParsersBackedAtom<boolean> {
return this._trues.has(str) || this._falses.has(str)
}

get optionCount() {
return 2
}

static defaultPaint = "constant.language"

_synthesizeAtom() {
Expand Down Expand Up @@ -1045,6 +1090,10 @@ class ParsersKeywordAtom extends ParsersAnyAtom {
_synthesizeAtom() {
return this._parserDefinitionParser.cueIfAny
}

get optionCount() {
return 1
}
}

class ParsersExtraAtomAtomTypeAtom extends AbstractParsersBackedAtom<string> {
Expand Down Expand Up @@ -1542,6 +1591,12 @@ class atomTypeDefinitionParser extends AbstractExtendibleParticle {
return options
}

get optionCount() {
const enumOptions = this._getEnumOptions()
if (enumOptions) return enumOptions.length
return Infinity
}

private _getEnumFromAtomTypeOptions(program: ParserBackedParticle) {
const particle = this._getParticleFromExtended(ParsersConstants.enumFromAtomTypes)
return particle ? Object.keys((<EnumFromAtomTypesTestParser>particle.getParticle(ParsersConstants.enumFromAtomTypes))._getEnumFromAtomTypes(program)) : undefined
Expand Down
2 changes: 1 addition & 1 deletion particle/Particle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3094,7 +3094,7 @@ class Particle extends AbstractParticle {
return str ? indent + str.replace(/\n/g, indent) : ""
}

static getVersion = () => "99.0.0"
static getVersion = () => "99.1.0"

static fromDisk(path: string): Particle {
const format = this._getFileFormat(path)
Expand Down
45 changes: 45 additions & 0 deletions products/Parsers.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,19 @@ class ParserBackedParticle extends Particle {
}
return newIndex
}
/**
* Returns the total information bits required to represent this particle and all its subparticles.
* This is calculated as the sum of:
* 1. Information bits of all atoms in this particle
* 2. Information bits of all subparticles (recursive)
*/
get bitsRequired() {
// Get information bits for all atoms in this particle
const atomBits = this.parsedAtoms.map(atom => atom.bitsRequired).reduce((sum, bits) => sum + bits, 0)
// Recursively get information bits from all subparticles
const subparticleBits = this.map(child => child.bitsRequired).reduce((sum, bits) => sum + bits, 0)
return atomBits + subparticleBits
}
getSubparticleInstancesOfParserId(parserId) {
return this.particleIndex[parserId] || []
}
Expand Down Expand Up @@ -629,6 +642,12 @@ class AbstractParsersBackedAtom {
this._atomTypeId = atomTypeId
this._parserDefinitionParser = parserDefinitionParser
}
get optionCount() {
return this._typeDef.optionCount
}
get bitsRequired() {
return Math.log2(this.optionCount)
}
getAtom() {
return this._particle.getAtom(this._index)
}
Expand Down Expand Up @@ -728,6 +747,9 @@ class ParsersBitAtom extends AbstractParsersBackedAtom {
const atom = this.getAtom()
return atom === "0" || atom === "1"
}
get optionCount() {
return 2
}
_synthesizeAtom() {
return Utils.getRandomString(1, "01".split(""))
}
Expand Down Expand Up @@ -757,6 +779,11 @@ class ParsersIntegerAtom extends ParsersNumberAtom {
if (isNaN(num)) return false
return num.toString() === atom
}
get optionCount() {
const minVal = parseInt(this.min) || -Infinity
const maxVal = parseInt(this.max) || Infinity
return maxVal - minVal + 1
}
_synthesizeAtom(seed) {
return Utils.randomUniformInt(parseInt(this.min), parseInt(this.max), seed).toString()
}
Expand All @@ -776,6 +803,13 @@ class ParsersFloatAtom extends ParsersNumberAtom {
const num = parseFloat(atom)
return !isNaN(num) && /^-?\d*(\.\d+)?([eE][+-]?\d+)?$/.test(atom)
}
get optionCount() {
// For floats, we'll estimate based on typical float32 precision
// ~7 decimal digits of precision
const minVal = parseInt(this.min) || -Infinity
const maxVal = parseInt(this.max) || Infinity
return (maxVal - minVal) * Math.pow(10, 7)
}
_synthesizeAtom(seed) {
return Utils.randomUniformFloat(parseFloat(this.min), parseFloat(this.max), seed).toString()
}
Expand All @@ -801,6 +835,9 @@ class ParsersBooleanAtom extends AbstractParsersBackedAtom {
const str = atom.toLowerCase()
return this._trues.has(str) || this._falses.has(str)
}
get optionCount() {
return 2
}
_synthesizeAtom() {
return Utils.getRandomString(1, ["1", "true", "t", "yes", "0", "false", "f", "no"])
}
Expand Down Expand Up @@ -836,6 +873,9 @@ class ParsersKeywordAtom extends ParsersAnyAtom {
_synthesizeAtom() {
return this._parserDefinitionParser.cueIfAny
}
get optionCount() {
return 1
}
}
ParsersKeywordAtom.defaultPaint = "keyword"
class ParsersExtraAtomAtomTypeAtom extends AbstractParsersBackedAtom {
Expand Down Expand Up @@ -1227,6 +1267,11 @@ class atomTypeDefinitionParser extends AbstractExtendibleParticle {
options.sort((a, b) => b.length - a.length)
return options
}
get optionCount() {
const enumOptions = this._getEnumOptions()
if (enumOptions) return enumOptions.length
return Infinity
}
_getEnumFromAtomTypeOptions(program) {
const particle = this._getParticleFromExtended(ParsersConstants.enumFromAtomTypes)
return particle ? Object.keys(particle.getParticle(ParsersConstants.enumFromAtomTypes)._getEnumFromAtomTypes(program)) : undefined
Expand Down
45 changes: 45 additions & 0 deletions products/Parsers.ts.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,19 @@ class ParserBackedParticle extends Particle {
}
return newIndex
}
/**
* Returns the total information bits required to represent this particle and all its subparticles.
* This is calculated as the sum of:
* 1. Information bits of all atoms in this particle
* 2. Information bits of all subparticles (recursive)
*/
get bitsRequired() {
// Get information bits for all atoms in this particle
const atomBits = this.parsedAtoms.map(atom => atom.bitsRequired).reduce((sum, bits) => sum + bits, 0)
// Recursively get information bits from all subparticles
const subparticleBits = this.map(child => child.bitsRequired).reduce((sum, bits) => sum + bits, 0)
return atomBits + subparticleBits
}
getSubparticleInstancesOfParserId(parserId) {
return this.particleIndex[parserId] || []
}
Expand Down Expand Up @@ -627,6 +640,12 @@ class AbstractParsersBackedAtom {
this._atomTypeId = atomTypeId
this._parserDefinitionParser = parserDefinitionParser
}
get optionCount() {
return this._typeDef.optionCount
}
get bitsRequired() {
return Math.log2(this.optionCount)
}
getAtom() {
return this._particle.getAtom(this._index)
}
Expand Down Expand Up @@ -726,6 +745,9 @@ class ParsersBitAtom extends AbstractParsersBackedAtom {
const atom = this.getAtom()
return atom === "0" || atom === "1"
}
get optionCount() {
return 2
}
_synthesizeAtom() {
return Utils.getRandomString(1, "01".split(""))
}
Expand Down Expand Up @@ -755,6 +777,11 @@ class ParsersIntegerAtom extends ParsersNumberAtom {
if (isNaN(num)) return false
return num.toString() === atom
}
get optionCount() {
const minVal = parseInt(this.min) || -Infinity
const maxVal = parseInt(this.max) || Infinity
return maxVal - minVal + 1
}
_synthesizeAtom(seed) {
return Utils.randomUniformInt(parseInt(this.min), parseInt(this.max), seed).toString()
}
Expand All @@ -774,6 +801,13 @@ class ParsersFloatAtom extends ParsersNumberAtom {
const num = parseFloat(atom)
return !isNaN(num) && /^-?\d*(\.\d+)?([eE][+-]?\d+)?$/.test(atom)
}
get optionCount() {
// For floats, we'll estimate based on typical float32 precision
// ~7 decimal digits of precision
const minVal = parseInt(this.min) || -Infinity
const maxVal = parseInt(this.max) || Infinity
return (maxVal - minVal) * Math.pow(10, 7)
}
_synthesizeAtom(seed) {
return Utils.randomUniformFloat(parseFloat(this.min), parseFloat(this.max), seed).toString()
}
Expand All @@ -799,6 +833,9 @@ class ParsersBooleanAtom extends AbstractParsersBackedAtom {
const str = atom.toLowerCase()
return this._trues.has(str) || this._falses.has(str)
}
get optionCount() {
return 2
}
_synthesizeAtom() {
return Utils.getRandomString(1, ["1", "true", "t", "yes", "0", "false", "f", "no"])
}
Expand Down Expand Up @@ -834,6 +871,9 @@ class ParsersKeywordAtom extends ParsersAnyAtom {
_synthesizeAtom() {
return this._parserDefinitionParser.cueIfAny
}
get optionCount() {
return 1
}
}
ParsersKeywordAtom.defaultPaint = "keyword"
class ParsersExtraAtomAtomTypeAtom extends AbstractParsersBackedAtom {
Expand Down Expand Up @@ -1225,6 +1265,11 @@ class atomTypeDefinitionParser extends AbstractExtendibleParticle {
options.sort((a, b) => b.length - a.length)
return options
}
get optionCount() {
const enumOptions = this._getEnumOptions()
if (enumOptions) return enumOptions.length
return Infinity
}
_getEnumFromAtomTypeOptions(program) {
const particle = this._getParticleFromExtended(ParsersConstants.enumFromAtomTypes)
return particle ? Object.keys(particle.getParticle(ParsersConstants.enumFromAtomTypes)._getEnumFromAtomTypes(program)) : undefined
Expand Down
2 changes: 1 addition & 1 deletion products/Particle.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -2598,7 +2598,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 = () => "99.0.0"
Particle.getVersion = () => "99.1.0"
class AbstractExtendibleParticle extends Particle {
_getFromExtended(cuePath) {
const hit = this._getParticleFromExtended(cuePath)
Expand Down
2 changes: 1 addition & 1 deletion products/Particle.js
Original file line number Diff line number Diff line change
Expand Up @@ -2588,7 +2588,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 = () => "99.0.0"
Particle.getVersion = () => "99.1.0"
class AbstractExtendibleParticle extends Particle {
_getFromExtended(cuePath) {
const hit = this._getParticleFromExtended(cuePath)
Expand Down
2 changes: 2 additions & 0 deletions products/jibberish.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ integerAtom
onoffAtom
enum on off
atomAtom
keywordAtom
topLevelPropertyAtom
paint constant.language
extends keywordAtom
opSymbolAtom
paint keyword.operator.arithmetic
Expand Down
2 changes: 2 additions & 0 deletions products/jibberish.nodejs.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ integerAtom
onoffAtom
enum on off
atomAtom
keywordAtom
topLevelPropertyAtom
paint constant.language
extends keywordAtom
opSymbolAtom
paint keyword.operator.arithmetic
Expand Down
Loading

0 comments on commit 18124ae

Please sign in to comment.