Compare commits
7 Commits
1db1b01b2a
...
ea5d318b62
Author | SHA1 | Date | |
---|---|---|---|
ea5d318b62 | |||
81a483d540 | |||
004db89c60 | |||
a786e9441c | |||
97cc99146b | |||
6369d15e93 | |||
acded68da5 |
14
carp/src/Pipfile
Normal file
14
carp/src/Pipfile
Normal file
@@ -0,0 +1,14 @@
|
||||
[[source]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[packages]
|
||||
flask = "*"
|
||||
requests = "*"
|
||||
msgpack = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3"
|
0
carp/src/bridge/__init__.py
Normal file
0
carp/src/bridge/__init__.py
Normal file
179
carp/src/bridge/bridge.py
Normal file
179
carp/src/bridge/bridge.py
Normal file
@@ -0,0 +1,179 @@
|
||||
import argparse
|
||||
import threading
|
||||
import sys
|
||||
from bridge import carp
|
||||
from bridge.hooks import *
|
||||
from bridge.object_registry import registry
|
||||
|
||||
def pbbreak():
|
||||
print("Breaking now")
|
||||
breakpoint()
|
||||
print("Continuing")
|
||||
|
||||
|
||||
class EvalCommand:
|
||||
statements = ""
|
||||
bindings = {}
|
||||
commandId = 0
|
||||
|
||||
def __init__(self, commandId, statements, bindings):
|
||||
self.statements = statements
|
||||
self.commandId = commandId
|
||||
self.bindings = bindings
|
||||
|
||||
def execute_using_env(self, env):
|
||||
try:
|
||||
return self.execute()
|
||||
except Exception as err:
|
||||
self.perform_proceed_action(notify_error(err,self))
|
||||
|
||||
def perform_proceed_action(self, actionDict):
|
||||
actionSymbol = actionDict['action']
|
||||
if actionSymbol == "IGNORE":
|
||||
pass
|
||||
if actionSymbol == "DROP_QUEUE":
|
||||
bridge.globals.globalCommandList.drop_queue()
|
||||
if actionSymbol == "REPLACE_COMMAND":
|
||||
commandDict = actionDict["command"]
|
||||
bridge.globals.globalCommandList.push_command_at_first(EvalCommand(
|
||||
commandDict["commandId"],
|
||||
commandDict["statements"],
|
||||
commandDict["bindings"]))
|
||||
|
||||
def command_id(self):
|
||||
return self.commandId
|
||||
|
||||
def execute(self):
|
||||
return bridge.globals.proc.evaluate(self.statements)
|
||||
|
||||
class Logger():
|
||||
def log(self, msg):
|
||||
print(str(msg), file=sys.stderr, flush=True)
|
||||
|
||||
class NoLogger():
|
||||
def log(self, msg):
|
||||
pass
|
||||
|
||||
# This List is thought to be multi-producer and single-consumer. For optimal results wait for push_command return value to push another command that depends on the previous one.
|
||||
class CommandList:
|
||||
currentCommandIndex = 0
|
||||
commandList = []
|
||||
listLock = threading.Lock()
|
||||
consumeSemaphore = threading.Semaphore(value=0)
|
||||
|
||||
# This method locks the thread until the command has been succesfully appended to the list. Even though that it has a lock inside, we do not expect long waiting time.
|
||||
def push_command(self, aCommand):
|
||||
self.listLock.acquire()
|
||||
self.commandList.append(aCommand)
|
||||
commandIndex = len(self.commandList) - 1
|
||||
self.listLock.release()
|
||||
self.consumeSemaphore.release()
|
||||
return commandIndex
|
||||
|
||||
def push_command_at_first(self, aCommand):
|
||||
self.listLock.acquire()
|
||||
self.commandList.insert(self.currentCommandIndex, aCommand)
|
||||
self.listLock.release()
|
||||
self.consumeSemaphore.release()
|
||||
return self.currentCommandIndex
|
||||
|
||||
def drop_queue(self):
|
||||
self.listLock.acquire()
|
||||
self.consumeSemaphore = threading.Semaphore(value=0)
|
||||
self.currentCommandIndex = len(self.commandList)
|
||||
self.listLock.release()
|
||||
|
||||
def consume_command(self):
|
||||
repeatMonitorFlag = True
|
||||
while repeatMonitorFlag:
|
||||
self.consumeSemaphore.acquire()
|
||||
self.listLock.acquire()
|
||||
repeatMonitorFlag = False
|
||||
if(self.currentCommandIndex >= len(self.commandList)):
|
||||
repeatMonitorFlag = True
|
||||
self.listLock.release()
|
||||
command = self.commandList[self.currentCommandIndex]
|
||||
self.currentCommandIndex += 1
|
||||
self.listLock.release()
|
||||
return command
|
||||
|
||||
def get_current_command(self):
|
||||
if self.currentCommandIndex == 0:
|
||||
return None
|
||||
self.listLock.acquire()
|
||||
command = self.commandList[self.currentCommandIndex-1]
|
||||
self.listLock.release()
|
||||
return command
|
||||
|
||||
def get_command_list(self):
|
||||
self.listLock.acquire()
|
||||
listCopy = self.commandList.copy()
|
||||
self.listLock.release()
|
||||
return listCopy
|
||||
|
||||
#### UTILS FUNCTIONS
|
||||
def clean_locals_env():
|
||||
return locals()
|
||||
|
||||
def deserialize(text):
|
||||
result = bridge.globals.msg_service.serializer.deserialize(text)
|
||||
bridge.globals.logger.log("DESERIALISE (bridge): " + str(result))
|
||||
if registry().isProxy(result):
|
||||
result = registry().resolve(result['__pyid__'])
|
||||
return result
|
||||
|
||||
def enqueue_command(data):
|
||||
bridge.globals.globalCommandList.push_command(EvalCommand(
|
||||
data["commandId"],
|
||||
data["statements"],
|
||||
{k: deserialize(v) for k, v in data["bindings"].items()}))
|
||||
|
||||
def run_bridge():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("-p", "--port", required=False,
|
||||
help="port to be used for receiving instructions")
|
||||
ap.add_argument("-o", "--pharo", required=True,
|
||||
help="port to be used for sending notifications back to pharo")
|
||||
ap.add_argument("-m", "--method", required=False,
|
||||
help="identifier for communication protocol strategy http or msgpack")
|
||||
ap.add_argument("--log", required=False, const=True, nargs="?",
|
||||
help="enable logging")
|
||||
args = vars(ap.parse_args())
|
||||
|
||||
bridge.globals.proc = carp.start_carp_proc()
|
||||
bridge.globals.pharoPort = args["pharo"]
|
||||
if args["log"]:
|
||||
bridge.globals.logger = Logger()
|
||||
else:
|
||||
bridge.globals.logger = NoLogger()
|
||||
bridge.globals.pyPort = args["port"]
|
||||
bridge.globals.globalCommandList = CommandList()
|
||||
globalCommandList = bridge.globals.globalCommandList
|
||||
env = clean_locals_env()
|
||||
msg_service = None
|
||||
if args["port"] == None:
|
||||
args["port"] = '0'
|
||||
if args["method"] == None:
|
||||
args["method"] = 'http'
|
||||
if args["method"] == 'http':
|
||||
from bridge import flask_platform
|
||||
msg_service = flask_platform.build_service(int(args["port"]), int(args["pharo"]), enqueue_command)
|
||||
elif args["method"] == 'msgpack':
|
||||
from bridge import msgpack_socket_platform
|
||||
msg_service = msgpack_socket_platform.build_service(int(args["port"]), int(args["pharo"]), enqueue_command)
|
||||
else:
|
||||
raise Exception("Invalid communication strategy.")
|
||||
bridge.globals.msg_service = msg_service
|
||||
msg_service.start()
|
||||
bridge.globals.logger.log("CARP: Carp version " + bridge.globals.proc.version_info())
|
||||
bridge.globals.logger.log("CARP: Start consuming commands")
|
||||
while True:
|
||||
command = globalCommandList.consume_command()
|
||||
bridge.globals.logger.log("CARP: Executing command " + command.command_id())
|
||||
bridge.globals.logger.log("CARP: bindings: " + str(command.bindings))
|
||||
bridge.globals.logger.log("CARP: " + command.statements)
|
||||
notify(command.execute_using_env(env), command.command_id())
|
||||
bridge.globals.logger.log("CARP: Finished command execution")
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_bridge()
|
44
carp/src/bridge/carp.py
Normal file
44
carp/src/bridge/carp.py
Normal file
@@ -0,0 +1,44 @@
|
||||
import re
|
||||
import time
|
||||
import diplomat
|
||||
|
||||
|
||||
class CarpProc:
|
||||
def __init__(self):
|
||||
self.proc = diplomat.Diplomat('carp')
|
||||
self._version_info = None
|
||||
self.adornment_re = re.compile(".\[33m.*?\[0m")
|
||||
|
||||
def wait_for_boot(self):
|
||||
while not self.proc.output():
|
||||
time.sleep(0.5)
|
||||
return self
|
||||
|
||||
def version_info(self):
|
||||
if not self._version_info:
|
||||
self._version_info = list(self.proc.output_stream())[0].replace("Welcome to Carp ", "")[:-1]
|
||||
return self._version_info
|
||||
|
||||
def read_output(self, old_output):
|
||||
while self.proc.output() == old_output:
|
||||
time.sleep(0.5)
|
||||
res = self.adornment_re.sub("", self.proc.output()[len(old_output):]).strip()
|
||||
if res.startswith("=> "):
|
||||
return {'result': 'success', 'value': res[3:]}
|
||||
if not res:
|
||||
return {'result': 'success', 'value': '()'}
|
||||
return {'result': 'error', 'value': res}
|
||||
|
||||
def evaluate(self, statements):
|
||||
assert self.proc.is_running(), "carp process has died"
|
||||
if not self._version_info:
|
||||
self.version_info()
|
||||
|
||||
old_output = self.proc.output()
|
||||
self.proc._process.stdin.write(statements.encode("utf-8") + b"\n")
|
||||
self.proc._process.stdin.flush()
|
||||
return self.read_output(old_output)
|
||||
|
||||
|
||||
def start_carp_proc():
|
||||
return CarpProc().wait_for_boot()
|
73
carp/src/bridge/flask_platform.py
Normal file
73
carp/src/bridge/flask_platform.py
Normal file
@@ -0,0 +1,73 @@
|
||||
from flask import Flask, request
|
||||
import http.client
|
||||
import json
|
||||
import threading
|
||||
import bridge.globals
|
||||
import bridge.utils
|
||||
from bridge import json_encoder
|
||||
import sys
|
||||
import logging
|
||||
import requests
|
||||
|
||||
class FlaskMsgService:
|
||||
|
||||
def __init__(self, port, pharo_port, feed_callback):
|
||||
self.serializer = json_encoder.JsonSerializer()
|
||||
log = logging.getLogger('werkzeug')
|
||||
log.setLevel(logging.ERROR)
|
||||
self.thread = None
|
||||
self.port = port
|
||||
self.pharo_port = pharo_port
|
||||
self.feed_callback = feed_callback
|
||||
self.app = Flask('carp_bridge')
|
||||
self.app.use_reloader=False
|
||||
self.session = requests.Session()
|
||||
self.session.trust_env = True
|
||||
|
||||
@self.app.route("/ENQUEUE", methods=["POST"])
|
||||
def eval_expression():
|
||||
data = request.get_json(force=True)
|
||||
self.feed_callback(data)
|
||||
return "{}"
|
||||
|
||||
@self.app.route("/IS_ALIVE", methods=["POST"])
|
||||
def status_endpoint():
|
||||
return "{}"
|
||||
|
||||
def addMapping(self, key_type, mapping_function):
|
||||
json_encoder.addMapping(key_type, mapping_function)
|
||||
|
||||
def _start(self):
|
||||
try:
|
||||
self.app.run(port=self.port)
|
||||
except OSError as err:
|
||||
bridge.globals.logger.log('Critical Error:' + str(err))
|
||||
exit(42)
|
||||
|
||||
def start(self):
|
||||
self.thread = threading.Thread(target=self._start, args=())
|
||||
self.thread.daemon = True
|
||||
self.thread.start()
|
||||
|
||||
def is_running(self):
|
||||
return self.thread != None
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
|
||||
def send_async_message(self, msg):
|
||||
self.send_sync_message(msg)
|
||||
|
||||
def send_sync_message(self, msg):
|
||||
msg['__sync'] = bridge.utils.random_str()
|
||||
bridge.globals.logger.log("SYNC_MSG: " + json.dumps(msg))
|
||||
response = self.session.post(
|
||||
'http://localhost:' + str(self.pharo_port) + '/' + msg['type'],
|
||||
data=json.dumps(msg),
|
||||
headers={'content-type': 'application/json'},
|
||||
allow_redirects=True).content.decode('utf-8')
|
||||
bridge.globals.logger.log("SYNC_ANS: " + response)
|
||||
return json.loads(response)
|
||||
|
||||
def build_service(port, pharo_port, feed_callback):
|
||||
return FlaskMsgService(port, pharo_port, feed_callback)
|
0
carp/src/bridge/globals.py
Normal file
0
carp/src/bridge/globals.py
Normal file
50
carp/src/bridge/hooks.py
Normal file
50
carp/src/bridge/hooks.py
Normal file
@@ -0,0 +1,50 @@
|
||||
from flask import Flask, request
|
||||
import http.client
|
||||
import argparse
|
||||
import sys
|
||||
import traceback
|
||||
import bridge.globals
|
||||
|
||||
def serialize(obj):
|
||||
return bridge.globals.msg_service.serializer.serialize(obj)
|
||||
|
||||
def deserialize(text):
|
||||
return bridge.globals.msg_service.serializer.deserialize(text)
|
||||
|
||||
def observer(commandId, observerId):
|
||||
return lambda obj: notify_observer(obj, commandId, observerId)
|
||||
|
||||
#### NOTIFICATION FUNCTIONS
|
||||
def notify(obj, notificationId):
|
||||
bridge.globals.logger.log("PYTHON: Notify " + str(notificationId))
|
||||
data = {}
|
||||
data["type"] = "EVAL"
|
||||
data["id"] = notificationId
|
||||
data["value"] = serialize(obj)
|
||||
bridge.globals.msg_service.send_async_message(data)
|
||||
|
||||
def notify_observer(obj, commandId, observerId):
|
||||
bridge.globals.logger.log("PYTHON: Notify observer " + str(commandId) + " " + str(observerId))
|
||||
data = {}
|
||||
data["type"] = "CALLBACK"
|
||||
data["commandId"] = commandId
|
||||
data["observerId"] = observerId
|
||||
data["value"] = serialize(obj)
|
||||
rawValue = bridge.globals.msg_service.send_sync_message(data)['value']
|
||||
return deserialize(rawValue)
|
||||
|
||||
def notify_error(ex, command):
|
||||
bridge.globals.logger.log("Error on command: " + str(command.command_id()))
|
||||
bridge.globals.logger.log("Exception: " + str(ex))
|
||||
data = {}
|
||||
data["type"] = "ERR"
|
||||
data["errMsg"] = str(ex)
|
||||
data["trace"] = traceback.format_exc(100)
|
||||
data["commandId"] = command.command_id()
|
||||
return bridge.globals.msg_service.send_sync_message(data)
|
||||
|
||||
def bridge_inspect(obj):
|
||||
if hasattr(obj,'__dict__'):
|
||||
return obj.__dict__
|
||||
else:
|
||||
return {}
|
28
carp/src/bridge/json_encoder.py
Normal file
28
carp/src/bridge/json_encoder.py
Normal file
@@ -0,0 +1,28 @@
|
||||
import json
|
||||
import io
|
||||
from bridge.object_registry import registry
|
||||
|
||||
mapper = {}
|
||||
|
||||
def addMapping(key_type, mapping_function):
|
||||
mapper[key_type] = mapping_function
|
||||
|
||||
class JsonEncoder(json.JSONEncoder):
|
||||
def __init__(self, *args, **kwargs):
|
||||
json.JSONEncoder.__init__(self, *args, **kwargs)
|
||||
self.mapper = mapper
|
||||
|
||||
def default(self, obj):
|
||||
if type(obj) in self.mapper:
|
||||
return self.mapper[type(obj)](obj)
|
||||
return {
|
||||
'__pyclass__': type(obj).__name__,
|
||||
'__pyid__': registry().register(obj)
|
||||
}
|
||||
|
||||
class JsonSerializer:
|
||||
def serialize(self, obj):
|
||||
return json.dumps(obj, cls=JsonEncoder)
|
||||
|
||||
def deserialize(self, text):
|
||||
return json.loads(text)
|
41
carp/src/bridge/msgpack_serializer.py
Normal file
41
carp/src/bridge/msgpack_serializer.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import msgpack
|
||||
from bridge.object_registry import registry
|
||||
|
||||
primitive_types = [
|
||||
type(None),
|
||||
bool,
|
||||
int,
|
||||
bytes,
|
||||
str,
|
||||
dict,
|
||||
list,
|
||||
memoryview,
|
||||
bytearray]
|
||||
|
||||
mapper = {}
|
||||
|
||||
def addMapping(key_type, mapping_function):
|
||||
mapper[key_type] = mapping_function
|
||||
|
||||
class MsgPackSerializer:
|
||||
def __init__(self):
|
||||
self.primitive_types = primitive_types
|
||||
|
||||
def mapper(self):
|
||||
return mapper
|
||||
|
||||
def default(self, obj):
|
||||
if type(obj) in self.primitive_types:
|
||||
return obj
|
||||
if type(obj) in self.mapper():
|
||||
return self.mapper()[type(obj)](obj)
|
||||
return {
|
||||
'__pyclass__': type(obj).__name__,
|
||||
'__pyid__': registry().register(obj)
|
||||
}
|
||||
|
||||
def serialize(self, obj):
|
||||
return msgpack.packb(obj, default=self.default, use_bin_type=True)
|
||||
|
||||
def deserialize(self, binary):
|
||||
return msgpack.unpackb(binary, raw=False)
|
120
carp/src/bridge/msgpack_socket_platform.py
Normal file
120
carp/src/bridge/msgpack_socket_platform.py
Normal file
@@ -0,0 +1,120 @@
|
||||
import msgpack
|
||||
import socket
|
||||
import _thread
|
||||
import threading
|
||||
import time
|
||||
import sys
|
||||
import bridge.globals
|
||||
from bridge import stoppable_thread, msgpack_serializer
|
||||
from uuid import uuid1
|
||||
|
||||
# Messages supported by this sockets must be Dictionaries. This is because we use special key __sync to know if it is
|
||||
# a synchronized message or not. If it is we hook a semaphore to that id under the __sync key and after we receive the
|
||||
# value we store there the return message and signal the semaphore.
|
||||
class MsgPackSocketPlatform:
|
||||
|
||||
def __init__(self, port):
|
||||
self.port = port
|
||||
self.client = None
|
||||
self.serializer = msgpack_serializer.MsgPackSerializer()
|
||||
self.unpacker = msgpack.Unpacker(raw=False)
|
||||
self.packer = msgpack.Packer(use_bin_type=True)
|
||||
self.sync_table = {}
|
||||
self.async_handlers = {}
|
||||
|
||||
def addMapping(self, key_type, mapping_function):
|
||||
msgpack_serializer.addMapping(key_type, mapping_function)
|
||||
|
||||
def set_handler(self, msg_type, async_handler):
|
||||
self.async_handlers[msg_type] = async_handler
|
||||
|
||||
def prim_handle(self):
|
||||
try:
|
||||
bridge.globals.logger.log("loop func")
|
||||
data = self.client.recv(2048)
|
||||
if len(data) == 0:
|
||||
time.sleep(0.005)
|
||||
else:
|
||||
self.unpacker.feed(data)
|
||||
for msg in self.unpacker:
|
||||
bridge.globals.logger.log("prim handle message")
|
||||
self.prim_handle_msg(msg)
|
||||
except OSError:
|
||||
bridge.globals.logger.log("OSError: " + str(err))
|
||||
self.stop()
|
||||
sys.exit()
|
||||
exit(-1)
|
||||
except Exception as err:
|
||||
bridge.globals.logger.log("ERROR message: " + str(err))
|
||||
|
||||
def setup_func(self):
|
||||
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.client.connect(('localhost', self.port))
|
||||
|
||||
def stop(self):
|
||||
if self.thread is not None:
|
||||
self.thread.stop()
|
||||
if self.client is not None:
|
||||
self.client.close()
|
||||
self.client = None
|
||||
|
||||
def send_answer(self, msg, answer):
|
||||
if answer['type'] != msg['type']:
|
||||
raise Exception('Type mismatch')
|
||||
answer['__sync'] = msg['__sync']
|
||||
self.send_async_message(answer)
|
||||
|
||||
def is_running(self):
|
||||
return self.client != None
|
||||
|
||||
def prim_handle_msg(self, raw_msg):
|
||||
msg = raw_msg
|
||||
msg_type = msg['type']
|
||||
if msg_type in self.async_handlers:
|
||||
self.async_handlers[msg['type']](msg)
|
||||
elif is_sync_msg(msg):
|
||||
sync_id = message_sync_id(msg)
|
||||
semaphore = self.sync_table[sync_id]
|
||||
self.sync_table[sync_id] = msg
|
||||
semaphore.release()
|
||||
else:
|
||||
bridge.globals.logger.log("Error! Msg couldnt be handled")
|
||||
raise Exception('Message couldn''t be handled')
|
||||
|
||||
|
||||
def start(self):
|
||||
self.thread = stoppable_thread.StoppableThread(
|
||||
loop_func= self.prim_handle,
|
||||
setup_func= self.setup_func)
|
||||
self.thread.start()
|
||||
time.sleep(.1)
|
||||
|
||||
def send_async_message(self, msg):
|
||||
self.client.send(self.packer.pack(msg))
|
||||
|
||||
def send_sync_message(self, msg):
|
||||
sync_id = mark_message_as_sync(msg)
|
||||
semaphore = threading.Semaphore(value=0)
|
||||
self.sync_table[sync_id] = semaphore
|
||||
self.send_async_message(msg)
|
||||
semaphore.acquire()
|
||||
ans = self.sync_table[sync_id]
|
||||
del self.sync_table[sync_id]
|
||||
return ans
|
||||
|
||||
def is_sync_msg(msg):
|
||||
return '__sync' in msg
|
||||
|
||||
def message_sync_id(msg):
|
||||
return msg['__sync']
|
||||
|
||||
def mark_message_as_sync(msg):
|
||||
sync_id = uuid1().hex
|
||||
msg['__sync'] = sync_id
|
||||
return sync_id
|
||||
|
||||
def build_service(port, pharo_port, feed_callback):
|
||||
service = MsgPackSocketPlatform(pharo_port)
|
||||
service.set_handler('ENQUEUE',feed_callback)
|
||||
service.set_handler('IS_ALIVE', lambda msg: service.send_answer(msg, {'type': 'IS_ALIVE'}))
|
||||
return service
|
88
carp/src/bridge/object_registry.py
Normal file
88
carp/src/bridge/object_registry.py
Normal file
@@ -0,0 +1,88 @@
|
||||
import bridge.globals
|
||||
from uuid import uuid1
|
||||
|
||||
def ensure_global_registry():
|
||||
if not hasattr(bridge.globals, 'ObjectRegistry'):
|
||||
bridge.globals.ObjectRegistry = Registry()
|
||||
|
||||
def registry():
|
||||
return bridge.globals.ObjectRegistry
|
||||
|
||||
primitive = (int, str, bool)
|
||||
|
||||
def is_primitive(obj):
|
||||
return isinstance(obj, primitive)
|
||||
|
||||
class Registry():
|
||||
|
||||
def __init__(self):
|
||||
self.idToObjMap = {}
|
||||
self.objToIdMap = {}
|
||||
|
||||
def hasId(self, anId):
|
||||
return anId in self.idToObjMap
|
||||
|
||||
def createNewObjId(self):
|
||||
return uuid1().hex
|
||||
|
||||
def register(self, obj):
|
||||
if obj is None or is_primitive(obj):
|
||||
return 0
|
||||
if id(obj) in self.objToIdMap:
|
||||
return self.objToIdMap[id(obj)]
|
||||
else:
|
||||
return self._register(obj, self.createNewObjId())
|
||||
|
||||
def register_with_id(self, obj, newObjId):
|
||||
if obj is None or is_primitive(obj):
|
||||
return RegisterForbiddenObject(obj)
|
||||
if id(obj) in self.objToIdMap:
|
||||
objId = self.objToIdMap[id(obj)]
|
||||
if objId == newObjId:
|
||||
return newObjId
|
||||
else:
|
||||
raise RegisterWithDifferentIdError(obj, newObjId)
|
||||
else:
|
||||
return self._register(obj, newObjId)
|
||||
|
||||
def resolve(self, objId):
|
||||
if objId in self.idToObjMap:
|
||||
return self.idToObjMap[objId]
|
||||
else:
|
||||
raise ResolveUnknownObject(objId)
|
||||
|
||||
def _register(self, obj, newObjId):
|
||||
self.idToObjMap[newObjId] = obj
|
||||
self.objToIdMap[id(obj)] = newObjId
|
||||
return newObjId
|
||||
|
||||
def clean(self, objId):
|
||||
obj = self.idToObjMap[objId]
|
||||
del self.idToObjMap[objId]
|
||||
del self.objToIdMap[id(obj)]
|
||||
|
||||
def isProxy(self, anObject):
|
||||
is_proxy = False
|
||||
|
||||
if isinstance(anObject, dict):
|
||||
if len(anObject.keys()) == 2 and ('__pyclass__' in anObject) and ('__pyid__' in anObject):
|
||||
is_proxy = True
|
||||
|
||||
return is_proxy
|
||||
|
||||
class RegistryError(Exception):
|
||||
pass
|
||||
|
||||
class RegisterWithDifferentIdError(RegistryError):
|
||||
def __init__(self, obj, newId):
|
||||
RegistryError.__init__(self,"Attempting to register object {0} with ID {1} with different ID {2}.".format(type(obj).__name__, registry().register(obj), newId))
|
||||
|
||||
class ResolveUnknownObject(RegistryError):
|
||||
def __init__(self, objId):
|
||||
RegistryError.__init__(self,"Attempting to resolve unknown object with id {0}.".format(objId))
|
||||
|
||||
class RegisterForbiddenObject(RegistryError):
|
||||
def __init__(self, obj):
|
||||
RegistryError.__init__(self,"Attempting to register forbidden object of type {0}.".format(type(obj).__name__))
|
||||
|
||||
ensure_global_registry()
|
24
carp/src/bridge/stoppable_thread.py
Normal file
24
carp/src/bridge/stoppable_thread.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import threading
|
||||
|
||||
class StoppableThread(threading.Thread):
|
||||
def __init__(self, loop_func, setup_func):
|
||||
threading.Thread.__init__(self)
|
||||
self._stop_event = threading.Event()
|
||||
self.daemon = True
|
||||
self.loop_func = loop_func
|
||||
self.setup_func = setup_func
|
||||
|
||||
# function using _stop function
|
||||
def stop(self):
|
||||
self._stop_event.set()
|
||||
|
||||
def stopped(self):
|
||||
return self._stop_event.isSet()
|
||||
|
||||
def run(self):
|
||||
self.setup_func()
|
||||
while True:
|
||||
if self.stopped():
|
||||
return
|
||||
self.loop_func()
|
||||
|
36
carp/src/bridge/tfactorial.py
Normal file
36
carp/src/bridge/tfactorial.py
Normal file
@@ -0,0 +1,36 @@
|
||||
import argparse
|
||||
import threading
|
||||
import time
|
||||
|
||||
|
||||
# Calculate the factorial
|
||||
def factorial(n, t):
|
||||
time.sleep(n*t/4)
|
||||
print("Start: " + str(t) + ": " + str(n))
|
||||
if n == 1:
|
||||
res = 1
|
||||
if t == 1:
|
||||
print("Feel free to break here")
|
||||
else:
|
||||
res = n * factorial(n-1, t)
|
||||
return res
|
||||
|
||||
|
||||
# Calculate the factorial and print the result
|
||||
def factorial_thread(n, t):
|
||||
time.sleep(2)
|
||||
result = factorial(n, t)
|
||||
print("Thread " + str(t) + " = "+str(result))
|
||||
|
||||
|
||||
def launch_factorials(n):
|
||||
threads = []
|
||||
print("Calculate: "+str(n))
|
||||
breakpoint()
|
||||
for i in range(n):
|
||||
threads.append(threading.Thread(target=factorial_thread, args=(n+i, i+1)))
|
||||
threads[-1].start()
|
||||
print("Wait for the results")
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
print("Done")
|
2
carp/src/bridge/tmp.py
Normal file
2
carp/src/bridge/tmp.py
Normal file
@@ -0,0 +1,2 @@
|
||||
import time
|
||||
time.sleep(3)
|
5
carp/src/bridge/utils.py
Normal file
5
carp/src/bridge/utils.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from uuid import uuid1
|
||||
|
||||
def random_str():
|
||||
return uuid1().hex
|
||||
|
17
carp/src/languagelink.carp
Normal file
17
carp/src/languagelink.carp
Normal file
@@ -0,0 +1,17 @@
|
||||
(load "/Users/veitheller/Documents/Code/Github/carp/archive/socket/sockets.carp")
|
||||
|
||||
(use Socket)
|
||||
|
||||
(defn main []
|
||||
(let-do [port (Maybe.from (from-string &(Maybe.from (nth &System.args 1) @"")) 0)]
|
||||
(IO.println &(fmt "Starting server on localhost, port %d" port))
|
||||
(Socket.with-server sock "127.0.0.1" port
|
||||
(if (Socket.valid? &sock)
|
||||
(Socket.while-connection &sock client
|
||||
(IO.println &(read &client))
|
||||
(send &client "hi")
|
||||
(IO.println "yay"))
|
||||
(IO.errorln "Server couldn’t be started.")))))
|
||||
|
||||
(build)
|
||||
(run)
|
4
carp/src/languagelink.py
Normal file
4
carp/src/languagelink.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from bridge import bridge as b
|
||||
from bridge.hooks import *
|
||||
|
||||
b.run_bridge()
|
@@ -8,7 +8,45 @@
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-17T22:22:31.801924+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-17T22:22:40.406467+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "3kLYI0GZDQCKnLdXBAU6hQ=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "[[Interlude: An Introduction to Carp]]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
@@ -41,43 +79,6 @@
|
||||
},
|
||||
"string" : "[[Introduction]]"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-17T22:22:30.537898+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-17T22:22:30.537898+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "3kLYI0GZDQCKnLdXBAU6hQ=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : ""
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
@@ -231,7 +232,119 @@
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:20.565513+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:20.565513+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "UXDVu4+dDQC/fqHFA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "[[Building a LanguageLink client]]"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:33.223032+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:33.223032+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "6dWWvI+dDQC/gM7QA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "[[Building a LanguageLink server]]"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:08:45.88618+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:08:48.608001+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "rYmTAZCdDQC/qIzPA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "[[What now?]]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
@@ -264,6 +377,81 @@
|
||||
},
|
||||
"string" : "[[Executing code]]"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:07:50.665361+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:07:59.692968+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "3NNC/o+dDQC/oLtxA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "[[Hooking up your LanguageLink server]]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:08:54.91122+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:09:11.691776+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "uAjiAZCdDQC/qqUDA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "[[A custom snippet type]]"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
|
@@ -232,7 +232,119 @@
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:20.565513+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:20.565513+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "UXDVu4+dDQC/fqHFA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "[[Building a LanguageLink client]]"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:33.223032+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:33.223032+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "6dWWvI+dDQC/gM7QA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "[[Building a LanguageLink server]]"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:08:45.88618+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:08:48.608001+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "rYmTAZCdDQC/qIzPA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "[[What now?]]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
@@ -265,6 +377,118 @@
|
||||
},
|
||||
"string" : "[[Executing code]]"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:07:50.665361+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:07:59.692968+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "3NNC/o+dDQC/oLtxA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "[[Hooking up your LanguageLink server]]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:08:54.91122+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:09:11.691776+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "uAjiAZCdDQC/qqUDA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "[[A custom snippet type]]"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:38:03.097269+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:38:05.781133+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "j+IkapCdDQCBVgDCA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "[[Fin]]"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
|
@@ -325,14 +325,14 @@
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-17T17:07:38.104346+02:00"
|
||||
"dateAndTimeString" : "2022-06-11T16:35:43.289314+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "Ddc1ljyZDQCZq2mSDqn2mw=="
|
||||
},
|
||||
"code" : "; this is what we will be able to do\r(IO.defn hello-world []\r (IO.println \"Hello world!\"))"
|
||||
"code" : "; this is what we will be able to do\r(defn hello-world []\r (IO.println \"Hello world!\"))"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
|
@@ -325,7 +325,7 @@
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-17T17:08:04.346367+02:00"
|
||||
"dateAndTimeString" : "2022-06-11T16:35:43.289314+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
@@ -359,7 +359,7 @@
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-17T16:54:20.656267+02:00"
|
||||
"dateAndTimeString" : "2022-06-11T17:10:18.677811+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
|
113
lepiter/98eic2g8xrl1zoo0c1rpxqe78.bak
Normal file
113
lepiter/98eic2g8xrl1zoo0c1rpxqe78.bak
Normal file
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"__schema" : "4.1",
|
||||
"__type" : "page",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T11:30:43.257961+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T20:46:56.443327+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "JUkMyTyZDQCZxrrZDqn2mw=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Getting code to execute is most likely the most tricky part of adding a language to GT. Most of the code in the Carp IDE deals with handling that part of the IDE experience. Additionally, {{gtPackage:LanguageLink requires a custom server setup, which needed to be written outside of GT."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:48:20.869905+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:02.268331+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "dwEUdoqdDQC+EJoFA3UANg=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Because both parts of this process make a cohesive whole, I split this chapter into two sub-chapters, [[Building a LanguageLink client]] and [[Building a LanguageLink server]]."
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-17T17:10:47.300048+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-17T17:10:47.300048+02:00"
|
||||
}
|
||||
},
|
||||
"pageType" : {
|
||||
"__type" : "namedPage",
|
||||
"title" : "Executing code"
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uuid",
|
||||
"uuid" : "647f0bc9-3c99-0d00-99c5-5d710ea9f69b"
|
||||
}
|
||||
}
|
@@ -18,7 +18,7 @@
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-17T17:10:53.313378+02:00"
|
||||
"dateAndTimeString" : "2022-06-11T11:30:43.257961+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
@@ -29,7 +29,7 @@
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-17T17:10:53.833743+02:00"
|
||||
"dateAndTimeString" : "2022-06-11T20:47:09.979091+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
@@ -39,7 +39,44 @@
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "TODO"
|
||||
"string" : "Getting code to execute is most likely the most tricky part of adding a language to GT. Most of the code in the Carp IDE deals with handling that part of the IDE experience. Additionally, LanguageLink requires a custom server setup, which needed to be written outside of GT."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:48:20.869905+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:02.268331+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "dwEUdoqdDQC+EJoFA3UANg=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Because both parts of this process make a cohesive whole, I split this chapter into two sub-chapters, [[Building a LanguageLink client]] and [[Building a LanguageLink server]]."
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@@ -103,7 +103,7 @@
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-17T18:04:44.753707+02:00"
|
||||
"dateAndTimeString" : "2022-04-18T21:16:33.659248+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
@@ -113,7 +113,7 @@
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Apart from that, I fear, I cannot help you much if things don’t go as planned. But maybe some of the things we will discuss in the next section, [[Building a parser from scratch]], will help you get from something that generates a raw parse tree to something that generates a real usable AST for your language. Take a peek!"
|
||||
"string" : "Apart from that, I fear, I cannot help you much if things don’t go as planned. But maybe some of the things we will discuss in the next section, [[Building a parser from scratch]], will help you get from something that generates a raw parse tree to something that generates a real usable AST for your language (look at Step II if you want to skip ahead). Take a peek!"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@@ -66,7 +66,7 @@
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-17T18:03:21.19204+02:00"
|
||||
"dateAndTimeString" : "2022-06-11T20:48:50.30896+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
|
@@ -510,7 +510,7 @@
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-18T21:22:40.888776+02:00"
|
||||
"dateAndTimeString" : "2022-04-18T21:22:56.54305+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
@@ -520,7 +520,7 @@
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "If you need another, simple example for a complete parser generating an"
|
||||
"string" : "If you need another, simple example for a complete parser generating an AST, you might want to check out the {{gtClass:JSONParser}}."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
|
@@ -214,7 +214,7 @@
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-18T21:12:52.520639+02:00"
|
||||
"dateAndTimeString" : "2022-06-11T20:49:10.152867+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
|
@@ -140,7 +140,7 @@
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-17T17:57:41.124314+02:00"
|
||||
"dateAndTimeString" : "2022-04-17T17:58:06.623815+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
@@ -150,7 +150,7 @@
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "You might also want to take a look at the esecti{{gtPage:How to parse sources in different languages|db=2j9m7db2i4oz116bexd7wbdxo}}"
|
||||
"string" : "You might also want to take a look at the section {{gtPage:How to parse sources in different languages|db=2j9m7db2i4oz116bexd7wbdxo}} in the Glamorous Toolkit book to get an overview. Maybe the language you want to add is already there!"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@@ -140,7 +140,7 @@
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-04-17T17:58:06.623815+02:00"
|
||||
"dateAndTimeString" : "2022-06-11T20:48:23.867543+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
|
@@ -140,7 +140,7 @@
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-10T16:44:28.640047+02:00"
|
||||
"dateAndTimeString" : "2022-06-11T20:50:28.716326+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
@@ -177,7 +177,7 @@
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-10T16:47:01.610149+02:00"
|
||||
"dateAndTimeString" : "2022-06-10T16:47:24.613405+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
@@ -187,7 +187,7 @@
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "In Carp, I also went down the extra mile of coloring parentheses according to their nesting level. The code for this is inside the rule for lists, maps and arrays, and it uses {{gtClass:CarpStylerUtilities}} to color the parentheses and register an event for when the cursor enters or leaves the region to highlight it. Should you want more complex highlighting and change it based on cursor position"
|
||||
"string" : "In Carp, I also went down the extra mile of coloring parentheses according to their nesting level. The code for this is inside the rule for lists, maps and arrays, and it uses {{gtClass:CarpStylerUtilities}} to color the parentheses and register an event for when the cursor enters or leaves the region to highlight it. Should you want more complex highlighting and change it based on cursor position and interactions, this might give you a taste of how to do it."
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@@ -140,7 +140,7 @@
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-10T16:44:28.640047+02:00"
|
||||
"dateAndTimeString" : "2022-06-11T20:50:30.609796+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
|
258
lepiter/9py149rplidcvk0jjdlnxeufv.bak
Normal file
258
lepiter/9py149rplidcvk0jjdlnxeufv.bak
Normal file
@@ -0,0 +1,258 @@
|
||||
{
|
||||
"__schema" : "4.1",
|
||||
"__type" : "page",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:09:27.48233+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:09:42.790324+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "n0WyA5CdDQC/sEIUA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Now that we have a LanguageLink server, we are all set, right? Well, not quite."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:09:49.137549+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:10:53.048149+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "YxldBZCdDQC/s15wA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Usually, a LanguageLink server is used within snippets as a driver for code execution. While you can use it yourself to execute some custom code and find some pleasure in that, we will first need an interface to type code *into* to make it truly worth our while."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:10:55.085183+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:11:56.629038+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "ChpOCZCdDQC/tYwmA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "But I understand that after all of the effort of building a LanguageLink implementation for your target you’re itching to try it out, so I’ll give you a little teaser of how it’s going to be used in the snippet:"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:11:58.378929+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:12:53.87069+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "BW4QDZCdDQC/tz6wA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "{{gtMethod:GtCarpCoderModel>>#bindAndExecute:|expanded}}"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:13:00.938416+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:13:26.816542+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "LBHBEJCdDQC/9sJRA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "This means that a simple snippet to test your LanguageLink implementation might look like this:"
|
||||
},
|
||||
{
|
||||
"__type" : "pharoSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:13:37.920717+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:18:19.754957+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "EjsQE5CdDQC/+NLCA8ExpA=="
|
||||
},
|
||||
"code" : "sourceString := '(IO.println \"Hello World!\")'.\t\"change this to your language\"\r\rapplication := CarpApplication uniqueInstance. \"change this to your application, might need to initialize the unique instance\"\rapplication isRunning ifFalse: [ application start ].\rcommandFactory := application newCommandFactory.\r\rcommandFactory\r\t<< sourceString;\r\tsendAndWait"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:09:20.062163+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:09:20.062163+02:00"
|
||||
}
|
||||
},
|
||||
"pageType" : {
|
||||
"__type" : "namedPage",
|
||||
"title" : "What now?"
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uuid",
|
||||
"uuid" : "9b9eb103-909d-0d00-bfaf-1b1203c131a4"
|
||||
}
|
||||
}
|
295
lepiter/9py149rplidcvk0jjdlnxeufv.lepiter
Normal file
295
lepiter/9py149rplidcvk0jjdlnxeufv.lepiter
Normal file
@@ -0,0 +1,295 @@
|
||||
{
|
||||
"__schema" : "4.1",
|
||||
"__type" : "page",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:09:27.48233+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:09:42.790324+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "n0WyA5CdDQC/sEIUA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Now that we have a LanguageLink server, we are all set, right? Well, not quite."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:09:49.137549+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:10:53.048149+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "YxldBZCdDQC/s15wA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Usually, a LanguageLink server is used within snippets as a driver for code execution. While you can use it yourself to execute some custom code and find some pleasure in that, we will first need an interface to type code *into* to make it truly worth our while."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:10:55.085183+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:11:56.629038+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "ChpOCZCdDQC/tYwmA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "But I understand that after all of the effort of building a LanguageLink implementation for your target you’re itching to try it out, so I’ll give you a little teaser of how it’s going to be used in the snippet:"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:11:58.378929+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:12:53.87069+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "BW4QDZCdDQC/tz6wA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "{{gtMethod:GtCarpCoderModel>>#bindAndExecute:|expanded}}"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:13:00.938416+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:13:26.816542+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "LBHBEJCdDQC/9sJRA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "This means that a simple snippet to test your LanguageLink implementation might look like this:"
|
||||
},
|
||||
{
|
||||
"__type" : "pharoSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:13:37.920717+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:18:32.957333+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "EjsQE5CdDQC/+NLCA8ExpA=="
|
||||
},
|
||||
"code" : "sourceString := '(IO.println \"Hello World!\")'.\t\"change this to your language\"\r\rapplication := CarpApplication uniqueInstance.\t\"change this to your application, might need to initialize the unique instance\"\rapplication isRunning ifFalse: [ application start ].\rcommandFactory := application newCommandFactory.\r\rcommandFactory\r\t<< sourceString;\r\tsendAndWait"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:18:42.650713+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:18:48.915283+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "pPclJZCdDQCADqoCA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "And that should be all you need to get going!"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:09:20.062163+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:09:20.062163+02:00"
|
||||
}
|
||||
},
|
||||
"pageType" : {
|
||||
"__type" : "namedPage",
|
||||
"title" : "What now?"
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uuid",
|
||||
"uuid" : "9b9eb103-909d-0d00-bfaf-1b1203c131a4"
|
||||
}
|
||||
}
|
187
lepiter/9py149svgo06hri6l3ym0kvvu.bak
Normal file
187
lepiter/9py149svgo06hri6l3ym0kvvu.bak
Normal file
@@ -0,0 +1,187 @@
|
||||
{
|
||||
"__schema" : "4.1",
|
||||
"__type" : "page",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:18:58.358497+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:19:44.830424+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "n4phA5CdDQC/rbQ7A8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "After the doozy that is setting up LanguageLink, you might think that making a custom snippet type is going to be even more effort. I’ve got good news for you."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:19:51.016989+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T20:45:57.641893+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "Occ9KZCdDQCAEXGwA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Creating a snippet type is actually quite simple. Almost all of the code for Carp is in {{gtPackage:Carp}}. The most important class is likely {{gtClass:LeCarpSnippet}}, because like {{gtClass:CarpApplication}} for LanguageLink, this class is the central player around which the rest of the team organizes."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:25:29.637968+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:29:42.230718+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "pS1HPZCdDQCAOUdiA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Most of the code you will write will just be specialization over readily-available Lepiter classes. The only things that will be truly custom will most likely be your version of {{gtClass:LeExternalServerStrategy}} (in the case of Carp that is {{gtClass:LeCarpApplicationStrategy}}), which will bridge the gap between your LanguageLink application and the snippet itself, and your {{gtClass:GtSourceCoder}} ({{gtClass:GtCarpCoderModel}})."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:28:08.711515+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:28:15.191912+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "Dv7PRJCdDQCASGWFA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "But more about that in the next section!"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:09:14.768068+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:09:14.768068+02:00"
|
||||
}
|
||||
},
|
||||
"pageType" : {
|
||||
"__type" : "namedPage",
|
||||
"title" : "A custom snippet type"
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uuid",
|
||||
"uuid" : "6ad66003-909d-0d00-bfac-dd3803c131a4"
|
||||
}
|
||||
}
|
187
lepiter/9py149svgo06hri6l3ym0kvvu.lepiter
Normal file
187
lepiter/9py149svgo06hri6l3ym0kvvu.lepiter
Normal file
@@ -0,0 +1,187 @@
|
||||
{
|
||||
"__schema" : "4.1",
|
||||
"__type" : "page",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:18:58.358497+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:19:44.830424+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "n4phA5CdDQC/rbQ7A8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "After the doozy that is setting up LanguageLink, you might think that making a custom snippet type is going to be even more effort. I’ve got good news for you."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:19:51.016989+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T20:46:02.5892+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "Occ9KZCdDQCAEXGwA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Creating a snippet type is actually quite simple. Almost all of the code for Carp is in {{gtPackage:Carp|tag=Lepiter}}. The most important class is likely {{gtClass:LeCarpSnippet}}, because like {{gtClass:CarpApplication}} for LanguageLink, this class is the central player around which the rest of the team organizes."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:25:29.637968+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:29:42.230718+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "pS1HPZCdDQCAOUdiA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Most of the code you will write will just be specialization over readily-available Lepiter classes. The only things that will be truly custom will most likely be your version of {{gtClass:LeExternalServerStrategy}} (in the case of Carp that is {{gtClass:LeCarpApplicationStrategy}}), which will bridge the gap between your LanguageLink application and the snippet itself, and your {{gtClass:GtSourceCoder}} ({{gtClass:GtCarpCoderModel}})."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:28:08.711515+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:28:15.191912+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "Dv7PRJCdDQCASGWFA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "But more about that in the next section!"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:09:14.768068+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:09:14.768068+02:00"
|
||||
}
|
||||
},
|
||||
"pageType" : {
|
||||
"__type" : "namedPage",
|
||||
"title" : "A custom snippet type"
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uuid",
|
||||
"uuid" : "6ad66003-909d-0d00-bfac-dd3803c131a4"
|
||||
}
|
||||
}
|
150
lepiter/9py149sz34c10e429aqq1v7qc.bak
Normal file
150
lepiter/9py149sz34c10e429aqq1v7qc.bak
Normal file
@@ -0,0 +1,150 @@
|
||||
{
|
||||
"__schema" : "4.1",
|
||||
"__type" : "page",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:59:53.327975+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:01:42.598848+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "bUpMu4+dDQC/fPzrA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Theoretically, you can use any technology that supports HTTP, JSON, and possibly MessagePack to construct a LanguageLink server, and you might be tempted to just do it in the language you are targetting, especially since it is quite likely that you are comfortable in it."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:01:44.277599+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-12T12:51:14.365509+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "Yzt86I+dDQC/lywBA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "I too was tempted to go down that route before realizing that that would mean understanding and implementing the LanguageLink protocol, a task I wasn’t particularly interested in. Instead, the Carp LanguageLink server uses the one provided by PythonBridge (which can be found [in the PythonBridge repository TODO:](https://github.com/feenkcom/PythonBridge/tree/master/PythonBridgeRuntime)). It includes all the infrastructure needed, and the only thing that likely needs to be changed is how `EvalCommand`s are handled: in the case of Carp, a simple subprocess handler that feeds the statements into a Carp REPL and reads the result. You can inspect the custom code I wrote [in the gt4carp repository TODO: good link](https://git.veitheller.de/carpentry/gt4carp)."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:06:15.752492+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:07:40.565555+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "tJmV+I+dDQC/nrmHA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "While I understand that this is a rather terse “figure it out yourself”, I don’t know the ins and outs of the LanguageLink protocol well enough to assist you any more—precisely because I took the effort of side-stepping the issue entirely. Hopefully you can too!"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:05.418793+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:05.418793+02:00"
|
||||
}
|
||||
},
|
||||
"pageType" : {
|
||||
"__type" : "namedPage",
|
||||
"title" : "Building a LanguageLink server"
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uuid",
|
||||
"uuid" : "e4a14bbb-8f9d-0d00-bf7b-383c03c131a4"
|
||||
}
|
||||
}
|
150
lepiter/9py149sz34c10e429aqq1v7qc.lepiter
Normal file
150
lepiter/9py149sz34c10e429aqq1v7qc.lepiter
Normal file
@@ -0,0 +1,150 @@
|
||||
{
|
||||
"__schema" : "4.1",
|
||||
"__type" : "page",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:59:53.327975+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:01:42.598848+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "bUpMu4+dDQC/fPzrA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Theoretically, you can use any technology that supports HTTP, JSON, and possibly MessagePack to construct a LanguageLink server, and you might be tempted to just do it in the language you are targetting, especially since it is quite likely that you are comfortable in it."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:01:44.277599+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-12T12:51:15.652112+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "Yzt86I+dDQC/lywBA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "I too was tempted to go down that route before realizing that that would mean understanding and implementing the LanguageLink protocol, a task I wasn’t particularly interested in. Instead, the Carp LanguageLink server uses the one provided by PythonBridge (which can be found [in the PythonBridge repository](https://github.com/feenkcom/PythonBridge/tree/master/PythonBridgeRuntime)). It includes all the infrastructure needed, and the only thing that likely needs to be changed is how `EvalCommand`s are handled: in the case of Carp, a simple subprocess handler that feeds the statements into a Carp REPL and reads the result. You can inspect the custom code I wrote [in the gt4carp repository TODO: good link](https://git.veitheller.de/carpentry/gt4carp)."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:06:15.752492+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:07:40.565555+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "tJmV+I+dDQC/nrmHA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "While I understand that this is a rather terse “figure it out yourself”, I don’t know the ins and outs of the LanguageLink protocol well enough to assist you any more—precisely because I took the effort of side-stepping the issue entirely. Hopefully you can too!"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:05.418793+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:05.418793+02:00"
|
||||
}
|
||||
},
|
||||
"pageType" : {
|
||||
"__type" : "namedPage",
|
||||
"title" : "Building a LanguageLink server"
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uuid",
|
||||
"uuid" : "e4a14bbb-8f9d-0d00-bf7b-383c03c131a4"
|
||||
}
|
||||
}
|
261
lepiter/9py149upn2jn86ntqk68tvld1.bak
Normal file
261
lepiter/9py149upn2jn86ntqk68tvld1.bak
Normal file
@@ -0,0 +1,261 @@
|
||||
{
|
||||
"__schema" : "4.1",
|
||||
"__type" : "page",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:28:18.00762+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:30:10.327276+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "xNZI/4+dDQC/o+CfA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Finally, finally we get to have a snippet type that actually knows how to execute code!"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:30:14.076728+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:31:02.274958+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "t3BjTpCdDQCAUTe6A8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "To make that happen, we will need an application strategy. Building one should be fairly straightforward, since it mostly holds onto your LanguageLink application and builds new ones if needed."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:31:19.494771+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:32:06.868833+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "E6NbUZCdDQCAU8nsA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "More interesting will be your coder model, which is responsible for taking source code from an application, handing it over to LanguageLink, and displaying the result. As such, it is the main link between the IDE and the execution engine."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:32:07.688865+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:34:29.49505+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "ypstVZCdDQCAYOo/A8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "In the section [[What now?]] I already showcased the method that is most central to that process: `bindAndExecute:`. In my case, {{gtMethod:GtCarpCoderModel>>#bindAndExecute:|expanded}} is the final result. A quick refresher:"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:34:40.493148+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:36:37.301362+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "WALsXZCdDQCBUGyRA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "The method will take in a source string directly from coder and send it off to the evaluator handled by the LanguageLink application. Before that happens, though, it will most likely add some funky code around the snippet to capture the statement as a variable if possible, to allow for better interaction with GT."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:36:42.952545+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:37:23.855402+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "R7ljZZCdDQCBUlkLA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "It might be more useful for you to start with a trimmed-down version of this method that doesn’t do anything with the bindings and just hands over the source string as-is. To harness the full power of interacting with G"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:08:06.046507+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:08:06.046507+02:00"
|
||||
}
|
||||
},
|
||||
"pageType" : {
|
||||
"__type" : "namedPage",
|
||||
"title" : "Hooking up your LanguageLink server"
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uuid",
|
||||
"uuid" : "e53a48ff-8f9d-0d00-bfa2-217603c131a4"
|
||||
}
|
||||
}
|
261
lepiter/9py149upn2jn86ntqk68tvld1.lepiter
Normal file
261
lepiter/9py149upn2jn86ntqk68tvld1.lepiter
Normal file
@@ -0,0 +1,261 @@
|
||||
{
|
||||
"__schema" : "4.1",
|
||||
"__type" : "page",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:28:18.00762+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:30:10.327276+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "xNZI/4+dDQC/o+CfA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Finally, finally we get to have a snippet type that actually knows how to execute code!"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:30:14.076728+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:31:02.274958+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "t3BjTpCdDQCAUTe6A8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "To make that happen, we will need an application strategy. Building one should be fairly straightforward, since it mostly holds onto your LanguageLink application and builds new ones if needed."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:31:19.494771+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:32:06.868833+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "E6NbUZCdDQCAU8nsA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "More interesting will be your coder model, which is responsible for taking source code from an application, handing it over to LanguageLink, and displaying the result. As such, it is the main link between the IDE and the execution engine."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:32:07.688865+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:34:29.49505+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "ypstVZCdDQCAYOo/A8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "In the section [[What now?]] I already showcased the method that is most central to that process: `bindAndExecute:`. In my case, {{gtMethod:GtCarpCoderModel>>#bindAndExecute:|expanded}} is the final result. A quick refresher:"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:34:40.493148+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:36:37.301362+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "WALsXZCdDQCBUGyRA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "The method will take in a source string directly from coder and send it off to the evaluator handled by the LanguageLink application. Before that happens, though, it will most likely add some funky code around the snippet to capture the statement as a variable if possible, to allow for better interaction with GT."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:36:42.952545+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:37:38.760779+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "R7ljZZCdDQCBUlkLA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "It might be more useful for you to start with a trimmed-down version of this method that doesn’t do anything with the bindings and just hands over the source string as-is. To harness the full power of interacting with GT, however, we will need to send variables and values back and forth sooner or later."
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:08:06.046507+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:08:06.046507+02:00"
|
||||
}
|
||||
},
|
||||
"pageType" : {
|
||||
"__type" : "namedPage",
|
||||
"title" : "Hooking up your LanguageLink server"
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uuid",
|
||||
"uuid" : "e53a48ff-8f9d-0d00-bfa2-217603c131a4"
|
||||
}
|
||||
}
|
224
lepiter/9py149uso8srjrtyq6opyrmzh.bak
Normal file
224
lepiter/9py149uso8srjrtyq6opyrmzh.bak
Normal file
@@ -0,0 +1,224 @@
|
||||
{
|
||||
"__schema" : "4.1",
|
||||
"__type" : "page",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:38:08.96254+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:38:10.799078+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "6bymapCdDQCBW13UA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "You made it!"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:38:12.929099+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:38:56.257815+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "IW3tapCdDQCBXcd8A8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "If you read this booklet linearly from start to finish and followed along with your own implementation, you should now be able to execute code in custom Lepiter snippets! Exciting indeed!"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:38:59.504959+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:40:09.625312+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "4R2abZCdDQCBX8vQA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Now, of course, the fun doesn’t stop here. For full interactivity, we might need to (de)serialize values in an almost seamless manner, like JSLink does. To do that, we will have to make GT understand our language semantically rather than just syntactically."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:40:10.264658+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:41:08.513478+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "kHzzcZCdDQCBYawWA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "We could also start using GT’s powers to visualize things about our codebase or to generate code, or we might want to create a custom IDE. Some of these fun adventures you will have to embark on on your own, but if you want some inspiration, the [[Bonus Chapters]] might hold some interest to you."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:41:12.090085+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:41:24.342689+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "nEKhdZCdDQCBgxEjA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "I hope you enjoyed our little journey, congratulate you to your new po"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:38:07.35881+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:38:07.35881+02:00"
|
||||
}
|
||||
},
|
||||
"pageType" : {
|
||||
"__type" : "namedPage",
|
||||
"title" : "Fin"
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uuid",
|
||||
"uuid" : "1d13a66a-909d-0d00-815a-f07803c131a4"
|
||||
}
|
||||
}
|
224
lepiter/9py149uso8srjrtyq6opyrmzh.lepiter
Normal file
224
lepiter/9py149uso8srjrtyq6opyrmzh.lepiter
Normal file
@@ -0,0 +1,224 @@
|
||||
{
|
||||
"__schema" : "4.1",
|
||||
"__type" : "page",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:38:08.96254+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:38:10.799078+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "6bymapCdDQCBW13UA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "You made it!"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:38:12.929099+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:38:56.257815+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "IW3tapCdDQCBXcd8A8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "If you read this booklet linearly from start to finish and followed along with your own implementation, you should now be able to execute code in custom Lepiter snippets! Exciting indeed!"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:38:59.504959+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:40:09.625312+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "4R2abZCdDQCBX8vQA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Now, of course, the fun doesn’t stop here. For full interactivity, we might need to (de)serialize values in an almost seamless manner, like JSLink does. To do that, we will have to make GT understand our language semantically rather than just syntactically."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:40:10.264658+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:41:08.513478+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "kHzzcZCdDQCBYawWA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "We could also start using GT’s powers to visualize things about our codebase or to generate code, or we might want to create a custom IDE. Some of these fun adventures you will have to embark on on your own, but if you want some inspiration, the [[Bonus Chapters]] might hold some interest to you."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:41:12.090085+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:41:41.069403+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "nEKhdZCdDQCBgxEjA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "I hope you enjoyed our little journey and congratulate you to your new powers! See you around."
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:38:07.35881+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T18:38:07.35881+02:00"
|
||||
}
|
||||
},
|
||||
"pageType" : {
|
||||
"__type" : "namedPage",
|
||||
"title" : "Fin"
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uuid",
|
||||
"uuid" : "1d13a66a-909d-0d00-815a-f07803c131a4"
|
||||
}
|
||||
}
|
224
lepiter/9py149ytik0od40b9dfzhll4q.bak
Normal file
224
lepiter/9py149ytik0od40b9dfzhll4q.bak
Normal file
@@ -0,0 +1,224 @@
|
||||
{
|
||||
"__schema" : "4.1",
|
||||
"__type" : "page",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:47.434396+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:50:11.430885+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "YVM4u4+dDQC/eTezA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Building a LanguageLink client is easy, but not necessarily simple, since it involves writing a lot of mostly glue code."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:50:15.711236+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:52:49.226165+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "suJsv4+dDQC/h6EvA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "As an entry-point, you will have to write a {{gtClass:LanguageLinkApplication}}. The (very spartan) one for Carp is {{gtClass:CarpApplication}}. Writing the application will give you a lay of the land, since it’s the central piece of infrastructure that holds on to all the rest."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:52:50.001285+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:53:48.39118+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "/4qmyI+dDQC/i6IPA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "In the Carp application, I tried to use stock classes from LanguageLink wherever possible. Only when that didn’t work did I add classes. I also took inspiration from {{gtClass:JSLinkApplication}}, since it was there and seemed to provide rich functionality."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:53:50.150304+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:57:15.031561+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "hy01zI+dDQC/j6rJA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "In total, all the classes that needed filling in were {{gtClass:CarpPostMortemDebugger}} (used in: {{gtMethod:CarpApplication>>debuggerClientFor:}}), {{gtClass:CarpExecutionHandler}} (used in {{gtMethod:CarpApplication>>#initializeHandlers}}), and all the classes in {{gtMethod:LanguageLinkSettings class>>carpDefaultSettings|expanded}} prefixed with `Carp`:"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:57:33.45648+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:59:17.862655+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "sPXB2I+dDQC/k6TTA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Implementing and understanding all of these classes might seem like a daunting task, and in many ways it is. But implementing most of these classes is simple and doesn’t at first require a thorough understanding of the system, at least that was the case for me. This means that you can just browse the existing implementors of any specific piece of infrastructure and “compare notes”. This approach got me f"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:04.110462+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:04.110462+02:00"
|
||||
}
|
||||
},
|
||||
"pageType" : {
|
||||
"__type" : "namedPage",
|
||||
"title" : "Building a LanguageLink client"
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uuid",
|
||||
"uuid" : "3aab37bb-8f9d-0d00-bf78-07ff03c131a4"
|
||||
}
|
||||
}
|
224
lepiter/9py149ytik0od40b9dfzhll4q.lepiter
Normal file
224
lepiter/9py149ytik0od40b9dfzhll4q.lepiter
Normal file
@@ -0,0 +1,224 @@
|
||||
{
|
||||
"__schema" : "4.1",
|
||||
"__type" : "page",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:47.434396+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:50:11.430885+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "YVM4u4+dDQC/eTezA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Building a LanguageLink client is easy, but not necessarily simple, since it involves writing a lot of mostly glue code."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:50:15.711236+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:52:49.226165+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "suJsv4+dDQC/h6EvA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "As an entry-point, you will have to write a {{gtClass:LanguageLinkApplication}}. The (very spartan) one for Carp is {{gtClass:CarpApplication}}. Writing the application will give you a lay of the land, since it’s the central piece of infrastructure that holds on to all the rest."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:52:50.001285+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:53:48.39118+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "/4qmyI+dDQC/i6IPA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "In the Carp application, I tried to use stock classes from LanguageLink wherever possible. Only when that didn’t work did I add classes. I also took inspiration from {{gtClass:JSLinkApplication}}, since it was there and seemed to provide rich functionality."
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:53:50.150304+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:57:15.031561+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "hy01zI+dDQC/j6rJA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "In total, all the classes that needed filling in were {{gtClass:CarpPostMortemDebugger}} (used in: {{gtMethod:CarpApplication>>debuggerClientFor:}}), {{gtClass:CarpExecutionHandler}} (used in {{gtMethod:CarpApplication>>#initializeHandlers}}), and all the classes in {{gtMethod:LanguageLinkSettings class>>carpDefaultSettings|expanded}} prefixed with `Carp`:"
|
||||
},
|
||||
{
|
||||
"__type" : "textSnippet",
|
||||
"children" : {
|
||||
"__type" : "snippets",
|
||||
"items" : [ ]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:57:33.45648+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:59:36.36081+02:00"
|
||||
}
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uid",
|
||||
"uidString" : "sPXB2I+dDQC/k6TTA8ExpA=="
|
||||
},
|
||||
"paragraphStyle" : {
|
||||
"__type" : "textStyle"
|
||||
},
|
||||
"string" : "Implementing and understanding all of these classes might seem like a daunting task, and in many ways it is. But implementing most of these classes is simple and doesn’t at first require a thorough understanding of the system, at least that was the case for me. This means that you can just browse the existing implementors of any specific piece of infrastructure and “compare notes”. This approach got me far enough to build a first version (with a little bit of added debugging), and it might get you there too!"
|
||||
}
|
||||
]
|
||||
},
|
||||
"createEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"createTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:04.110462+02:00"
|
||||
}
|
||||
},
|
||||
"editEmail" : {
|
||||
"__type" : "email",
|
||||
"emailString" : "<unknown>"
|
||||
},
|
||||
"editTime" : {
|
||||
"__type" : "time",
|
||||
"time" : {
|
||||
"__type" : "dateAndTime",
|
||||
"dateAndTimeString" : "2022-06-11T17:49:04.110462+02:00"
|
||||
}
|
||||
},
|
||||
"pageType" : {
|
||||
"__type" : "namedPage",
|
||||
"title" : "Building a LanguageLink client"
|
||||
},
|
||||
"uid" : {
|
||||
"__type" : "uuid",
|
||||
"uuid" : "3aab37bb-8f9d-0d00-bf78-07ff03c131a4"
|
||||
}
|
||||
}
|
@@ -2,5 +2,5 @@
|
||||
"uuid" : "de53e067-3c99-0d00-9999-34310ea9f69b",
|
||||
"tableOfContents" : "98eic2d1mangtosf26n3aq420",
|
||||
"schema" : "4.1",
|
||||
"databaseName" : "Adding a Language to the Glamorous Toolkit"
|
||||
"databaseName" : "Adding a Language to Glamorous Toolkit"
|
||||
}
|
@@ -6,11 +6,13 @@ Class {
|
||||
|
||||
{ #category : #baseline }
|
||||
BaselineOfCarp >> baseline: spec [
|
||||
|
||||
<baseline>
|
||||
spec for: #common do: [
|
||||
spec
|
||||
baseline: 'GToolkit4SmaCC'
|
||||
with: [ spec repository: 'github://feenkcom/gt4smacc:main/src' ].
|
||||
spec package: 'Carp' with: [ spec requires: #( 'GToolkit4SmaCC' ) ] ]
|
||||
spec
|
||||
for: #common
|
||||
do: [ spec
|
||||
baseline: 'GToolkit4SmaCC'
|
||||
with: [ spec repository: 'github://feenkcom/gt4smacc:main/src' ].
|
||||
spec package: 'Carp' with: [ spec requires: #('GToolkit4SmaCC') ].
|
||||
spec package: 'Carp-Parser' with: [ spec requires: #('GToolkit4SmaCC') ].
|
||||
spec package: 'Carp-AST' with: [ spec requires: #('GToolkit4SmaCC') ] ]
|
||||
]
|
||||
|
@@ -13,6 +13,11 @@ CarpCharacterNode >> acceptVisitor: anExpressionVisitor [
|
||||
^ anExpressionVisitor visitCharacter: self
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpCharacterNode >> toPharo [
|
||||
^ value source asCharacter
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpCharacterNode >> tokenVariables [
|
||||
|
||||
|
@@ -25,3 +25,8 @@ CarpExpressionNode >> isQuoted [
|
||||
CarpExpressionNode >> listDepth [
|
||||
^ parent ifNil: [ 0 ] ifNotNil: [ parent listDepth + 1 ]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpExpressionNode >> toPharo [
|
||||
^ self subclassResponsibility
|
||||
]
|
||||
|
@@ -13,6 +13,11 @@ CarpNumberNode >> acceptVisitor: anExpressionVisitor [
|
||||
^ anExpressionVisitor visitNumber: self
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpNumberNode >> toPharo [
|
||||
^ value source asInteger
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpNumberNode >> tokenVariables [
|
||||
|
||||
|
@@ -34,6 +34,11 @@ CarpPairNode >> nodeVariables [
|
||||
^ #( #key #value )
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpPairNode >> toPharo [
|
||||
^ Association key: key toPharo value: value toPharo
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpPairNode >> value [
|
||||
|
||||
|
@@ -29,6 +29,11 @@ CarpQuoteNode >> nodeVariables [
|
||||
^ #( #value )
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpQuoteNode >> toPharo [
|
||||
^ {#quote . value toPharo }
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpQuoteNode >> value [
|
||||
|
||||
|
@@ -38,3 +38,8 @@ CarpStartNode >> initialize [
|
||||
super initialize.
|
||||
expressions := OrderedCollection new: 2.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpStartNode >> toPharo [
|
||||
^ expressions collect: #toPharo
|
||||
]
|
||||
|
@@ -13,6 +13,11 @@ CarpStringNode >> acceptVisitor: anExpressionVisitor [
|
||||
^ anExpressionVisitor visitString: self
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpStringNode >> toPharo [
|
||||
^ value source
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpStringNode >> tokenVariables [
|
||||
|
||||
|
@@ -13,6 +13,11 @@ CarpVariableNode >> acceptVisitor: anExpressionVisitor [
|
||||
^ anExpressionVisitor visitVariable: self
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpVariableNode >> toPharo [
|
||||
^ value source asSymbol
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpVariableNode >> tokenVariables [
|
||||
|
||||
|
@@ -65,6 +65,11 @@ CarpArrayNode >> rightBracket: aSmaCCToken [
|
||||
rightBracket := aSmaCCToken
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpArrayNode >> toPharo [
|
||||
^ expressions collect: #toPharo
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpArrayNode >> tokenVariables [
|
||||
|
||||
|
@@ -32,6 +32,11 @@ CarpDerefNode >> nodeVariables [
|
||||
^ #( #value )
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpDerefNode >> toPharo [
|
||||
^ {#deref . value toPharo}
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpDerefNode >> tokenVariables [
|
||||
|
||||
|
@@ -65,6 +65,11 @@ CarpListNode >> rightParen: aSmaCCToken [
|
||||
rightParen := aSmaCCToken
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpListNode >> toPharo [
|
||||
^ expressions collect: #toPharo
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpListNode >> tokenVariables [
|
||||
|
||||
|
@@ -65,6 +65,11 @@ CarpMapNode >> rightBrace: aSmaCCToken [
|
||||
rightBrace := aSmaCCToken
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpMapNode >> toPharo [
|
||||
^ (pairs collect: #toPharo) asDictionary
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpMapNode >> tokenVariables [
|
||||
|
||||
|
@@ -32,6 +32,11 @@ CarpModuleOrTypeNode >> nodeVariables [
|
||||
^ #( #value )
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpModuleOrTypeNode >> toPharo [
|
||||
^ value source asSymbol
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpModuleOrTypeNode >> tokenVariables [
|
||||
|
||||
|
@@ -6,7 +6,7 @@ Class {
|
||||
|
||||
{ #category : #'generated-accessing' }
|
||||
CarpParser class >> cacheId [
|
||||
^'2022-04-17T17:01:25.369965+02:00'
|
||||
^'2022-06-13T14:48:36.40126+02:00'
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
@@ -16,6 +16,26 @@ CarpParser class >> definitionComment [
|
||||
%root Expression;
|
||||
%prefix Carp;
|
||||
%suffix Node;
|
||||
|
||||
%hierarchy Expression (
|
||||
Array
|
||||
Deref
|
||||
List
|
||||
Map
|
||||
ModuleOrType
|
||||
Pattern
|
||||
RefCall
|
||||
Ref
|
||||
Unquote
|
||||
Character
|
||||
Number
|
||||
Pair
|
||||
Quote
|
||||
Start
|
||||
String
|
||||
Variable
|
||||
);
|
||||
|
||||
<escape>
|
||||
: \\ (. | u[0-9A-F]{4,4} | o[0-7]{3,3} | newline | return | space | tab | space | backspace | formfeed) # other character types
|
||||
;
|
||||
@@ -155,44 +175,44 @@ String
|
||||
{ #category : #generated }
|
||||
CarpParser class >> reduceTable [
|
||||
^#(
|
||||
#(24 0 #reduceActionForExpressions1: 1289217 false)
|
||||
#(23 1 #reduceActionForStart1: 1258497 false)
|
||||
#(32 0 #reduceActionForExpressions1: 1803265 false)
|
||||
#(43 1 #reduceActionForString1: 2446337 false)
|
||||
#(40 1 #reduceActionForVariable1: 2233345 false)
|
||||
#(41 1 #reduceActionForModuleOrType2: 2273282 false)
|
||||
#(36 1 #reduceActionForNumber1: 2013185 false)
|
||||
#(35 1 #reduceActionForCharacter1: 1971201 false)
|
||||
#(24 2 #reduceActionForExpressions2: 1289218 false)
|
||||
#(25 1 #liftFirstValue: 1347588 false)
|
||||
#(25 1 #liftFirstValue: 1347589 false)
|
||||
#(25 1 #liftFirstValue: 1347587 false)
|
||||
#(25 1 #liftFirstValue: 1347586 false)
|
||||
#(25 1 #liftFirstValue: 1347585 false)
|
||||
#(30 1 #liftFirstValue: 1652745 false)
|
||||
#(30 1 #liftFirstValue: 1652744 false)
|
||||
#(30 1 #liftFirstValue: 1652743 false)
|
||||
#(30 1 #liftFirstValue: 1652742 false)
|
||||
#(30 1 #liftFirstValue: 1652739 false)
|
||||
#(30 1 #liftFirstValue: 1652741 false)
|
||||
#(30 1 #liftFirstValue: 1652740 false)
|
||||
#(39 1 #liftFirstValue: 2195458 false)
|
||||
#(39 1 #liftFirstValue: 2195457 false)
|
||||
#(30 1 #liftFirstValue: 1652738 false)
|
||||
#(30 1 #liftFirstValue: 1652737 false)
|
||||
#(34 2 #reduceActionForPattern1: 1906689 false)
|
||||
#(27 2 #reduceActionForUnquote1: 1466369 false)
|
||||
#(27 2 #reduceActionForUnquote1: 1466370 false)
|
||||
#(28 2 #reduceActionForRef1: 1548289 false)
|
||||
#(29 2 #reduceActionForDeref1: 1598465 false)
|
||||
#(26 2 #reduceActionForRefCall1: 1412097 false)
|
||||
#(38 2 #reduceActionForQuote1: 2150401 false)
|
||||
#(31 3 #reduceActionForMap1: 1744897 false)
|
||||
#(32 2 #reduceActionForExpressions2: 1803266 false)
|
||||
#(42 3 #reduceActionForList1: 2364417 false)
|
||||
#(41 3 #reduceActionForModuleOrType1: 2273281 false)
|
||||
#(37 3 #reduceActionForArray1: 2059265 false)
|
||||
#(33 2 #reduceActionForMapPair1: 1846273 false)
|
||||
#(24 0 #reduceActionForExpressions1: 1449985 false)
|
||||
#(23 1 #reduceActionForStart1: 1419265 false)
|
||||
#(32 0 #reduceActionForExpressions1: 1964033 false)
|
||||
#(43 1 #reduceActionForString1: 2607105 false)
|
||||
#(40 1 #reduceActionForVariable1: 2394113 false)
|
||||
#(41 1 #reduceActionForModuleOrType2: 2434050 false)
|
||||
#(36 1 #reduceActionForNumber1: 2173953 false)
|
||||
#(35 1 #reduceActionForCharacter1: 2131969 false)
|
||||
#(24 2 #reduceActionForExpressions2: 1449986 false)
|
||||
#(25 1 #liftFirstValue: 1508356 false)
|
||||
#(25 1 #liftFirstValue: 1508357 false)
|
||||
#(25 1 #liftFirstValue: 1508355 false)
|
||||
#(25 1 #liftFirstValue: 1508354 false)
|
||||
#(25 1 #liftFirstValue: 1508353 false)
|
||||
#(30 1 #liftFirstValue: 1813513 false)
|
||||
#(30 1 #liftFirstValue: 1813512 false)
|
||||
#(30 1 #liftFirstValue: 1813511 false)
|
||||
#(30 1 #liftFirstValue: 1813510 false)
|
||||
#(30 1 #liftFirstValue: 1813507 false)
|
||||
#(30 1 #liftFirstValue: 1813509 false)
|
||||
#(30 1 #liftFirstValue: 1813508 false)
|
||||
#(39 1 #liftFirstValue: 2356226 false)
|
||||
#(39 1 #liftFirstValue: 2356225 false)
|
||||
#(30 1 #liftFirstValue: 1813506 false)
|
||||
#(30 1 #liftFirstValue: 1813505 false)
|
||||
#(34 2 #reduceActionForPattern1: 2067457 false)
|
||||
#(27 2 #reduceActionForUnquote1: 1627137 false)
|
||||
#(27 2 #reduceActionForUnquote1: 1627138 false)
|
||||
#(28 2 #reduceActionForRef1: 1709057 false)
|
||||
#(29 2 #reduceActionForDeref1: 1759233 false)
|
||||
#(26 2 #reduceActionForRefCall1: 1572865 false)
|
||||
#(38 2 #reduceActionForQuote1: 2311169 false)
|
||||
#(31 3 #reduceActionForMap1: 1905665 false)
|
||||
#(32 2 #reduceActionForExpressions2: 1964034 false)
|
||||
#(42 3 #reduceActionForList1: 2525185 false)
|
||||
#(41 3 #reduceActionForModuleOrType1: 2434049 false)
|
||||
#(37 3 #reduceActionForArray1: 2220033 false)
|
||||
#(33 2 #reduceActionForMapPair1: 2007041 false)
|
||||
).
|
||||
]
|
||||
|
||||
|
@@ -26,6 +26,11 @@ CarpPatternNode >> patternGlyph: aSmaCCToken [
|
||||
patternGlyph := aSmaCCToken
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpPatternNode >> toPharo [
|
||||
^ value source
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpPatternNode >> tokenVariables [
|
||||
|
||||
|
@@ -32,6 +32,11 @@ CarpRefCallNode >> refGlyph: aSmaCCToken [
|
||||
refGlyph := aSmaCCToken
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpRefCallNode >> toPharo [
|
||||
^ {#'ref-call' . value toPharo}
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpRefCallNode >> tokenVariables [
|
||||
|
||||
|
@@ -32,6 +32,11 @@ CarpRefNode >> refGlyph: aSmaCCToken [
|
||||
refGlyph := aSmaCCToken
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpRefNode >> toPharo [
|
||||
^ {#ref . value toPharo}
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpRefNode >> tokenVariables [
|
||||
|
||||
|
@@ -30,80 +30,72 @@ CarpScanner >> scan1 [
|
||||
|
||||
{ #category : #generated }
|
||||
CarpScanner >> scan2 [
|
||||
|
||||
self recordMatch: #( 13 ).
|
||||
self recordMatch: #(13).
|
||||
self step.
|
||||
currentCharacter isDigit ifTrue: [ ^ self scan3 ].
|
||||
(currentCharacter isLowercase or: [
|
||||
currentCharacter isUppercase or: [
|
||||
('!$' includes: currentCharacter) or: [
|
||||
(currentCharacter between: $* and: $+) or: [
|
||||
('-/:' includes: currentCharacter) or: [
|
||||
(currentCharacter between: $< and: $?) or: [
|
||||
currentCharacter == $_ ] ] ] ] ] ]) ifTrue: [
|
||||
[
|
||||
self recordMatch: #( 13 ).
|
||||
self step.
|
||||
currentCharacter isLowercase or: [
|
||||
currentCharacter isUppercase or: [
|
||||
currentCharacter isDigit or: [
|
||||
('!$' includes: currentCharacter) or: [
|
||||
(currentCharacter between: $* and: $+) or: [
|
||||
('-/:' includes: currentCharacter) or: [
|
||||
(currentCharacter between: $< and: $?) or: [
|
||||
currentCharacter == $_ ] ] ] ] ] ] ] ] whileTrue ].
|
||||
(currentCharacter isLowercase
|
||||
or: [ currentCharacter isUppercase
|
||||
or: [ ('!$' includes: currentCharacter)
|
||||
or: [ (currentCharacter between: $* and: $+)
|
||||
or: [ currentCharacter == $-
|
||||
or: [ (currentCharacter between: $/ and: $:)
|
||||
or: [ (currentCharacter between: $< and: $?) or: [ currentCharacter == $_ ] ] ] ] ] ] ])
|
||||
ifTrue: [ [ self recordMatch: #(13).
|
||||
self step.
|
||||
currentCharacter isLowercase
|
||||
or: [ currentCharacter isUppercase
|
||||
or: [ currentCharacter isDigit
|
||||
or: [ ('!$' includes: currentCharacter)
|
||||
or: [ (currentCharacter between: $* and: $+)
|
||||
or: [ ('-/:' includes: currentCharacter)
|
||||
or: [ (currentCharacter between: $< and: $?) or: [ currentCharacter == $_ ] ] ] ] ] ] ] ]
|
||||
whileTrue ].
|
||||
^ self reportLastMatch
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpScanner >> scan3 [
|
||||
|
||||
[
|
||||
self recordMatch: #( 13 18 ).
|
||||
[ self recordMatch: #(13 18).
|
||||
self step.
|
||||
currentCharacter == $. ifTrue: [ ^ self scan4 ].
|
||||
currentCharacter isDigit ] whileTrue.
|
||||
('bfl' includes: currentCharacter) ifTrue: [
|
||||
self recordMatch: #( 13 18 ).
|
||||
self step.
|
||||
(currentCharacter isLowercase or: [
|
||||
currentCharacter isUppercase or: [
|
||||
currentCharacter isDigit or: [
|
||||
('!$' includes: currentCharacter) or: [
|
||||
(currentCharacter between: $* and: $+) or: [
|
||||
('-/:' includes: currentCharacter) or: [
|
||||
(currentCharacter between: $< and: $?) or: [
|
||||
currentCharacter == $_ ] ] ] ] ] ] ]) ifTrue: [
|
||||
[
|
||||
self recordMatch: #( 13 ).
|
||||
('bfl' includes: currentCharacter)
|
||||
ifTrue: [ self recordMatch: #(13 18).
|
||||
self step.
|
||||
currentCharacter isLowercase or: [
|
||||
currentCharacter isUppercase or: [
|
||||
currentCharacter isDigit or: [
|
||||
('!$' includes: currentCharacter) or: [
|
||||
(currentCharacter between: $* and: $+) or: [
|
||||
('-/:' includes: currentCharacter) or: [
|
||||
(currentCharacter between: $< and: $?) or: [
|
||||
currentCharacter == $_ ] ] ] ] ] ] ] ] whileTrue ].
|
||||
^ self reportLastMatch ].
|
||||
(currentCharacter isUppercase or: [
|
||||
currentCharacter isLowercase or: [
|
||||
('!$' includes: currentCharacter) or: [
|
||||
(currentCharacter between: $* and: $+) or: [
|
||||
('-/:' includes: currentCharacter) or: [
|
||||
(currentCharacter between: $< and: $?) or: [
|
||||
currentCharacter == $_ ] ] ] ] ] ]) ifTrue: [
|
||||
[
|
||||
self recordMatch: #( 13 ).
|
||||
self step.
|
||||
currentCharacter isLowercase or: [
|
||||
currentCharacter isUppercase or: [
|
||||
currentCharacter isDigit or: [
|
||||
('!$' includes: currentCharacter) or: [
|
||||
(currentCharacter between: $* and: $+) or: [
|
||||
('-/:' includes: currentCharacter) or: [
|
||||
(currentCharacter between: $< and: $?) or: [
|
||||
currentCharacter == $_ ] ] ] ] ] ] ] ] whileTrue ].
|
||||
(currentCharacter isLowercase
|
||||
or: [ currentCharacter isUppercase
|
||||
or: [ currentCharacter isDigit
|
||||
or: [ ('!$' includes: currentCharacter)
|
||||
or: [ (currentCharacter between: $* and: $+)
|
||||
or: [ ('-/:' includes: currentCharacter)
|
||||
or: [ (currentCharacter between: $< and: $?) or: [ currentCharacter == $_ ] ] ] ] ] ] ])
|
||||
ifTrue: [ [ self recordMatch: #(13).
|
||||
self step.
|
||||
currentCharacter isLowercase
|
||||
or: [ currentCharacter isUppercase
|
||||
or: [ currentCharacter isDigit
|
||||
or: [ ('!$' includes: currentCharacter)
|
||||
or: [ (currentCharacter between: $* and: $+)
|
||||
or: [ ('-/:' includes: currentCharacter)
|
||||
or: [ (currentCharacter between: $< and: $?) or: [ currentCharacter == $_ ] ] ] ] ] ] ] ]
|
||||
whileTrue ].
|
||||
^ self reportLastMatch ].
|
||||
(currentCharacter isUppercase
|
||||
or: [ currentCharacter isLowercase
|
||||
or: [ ('!$' includes: currentCharacter)
|
||||
or: [ (currentCharacter between: $* and: $+)
|
||||
or: [ (currentCharacter between: $- and: $:)
|
||||
or: [ (currentCharacter between: $< and: $?) or: [ currentCharacter == $_ ] ] ] ] ] ])
|
||||
ifTrue: [ [ self recordMatch: #(13).
|
||||
self step.
|
||||
currentCharacter isLowercase
|
||||
or: [ currentCharacter isUppercase
|
||||
or: [ currentCharacter isDigit
|
||||
or: [ ('!$' includes: currentCharacter)
|
||||
or: [ (currentCharacter between: $* and: $+)
|
||||
or: [ ('-/:' includes: currentCharacter)
|
||||
or: [ (currentCharacter between: $< and: $?) or: [ currentCharacter == $_ ] ] ] ] ] ] ] ]
|
||||
whileTrue ].
|
||||
^ self reportLastMatch
|
||||
]
|
||||
|
||||
@@ -152,12 +144,9 @@ CarpScanner >> scan7 [
|
||||
|
||||
{ #category : #generated }
|
||||
CarpScanner >> scanForToken [
|
||||
|
||||
self step.
|
||||
currentCharacter == $" ifTrue: [ ^ self scan1 ].
|
||||
currentCharacter == $# ifTrue: [ ^ self recordAndReportMatch: #( 1 ) ].
|
||||
currentCharacter == $% ifTrue: [ ^ self scanForTokenX7 ].
|
||||
currentCharacter == $& ifTrue: [ ^ self recordAndReportMatch: #( 4 ) ].
|
||||
currentCharacter == $# ifTrue: [ ^ self recordAndReportMatch: #(1) ].
|
||||
^ self scanForTokenX9
|
||||
]
|
||||
|
||||
@@ -330,47 +319,36 @@ CarpScanner >> scanForTokenX7 [
|
||||
|
||||
{ #category : #generated }
|
||||
CarpScanner >> scanForTokenX8 [
|
||||
|
||||
currentCharacter == $} ifTrue: [ ^ self recordAndReportMatch: #( 7 ) ].
|
||||
currentCharacter == $~ ifTrue: [ ^ self recordAndReportMatch: #( 8 ) ].
|
||||
currentCharacter == $] ifTrue: [ ^ self recordAndReportMatch: #(17) ].
|
||||
currentCharacter == ${ ifTrue: [ ^ self recordAndReportMatch: #(6) ].
|
||||
currentCharacter == $} ifTrue: [ ^ self recordAndReportMatch: #(7) ].
|
||||
currentCharacter == $~ ifTrue: [ ^ self recordAndReportMatch: #(8) ].
|
||||
currentCharacter isDigit ifTrue: [ ^ self scan5 ].
|
||||
('''`' includes: currentCharacter) ifTrue: [
|
||||
^ self recordAndReportMatch: #( 12 ) ].
|
||||
(currentCharacter isSeparator or: [
|
||||
currentCharacter == Character pageUp ]) ifTrue: [
|
||||
^ self scanForTokenX6 ].
|
||||
('''`' includes: currentCharacter)
|
||||
ifTrue: [ ^ self recordAndReportMatch: #(12) ].
|
||||
(currentCharacter isSeparator or: [ currentCharacter == Character pageUp ])
|
||||
ifTrue: [ ^ self scanForTokenX6 ].
|
||||
currentCharacter isUppercase ifTrue: [ ^ self scanForTokenX3 ].
|
||||
(currentCharacter isLowercase or: [
|
||||
('!$' includes: currentCharacter) or: [
|
||||
(currentCharacter between: $* and: $+) or: [
|
||||
('/:' includes: currentCharacter) or: [
|
||||
(currentCharacter between: $< and: $?) or: [
|
||||
currentCharacter == $_ ] ] ] ] ]) ifTrue: [
|
||||
self scanForTokenX4 ].
|
||||
(currentCharacter isLowercase
|
||||
or: [ (currentCharacter between: $! and: $?) or: [ currentCharacter == $_ ] ])
|
||||
ifTrue: [ self scanForTokenX4 ].
|
||||
^ self reportLastMatch
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpScanner >> scanForTokenX9 [
|
||||
|
||||
currentCharacter == $( ifTrue: [
|
||||
^ self recordAndReportMatch: #( 10 ) ].
|
||||
currentCharacter == $) ifTrue: [
|
||||
^ self recordAndReportMatch: #( 11 ) ].
|
||||
currentCharacter == $, ifTrue: [
|
||||
^ self recordAndReportMatch: #( 19 ) ].
|
||||
currentCharacter == $% ifTrue: [ ^ self scanForTokenX7 ].
|
||||
currentCharacter == $& ifTrue: [ ^ self recordAndReportMatch: #(4) ].
|
||||
currentCharacter == $( ifTrue: [ ^ self recordAndReportMatch: #(10) ].
|
||||
currentCharacter == $) ifTrue: [ ^ self recordAndReportMatch: #(11) ].
|
||||
currentCharacter == $, ifTrue: [ ^ self recordAndReportMatch: #(19) ].
|
||||
currentCharacter == $- ifTrue: [ ^ self scan2 ].
|
||||
currentCharacter == $. ifTrue: [
|
||||
^ self recordAndReportMatch: #( 15 ) ].
|
||||
currentCharacter == $. ifTrue: [ ^ self recordAndReportMatch: #(15) ].
|
||||
currentCharacter == $0 ifTrue: [ ^ self scanForTokenX2 ].
|
||||
currentCharacter == $; ifTrue: [ ^ self scanForTokenX5 ].
|
||||
currentCharacter == $@ ifTrue: [ ^ self recordAndReportMatch: #( 5 ) ].
|
||||
currentCharacter == $[ ifTrue: [
|
||||
^ self recordAndReportMatch: #( 16 ) ].
|
||||
currentCharacter == $@ ifTrue: [ ^ self recordAndReportMatch: #(5) ].
|
||||
currentCharacter == $[ ifTrue: [ ^ self recordAndReportMatch: #(16) ].
|
||||
currentCharacter == $\ ifTrue: [ ^ self scanForTokenX1 ].
|
||||
currentCharacter == $] ifTrue: [
|
||||
^ self recordAndReportMatch: #( 17 ) ].
|
||||
currentCharacter == ${ ifTrue: [ ^ self recordAndReportMatch: #( 6 ) ].
|
||||
^ self scanForTokenX8
|
||||
]
|
||||
|
||||
|
@@ -25,6 +25,11 @@ CarpUnquoteNode >> nodeVariables [
|
||||
^ #( #value )
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpUnquoteNode >> toPharo [
|
||||
^ {#unquote . value toPharo}
|
||||
]
|
||||
|
||||
{ #category : #generated }
|
||||
CarpUnquoteNode >> tokenVariables [
|
||||
|
||||
|
10
src/Carp/CarpCommand.class.st
Normal file
10
src/Carp/CarpCommand.class.st
Normal file
@@ -0,0 +1,10 @@
|
||||
Class {
|
||||
#name : #CarpCommand,
|
||||
#superclass : #LanguageLinkCommand,
|
||||
#category : #'Carp-LanguageLink'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpCommand >> codeForRemote [
|
||||
^ (Character space join: self instructions) copyReplaceAll: Character cr asString with: Character lf asString
|
||||
]
|
@@ -3,3 +3,13 @@ Class {
|
||||
#superclass : #LanguageLinkCommandFactory,
|
||||
#category : #'Carp-Execution'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpCommandFactory >> command [
|
||||
^ command
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpCommandFactory >> instructionsWithNotifyAtEnd [
|
||||
^ instructions
|
||||
]
|
||||
|
@@ -4,19 +4,19 @@ Class {
|
||||
#category : #'Carp-Serialization'
|
||||
}
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
CarpDeserializer class >> deserialize: anObject [
|
||||
^ self new
|
||||
deserialize: anObject
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpDeserializer >> buildProxyFor: rawObject [
|
||||
| proxy |
|
||||
proxy := CarpProxyObject
|
||||
carpType: (rawObject at: #carptype)
|
||||
var: (rawObject at: #carpvar) asJSGI
|
||||
var: (rawObject at: #carpvar)
|
||||
application: self application.
|
||||
self executionHandler registerObject: proxy.
|
||||
^ proxy
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpDeserializer >> deserialize: anObject [
|
||||
^ self new
|
||||
deserialize: anObject
|
||||
]
|
||||
|
@@ -7,6 +7,11 @@ Class {
|
||||
#category : #'Carp-Processes'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpPlatform class >> uiManagerClass [
|
||||
^ LanguageLinkPharoUiManager
|
||||
]
|
||||
|
||||
{ #category : #hooks }
|
||||
CarpPlatform class >> weakRegistryClass [
|
||||
^ LanguageLinkPharoWeakRegistry
|
||||
|
@@ -23,7 +23,7 @@ CarpPostMortemDebugger >> exception: anException [
|
||||
CarpPostMortemDebugger >> initialize [
|
||||
|
||||
super initialize.
|
||||
frameRegex := '\s+at.+\(([^:]+)\:(\d+)\:(\d+)\)' asRegexIgnoringCase.
|
||||
frameRegex := '(.*)\s+at.+([^:]+)\:(\d+)\:(\d+)\.' asRegexIgnoringCase.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
@@ -37,16 +37,19 @@ CarpPostMortemDebugger >> sourceStyler [
|
||||
CarpPostMortemDebugger >> stackFrameFromLine: aString ordinal: ordinal [
|
||||
"Answer a frame if the supplied string contains a valid file and line number, or nil"
|
||||
<return: #GtPythonPostMortemStackFrame or: nil>
|
||||
| file line column |
|
||||
| file line column source |
|
||||
|
||||
^ (frameRegex search: aString) ifTrue:
|
||||
[ file := frameRegex subexpression: 2.
|
||||
line := frameRegex subexpression: 3.
|
||||
column := frameRegex subexpression: 4.
|
||||
file := frameRegex subexpression: 3.
|
||||
line := frameRegex subexpression: 4.
|
||||
column := frameRegex subexpression: 5.
|
||||
self halt.
|
||||
CarpPostMortemStackFrame new
|
||||
ordinal: ordinal;
|
||||
displayString: aString;
|
||||
exception: exception;
|
||||
source: source;
|
||||
file: file asFileReference;
|
||||
line: line asNumber;
|
||||
column: column asNumber ]
|
||||
|
@@ -1,5 +1,18 @@
|
||||
Class {
|
||||
#name : #CarpPostMortemStackFrame,
|
||||
#superclass : #GtJavaScriptPostMortemStackFrame,
|
||||
#instVars : [
|
||||
'source'
|
||||
],
|
||||
#category : #'Carp-Debugger'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpPostMortemStackFrame >> source: aString [
|
||||
source := aString
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpPostMortemStackFrame >> sourceText [
|
||||
^ source
|
||||
]
|
||||
|
@@ -11,26 +11,27 @@ Class {
|
||||
#category : #'Carp-Processes'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpProcess class >> program [
|
||||
^ 'carp'
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpProcess class >> resolveCarpPath [
|
||||
| proc |
|
||||
|
||||
proc := GtSubprocessWithInMemoryOutput new
|
||||
command: 'which';
|
||||
arguments: { 'carp' }.
|
||||
arguments: { self program}.
|
||||
CarpPlatform subProcessEnvironmentDictionary keysAndValuesDo: [ :key :value |
|
||||
proc environmentAt: key put: value ].
|
||||
proc runAndWait.
|
||||
(#(0 1) includes: proc exitCode) ifFalse:
|
||||
[ self error: 'Unable to request carp location' ].
|
||||
[ self error: 'Unable to request', self program, ' location' ].
|
||||
^ proc stdout trim asFileReference
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpProcess class >> resolveNodejsPath [
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpProcess class >> serverPath [
|
||||
^ CarpPath
|
||||
@@ -67,16 +68,17 @@ CarpProcess >> isRunning [
|
||||
ifNotNil: [ process isRunning ]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpProcess >> newProcess| newProcess [ |
|
||||
{ #category : #'start-stop' }
|
||||
CarpProcess >> newProcess [
|
||||
| newProcess |
|
||||
newProcess := GtSubprocessWithInMemoryOutput new
|
||||
command: self serverPath fullName;
|
||||
arguments: self processArguments;
|
||||
workingDirectory: self workingDirectory resolve fullName;
|
||||
terminateOnShutdown;
|
||||
yourself.
|
||||
environmentVariables associationsDo: [ :assoc |
|
||||
newProcess environmentAt: assoc key put: assoc value ].
|
||||
command: self serverPath fullName;
|
||||
arguments: self processArguments;
|
||||
workingDirectory: self workingDirectory resolve fullName;
|
||||
terminateOnShutdown;
|
||||
yourself.
|
||||
environmentVariables
|
||||
associationsDo: [ :assoc | newProcess environmentAt: assoc key put: assoc value ].
|
||||
^ newProcess
|
||||
]
|
||||
|
||||
@@ -88,12 +90,17 @@ CarpProcess >> processArguments [
|
||||
self settings serverDebugMode ifTrue:
|
||||
[ args add: '--inspect' ].
|
||||
args
|
||||
add: (self workingDirectory / 'src/languagelink.carp') resolve fullName;
|
||||
add: (self workingDirectory / self programFile) resolve fullName;
|
||||
add: self settings serverSocketAddress port asString;
|
||||
add: self settings clientSocketAddress port asString.
|
||||
^ args
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpProcess >> programFile [
|
||||
^ 'src/languagelink.carp'
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpProcess >> serverPath [
|
||||
| fileReference |
|
||||
|
40
src/Carp/CarpPythonProcess.class.st
Normal file
40
src/Carp/CarpPythonProcess.class.st
Normal file
@@ -0,0 +1,40 @@
|
||||
Class {
|
||||
#name : #CarpPythonProcess,
|
||||
#superclass : #CarpProcess,
|
||||
#category : #'Carp-Processes'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpPythonProcess class >> program [
|
||||
^ 'python'
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpPythonProcess >> processArguments [
|
||||
| args |
|
||||
|
||||
args := OrderedCollection new.
|
||||
self settings serverDebugMode ifTrue:
|
||||
[ args addAll: {
|
||||
'-m'.
|
||||
'debugpy'.
|
||||
'--listen'.
|
||||
self settings debugSocketAddress printAddress.
|
||||
'--wait-for-client'. } ].
|
||||
args
|
||||
add: (self workingDirectory / self programFile) resolve fullName;
|
||||
add: '--port';
|
||||
add: self settings serverSocketAddress port asString;
|
||||
add: '--pharo';
|
||||
add: self settings clientSocketAddress port asString;
|
||||
add: '--method';
|
||||
add: 'http'.
|
||||
"self debugMode ifTrue: [ args add: '--log' ]."
|
||||
args add: '--log'.
|
||||
^ args
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
CarpPythonProcess >> programFile [
|
||||
^ 'src/languagelink.py'
|
||||
]
|
@@ -3,7 +3,8 @@ Class {
|
||||
#superclass : #GtSourceCoder,
|
||||
#instVars : [
|
||||
'pharoBindings',
|
||||
'carpLinkApplicationStrategy'
|
||||
'carpLinkApplicationStrategy',
|
||||
'exception'
|
||||
],
|
||||
#category : #'Carp-Coder'
|
||||
}
|
||||
@@ -24,32 +25,37 @@ GtCarpCoderModel >> asCoderViewModel [
|
||||
{ #category : #accessing }
|
||||
GtCarpCoderModel >> bindAndExecute: sourceString [
|
||||
"Answer the source code with all declared variables returned in an immediate dictionary"
|
||||
|
||||
<gtIgnoreConstraint: #GtRBAcceptVisitorCalledFromNonVisitingMethods>
|
||||
| carpSource trimmedSource ast varNames lastStatement application commandFactory |
|
||||
|
||||
<remoteDebuggerSignal>
|
||||
| carpSource trimmedSource ast varNames lastStatement application commandFactory res |
|
||||
trimmedSource := SmaCCString on: sourceString trimRight.
|
||||
ast := CarpParser parse: trimmedSource.
|
||||
"The variables to be returned are names that are in pharoBindings"
|
||||
varNames := pharoBindings bindingNames asSet.
|
||||
|
||||
"Assign the final statement to snippetResult"
|
||||
ast := CarpParser parse: trimmedSource. "The variables to be returned are names that are in pharoBindings"
|
||||
varNames := pharoBindings bindingNames asSet. "Assign the final statement to snippetResult"
|
||||
lastStatement := ast expressions last.
|
||||
trimmedSource
|
||||
insert: '(defdynamic snippetResult '
|
||||
at: lastStatement startPosition.
|
||||
varNames add: 'snippetResult'.
|
||||
|
||||
"Get the final source to execute"
|
||||
carpSource := self sourceFrom: trimmedSource asString returnedVarNames: varNames.
|
||||
trimmedSource insert: ')' at: lastStatement stopPosition.
|
||||
varNames add: 'snippetResult'. "Get the final source to execute"
|
||||
carpSource := self
|
||||
sourceFrom: trimmedSource asString
|
||||
returnedVarNames: varNames.
|
||||
|
||||
application := carpLinkApplicationStrategy applicationServer.
|
||||
application isRunning ifFalse: [ application start ].
|
||||
commandFactory := application newCommandFactory.
|
||||
|
||||
^ commandFactory
|
||||
<< carpSource;
|
||||
sendAndWait.
|
||||
res := commandFactory
|
||||
<< carpSource;
|
||||
sendAndWait.
|
||||
|
||||
(res at: #result) = 'success' ifTrue: [ ^ res at: #value ].
|
||||
exception := (PharoLinkRemoteError new
|
||||
application: application;
|
||||
command: commandFactory command;
|
||||
trace: (res at: #value)).
|
||||
exception signal
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
@@ -63,6 +69,11 @@ GtCarpCoderModel >> computeAst: theSourceString [
|
||||
parseWithErrors: theSourceString
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GtCarpCoderModel >> exception [
|
||||
^ exception
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GtCarpCoderModel >> initializeAddOns: addOns [
|
||||
super initializeAddOns: addOns.
|
||||
@@ -110,36 +121,17 @@ GtCarpCoderModel >> pharoBindings: anObject [
|
||||
|
||||
{ #category : #accessing }
|
||||
GtCarpCoderModel >> primitiveEvaluate: aSourceString inContext: aGtSourceCoderEvaluationContext onFailDo: anEvaluationFailBlock [
|
||||
| result |
|
||||
|
||||
result := self bindAndExecute: aSourceString.
|
||||
result associationsDo: [ :binding |
|
||||
(pharoBindings bindingOf: binding key asSymbol) value: binding value ].
|
||||
|
||||
^ result
|
||||
at: 'snippetResult'
|
||||
ifAbsent: anEvaluationFailBlock
|
||||
^ (CarpParser parse: (self bindAndExecute: aSourceString)) expressions first toPharo
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GtCarpCoderModel >> sourceFrom: trimmedSourceString returnedVarNames: varNames [
|
||||
"Answer the modified source to return the declared variables"
|
||||
|
||||
^ String streamContents: [ :stream |
|
||||
stream << trimmedSourceString.
|
||||
stream
|
||||
cr
|
||||
<< '{ '.
|
||||
varNames do: [ :varName |
|
||||
stream
|
||||
<< '(quote ';
|
||||
<< varName;
|
||||
<< ') ';
|
||||
<< varName;
|
||||
<< ' ' ].
|
||||
"Answer the variable dictionary as an immediate object"
|
||||
stream
|
||||
<< '(quote carpLinkImmediate) true }' ]
|
||||
^ String
|
||||
streamContents: [ :stream |
|
||||
stream << trimmedSourceString.
|
||||
stream lf << 'snippetResult' ]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
|
@@ -9,10 +9,10 @@ LanguageLinkSettings class >> carpDefaultSettings [
|
||||
serverSocketAddress: (LanguageLinkSocketAddress
|
||||
ipOrName: 'localhost' port: (9900 + 99 atRandom));
|
||||
messageBrokerStrategy: LanguageLinkHttpMessageBroker;
|
||||
serverProcessClass: CarpProcess;
|
||||
serverProcessClass: CarpPythonProcess;
|
||||
platform: CarpPlatform new;
|
||||
commandFactoryClass: CarpCommandFactory;
|
||||
commandClass: LanguageLinkCommand;
|
||||
commandClass: CarpCommand;
|
||||
serializerClass: LanguageLinkSerializer;
|
||||
deserializerClass: CarpDeserializer;
|
||||
parserClass: CarpParser;
|
||||
|
@@ -41,15 +41,16 @@ LeCarpApplicationStrategy >> newCarpApplicationFor: aLeDatabase [
|
||||
{ #category : #accessing }
|
||||
LeCarpApplicationStrategy >> updatedSettings: applicationCarpSettings [
|
||||
"Update the supplied settings with the lepiter configuration"
|
||||
| lepiterCarpSettings lepiterDatabase carpDir |
|
||||
|
||||
| lepiterCarpSettings lepiterDatabase carpDir |
|
||||
lepiterDatabase := content database.
|
||||
(lepiterDatabase isKindOf: LeNullDatabase)
|
||||
ifTrue: [ ^ applicationCarpSettings ].
|
||||
lepiterCarpSettings := lepiterDatabase properties carpLinkSettings.
|
||||
lepiterCarpSettings directory ifNotNil:
|
||||
[ :relativeDir |
|
||||
lepiterCarpSettings directory
|
||||
ifNotNil: [ :relativeDir |
|
||||
carpDir := lepiterDatabase localStoreRootDirectory resolve: relativeDir.
|
||||
applicationCarpSettings workingDirectory: carpDir ].
|
||||
"lepiterCarpSettings carpPath ifNotNil:
|
||||
applicationCarpSettings workingDirectory: carpDir ]. "lepiterCarpSettings carpPath ifNotNil:
|
||||
[ :carpPath | applicationCarpSettings serverExecutable: carpPath ]."
|
||||
applicationCarpSettings serverDebugMode: lepiterCarpSettings serverDebugMode.
|
||||
|
||||
|
Reference in New Issue
Block a user