Multiplication is now supported as a built-in operation. The prelude has also been...
authorimode <immediate.mode@gmail.com>
Tue, 13 Nov 2018 19:56:19 +0000 (11:56 -0800)
committerimode <immediate.mode@gmail.com>
Tue, 13 Nov 2018 19:56:19 +0000 (11:56 -0800)
modal.py
prelude.modal

index 34092a6..f802cc6 100644 (file)
--- a/modal.py
+++ b/modal.py
@@ -1,4 +1,14 @@
-import sys;
+import sys, time;
+
+def measure(function):
+    def measurement(*arguments):
+        start        = time.time();
+        result       = function(*arguments);
+        end          = time.time();
+        milliseconds = (end - start) * 1000.0;
+        print("\nTook {:.3f}ms".format(milliseconds))
+        return result;
+    return measurement;
 
 def enqueue(queue, item):
     return queue + item;
@@ -139,6 +149,33 @@ def subtract(queue, rules, pattern):
             return (True, queue);
     return (False, roll(queue));
 
+def multiply(queue, rules, pattern):
+    context = match(pattern, queue);
+    left    = context["left"];
+    right   = context["right"];
+    if left and right and len(left) == 1 and len(right) == 1:
+        if left[0][0] == "NUM" and right[0][0] == "NUM":
+            queue = dequeue(queue, len(construct(pattern, context)));
+            queue = enqueue(queue, parse(str(left[0][1] * right[0][1])));
+            return (True, queue);
+    return (False, roll(queue));
+
+def display(queue, rules, pattern):
+    context = match(pattern, queue);
+    left    = context["left"];
+    if left:
+        if left[0][0] == "LIT" or left[0][0] == "NUM":
+            if left[0][1] == "space":
+                print(' ', end="");
+            elif left[0][1] == "newline":
+                print('\n', end="");
+            elif left[0][1] == "tab":
+                print('\t', end="");
+            else:
+                print(left[0][1], end="");
+            return (True, dequeue(queue, len(construct(pattern, context))));
+    return (False, roll(queue));
+
 def applicable(rules, queue):
     results = [];
     for pattern, operation, parameters in rules:
@@ -204,7 +241,8 @@ def parse(string, index=0):
                 results.append(["LIT", token]);
     return results;
 
-def run(rules, queue, limit=pow(2, 16)):
+@measure
+def run(rules, queue, limit=pow(2, 32)):
     steps      = 0;
     failures   = 0;
     queue      = [["SRT"]] + queue;
@@ -258,7 +296,9 @@ def main():
                    (parse("define ?left ?right"),               define,   []),
                    (parse("undefine ?left"),                    undefine, []),
                    (parse("add (num ?left) (num ?right)"),      add,      []),
-                   (parse("subtract (num ?left) (num ?right)"), subtract, [])
+                   (parse("subtract (num ?left) (num ?right)"), subtract, []),
+                   (parse("multiply (num ?left) (num ?right)"), multiply, []),
+                   (parse("display (?left)"),                   display,  [])
                ];
     rules = defaults;
     if len(sys.argv) >= 2:
@@ -266,6 +306,7 @@ def main():
         if content == None:
             print("No such file.");
             return;
+        print("Initializating...");
         run(rules, parse(content));
     print("Modal v0.01");
     help();
@@ -286,6 +327,7 @@ def main():
         elif parse(input) == parse("quit") or parse(input) == parse("exit"):
             break;
         else:
+            print("Reducing...");
             print(inspect(seek(run(rules, parse(input)), ["SRT"])));
     return;
 
index b0a6a4f..c993f3d 100644 (file)
@@ -1,18 +1,21 @@
-Let's give ourselves some sugar.
 define (def ?x ?y) (define ?x ?y)
+define (?x -> ?y) (def ?x ?y)
 
-Even more sugar.
-def (?x -> ?y)  (def ?x ?y)
+def (?x + ?y) (add ?x ?y)
+def (?x - ?y) (subtract ?x ?y)
+def (?x * ?y) (multiply ?x ?y)
 
-Maybe some Prolog?
-(assert ?x ?y) -> (?y -> ?x)
-(retract ?x)   -> (undefine ?x)
-(fact ?x)      -> (?x -> true)
+(factorial (1))      -> (1)
+(factorial (num ?x)) -> ((num ?x) * (factorial ((num ?x) - (1))))
 
-Looking good.
-fact (man socrates)
+(fold (?f) ?i (nil))     -> (?f ?i)
+(fold (?f) ?i (?h : ?t)) -> (?f ?h fold (?f) ?i ?t)
 
-Looking really good.
-assert (man ?x) (mortal ?x)
+(prepend ?x (nil))     -> (?x : (nil))
+(prepend ?x (?h : ?t)) -> (?x : (?h : ?t))
 
-Now you can query for `mortal socrates` and get back `true`.
+(hello ?x) -> ((Hello,) : ((space) : ?x))
+world      -> ((world!) : (nil))
+intro      -> (hello (world))
+
+fold (display) (newline) (prepend (newline) (intro))