add a proper command line interface
This commit is contained in:
parent
200d01f9ad
commit
e8da284365
15
README.md
15
README.md
|
@ -1,15 +1,14 @@
|
|||
# desmos-computer
|
||||
|
||||
## What is this?
|
||||
- a client-server architecture for synchronizing a file containing Desmos expressions to a graph,
|
||||
- a test suite for evaluating the 'correctness' of Desmos expressions,
|
||||
- an instruction set architecture for Turing machines whose cells contain IEEE 754 compliant integers in each cell,
|
||||
- an assembler for that instruction set architecture,
|
||||
- and other utilities.
|
||||
- a client-server architecture for synchronizing a file containing Desmos expressions to a graph, (`cli/lib/server.py` and `cli/lib/clientside.py`)
|
||||
- an instruction set architecture for Turing machines whose cells contain IEEE 754 compliant integers in each cell, (`cli/data/computer.py`)
|
||||
- an assembler for that instruction set architecture, (not yet!)
|
||||
- and other utilities. (disassembler, etc.)
|
||||
|
||||
## How does the ISA work?
|
||||
The 'CPU', implemented in Desmos, takes in a list (aka an array, Turing tape, etc.) and starts execution at cell 1 (lists have 1-based indexes in Desmos).
|
||||
The list also serves as the memory, as well. (Think like Befunge's `p` command.
|
||||
The list also serves as the memory, as well. (Think like Befunge's `p` command.)
|
||||
|
||||
*Todo: disconnect opcode definitions and opcodes from the actual CPU implementation. Because of this, don't rely on this table! Check the implementation in `data/computer.desmos`.*
|
||||
|
||||
|
@ -43,10 +42,10 @@ Things we're optimizing for:
|
|||
In general: *embed the intelligence into the machine code, **not** the CPU/ISA!*
|
||||
|
||||
## Things to do
|
||||
- [ ] Write a test suite for evaluating arbitrary Desmos expressions and getting their expected outputs.
|
||||
- [x] Write a test suite for the various instruction of the ISA executing *in Desmos*
|
||||
- [ ] Write an assembler to compile a custom Assembly language to native Desmos list format.
|
||||
- [ ] Simplify all this into a command line tool.
|
||||
- [ ] Simplify the synchronization stack.
|
||||
- [x] Simplify the synchronization stack.
|
||||
- [ ] Write documentation for all of this.
|
||||
|
||||
## License
|
||||
|
|
99
cli/cli.py
99
cli/cli.py
|
@ -2,29 +2,86 @@ from .lib.server import DesmosGraphServer
|
|||
from .lib.graphparser import DesmosGraph, DesmosGraphOverride
|
||||
|
||||
from .lib.clientside import payload as JSGraphPayload
|
||||
from .tests.isa import test_entry_point
|
||||
from .data.computer import payload as ComputerPayload
|
||||
from .data.testing import payload as TestingPayload
|
||||
|
||||
import pyperclip
|
||||
|
||||
import argparse
|
||||
|
||||
def handle_sync(parser):
|
||||
if parser.copy_userscript:
|
||||
pyperclip.copy(JSGraphPayload)
|
||||
print("copied userscript to clipboard")
|
||||
|
||||
if parser.filename:
|
||||
graph = DesmosGraph.from_file(parser.filename)
|
||||
|
||||
if parser.override:
|
||||
override = DesmosGraphOverride.from_file(parser.override)
|
||||
graph.include_override(override)
|
||||
|
||||
server = DesmosGraphServer()
|
||||
server.instructions_to_run = []
|
||||
server.append_inst({
|
||||
"type": "insert_graph",
|
||||
"graph": graph,
|
||||
})
|
||||
server.start(no_stop=True)
|
||||
|
||||
def handle_data(parser):
|
||||
if parser.dataname:
|
||||
if parser.dataname == "computer.desmos":
|
||||
print(ComputerPayload)
|
||||
elif parser.dataname == "testing.desmos":
|
||||
print(TestingPayload)
|
||||
return
|
||||
|
||||
if parser.list:
|
||||
parsers = ["computer.desmos", "testing.desmos"]
|
||||
print('\n'.join(parsers))
|
||||
|
||||
def main():
|
||||
# graph = DesmosGraph.from_file("data/computer.desmos")
|
||||
# override = DesmosGraphOverride.from_file("test.override")
|
||||
#
|
||||
# graph.include_override(override)
|
||||
# server = DesmosGraphServer()
|
||||
# server.append_inst({
|
||||
# "type": "insert_graph",
|
||||
# "graph": graph,
|
||||
# })
|
||||
# server.append_inst({
|
||||
# "type": "test_graph",
|
||||
# "graph": graph,
|
||||
# "name": "test and assert addition",
|
||||
# "expectedOutput": [1, 4, 6, 0, 0, 4],
|
||||
# "expression": "B",
|
||||
# })
|
||||
# server.start()
|
||||
# print(server.outputs)
|
||||
#
|
||||
test_entry_point()
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="desmosisa",
|
||||
description="a smörgåsbord of utilities for desmos, including some implementations of an desmos-based isa",
|
||||
)
|
||||
subparsers = parser.add_subparsers(dest="subparser_name")
|
||||
sync_parser = subparsers.add_parser("sync", help="desmos calculator synchronization utilities")
|
||||
sync_parser.add_argument(
|
||||
'filename',
|
||||
nargs='?',
|
||||
help="filename of DesmosExpressions to synchronize with client"
|
||||
)
|
||||
sync_parser.add_argument(
|
||||
'-o', '--override',
|
||||
help="filename of DesmosOverride file, to override certain expressions in the DesmosExpression file",
|
||||
action="store"
|
||||
)
|
||||
sync_parser.add_argument(
|
||||
'-c', '--copy-userscript',
|
||||
help="copy the userscript to the clipboard, to be pasted into the JS console within the calculator.",
|
||||
action="store_true"
|
||||
)
|
||||
|
||||
data_parser = subparsers.add_parser("data", help="access various prebuilt files")
|
||||
data_parser.add_argument(
|
||||
'dataname',
|
||||
nargs='?',
|
||||
help='name of the datafile requested'
|
||||
)
|
||||
data_parser.add_argument(
|
||||
'-l', '--list',
|
||||
help='list available datafiles',
|
||||
action='store_true'
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.subparser_name == "sync":
|
||||
handle_sync(args)
|
||||
if args.subparser_name == "data":
|
||||
handle_data(args)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -11,6 +11,8 @@ function arraysEqual(a, b) {
|
|||
return true;
|
||||
}
|
||||
|
||||
var refresh = true;
|
||||
|
||||
function main() {
|
||||
let socket = new WebSocket("ws://localhost:8764");
|
||||
var toCompare = "";
|
||||
|
@ -21,10 +23,12 @@ function main() {
|
|||
}
|
||||
|
||||
socket.onclose = function(e) {
|
||||
if (refresh) {
|
||||
setTimeout(function() {
|
||||
main();
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
socket.onmessage = function(e) {
|
||||
var message = JSON.parse(e.data);
|
||||
|
@ -83,5 +87,5 @@ function main() {
|
|||
console.log(`[LOG] couldn't parse message ${e.data}`)
|
||||
}
|
||||
}
|
||||
} main();
|
||||
}
|
||||
"""
|
||||
|
|
|
@ -89,18 +89,25 @@ class DesmosGraphServer:
|
|||
}
|
||||
)
|
||||
|
||||
if self.stop:
|
||||
self.stop.set_result("sotp please!!!!")
|
||||
|
||||
async def main(self, stop):
|
||||
async with serve(self.ws_main, "localhost", 8764):
|
||||
self.stop = stop
|
||||
if not stop:
|
||||
await asyncio.Future()
|
||||
else:
|
||||
await stop
|
||||
|
||||
def start(self):
|
||||
def start(self, no_stop=False):
|
||||
loop = asyncio.get_event_loop()
|
||||
stop = loop.create_future()
|
||||
|
||||
loop.run_until_complete(self.main(stop))
|
||||
if no_stop:
|
||||
loop.run_until_complete(self.main(stop=None))
|
||||
else:
|
||||
loop.run_until_complete(self.main(stop=stop))
|
||||
|
||||
def append_inst(self, inst):
|
||||
self.instructions_to_run.append(inst)
|
||||
|
|
Loading…
Reference in New Issue