Created
August 9, 2022 07:15
-
-
Save kissarat/4c8d89fce7edb24fd774f14b391ca678 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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