ソースを参照

extensive testing, rewrite of argument passing, fixes editor and gtn

mntmn 8 年 前
コミット
b8d5ad2378
7 ファイル変更140 行追加82 行削除
  1. 69 66
      sledge/compiler_new.c
  2. 1 2
      sledge/compiler_new.h
  3. 6 0
      sledge/jit_m68k.c
  4. 1 2
      sledge/jit_x64.c
  5. 8 3
      sledge/os/lib.l
  6. 53 7
      sledge/tests/tests.l
  7. 2 2
      sledge/writer.c

+ 69 - 66
sledge/compiler_new.c

@@ -27,8 +27,6 @@ Cell* insert_symbol(Cell* symbol, Cell* cell, env_t** env) {
   env_entry* e;
   env_entry* e;
   int found = sm_get(*env, symbol->ar.addr, (void**)&e);
   int found = sm_get(*env, symbol->ar.addr, (void**)&e);
   
   
-  //printf("sm_get res: %d\r\n",found);
-  
   if (found) {
   if (found) {
     e->cell = cell;
     e->cell = cell;
     //printf("[insert_symbol] update %s entry at %p (cell: %p value: %d)\r\n",symbol->ar.addr,e,e->cell,e->cell->ar.value);
     //printf("[insert_symbol] update %s entry at %p (cell: %p value: %d)\r\n",symbol->ar.addr,e,e->cell,e->cell->ar.value);
@@ -95,20 +93,6 @@ void load_int(int dreg, Arg arg, Frame* f) {
     // argument is a constant like 123, "foo"
     // argument is a constant like 123, "foo"
     jit_movi(dreg, (jit_word_t)arg.cell->ar.value);
     jit_movi(dreg, (jit_word_t)arg.cell->ar.value);
   }
   }
-  else if (arg.type == ARGT_CELL) {
-    if (arg.cell == NULL) {
-      // not sure what this is
-      //if (dreg!=R0) jit_movr(dreg, R0);
-      if (dreg!=R1+arg.slot) {
-        jit_movr(dreg, R1+arg.slot); // FIXME: really true?
-      }
-      jit_ldr(dreg);
-    } else {
-      // argument is a cell pointer
-      jit_lea(dreg, arg.cell);
-      jit_ldr(dreg);
-    }
-  }
   else if (arg.type == ARGT_ENV) {
   else if (arg.type == ARGT_ENV) {
     // argument is an environment table entry, load e->cell->ar.value
     // argument is an environment table entry, load e->cell->ar.value
     jit_lea(dreg, arg.env);
     jit_lea(dreg, arg.env);
@@ -117,20 +101,22 @@ void load_int(int dreg, Arg arg, Frame* f) {
   }
   }
   else if (arg.type == ARGT_REG) {
   else if (arg.type == ARGT_REG) {
     // argument comes from a register
     // argument comes from a register
-    jit_movr(dreg, LBDREG+arg.slot);
+    jit_movr(dreg, arg.slot);
     jit_ldr(dreg);
     jit_ldr(dreg);
   }
   }
-  else if (arg.type == ARGT_INT) {
-    if (dreg!=R1+arg.slot) {
-      jit_movr(dreg, R1+arg.slot); // FIXME: really true?
+  else if (arg.type == ARGT_REG_INT) {
+    if (dreg!=arg.slot) {
+      jit_movr(dreg, arg.slot);
     }
     }
   }
   }
   else if (arg.type == ARGT_STACK) {
   else if (arg.type == ARGT_STACK) {
-    jit_ldr_stack(dreg, PTRSZ*(arg.slot+f->sp));
+    //printf("loading int from stack slot %d + sp %d to reg %d\n",arg.slot,f->sp,dreg);
+    jit_ldr_stack(dreg, PTRSZ*(f->sp-arg.slot));
     jit_ldr(dreg);
     jit_ldr(dreg);
   }
   }
   else if (arg.type == ARGT_STACK_INT) {
   else if (arg.type == ARGT_STACK_INT) {
-    jit_ldr_stack(dreg, PTRSZ*(arg.slot+f->sp));
+    //printf("loading int from stack_int sp %d - slot %d to reg %d\n",f->sp,arg.slot,dreg);
+    jit_ldr_stack(dreg, PTRSZ*(f->sp-arg.slot));
   }
   }
   else {
   else {
     jit_movi(dreg, 0xdeadbeef);
     jit_movi(dreg, 0xdeadbeef);
@@ -138,40 +124,36 @@ void load_int(int dreg, Arg arg, Frame* f) {
 }
 }
 
 
 void load_cell(int dreg, Arg arg, Frame* f) {
 void load_cell(int dreg, Arg arg, Frame* f) {
-  if (arg.type == ARGT_CELL || arg.type == ARGT_CONST) {
-    if (arg.cell == NULL) {
-      // not sure what this is
-      jit_movr(dreg, R1+arg.slot); // FIXME: really true?
-    } else {
-      // argument is a cell pointer
-      jit_lea(dreg, arg.cell);
-    }
+  if (arg.type == ARGT_CONST) {
+    // argument is a constant like 123, "foo"
+    jit_movi(dreg, (jit_word_t)arg.cell);
   }
   }
   else if (arg.type == ARGT_ENV) {
   else if (arg.type == ARGT_ENV) {
     jit_lea(dreg, arg.env);
     jit_lea(dreg, arg.env);
     jit_ldr(dreg);
     jit_ldr(dreg);
   }
   }
   else if (arg.type == ARGT_REG) {
   else if (arg.type == ARGT_REG) {
-    jit_movr(dreg, LBDREG+arg.slot);
+    jit_movr(dreg, arg.slot);
+  }
+  else if (arg.type == ARGT_REG_INT) {
+    jit_call(alloc_int, "alloc_int");
+    jit_movr(dreg,R0);
   }
   }
   else if (arg.type == ARGT_STACK) {
   else if (arg.type == ARGT_STACK) {
-    jit_ldr_stack(dreg, PTRSZ*(arg.slot+f->sp));
+    //printf("loading cell from stack slot %d + sp %d to reg %d\n",arg.slot,f->sp,dreg);
+    jit_ldr_stack(dreg, PTRSZ*(f->sp-arg.slot));
   }
   }
   else if (arg.type == ARGT_STACK_INT) {
   else if (arg.type == ARGT_STACK_INT) {
-    // FIXME possible ARGR0 clobbering
     int adjust = 0;
     int adjust = 0;
+    //printf("loading cell from stack_int sp %d - slot %d + adjust %d = %d to reg %d\n",f->sp,arg.slot,adjust,f->sp-arg.slot+adjust,dreg);
     if (dreg!=ARGR0) {jit_push(ARGR0,ARGR0); adjust++;}
     if (dreg!=ARGR0) {jit_push(ARGR0,ARGR0); adjust++;}
     if (dreg!=R0) {jit_push(R0,R0); adjust++;}
     if (dreg!=R0) {jit_push(R0,R0); adjust++;}
-    jit_ldr_stack(ARGR0, PTRSZ*(arg.slot+f->sp+adjust));
+    jit_ldr_stack(ARGR0, PTRSZ*(f->sp-arg.slot+adjust));
     jit_call(alloc_int, "alloc_int");
     jit_call(alloc_int, "alloc_int");
     jit_movr(dreg,R0);
     jit_movr(dreg,R0);
     if (dreg!=R0) jit_pop(R0,R0);
     if (dreg!=R0) jit_pop(R0,R0);
     if (dreg!=ARGR0) jit_pop(ARGR0,ARGR0);
     if (dreg!=ARGR0) jit_pop(ARGR0,ARGR0);
   }
   }
-  else if (arg.type == ARGT_INT) {
-    jit_call(alloc_int, "alloc_int");
-    jit_movr(dreg,R0);
-  }
   else {
   else {
     printf("arg.type: %d\r\n",arg.type);
     printf("arg.type: %d\r\n",arg.type);
     jit_movi(dreg, 0xdeadcafe);
     jit_movi(dreg, 0xdeadcafe);
@@ -285,6 +267,15 @@ int compatible_type(int given, int required) {
   return 0;
   return 0;
 }
 }
 
 
+int clean_return(int args_pushed, Frame* frame, int compiled_type) {
+  if (args_pushed) {
+    jit_inc_stack(args_pushed*PTRSZ);
+    frame->sp-=args_pushed;
+  }
+
+  return compiled_type;
+}
+
 int compile_expr(Cell* expr, Frame* frame, int return_type) {
 int compile_expr(Cell* expr, Frame* frame, int return_type) {
   int compiled_type = TAG_ANY;
   int compiled_type = TAG_ANY;
   Arg* fn_frame = frame->f;
   Arg* fn_frame = frame->f;
@@ -293,6 +284,7 @@ int compile_expr(Cell* expr, Frame* frame, int return_type) {
   
   
   int is_let = 0;
   int is_let = 0;
   int argi = 0;
   int argi = 0;
+  int args_pushed = 0;
   Arg argdefs[MAXARGS];
   Arg argdefs[MAXARGS];
 
 
   if (!expr) return 0;
   if (!expr) return 0;
@@ -427,7 +419,7 @@ int compile_expr(Cell* expr, Frame* frame, int return_type) {
       if (!signature_args) {
       if (!signature_args) {
         // any number of arguments allowed
         // any number of arguments allowed
         argdefs[argi].cell = arg;
         argdefs[argi].cell = arg;
-        argdefs[argi].type = ARGT_CELL;
+        argdefs[argi].type = ARGT_STACK;
       }
       }
       else if (sig_tag == TAG_LAMBDA) {
       else if (sig_tag == TAG_LAMBDA) {
         // lazy evaluation by form
         // lazy evaluation by form
@@ -435,32 +427,40 @@ int compile_expr(Cell* expr, Frame* frame, int return_type) {
         argdefs[argi].type = ARGT_LAMBDA;
         argdefs[argi].type = ARGT_LAMBDA;
       }
       }
       else if (arg->tag == TAG_CONS) {
       else if (arg->tag == TAG_CONS) {
+        int k;
         // eager evaluation
         // eager evaluation
         // nested expression
         // nested expression
         if (argi>0) {
         if (argi>0) {
           // save registers
           // save registers
           // FIXME RETHINK
           // FIXME RETHINK
 
 
-          jit_push(R1,R1+argi-1);
-          frame->sp+=(1+argi-1);
+          //jit_push(R1,R1+argi-1);
+          //frame->sp+=(1+argi-1);
         }
         }
         given_tag = compile_expr(arg, frame, sig_tag);
         given_tag = compile_expr(arg, frame, sig_tag);
         if (given_tag<1) return given_tag; // failure
         if (given_tag<1) return given_tag; // failure
         
         
         argdefs[argi].cell = NULL; // cell is in R0 at runtime
         argdefs[argi].cell = NULL; // cell is in R0 at runtime
-        argdefs[argi].slot = argi;
+        argdefs[argi].slot = ++frame->sp; // record sp at this point
+
+        /*for (k=0; k<argi; k++) {
+          if (argdefs[k].type == ARGT_STACK || argdefs[k].type == ARGT_STACK_INT) {
+            argdefs[k].slot++;
+          }
+        }*/
 
 
         if (given_tag == TAG_INT) {
         if (given_tag == TAG_INT) {
-          argdefs[argi].type = ARGT_INT;
-          jit_movr(R1+argi,ARGR0);
+          argdefs[argi].type = ARGT_STACK_INT;
         } else {
         } else {
-          argdefs[argi].type = ARGT_CELL;
-          jit_movr(R1+argi,R0);
+          argdefs[argi].type = ARGT_STACK;
         }
         }
+        jit_push(R0,R0);
+        //frame->sp++;
+        args_pushed++;
         
         
         if (argi>0) {
         if (argi>0) {
-          jit_pop(R1,R1+argi-1);
-          frame->sp-=(1+argi-1);
+          //jit_pop(R1,R1+argi-1);
+          //frame->sp-=(1+argi-1);
         }
         }
       }
       }
       else if (given_tag == TAG_SYM && sig_tag != TAG_SYM) {
       else if (given_tag == TAG_SYM && sig_tag != TAG_SYM) {
@@ -490,12 +490,12 @@ int compile_expr(Cell* expr, Frame* frame, int return_type) {
       else if (compatible_type(given_tag, sig_tag) || sig_tag==TAG_ANY) {
       else if (compatible_type(given_tag, sig_tag) || sig_tag==TAG_ANY) {
         argdefs[argi].cell = arg;
         argdefs[argi].cell = arg;
         argdefs[argi].slot = argi-1;
         argdefs[argi].slot = argi-1;
-        argdefs[argi].type = ARGT_CELL;
+        argdefs[argi].type = ARGT_CONST;
 
 
         if (given_tag == TAG_SYM || given_tag == TAG_CONS || given_tag == TAG_INT || given_tag == TAG_STR || given_tag == TAG_BYTES) {
         if (given_tag == TAG_SYM || given_tag == TAG_CONS || given_tag == TAG_INT || given_tag == TAG_STR || given_tag == TAG_BYTES) {
-          argdefs[argi].type = ARGT_CONST;
-          //printf("const arg of type %d at %p\n",arg->tag,arg);
+          //argdefs[argi].type = ARGT_CONST;
         }
         }
+        //printf("const arg of type %d at %p\n",arg->tag,arg);
       } else {
       } else {
         // check if we can typecast
         // check if we can typecast
         // else, fail with type error
         // else, fail with type error
@@ -518,6 +518,8 @@ int compile_expr(Cell* expr, Frame* frame, int return_type) {
     argi++;
     argi++;
   } while (argi<MAXARGS && (args = cdr(args)) && (!signature_args || (signature_args = cdr(signature_args))));
   } while (argi<MAXARGS && (args = cdr(args)) && (!signature_args || (signature_args = cdr(signature_args))));
 
 
+  // args are prepared, execute op
+
   if (op->tag == TAG_BUILTIN) {
   if (op->tag == TAG_BUILTIN) {
     switch (op->ar.value) {
     switch (op->ar.value) {
     case BUILTIN_BITAND: {
     case BUILTIN_BITAND: {
@@ -708,7 +710,7 @@ int compile_expr(Cell* expr, Frame* frame, int return_type) {
 
 
       // el cheapo type inference
       // el cheapo type inference
       if (1 &&
       if (1 &&
-          (argdefs[1].type == ARGT_INT ||
+          (argdefs[1].type == ARGT_REG_INT ||
            argdefs[1].type == ARGT_STACK_INT ||
            argdefs[1].type == ARGT_STACK_INT ||
            (argdefs[1].type == ARGT_CONST && argdefs[1].cell->tag == TAG_INT) ||
            (argdefs[1].type == ARGT_CONST && argdefs[1].cell->tag == TAG_INT) ||
            (fidx>=0 && fn_frame[fidx].type == ARGT_STACK_INT) // already defined as int TODO: error on attempted type change
            (fidx>=0 && fn_frame[fidx].type == ARGT_STACK_INT) // already defined as int TODO: error on attempted type change
@@ -739,13 +741,13 @@ int compile_expr(Cell* expr, Frame* frame, int return_type) {
         } else {
         } else {
           fn_frame[offset].type = ARGT_STACK;
           fn_frame[offset].type = ARGT_STACK;
         }
         }
-        fn_frame[offset].slot = frame->locals;
+        fn_frame[offset].slot = -frame->locals;
         //printf("++ frame entry %s, new stack-local idx %d, is_int %d\n",fn_frame[offset].name,fn_frame[offset].slot,is_int);
         //printf("++ frame entry %s, new stack-local idx %d, is_int %d\n",fn_frame[offset].name,fn_frame[offset].slot,is_int);
         frame->locals++;
         frame->locals++;
       }
       }
 
 
       if (!is_reg) {
       if (!is_reg) {
-        jit_str_stack(R0,PTRSZ*(fn_frame[offset].slot+frame->sp));
+        jit_str_stack(R0,PTRSZ*(frame->sp-fn_frame[offset].slot));
       }
       }
       
       
       if (compiled_type == TAG_INT && return_type == TAG_ANY) {
       if (compiled_type == TAG_INT && return_type == TAG_ANY) {
@@ -755,8 +757,8 @@ int compile_expr(Cell* expr, Frame* frame, int return_type) {
       }
       }
 
 
       if (is_reg) {
       if (is_reg) {
-        jit_movr(LBDREG + fn_frame[offset].slot, R0);
-        printf("let %s to reg: %d\r\n",fn_frame[offset].name, LBDREG + fn_frame[offset].slot);
+        jit_movr(fn_frame[offset].slot, R0);
+        printf("let %s to reg: %d\r\n",fn_frame[offset].name, fn_frame[offset].slot);
       }
       }
       
       
       break;
       break;
@@ -801,12 +803,12 @@ int compile_expr(Cell* expr, Frame* frame, int return_type) {
 
 
         if (j>=ARG_SPILLOVER) { // max args passed in registers
         if (j>=ARG_SPILLOVER) { // max args passed in registers
           fn_new_frame[j].type = ARGT_STACK;
           fn_new_frame[j].type = ARGT_STACK;
-          fn_new_frame[j].slot = num_lets + j - 1;
+          fn_new_frame[j].slot = -num_lets - j + 1;
           spo_count++;
           spo_count++;
         }
         }
         else {
         else {
           fn_new_frame[j].type = ARGT_REG;
           fn_new_frame[j].type = ARGT_REG;
-          fn_new_frame[j].slot = j;
+          fn_new_frame[j].slot = j + LBDREG;
         }
         }
         fn_new_frame[j].name = argdefs[j].cell->ar.addr;
         fn_new_frame[j].name = argdefs[j].cell->ar.addr;
         fn_argc++;
         fn_argc++;
@@ -880,10 +882,11 @@ int compile_expr(Cell* expr, Frame* frame, int return_type) {
       jit_cmpi(R0,0);
       jit_cmpi(R0,0);
       jit_je(label_skip);
       jit_je(label_skip);
 
 
+      // then
       tag = compile_expr(argdefs[1].cell, frame, return_type);
       tag = compile_expr(argdefs[1].cell, frame, return_type);
       if (!tag) return 0;
       if (!tag) return 0;
 
 
-      // else?
+      // else
       if (argdefs[2].cell) {
       if (argdefs[2].cell) {
         char label_end[64];
         char label_end[64];
         sprintf(label_end,"Lendif_%d",++label_skip_count);
         sprintf(label_end,"Lendif_%d",++label_skip_count);
@@ -1295,24 +1298,24 @@ int compile_expr(Cell* expr, Frame* frame, int return_type) {
 
 
     int pushed = push_frame_regs(frame->f);
     int pushed = push_frame_regs(frame->f);
     frame->sp+=pushed;
     frame->sp+=pushed;
-
+    
     for (j=argi-2; j>=0; j--) {
     for (j=argi-2; j>=0; j--) {
       if (j>=ARG_SPILLOVER) {
       if (j>=ARG_SPILLOVER) {
         // pass arg on stack
         // pass arg on stack
-          
+
         load_cell(R0, argdefs[j], frame);
         load_cell(R0, argdefs[j], frame);
         jit_push(R0,R0);
         jit_push(R0,R0);
         spo_adjust++;
         spo_adjust++;
-
         frame->sp++;
         frame->sp++;
       } else {
       } else {
         // pass arg in reg (LBDREG + slot)
         // pass arg in reg (LBDREG + slot)
         
         
         if (argdefs[j].type == ARGT_REG) {
         if (argdefs[j].type == ARGT_REG) {
-          if (argdefs[j].slot<j) {
+          if (1 || argdefs[j].slot<j+LBDREG) {
+            int offset = ((pushed+spo_adjust) - (argdefs[j].slot-LBDREG) - 1);
             // register already clobbered, load from stack
             // register already clobbered, load from stack
-            printf("-- loading clobbered reg %d from stack to reg %d\n",argdefs[j].slot,LBDREG+j);
-            jit_ldr_stack(LBDREG+j, (pushed-1-argdefs[j].slot)*PTRSZ);
+            //printf("-- loading clobbered reg %d from stack offset %d to reg %d\n",argdefs[j].slot,offset,LBDREG+j);
+            jit_ldr_stack(LBDREG+j, offset*PTRSZ);
           } else {
           } else {
             // no need to move a reg into itself
             // no need to move a reg into itself
             if (argdefs[j].slot!=j) {
             if (argdefs[j].slot!=j) {
@@ -1345,7 +1348,7 @@ int compile_expr(Cell* expr, Frame* frame, int return_type) {
 #endif
 #endif
 
 
   // at this point, registers R1-R6 are filled, execute
   // at this point, registers R1-R6 are filled, execute
-  return compiled_type;
+  return clean_return(args_pushed, frame, compiled_type);
 }
 }
 
 
 env_t* get_global_env() {
 env_t* get_global_env() {

+ 1 - 2
sledge/compiler_new.h

@@ -10,11 +10,10 @@ typedef void* (*funcptr)();
 
 
 typedef enum arg_t {
 typedef enum arg_t {
   ARGT_CONST,
   ARGT_CONST,
-  ARGT_CELL,
   ARGT_ENV,
   ARGT_ENV,
   ARGT_LAMBDA,
   ARGT_LAMBDA,
   ARGT_REG,
   ARGT_REG,
-  ARGT_INT,
+  ARGT_REG_INT,
   ARGT_STACK,
   ARGT_STACK,
   ARGT_STACK_INT
   ARGT_STACK_INT
 } arg_t;
 } arg_t;

+ 6 - 0
sledge/jit_m68k.c

@@ -434,6 +434,12 @@ void jit_je(char* label) {
   jit_emit_branch(label);
   jit_emit_branch(label);
 }
 }
 
 
+void jit_jne(char* label) {
+  code[code_idx++] = 0x66; // bne
+  code[code_idx++] = 0x00;
+  jit_emit_branch(label);
+}
+
 void jit_jneg(char* label) {
 void jit_jneg(char* label) {
   code[code_idx++] = 0x6b; // bmi
   code[code_idx++] = 0x6b; // bmi
   code[code_idx++] = 0x00;
   code[code_idx++] = 0x00;

+ 1 - 2
sledge/jit_x64.c

@@ -263,7 +263,6 @@ void debug_handler(char* line, Frame* frame) {
         if (a.type) {
         if (a.type) {
           switch (a.type) {
           switch (a.type) {
           case ARGT_CONST: typestr = "CONST"; break;
           case ARGT_CONST: typestr = "CONST"; break;
-          case ARGT_CELL: typestr = "CELL"; break;
           case ARGT_ENV: typestr = "ENV"; break;
           case ARGT_ENV: typestr = "ENV"; break;
           case ARGT_LAMBDA: typestr = "LAMBDA"; break;
           case ARGT_LAMBDA: typestr = "LAMBDA"; break;
           case ARGT_REG: {
           case ARGT_REG: {
@@ -272,7 +271,7 @@ void debug_handler(char* line, Frame* frame) {
             typestr = buf;
             typestr = buf;
             break;
             break;
           }
           }
-          case ARGT_INT: typestr = "INT"; break;
+          case ARGT_REG_INT: typestr = "INT"; break;
           case ARGT_STACK: typestr = "STACK"; break;
           case ARGT_STACK: typestr = "STACK"; break;
           case ARGT_STACK_INT: typestr = "STACK_INT"; break;
           case ARGT_STACK_INT: typestr = "STACK_INT"; break;
           }
           }

+ 8 - 3
sledge/os/lib.l

@@ -25,6 +25,7 @@
 )))
 )))
 
 
 (def split (fn str sepstr (do
 (def split (fn str sepstr (do
+  (print (list "split" str sepstr))
   (let sep (get sepstr 0))
   (let sep (get sepstr 0))
   (let result (quote ()))
   (let result (quote ()))
   (let sz (size str))
   (let sz (size str))
@@ -51,10 +52,11 @@
   (let i 0)
   (let i 0)
   (let c 0)
   (let c 0)
 
 
-  ;(print (list "copy: " buf from to num))
+  (print (list "copy: " buf from to num))
   
   
   (if (lt from to)
   (if (lt from to)
-    (do 
+    (do
+      (print "mode1")
       (let i (- num 1)) 
       (let i (- num 1)) 
       (while (gt i -1) (do
       (while (gt i -1) (do
         (let c (get buf (+ from i)))
         (let c (get buf (+ from i)))
@@ -62,6 +64,7 @@
         (let i (- i 1))
         (let i (- i 1))
       )) 0)
       )) 0)
     (do
     (do
+      (print "mode2")
       (let i 0)
       (let i 0)
       (while (lt i num) (do
       (while (lt i num) (do
         (let c (get buf (+ from i)))
         (let c (get buf (+ from i)))
@@ -78,7 +81,9 @@
   (let p (+ pos 0))
   (let p (+ pos 0))
   (let from (+ pos 1))
   (let from (+ pos 1))
   (let num (- (size buf) pos))
   (let num (- (size buf) pos))
+  (print (list "remove" buf pos p from (- num 1)))
   (copy buf from p num)
   (copy buf from p num)
+  (print "copied")
   (put buf (- (size buf) 1) 0)
   (put buf (- (size buf) 1) 0)
   buf
   buf
 )))
 )))
@@ -97,7 +102,7 @@
   (let i 0)
   (let i 0)
   (let sz (size s))
   (let sz (size s))
   (let c (get s 0))
   (let c (get s 0))
-  (while (* (gt c 0) (lt i sz)) (do
+  (while (and (gt c 0) (lt i sz)) (do
     (let i (+ i 1))
     (let i (+ i 1))
     (let c (get s i))
     (let c (get s i))
   ))
   ))

+ 53 - 7
sledge/tests/tests.l

@@ -27,19 +27,13 @@
 (test 13 (= 3 (size (do 1 2 "foo"))))
 (test 13 (= 3 (size (do 1 2 "foo"))))
 
 
 (def fib (fn n 0))
 (def fib (fn n 0))
-(def fib (fn n (if (lt n 3) 1
-                 (+ (fib (- n 1)) (fib (- n 2))) )))
+(def fib (fn n (if (lt n 3) 1 (+ (fib (- n 1)) (fib (- n 2))) )))
 
 
 (test 14 (= (fib 10) 55))
 (test 14 (= (fib 10) 55))
 
 
 (def foo (fn a b (+ a b)))
 (def foo (fn a b (+ a b)))
 (test 15 (do (def a 5) (def b 6) (= (foo (+ a 1) (- b 2)) 10)))
 (test 15 (do (def a 5) (def b 6) (= (foo (+ a 1) (- b 2)) 10)))
 
 
-(def func-a (fn xx yy (* (+ xx 1) (+ yy 1))))
-(def func-b (fn x y (func-a x y)))
-
-(test 16 (= 12 (strlen (concat "hello" "worlden"))))
-
 (test 17 (= (get [65] 0) (get "beef" 1)))
 (test 17 (= (get [65] 0) (get "beef" 1)))
 (test 18 (= (get [66] 0) (get "beef" 3)))
 (test 18 (= (get [66] 0) (get "beef" 3)))
 
 
@@ -48,3 +42,55 @@
 (test 21 (eq 666 (* -1 -666)))
 (test 21 (eq 666 (* -1 -666)))
 
 
 (test 22 (= (get (substr "hellaz" 1 3) 0) 101))
 (test 22 (= (get (substr "hellaz" 1 3) 0) 101))
+
+(def fun1 (fn a b c (list a b c)))
+(def fun2 (fn a b c (fun1 c a b)))
+
+(print (fun2 2 3 1))
+
+(test 23 (= 5 (+ (+ (+ 1 1) 1) (+ 1 1))))
+(test 24 (= 4 (+ (+ 1 1) (+ 1 1))))
+(test 25 (= 3 (+ (+ 1 1) 1)))
+
+(def func-a (fn xx yy (* (+ xx 1) (+ yy 1))))
+(def func-b (fn x y (func-a x y)))
+(test 26 (= (func-b 5 5) 36))
+
+(test 16 (= 12 (strlen (concat "hello" "worlden"))))
+
+(def lett (fn g (do
+  (let a 23)
+  (let b 46)
+  (let c 66)
+  (let d 72)
+  (let e "foo")
+  (list g a b c d e g)
+)))
+
+(print (lett 6))
+
+(def spillover (fn a b c d e f (do
+  (print (list a b c d e f))
+  (print (list f e d c b a))
+)))
+(spillover 1 2 3 4 5 6)
+
+(def fa (fn x y z w (do
+  (let a 8)
+  (let b 9)
+  (print a)
+  (print b)
+  (print x)
+  (print y)
+  (print z)
+  
+  (print (list "fa: " a b x y z w))
+)))
+
+(def fb (fn a b (do
+  (print a)
+  (print b)
+  (fa a b "3" "4")
+)))
+
+(fb 1 2)

+ 2 - 2
sledge/writer.c

@@ -75,10 +75,10 @@ char* write_(Cell* cell, char* buffer, int in_list, int bufsize) {
   } else if (cell->tag == TAG_LAMBDA) {
   } else if (cell->tag == TAG_LAMBDA) {
     char tmp_args[TMP_BUF_SIZE];
     char tmp_args[TMP_BUF_SIZE];
     char tmp_body[TMP_BUF_SIZE*2];
     char tmp_body[TMP_BUF_SIZE*2];
-    tmp_args[0]=0;
-    tmp_body[0]=0;
     Cell* args = car(cell->ar.addr);
     Cell* args = car(cell->ar.addr);
     int ai = 0;
     int ai = 0;
+    tmp_args[0]=0;
+    tmp_body[0]=0;
     while (args && car(car(args))) {
     while (args && car(car(args))) {
       ai += snprintf(tmp_args+ai, TMP_BUF_SIZE-ai, "%s ", (char*)(car(car(args)))->ar.addr);
       ai += snprintf(tmp_args+ai, TMP_BUF_SIZE-ai, "%s ", (char*)(car(car(args)))->ar.addr);
       args = cdr(args);
       args = cdr(args);