Updated python source
This commit is contained in:
parent
77655f3b7f
commit
8b79c3007b
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
define (M ?x) (?x ?x)
|
||||||
|
define (KI ?x ?y) (?y)
|
||||||
|
define (T ?x ?y) (?y ?y)
|
||||||
|
define (W ?x ?y) (?x ?y ?y)
|
||||||
|
define (K ?x ?y) (?x)
|
||||||
|
define (C ?x ?y ?z) (?x ?z ?y)
|
||||||
|
define (B ?x ?y ?z) (?x (?y ?z))
|
||||||
|
define (I ?x) (?x)
|
||||||
|
define (S ?x ?y ?z) (?x ?z (?y ?z))
|
||||||
|
|
386
modal.py
386
modal.py
|
@ -7,344 +7,341 @@
|
||||||
|is based on the idea of cyclic delimited string rewriting |
|
|is based on the idea of cyclic delimited string rewriting |
|
||||||
|using a central queue and a dictionary of variable bindings.|
|
|using a central queue and a dictionary of variable bindings.|
|
||||||
| |
|
| |
|
||||||
|© 2019 imode, Immediate Mode Technologies |
|
|© 2019-2024 wryl, Paradigital |
|
||||||
*------------------------------------------------------------*
|
*------------------------------------------------------------*
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# `sys` for I/O and arguments.
|
# `sys` for I/O and arguments.
|
||||||
# `time` for measuring the runtime of the interpreter.
|
# `time` for measuring the runtime of the interpreter.
|
||||||
import sys, time;
|
import sys, time
|
||||||
|
|
||||||
# A decorator intended for measuring the runtime of a given function.
|
# A decorator intended for measuring the runtime of a given function.
|
||||||
def measure(function):
|
def measure(function):
|
||||||
def measurement(*arguments):
|
def measurement(*arguments):
|
||||||
start = time.time();
|
start = time.time()
|
||||||
result = function(*arguments);
|
result = function(*arguments)
|
||||||
end = time.time();
|
end = time.time()
|
||||||
milliseconds = (end - start) * 1000.0;
|
milliseconds = (end - start) * 1000.0
|
||||||
print("\nTook {:.3f}ms".format(milliseconds))
|
print("\nTook {:.3f}ms".format(milliseconds))
|
||||||
return result;
|
return result
|
||||||
return measurement;
|
return measurement
|
||||||
|
|
||||||
# Enqueue an item by appending it to the queue.
|
# Enqueue an item by appending it to the queue.
|
||||||
def enqueue(queue, item):
|
def enqueue(queue, item):
|
||||||
return queue + item;
|
return queue + item
|
||||||
|
|
||||||
# Dequeue an item by slicing the queue. The last item is the head.
|
# Dequeue an item by slicing the queue. The last item is the head.
|
||||||
def dequeue(queue, length=1):
|
def dequeue(queue, length=1):
|
||||||
if length > len(queue):
|
if length > len(queue):
|
||||||
return queue;
|
return queue
|
||||||
return queue[length:];
|
return queue[length:]
|
||||||
|
|
||||||
# Get the item(s) at the head of the queue.
|
# Get the item(s) at the head of the queue.
|
||||||
def peek(queue, length=1):
|
def peek(queue, length=1):
|
||||||
if length > len(queue):
|
if length > len(queue):
|
||||||
return None;
|
return None
|
||||||
if length == 1:
|
if length == 1:
|
||||||
return queue[0];
|
return queue[0]
|
||||||
return queue[:length];
|
return queue[:length]
|
||||||
|
|
||||||
# Roll/cycle the queue by a certain amount by slicing.
|
# Roll/cycle the queue by a certain amount by slicing.
|
||||||
# This dequeues and enqueues a number of items, "cycling" the queue.
|
# This dequeues and enqueues a number of items, "cycling" the queue.
|
||||||
def roll(queue, length=1):
|
def roll(queue, length=1):
|
||||||
if length > len(queue):
|
if length > len(queue):
|
||||||
return queue;
|
return queue
|
||||||
return queue[length:] + queue[:length];
|
return queue[length:] + queue[:length]
|
||||||
|
|
||||||
# Seek to a certain position in the queue by repeatedly rolling it.
|
# Seek to a certain position in the queue by repeatedly rolling it.
|
||||||
def seek(queue, pattern):
|
def seek(queue, pattern):
|
||||||
if pattern not in queue:
|
if pattern not in queue:
|
||||||
return queue;
|
return queue
|
||||||
while peek(queue, len(pattern)) != pattern:
|
while peek(queue, len(pattern)) != pattern:
|
||||||
queue = roll(queue);
|
queue = roll(queue)
|
||||||
return queue;
|
return queue
|
||||||
|
|
||||||
# Extract a delimited fragment (subtree) from the queue.
|
# Extract a delimited fragment (subtree) from the queue.
|
||||||
def extract(queue):
|
def extract(queue):
|
||||||
results = [];
|
results = []
|
||||||
depth = 0;
|
depth = 0
|
||||||
for element in queue:
|
for element in queue:
|
||||||
if element[0] == "SRT":
|
if element[0] == "SRT":
|
||||||
return [];
|
return []
|
||||||
if element[0] == "INC":
|
if element[0] == "INC":
|
||||||
depth = depth + 1;
|
depth = depth + 1
|
||||||
if element[0] == "DEC":
|
if element[0] == "DEC":
|
||||||
if depth == 0:
|
if depth == 0:
|
||||||
return results;
|
return results
|
||||||
depth = depth - 1;
|
depth = depth - 1
|
||||||
results.append(element);
|
results.append(element)
|
||||||
if depth == 0:
|
if depth == 0:
|
||||||
return results;
|
return results
|
||||||
return results;
|
return results
|
||||||
|
|
||||||
# Generate a list of variable bindings from the current queue and a pattern.
|
# Generate a list of variable bindings from the current queue and a pattern.
|
||||||
def match(pattern, queue, context=None):
|
def match(pattern, queue, context=None):
|
||||||
if context == None:
|
if context == None:
|
||||||
context = {};
|
context = {}
|
||||||
if peek(queue) == None:
|
if peek(queue) == None:
|
||||||
return context;
|
return context
|
||||||
for element in pattern:
|
for element in pattern:
|
||||||
if element[0] == "VAR":
|
if element[0] == "VAR":
|
||||||
variable = element[1];
|
variable = element[1]
|
||||||
value = extract(queue);
|
value = extract(queue)
|
||||||
if variable in context:
|
if variable in context:
|
||||||
if context[variable] != value:
|
if context[variable] != value:
|
||||||
return None;
|
return None
|
||||||
queue = dequeue(queue, len(context[variable]));
|
queue = dequeue(queue, len(context[variable]))
|
||||||
else:
|
else:
|
||||||
if len(value) == 0:
|
if len(value) == 0:
|
||||||
return None;
|
return None
|
||||||
context[variable] = value;
|
context[variable] = value
|
||||||
queue = dequeue(queue, len(context[variable]));
|
queue = dequeue(queue, len(context[variable]))
|
||||||
elif element != peek(queue):
|
elif element != peek(queue):
|
||||||
return None;
|
return None
|
||||||
else:
|
else:
|
||||||
queue = dequeue(queue);
|
queue = dequeue(queue)
|
||||||
return context;
|
return context
|
||||||
|
|
||||||
# Fill in a pattern with variables in it using a list of variable bindings.
|
# Fill in a pattern with variables in it using a list of variable bindings.
|
||||||
def construct(pattern, context):
|
def construct(pattern, context):
|
||||||
results = [];
|
results = []
|
||||||
for element in pattern:
|
for element in pattern:
|
||||||
if element[0] == "VAR":
|
if element[0] == "VAR":
|
||||||
if element[1] in context:
|
if element[1] in context:
|
||||||
for element in context[element[1]]:
|
for element in context[element[1]]:
|
||||||
results.append(element);
|
results.append(element)
|
||||||
else:
|
else:
|
||||||
results.append(element);
|
results.append(element)
|
||||||
else:
|
else:
|
||||||
results.append(element);
|
results.append(element)
|
||||||
return results;
|
return results
|
||||||
|
|
||||||
# Apply a pattern/replacement rule to the queue.
|
# Apply a pattern/replacement rule to the queue.
|
||||||
def apply(queue, rules, pattern, replacement):
|
def apply(queue, rules, pattern, replacement):
|
||||||
context = match(pattern, queue);
|
context = match(pattern, queue)
|
||||||
if context == None:
|
if context == None:
|
||||||
return (False, roll(queue));
|
return (False, roll(queue))
|
||||||
pattern = construct(pattern, context);
|
pattern = construct(pattern, context)
|
||||||
if not pattern:
|
if not pattern:
|
||||||
return (False, roll(queue));
|
return (False, roll(queue))
|
||||||
replacement = construct(replacement, context);
|
replacement = construct(replacement, context)
|
||||||
if len(replacement) == 0:
|
|
||||||
return (True, dequeue(queue, len(pattern)))
|
|
||||||
if not replacement:
|
if not replacement:
|
||||||
return (True, roll(queue));
|
return (False, roll(queue))
|
||||||
return (True, enqueue(dequeue(queue, len(pattern)), replacement));
|
return (True, enqueue(dequeue(queue, len(pattern)), replacement))
|
||||||
|
|
||||||
def define(queue, rules, pattern):
|
def define(queue, rules, pattern):
|
||||||
context = match(pattern, queue);
|
context = match(pattern, queue)
|
||||||
left = context["left"];
|
left = context["left"]
|
||||||
right = context["right"];
|
right = context["right"]
|
||||||
if right and left:
|
if right and left:
|
||||||
if len(left) > 1:
|
if len(left) > 1:
|
||||||
left = left[1:][:-1];
|
left = left[1:][:-1]
|
||||||
if len(right) > 1:
|
if len(right) > 1:
|
||||||
right = right[1:][:-1];
|
right = right[1:][:-1]
|
||||||
rules.append((left, apply, [right]));
|
rules.append((left, apply, [right]))
|
||||||
return (True, dequeue(queue, len(construct(pattern, context))));
|
return (True, dequeue(queue, len(construct(pattern, context))))
|
||||||
return (False, roll(queue));
|
return (False, roll(queue))
|
||||||
|
|
||||||
def undefine(queue, rules, pattern):
|
def undefine(queue, rules, pattern):
|
||||||
context = match(pattern, queue);
|
context = match(pattern, queue)
|
||||||
left = context["left"];
|
left = context["left"]
|
||||||
if left:
|
if left:
|
||||||
if len(left) > 1:
|
if len(left) > 1:
|
||||||
left = left[1:][:-1];
|
left = left[1:][:-1]
|
||||||
for rule, index in zip(rules, range(0, len(rules))):
|
for rule, index in zip(rules, range(0, len(rules))):
|
||||||
candidate , _, _ = rule;
|
candidate , _, _ = rule
|
||||||
if candidate == left:
|
if candidate == left:
|
||||||
del rules[index];
|
del rules[index]
|
||||||
return (True, dequeue(queue, len(construct(pattern, context))));
|
return (True, dequeue(queue, len(construct(pattern, context))))
|
||||||
return (False, roll(queue));
|
return (False, roll(queue))
|
||||||
|
|
||||||
def add(queue, rules, pattern):
|
def add(queue, rules, pattern):
|
||||||
context = match(pattern, queue);
|
context = match(pattern, queue)
|
||||||
left = context["left"];
|
left = context["left"]
|
||||||
right = context["right"];
|
right = context["right"]
|
||||||
if left and right:
|
if left and right:
|
||||||
if left[0][0] == "NUM" and right[0][0] == "NUM":
|
if left[0][0] == "NUM" and right[0][0] == "NUM":
|
||||||
queue = dequeue(queue, len(construct(pattern, context)));
|
queue = dequeue(queue, len(construct(pattern, context)))
|
||||||
queue = enqueue(queue, parse(str(left[0][1] + right[0][1])));
|
queue = enqueue(queue, parse(str(left[0][1] + right[0][1])))
|
||||||
return (True, queue);
|
return (True, queue)
|
||||||
return (False, roll(queue));
|
return (False, roll(queue))
|
||||||
|
|
||||||
def subtract(queue, rules, pattern):
|
def subtract(queue, rules, pattern):
|
||||||
context = match(pattern, queue);
|
context = match(pattern, queue)
|
||||||
left = context["left"];
|
left = context["left"]
|
||||||
right = context["right"];
|
right = context["right"]
|
||||||
if left and right:
|
if left and right:
|
||||||
if left[0][0] == "NUM" and right[0][0] == "NUM":
|
if left[0][0] == "NUM" and right[0][0] == "NUM":
|
||||||
queue = dequeue(queue, len(construct(pattern, context)));
|
queue = dequeue(queue, len(construct(pattern, context)))
|
||||||
queue = enqueue(queue, parse(str(left[0][1] - right[0][1])));
|
queue = enqueue(queue, parse(str(left[0][1] - right[0][1])))
|
||||||
return (True, queue);
|
return (True, queue)
|
||||||
return (False, roll(queue));
|
return (False, roll(queue))
|
||||||
|
|
||||||
def multiply(queue, rules, pattern):
|
def multiply(queue, rules, pattern):
|
||||||
context = match(pattern, queue);
|
context = match(pattern, queue)
|
||||||
left = context["left"];
|
left = context["left"]
|
||||||
right = context["right"];
|
right = context["right"]
|
||||||
if left and right:
|
if left and right:
|
||||||
if left[0][0] == "NUM" and right[0][0] == "NUM":
|
if left[0][0] == "NUM" and right[0][0] == "NUM":
|
||||||
queue = dequeue(queue, len(construct(pattern, context)));
|
queue = dequeue(queue, len(construct(pattern, context)))
|
||||||
queue = enqueue(queue, parse(str(left[0][1] * right[0][1])));
|
queue = enqueue(queue, parse(str(left[0][1] * right[0][1])))
|
||||||
return (True, queue);
|
return (True, queue)
|
||||||
return (False, roll(queue));
|
return (False, roll(queue))
|
||||||
|
|
||||||
def divide(queue, rules, pattern):
|
def divide(queue, rules, pattern):
|
||||||
context = match(pattern, queue);
|
context = match(pattern, queue)
|
||||||
left = context["left"];
|
left = context["left"]
|
||||||
right = context["right"];
|
right = context["right"]
|
||||||
if left and right:
|
if left and right:
|
||||||
if left[0][0] == "NUM" and right[0][0] == "NUM":
|
if left[0][0] == "NUM" and right[0][0] == "NUM":
|
||||||
queue = dequeue(queue, len(construct(pattern, context)));
|
queue = dequeue(queue, len(construct(pattern, context)))
|
||||||
queue = enqueue(queue, parse(str(left[0][1] // right[0][1])));
|
queue = enqueue(queue, parse(str(left[0][1] // right[0][1])))
|
||||||
return (True, queue);
|
return (True, queue)
|
||||||
return (False, roll(queue));
|
return (False, roll(queue))
|
||||||
|
|
||||||
def modulo(queue, rules, pattern):
|
def modulo(queue, rules, pattern):
|
||||||
context = match(pattern, queue);
|
context = match(pattern, queue)
|
||||||
left = context["left"];
|
left = context["left"]
|
||||||
right = context["right"];
|
right = context["right"]
|
||||||
if left and right:
|
if left and right:
|
||||||
if left[0][0] == "NUM" and right[0][0] == "NUM":
|
if left[0][0] == "NUM" and right[0][0] == "NUM":
|
||||||
queue = dequeue(queue, len(construct(pattern, context)));
|
queue = dequeue(queue, len(construct(pattern, context)))
|
||||||
queue = enqueue(queue, parse(str(left[0][1] % right[0][1])));
|
queue = enqueue(queue, parse(str(left[0][1] % right[0][1])))
|
||||||
return (True, queue);
|
return (True, queue)
|
||||||
return (False, roll(queue));
|
return (False, roll(queue))
|
||||||
|
|
||||||
def display(queue, rules, pattern):
|
def display(queue, rules, pattern):
|
||||||
context = match(pattern, queue);
|
context = match(pattern, queue)
|
||||||
left = context["left"];
|
left = context["left"]
|
||||||
if left:
|
if left:
|
||||||
if left[0][0] == "LIT" or left[0][0] == "NUM":
|
if left[0][0] == "LIT" or left[0][0] == "NUM":
|
||||||
if left[0][1] == "space":
|
if left[0][1] == "space":
|
||||||
print(' ', end="");
|
print(' ', end="")
|
||||||
elif left[0][1] == "newline":
|
elif left[0][1] == "newline":
|
||||||
print('\n', end="");
|
print('\n', end="")
|
||||||
elif left[0][1] == "tab":
|
elif left[0][1] == "tab":
|
||||||
print('\t', end="");
|
print('\t', end="")
|
||||||
else:
|
else:
|
||||||
print(left[0][1], end="");
|
print(left[0][1], end="")
|
||||||
return (True, dequeue(queue, len(construct(pattern, context))));
|
return (True, dequeue(queue, len(construct(pattern, context))))
|
||||||
return (False, roll(queue));
|
return (False, roll(queue))
|
||||||
|
|
||||||
def applicable(rules, queue):
|
def applicable(rules, queue):
|
||||||
results = [];
|
results = []
|
||||||
for pattern, operation, parameters in rules:
|
for pattern, operation, parameters in rules:
|
||||||
if match(pattern, queue) != None:
|
if match(pattern, queue) != None:
|
||||||
results.append((pattern, operation, parameters));
|
results.append((pattern, operation, parameters))
|
||||||
return results;
|
return results
|
||||||
|
|
||||||
def pick(list):
|
def pick(list):
|
||||||
if len(list) == 0:
|
if len(list) == 0:
|
||||||
return None;
|
return None
|
||||||
return list[0];
|
return list[0]
|
||||||
|
|
||||||
def reconstruct(pattern):
|
def reconstruct(pattern):
|
||||||
for element in pattern:
|
for element in pattern:
|
||||||
if element[0] == "INC":
|
if element[0] == "INC":
|
||||||
yield '(';
|
yield '('
|
||||||
elif element[0] == "DEC":
|
elif element[0] == "DEC":
|
||||||
yield ')';
|
yield ')'
|
||||||
elif element[0] == "NUM":
|
elif element[0] == "NUM":
|
||||||
yield str(element[1]);
|
yield str(element[1])
|
||||||
elif element[0] == "LIT":
|
elif element[0] == "LIT":
|
||||||
yield element[1];
|
yield element[1]
|
||||||
elif element[0] == "VAR":
|
elif element[0] == "VAR":
|
||||||
yield '?' + element[1];
|
yield '?' + element[1]
|
||||||
yield ' ';
|
yield ' '
|
||||||
|
|
||||||
def number(string):
|
def number(string):
|
||||||
try:
|
try:
|
||||||
result = int(string);
|
result = int(string)
|
||||||
return True;
|
return True
|
||||||
except:
|
except:
|
||||||
return False;
|
return False
|
||||||
|
|
||||||
def literal(string, index=0):
|
def literal(string, index=0):
|
||||||
token = "";
|
token = ""
|
||||||
while index != len(string):
|
while index != len(string):
|
||||||
character = string[index];
|
character = string[index]
|
||||||
if character in ['(', ')', '{', '}', '[', ']', '?', ' ', '\t', '\n', '\r']:
|
if character in ['(', ')', '{', '}', '[', ']', '?', ' ', '\t', '\n', '\r']:
|
||||||
break;
|
break
|
||||||
else:
|
else:
|
||||||
token = token + string[index];
|
token = token + string[index]
|
||||||
index = index + 1;
|
index = index + 1
|
||||||
return (token, index);
|
return (token, index)
|
||||||
|
|
||||||
def parse(string, index=0):
|
def parse(string, index=0):
|
||||||
results = [];
|
results = []
|
||||||
while index != len(string):
|
while index != len(string):
|
||||||
character = string[index];
|
character = string[index]
|
||||||
if character in ['(', ')', '{', '}', '[', ']', '?', ' ', '\t', '\n', '\r']:
|
if character in ['(', ')', '{', '}', '[', ']', '?', ' ', '\t', '\n', '\r']:
|
||||||
index = index + 1;
|
index = index + 1
|
||||||
if character in ['(', '{', '[']:
|
if character in ['(', '{', '[']:
|
||||||
results.append(["INC"]);
|
results.append(["INC"])
|
||||||
elif character in [')', '}', ']']:
|
elif character in [')', '}', ']']:
|
||||||
results.append(["DEC"]);
|
results.append(["DEC"])
|
||||||
elif character not in [' ', '\t', '\n', '\r']:
|
elif character not in [' ', '\t', '\n', '\r']:
|
||||||
token, index = literal(string, index);
|
token, index = literal(string, index)
|
||||||
if character == '?':
|
if character == '?':
|
||||||
results.append(["VAR", token]);
|
results.append(["VAR", token])
|
||||||
elif number(token):
|
elif number(token):
|
||||||
results.append(["NUM", int(token)]);
|
results.append(["NUM", int(token)])
|
||||||
else:
|
else:
|
||||||
results.append(["LIT", token]);
|
results.append(["LIT", token])
|
||||||
return results;
|
return results
|
||||||
|
|
||||||
@measure
|
@measure
|
||||||
def run(rules, queue, limit=pow(2, 32)):
|
def run(rules, queue, limit=pow(2, 32)):
|
||||||
steps = 0;
|
steps = 0
|
||||||
failures = 0;
|
failures = 0
|
||||||
queue = [["SRT"]] + queue;
|
queue = [["SRT"]] + queue
|
||||||
while failures != len(queue) and steps != limit:
|
while failures != len(queue) and steps != limit:
|
||||||
rule = pick(applicable(rules, queue));
|
rule = pick(applicable(rules, queue))
|
||||||
if rule == None:
|
if rule == None:
|
||||||
queue = roll(queue);
|
queue = roll(queue)
|
||||||
failures = failures + 1;
|
failures = failures + 1
|
||||||
print("<>: ", inspect(queue))
|
|
||||||
else:
|
else:
|
||||||
pattern, operation, parameters = rule;
|
pattern, operation, parameters = rule
|
||||||
result, queue = operation(queue, rules, pattern, *parameters);
|
result, queue = operation(queue, rules, pattern, *parameters)
|
||||||
if result == True:
|
if result == True:
|
||||||
failures = 0;
|
failures = 0
|
||||||
#print("<>: ", inspect(seek(queue, ["SRT"])), ":::", inspect(pattern))
|
#print("<>: ", inspect(seek(queue, ["SRT"])))
|
||||||
print("<>: ", inspect(queue), ":::", inspect(pattern))
|
#print("<>: ", inspect(queue))
|
||||||
#input()
|
#input()
|
||||||
steps = steps + 1;
|
steps = steps + 1
|
||||||
if steps == limit:
|
if steps == limit:
|
||||||
print("Execution limit reached.");
|
print("Execution limit reached.")
|
||||||
return queue;
|
return queue
|
||||||
|
|
||||||
def read(file):
|
def read(file):
|
||||||
try:
|
try:
|
||||||
with open(file) as file:
|
with open(file) as file:
|
||||||
content = file.read();
|
content = file.read()
|
||||||
return content;
|
return content
|
||||||
except EnvironmentError:
|
except EnvironmentError:
|
||||||
return None;
|
return None
|
||||||
|
|
||||||
def inspect(pattern):
|
def inspect(pattern):
|
||||||
return "".join(reconstruct(pattern));
|
return "".join(reconstruct(pattern))
|
||||||
|
|
||||||
def usage(name):
|
def usage(name):
|
||||||
print(name + ':', "a programming language based on rewriting.");
|
print(name + ':', "a programming language based on rewriting.")
|
||||||
print("Usage:");
|
print("Usage:")
|
||||||
print((' ' * 4) + name, "<file>");
|
print((' ' * 4) + name, "<file>")
|
||||||
|
|
||||||
def prompt(prompt):
|
def prompt(prompt):
|
||||||
try:
|
try:
|
||||||
return input(prompt);
|
return input(prompt)
|
||||||
except:
|
except:
|
||||||
return None;
|
return None
|
||||||
|
|
||||||
def help():
|
def help():
|
||||||
prefix = ' ' * 4;
|
prefix = ' ' * 4
|
||||||
print("Commands:");
|
print("Commands:")
|
||||||
print(prefix + "rules : Display the current ruleset.");
|
print(prefix + "rules : Display the current ruleset.")
|
||||||
print(prefix + "clear : Clear the current ruleset.");
|
print(prefix + "clear : Clear the current ruleset.")
|
||||||
print(prefix + "help : This message.");
|
print(prefix + "help : This message.")
|
||||||
print(prefix + "quit : Quit.");
|
print(prefix + "quit : Quit.")
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
defaults = [
|
defaults = [
|
||||||
|
@ -385,37 +382,40 @@ def main():
|
||||||
(parse("?left / ?right"), divide, []),
|
(parse("?left / ?right"), divide, []),
|
||||||
(parse("?left % ?right"), modulo, []),
|
(parse("?left % ?right"), modulo, []),
|
||||||
(parse("display ?left"), display, []),
|
(parse("display ?left"), display, []),
|
||||||
];
|
]
|
||||||
rules = defaults;
|
rules = defaults.copy()
|
||||||
if len(sys.argv) >= 2:
|
if len(sys.argv) >= 2:
|
||||||
content = read(sys.argv[1]);
|
content = read(sys.argv[1])
|
||||||
if content == None:
|
if content == None:
|
||||||
print("No such file.");
|
print("No such file.")
|
||||||
return;
|
return
|
||||||
print("Initializating...");
|
print("Initializating...")
|
||||||
run(rules, parse(content));
|
run(rules, parse(content))
|
||||||
print("Modal v0.02");
|
else:
|
||||||
help();
|
usage(sys.argv[0])
|
||||||
|
return
|
||||||
|
print("Modal v0.02")
|
||||||
|
help()
|
||||||
while True:
|
while True:
|
||||||
input = prompt("::> ");
|
input = prompt("::> ")
|
||||||
if input == None:
|
if input == None:
|
||||||
break;
|
break
|
||||||
elif parse(input) == parse("rules"):
|
elif parse(input) == parse("rules"):
|
||||||
print("Rules:");
|
print("Rules:")
|
||||||
prefix = ' ' * 4;
|
prefix = ' ' * 4
|
||||||
for pattern, operation, parameters in rules:
|
for pattern, operation, parameters in rules:
|
||||||
if operation == apply:
|
if operation == apply:
|
||||||
print(prefix + inspect(pattern) + "-> " + inspect(parameters[0]));
|
print(prefix + inspect(pattern) + "-> " + inspect(parameters[0]))
|
||||||
elif parse(input) == parse("clear"):
|
elif parse(input) == parse("clear"):
|
||||||
rules = defaults;
|
rules = defaults
|
||||||
elif parse(input) == parse("help"):
|
elif parse(input) == parse("help"):
|
||||||
help();
|
help()
|
||||||
elif parse(input) == parse("quit") or parse(input) == parse("exit"):
|
elif parse(input) == parse("quit") or parse(input) == parse("exit"):
|
||||||
break;
|
break
|
||||||
else:
|
else:
|
||||||
print("Reducing...");
|
print("Reducing...")
|
||||||
print(inspect(seek(run(rules, parse(input)), ["SRT"])));
|
print(inspect(seek(run(rules, parse(input)), ["SRT"])))
|
||||||
return;
|
return
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main();
|
main()
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
define nil ((0))
|
||||||
|
define (cons ?x (?y)) ((?x ?y))
|
||||||
|
define (car (?x)) ?x
|
||||||
|
|
Loading…
Reference in New Issue