159 lines
3.6 KiB
TypeScript
159 lines
3.6 KiB
TypeScript
/**
|
|
* Demonstrates the ADD opcode working with dicts
|
|
*
|
|
* ADD now handles dict merging:
|
|
* - {a: 1} + {b: 2} === {a: 1, b: 2}
|
|
* - If both operands are dicts, they are merged
|
|
* - Keys from the second dict overwrite keys from the first on conflict
|
|
*/
|
|
|
|
import { toBytecode, run } from "#reef"
|
|
|
|
// Basic dict merge
|
|
const basicMerge = toBytecode([
|
|
["PUSH", "a"],
|
|
["PUSH", 1],
|
|
["MAKE_DICT", 1],
|
|
["PUSH", "b"],
|
|
["PUSH", 2],
|
|
["MAKE_DICT", 1],
|
|
["ADD"],
|
|
["HALT"]
|
|
])
|
|
|
|
console.log('Basic dict merge ({a: 1} + {b: 2}):')
|
|
const result1 = await run(basicMerge)
|
|
console.log(result1)
|
|
// Output: { type: 'dict', value: Map { a: 1, b: 2 } }
|
|
|
|
// Merge with overlapping keys
|
|
const overlapMerge = toBytecode([
|
|
["PUSH", "a"],
|
|
["PUSH", 1],
|
|
["PUSH", "b"],
|
|
["PUSH", 2],
|
|
["MAKE_DICT", 2],
|
|
["PUSH", "b"],
|
|
["PUSH", 99],
|
|
["PUSH", "c"],
|
|
["PUSH", 3],
|
|
["MAKE_DICT", 2],
|
|
["ADD"],
|
|
["HALT"]
|
|
])
|
|
|
|
console.log('\nMerge with overlapping keys ({a: 1, b: 2} + {b: 99, c: 3}):')
|
|
const result2 = await run(overlapMerge)
|
|
console.log(result2)
|
|
console.log('Note: b is overwritten from 2 to 99')
|
|
// Output: { type: 'dict', value: Map { a: 1, b: 99, c: 3 } }
|
|
|
|
// Merge multiple dicts in sequence
|
|
const multipleMerge = toBytecode([
|
|
["PUSH", "a"],
|
|
["PUSH", 1],
|
|
["MAKE_DICT", 1],
|
|
["PUSH", "b"],
|
|
["PUSH", 2],
|
|
["MAKE_DICT", 1],
|
|
["ADD"],
|
|
["PUSH", "c"],
|
|
["PUSH", 3],
|
|
["MAKE_DICT", 1],
|
|
["ADD"],
|
|
["PUSH", "d"],
|
|
["PUSH", 4],
|
|
["MAKE_DICT", 1],
|
|
["ADD"],
|
|
["HALT"]
|
|
])
|
|
|
|
console.log('\nMultiple merges ({a: 1} + {b: 2} + {c: 3} + {d: 4}):')
|
|
const result3 = await run(multipleMerge)
|
|
console.log(result3)
|
|
// Output: { type: 'dict', value: Map { a: 1, b: 2, c: 3, d: 4 } }
|
|
|
|
// Merge dicts with different value types
|
|
const mixedTypes = toBytecode([
|
|
["PUSH", "num"],
|
|
["PUSH", 42],
|
|
["PUSH", "str"],
|
|
["PUSH", "hello"],
|
|
["MAKE_DICT", 2],
|
|
["PUSH", "bool"],
|
|
["PUSH", true],
|
|
["PUSH", "null"],
|
|
["PUSH", null],
|
|
["MAKE_DICT", 2],
|
|
["ADD"],
|
|
["HALT"]
|
|
])
|
|
|
|
console.log('\nMerge dicts with different types ({num: 42, str: "hello"} + {bool: true, null: null}):')
|
|
const result4 = await run(mixedTypes)
|
|
console.log(result4)
|
|
// Output: { type: 'dict', value: Map { num: 42, str: 'hello', bool: true, null: null } }
|
|
|
|
// Merge empty dict with non-empty
|
|
const emptyMerge = toBytecode([
|
|
["MAKE_DICT", 0],
|
|
["PUSH", "x"],
|
|
["PUSH", 100],
|
|
["PUSH", "y"],
|
|
["PUSH", 200],
|
|
["MAKE_DICT", 2],
|
|
["ADD"],
|
|
["HALT"]
|
|
])
|
|
|
|
console.log('\nMerge empty dict with {x: 100, y: 200} ({} + {x: 100, y: 200}):')
|
|
const result5 = await run(emptyMerge)
|
|
console.log(result5)
|
|
// Output: { type: 'dict', value: Map { x: 100, y: 200 } }
|
|
|
|
// Merge dicts with nested structures
|
|
const nestedMerge = toBytecode([
|
|
["PUSH", "data"],
|
|
["PUSH", 1],
|
|
["PUSH", 2],
|
|
["MAKE_ARRAY", 2],
|
|
["MAKE_DICT", 1],
|
|
["PUSH", "config"],
|
|
["PUSH", "debug"],
|
|
["PUSH", true],
|
|
["MAKE_DICT", 1],
|
|
["MAKE_DICT", 1],
|
|
["ADD"],
|
|
["HALT"]
|
|
])
|
|
|
|
console.log('\nMerge dicts with nested structures:')
|
|
const result6 = await run(nestedMerge)
|
|
console.log(result6)
|
|
// Output: { type: 'dict', value: Map { data: [1, 2], config: { debug: true } } }
|
|
|
|
// Building configuration objects
|
|
const configBuild = toBytecode([
|
|
// Default config
|
|
["PUSH", "debug"],
|
|
["PUSH", false],
|
|
["PUSH", "port"],
|
|
["PUSH", 3000],
|
|
["PUSH", "host"],
|
|
["PUSH", "localhost"],
|
|
["MAKE_DICT", 3],
|
|
// Override with user config
|
|
["PUSH", "debug"],
|
|
["PUSH", true],
|
|
["PUSH", "port"],
|
|
["PUSH", 8080],
|
|
["MAKE_DICT", 2],
|
|
["ADD"],
|
|
["HALT"]
|
|
])
|
|
|
|
console.log('\nBuilding config (defaults + overrides):')
|
|
const result7 = await run(configBuild)
|
|
console.log(result7)
|
|
// Output: { type: 'dict', value: Map { debug: true, port: 8080, host: 'localhost' } }
|