Skip to content

Instantly share code, notes, and snippets.

@kissarat
Created August 9, 2022 07:15
Show Gist options
  • Save kissarat/4c8d89fce7edb24fd774f14b391ca678 to your computer and use it in GitHub Desktop.
Save kissarat/4c8d89fce7edb24fd774f14b391ca678 to your computer and use it in GitHub Desktop.
function $(...params) {
return [...params]
}
class NameLocation {
constructor(root, namespace = []) {
this.root = root
this.namespace = namespace
}
}
class Parent {
constructor(params) {
this.assign(params)
}
getType() {
return this.constructor
}
getTypeName() {
return this.getType().name
}
createType(params) {
const Type = this.getType()
return new Type(params)
}
derive(namespace, params) {
const location = new NameLocation(this)
return params
? this.createType({
...this,
...params
}, location)
: this.createType(this, location)
}
assign(params) {
if (params) {
return Object.assign(this, params)
}
return null
}
assignDefaults(params) {
if (params) {
for(const name in params) {
if (!this[name]) {
this[name] = params[name]
}
}
}
return null
}
}
class Child extends Parent {
constructor(params, location = new NameLocation()) {
this.assign(params)
this.location = location
}
}
/**
*
* @param {{
* associative: Map
* }} context
* @returns
*/
const createCommands = (context) => ({
'@'(name, value) {
return context.associative.set(name, value)
},
'+'(first, second) {
return first + second
}
})
class CommandError extends Command {
constructor(name, params, reason) {
let message = name + ' '
message += params.join(' ')
if (reason) {
message += ' ' + reason.message
}
super(message)
this.name = name
this.params = params
this.reason = reason
}
}
class DirectorSam extends Child {
createInitialProperties() {
const commands = createCommands(this)
return {
associative: new Map(),
commands,
stack: []
}
}
constructor(params, location = new NameLocation()) {
super(params, location)
this.assignDefaults(this.createInitialProperties())
}
getCommand(name) {
const command = this.commands[name]
if (!command) {
throw new Error(`Command ${name} not found`)
}
return command
}
pushResult(result) {
this.stack.push(result)
}
executeCommand(name, ...params) {
try {
const command = this.getCommand(name)
this.pushResult(command(...params))
} catch(err) {
throw new CommandError(name, params, err)
}
}
execute(cb) {
return cb({
$: (name, ...params) => this.executeCommand(name, ...params)
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment