From 2b7d974851f763431a70fe7b59728c94cfabddf7 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Tue, 14 May 2024 14:49:15 +0200
Subject: [PATCH] update runtime with new vm-instructions & improve example in
 main.rs

---
 src/main.rs    | 169 +++++++++++++--------------------
 src/runtime.rs | 248 +++++++++++++++++++++++++++----------------------
 2 files changed, 199 insertions(+), 218 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index c14e719..9125613 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -42,24 +42,6 @@ fn main() {
     let main_scope = Scope::with_parent(&root_scope);
     let typectx = main_scope.read().unwrap().typectx.clone();
 
-    /* define type of the symbol
-     */
-    main_scope.write().unwrap().declare_static_parse(
-        "hello-string",
-        "<Seq Char
-                  ~Ascii
-                  ~machine::Word>
-             ~<NullTerminatedSeq machine::Word>",
-    );
-
-    main_scope.write().unwrap().declare_static_parse(
-        "pfxstr",
-        "<Seq Char
-                  ~Ascii
-                  ~machine::Word>
-             ~<LengthPrefixedSeq machine::Word>",
-    );
-
     /* link assembly-program to symbols
      */
     linker.add_procedure(
@@ -68,102 +50,79 @@ fn main() {
             &main_scope,
             "main",
             "{
-             let print-nullterm =
-                 λ str : <Ref <Seq Char~Ascii~machine::Word>>
-                       ~ <Ref <NullTerminatedArray machine::Word>>
-                       ~ machine::Address
-                       ~ machine::Word
-                       .
-                 {
-                     while (@ str) {
-                         emit (@ str);
-                         ! str (i+ str 1);
-                     }
-                 };
+                let print-nullterm =
+                    λ{} : < Seq  Char~Ascii~machine::Word >
+                        ~ < NullTerminatedArray machine::Word >
+                    ↦ {
+                       while(dup) { emit; }
+                       emit;
+                    };
 
-            let print-len =
-                λ len : ℤ_2^64
-                      ~ machine::UInt64
-                      ~ machine::Word
-                      .
-                λ str : <Ref <Seq Char~Ascii~machine::Word>>
-                      ~ <Ref <Array machine::Word>>
-                      ~ machine::Address
-                      ~ machine::Word
-                      .
-                {
-                    let end = (i+ str len);
-                    while (i- str end) {
-                        emit (@ str);
-                        ! str (i+ str 1);
-                    }
+                print-nullterm 'H' 'a' 'l' 'l' 'o' ' ' 'W' 'e' 'l' 't' '!' '\n' '\0';
+
+                let print-uint =
+                    λx : ℕ ~ ℤ_2^64 ~ machine::UInt64
+                    ↦ {
+                        if( x ) {
+                            print-nullterm {
+                                '\0';
+                                while( x ) {
+                                    i+ '0' (i% x 10);
+                                    ! x (i/ x 10);
+                                }
+                            };
+                        } else {
+                            emit '0';
+                        };
+                    };
+
+                let int-neg  = λx : ℤ~machine::Int64~machine::Word ↦ i+ (bit-neg x) 1;
+                let int-sign = λx : ℤ~machine::Int64~machine::Word ↦ bit-and (bit-shr x 63) 1;
+
+                let int-lte = λ{
+                    a : ℤ~machine::Int64~machine::Word;
+                    b : ℤ~machine::Int64~machine::Word;
+                } ↦ int-sign (i- a b);
+
+                let int-max = λ{
+                    a : ℤ~machine::Int64~machine::Word;
+                    b : ℤ~machine::Int64~machine::Word;
+                } ↦ if( int-lte b a ) { a; } else { b; };
+
+                let vec3i-add = λ{
+                    { ax:ℤ_2^64; ay:ℤ_2^64; az:ℤ_2^64; } : <Vec3 ℤ_2^64~machine::UInt64>;
+                    { bx:ℤ_2^64; by:ℤ_2^64; bz:ℤ_2^64; } : <Vec3 ℤ_2^64~machine::UInt64>;
+                } ↦ {
+                    i+ az bz;
+                    i+ ay by;
+                    i+ ax bx;
                 };
 
-            let print-lenprefix =
-                λ str : <Ref <Seq Char~Ascii~machine::Word>>
-                      ~ <Ref <LenPrefixArray machine::Word>>
-                      ~ <Ref <Struct
-                           <len ℤ_2^64
-                               ~machine::UInt64
-                               ~machine::Word>
-                           <data <Array machine::Word>>
-                         >>
-                      ~ machine::Address
-                      ~ machine::Word
-                      .
-            {
-                let len = (@ str);
-                ! str (i+ str 1);
-                print-len len str;
-            };
+                let print-vec3i =
+                    λ{ x:ℤ_2^64; y:ℤ_2^64; z:ℤ_2^64; } : <Vec3 ℤ_2^64~machine::UInt64>
+                    ↦ {
+                        print-nullterm '{' 'x' '=' '\0';
+                        print-uint x;
+                        print-nullterm ';' ' ' 'y' '=' '\0';
+                        print-uint y;
+                        print-nullterm ';' ' ' 'z' '=' '\0';
+                        print-uint z;
+                        print-nullterm '}' '\0';
+                    };
 
-            let hello = λ.{
-                print-nullterm hello-string;
-                print-lenprefix pfxstr;
-
-                let isquare = λx:ℤ. i* x x;
-                let imagnitude2 = λx:ℤ.λy:ℤ. i+ (isquare x) (isquare y);
-                let factorial = λn:ℤ.
-                    if( n ){ i* n (factorial (i- n 1)); }
-                    else   { 1; };
-
-                factorial 20;
-
-                if ( i- (imagnitude2 10 20) 500 ) {
-                    emit '?';
-                } else {
-                    emit '!';
-                };
+                let red-u8
+                    : <Fn <> Color ~ RGB ~ <Vec3 ℝ_0,1 ~ ℤ_256 ~ machine::UInt64>>
+                    = λ{} ↦ { 0; 0; 255; };
+                let green-u8 = λ{} ↦ { 0; 255; 0; };
+                let blue-u8 = λ{} ↦ { 255; 0; 0; };
+                let yellow-u8 = λ{} ↦ { 0; 220; 220; };
 
+                print-vec3i (vec3i-add green-u8 blue-u8);
                 emit '\n';
-                emit (i+ '0' (isquare 3));
-                emit '\n';
-            };
-
-            hello;
-        }",
+            }"
         ),
     );
 
-    linker.add_static(
-        "hello-string",
-        "Hallo Welt!\n\0"
-            .chars()
-            .map(|c| (c as u8) as tisc::VM_Word)
-            .collect(),
-    );
-
-    linker.add_static(
-        "pfxstr",
-        vec![
-            3,
-            'a' as tisc::VM_Word,
-            'b' as tisc::VM_Word,
-            'c' as tisc::VM_Word,
-            'd' as tisc::VM_Word,
-        ],
-    );
-
     let main_addr = linker
         .get_link_addr(&"main".into())
         .expect("'main' not linked");
diff --git a/src/runtime.rs b/src/runtime.rs
index 47b613e..6c7e1a3 100644
--- a/src/runtime.rs
+++ b/src/runtime.rs
@@ -18,13 +18,14 @@ pub fn init_runtime(linker: &mut Linker) -> Arc<RwLock<Scope>> {
         vec!["T~machine::Word", "T~machine::Word"],
     );
 
-    linker.add_procedure(
-        "dup",
-        tisc::Assembler::new()
-            .inst(tisc::VM_Instruction::Dup)
-            .build(),
+    /* drop topmost element
+     */
+    symbols.write().unwrap().declare_proc_parse(
+        "drop",
+        vec!["T"],
+        vec!["T~machine::Word"],
+        vec![],
     );
-
     /* Put a single Ascii character on stdout
      */
     symbols.write().unwrap().declare_proc_parse(
@@ -33,14 +34,18 @@ pub fn init_runtime(linker: &mut Linker) -> Arc<RwLock<Scope>> {
         vec!["Char~Ascii~machine::Word"],
         vec![],
     );
-
-    linker.add_procedure(
-        "emit",
-        tisc::Assembler::new()
-            .inst(tisc::VM_Instruction::Emit)
-            .build(),
+    symbols.write().unwrap().declare_proc_parse(
+        "accept",
+        vec![],
+        vec![],
+        vec!["Char~Ascii~machine::Word"],
     );
 
+    linker.add_procedure("dup", tisc::Assembler::new().inst(tisc::VM_Instruction::Dup).build());
+    linker.add_procedure("drop", tisc::Assembler::new().inst(tisc::VM_Instruction::Accept).build());
+    linker.add_procedure("emit", tisc::Assembler::new().inst(tisc::VM_Instruction::Emit).build());
+    linker.add_procedure("accept", tisc::Assembler::new().inst(tisc::VM_Instruction::Accept).build());
+
     /* The top two items must be native u64 integers,
      * which are replaced by their sum.
      * We do not know wheter a sum of two integers actually
@@ -55,16 +60,43 @@ pub fn init_runtime(linker: &mut Linker) -> Arc<RwLock<Scope>> {
         ],
         vec!["ℤ_2^64~machine::UInt64~machine::Word"],
     );
-
-    linker.add_procedure(
-        "i+",
-        tisc::Assembler::new()
-            .inst(tisc::VM_Instruction::IntAdd)
-            .build(),
+    symbols.write().unwrap().declare_proc_parse(
+        "i-",
+        vec![],
+        vec![
+            "ℤ_2^64~machine::UInt64~machine::Word",
+            "ℤ_2^64~machine::UInt64~machine::Word",
+        ],
+        vec!["ℤ_2^64~machine::UInt64~machine::Word"],
+    );
+    symbols.write().unwrap().declare_proc_parse(
+        "i*",
+        vec![],
+        vec![
+            "ℤ_2^64~machine::UInt64~machine::Word",
+            "ℤ_2^64~machine::UInt64~machine::Word",
+        ],
+        vec!["ℤ_2^64~machine::UInt64~machine::Word"],
+    );
+    symbols.write().unwrap().declare_proc_parse(
+        "i/",
+        vec![],
+        vec![
+            "ℤ_2^64~machine::UInt64~machine::Word",
+            "ℤ_2^64~machine::UInt64~machine::Word",
+        ],
+        vec!["ℤ_2^64~machine::UInt64~machine::Word"],
+    );
+    symbols.write().unwrap().declare_proc_parse(
+        "i%",
+        vec![],
+        vec![
+            "ℤ_2^64~machine::UInt64~machine::Word",
+            "ℤ_2^64~machine::UInt64~machine::Word",
+        ],
+        vec!["ℤ_2^64~machine::UInt64~machine::Word"],
     );
 
-    /* Floating-point Addition
-     */
     symbols.write().unwrap().declare_proc_parse(
         "f+",
         vec![],
@@ -75,35 +107,93 @@ pub fn init_runtime(linker: &mut Linker) -> Arc<RwLock<Scope>> {
         vec!["ℝ~machine::f64~machine::Word"],
     );
 
-    linker.add_procedure(
-        "f+",
-        tisc::Assembler::new()
-            .inst(tisc::VM_Instruction::FltAdd)
-            .build(),
-    );
-
-    /* Integer Subtraction
-     */
     symbols.write().unwrap().declare_proc_parse(
-        "i-",
+        "f-",
         vec![],
         vec![
-            "ℤ_2^64~machine::UInt64~machine::Word",
-            "ℤ_2^64~machine::UInt64~machine::Word",
+            "ℝ~machine::f64~machine::Word",
+            "ℝ~machine::f64~machine::Word",
         ],
-        vec!["ℤ_2^64~machine::UInt64~machine::Word"],
+        vec!["ℝ~machine::f64~machine::Word"],
     );
-    linker.add_procedure(
-        "i-",
-        tisc::Assembler::new()
-            .inst(tisc::VM_Instruction::Swap)
-            .inst(tisc::VM_Instruction::BitNeg)
-            .lit(1)
-            .inst(tisc::VM_Instruction::IntAdd)
-            .inst(tisc::VM_Instruction::IntAdd)
-            .build(),
+
+    symbols.write().unwrap().declare_proc_parse(
+        "f*",
+        vec![],
+        vec![
+            "ℝ~machine::f64~machine::Word",
+            "ℝ~machine::f64~machine::Word",
+        ],
+        vec!["ℝ~machine::f64~machine::Word"],
     );
 
+    symbols.write().unwrap().declare_proc_parse(
+        "f/",
+        vec![],
+        vec![
+            "ℝ~machine::f64~machine::Word",
+            "ℝ~machine::f64~machine::Word",
+        ],
+        vec!["ℝ~machine::f64~machine::Word"],
+    );
+
+    symbols.write().unwrap().declare_proc_parse(
+        "f%",
+        vec![],
+        vec![
+            "ℝ~machine::f64~machine::Word",
+            "ℝ~machine::f64~machine::Word",
+        ],
+        vec!["ℝ~machine::f64~machine::Word"],
+    );
+
+    linker.add_procedure("i+", tisc::Assembler::new().inst(tisc::VM_Instruction::IntAdd).build());
+    linker.add_procedure("i-", tisc::Assembler::new().inst(tisc::VM_Instruction::IntSub).build());
+    linker.add_procedure("i*", tisc::Assembler::new().inst(tisc::VM_Instruction::IntMul).build());
+    linker.add_procedure("i/", tisc::Assembler::new().inst(tisc::VM_Instruction::IntDiv).build());
+    linker.add_procedure("i%", tisc::Assembler::new().inst(tisc::VM_Instruction::IntRem).build());
+
+    linker.add_procedure("f+", tisc::Assembler::new().inst(tisc::VM_Instruction::FltAdd).build());
+    linker.add_procedure("f-", tisc::Assembler::new().inst(tisc::VM_Instruction::FltSub).build());
+    linker.add_procedure("f*", tisc::Assembler::new().inst(tisc::VM_Instruction::FltMul).build());
+    linker.add_procedure("f/", tisc::Assembler::new().inst(tisc::VM_Instruction::FltDiv).build());
+    linker.add_procedure("f%", tisc::Assembler::new().inst(tisc::VM_Instruction::FltRem).build());
+
+
+
+    symbols.write().unwrap().declare_proc_parse(
+        "bit-neg",
+        vec![], vec!["machine::Word", "machine::Word"], vec!["machine::Word"],
+    );
+    symbols.write().unwrap().declare_proc_parse(
+        "bit-and",
+        vec![], vec!["machine::Word", "machine::Word"], vec!["machine::Word"],
+    );    
+    symbols.write().unwrap().declare_proc_parse(
+        "bit-or",
+        vec![], vec!["machine::Word", "machine::Word"], vec!["machine::Word"],
+    );    
+    symbols.write().unwrap().declare_proc_parse(
+        "bit-xor",
+        vec![], vec!["machine::Word", "machine::Word"], vec!["machine::Word"],
+    );
+     symbols.write().unwrap().declare_proc_parse(
+        "bit-shl",
+        vec![], vec!["machine::Word", "machine::Word"], vec!["machine::Word"],
+    );    
+    symbols.write().unwrap().declare_proc_parse(
+        "bit-shr",
+        vec![], vec!["machine::Word", "machine::Word"], vec!["machine::Word"],
+    );
+
+    linker.add_procedure("bit-neg", tisc::Assembler::new().inst(tisc::VM_Instruction::BitNeg).build());
+    linker.add_procedure("bit-and", tisc::Assembler::new().inst(tisc::VM_Instruction::BitAnd).build());
+    linker.add_procedure("bit-or", tisc::Assembler::new().inst(tisc::VM_Instruction::BitOr).build());
+    linker.add_procedure("bit-xor", tisc::Assembler::new().inst(tisc::VM_Instruction::BitXor).build());
+    linker.add_procedure("bit-shl", tisc::Assembler::new().inst(tisc::VM_Instruction::BitShl).build());
+    linker.add_procedure("bit-shr", tisc::Assembler::new().inst(tisc::VM_Instruction::BitShr).build());
+
+
     /* Fetch memory address
      */
     symbols.write().unwrap().declare_proc_parse(
@@ -112,13 +202,6 @@ pub fn init_runtime(linker: &mut Linker) -> Arc<RwLock<Scope>> {
         vec!["<MutRef T~machine::Word>~machine::Address~machine::Word"],
         vec!["T~machine::Word"],
     );
-    linker.add_procedure(
-        "@",
-        tisc::Assembler::new()
-            .inst(tisc::VM_Instruction::Fetch)
-            .build(),
-    );
-
     /* Store to memory
      */
     symbols.write().unwrap().declare_proc_parse(
@@ -130,72 +213,11 @@ pub fn init_runtime(linker: &mut Linker) -> Arc<RwLock<Scope>> {
         ],
         vec![],
     );
-    linker.add_procedure(
-        "!",
-        tisc::Assembler::new()
-            .inst(tisc::VM_Instruction::Store)
-            .build(),
-    );
 
-    /*
-     * let muli = λa.λb.{
-     *    let mut sum = 0;
-     *    while( b != 0 ) {
-     *        sum := (addi sum a);
-     *        b := (subi b 1);
-     *    }
-     *    sum
-     * };
-     */
-    symbols.write().unwrap().declare_proc_parse(
-        "i*",
-        vec![],
-        vec![
-            "ℤ_2^64~machine::UInt64~machine::Word",
-            "ℤ_2^64~machine::UInt64~machine::Word",
-        ],
-        vec!["ℤ_2^64~machine::UInt64~machine::Word"],
-    );
+    linker.add_procedure("@",  tisc::Assembler::new().inst(tisc::VM_Instruction::Fetch).build());
+    linker.add_procedure("!", tisc::Assembler::new().inst(tisc::VM_Instruction::Store).build());
+
 
-    linker.add_procedure(
-        "i*",
-        tisc::Assembler::new()
-            .lit(0) // [ a b ] -- [ a b sum ]
-            .while_loop(
-                // condition
-                tisc::Assembler::new()
-                    // [ a b sum ] -- [ a b sum b ]
-                    .lit(2)
-                    .inst(tisc::VM_Instruction::Pick),
-                // body
-                tisc::Assembler::new()
-                    // [ a b sum ] -- [ a b sum a ]
-                    .lit(3)
-                    .inst(tisc::VM_Instruction::Pick)
-                    // [ a b sum a -- a b (sum+a) ]
-                    .inst(tisc::VM_Instruction::IntAdd)
-                    // [ a b sum -- a sum b ]
-                    .inst(tisc::VM_Instruction::Swap)
-                    // [ a sum b -- a sum b 1 ]
-                    .lit(1)
-                    // [ a sum b -- a sum (b-1) ]
-                    .inst(tisc::VM_Instruction::Swap)
-                    .call("i-")
-                    // [ a sum b -- a b sum ]
-                    .inst(tisc::VM_Instruction::Swap),
-            )
-            // [ a b sum -- a sum b ]
-            .lit(2)
-            .inst(tisc::VM_Instruction::Roll)
-            // [ a sum b -- a sum ]
-            .inst(tisc::VM_Instruction::Drop)
-            // [ a sum -- sum a ]
-            .lit(2)
-            .inst(tisc::VM_Instruction::Roll)
-            // [ sum a -- sum ]
-            .inst(tisc::VM_Instruction::Drop)
-            .build(),
-    );
 
     symbols.write().unwrap().declare_static_parse(
         "data-frame-ptr",