/[cvs]/stack/stack.c
ViewVC logotype

Diff of /stack/stack.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.53 by teddy, Thu Feb 7 23:56:54 2002 UTC revision 1.69 by masse, Mon Feb 11 00:54:04 2002 UTC
# Line 48  typedef symbol *hashtbl[HASHTBLSIZE]; /* Line 48  typedef symbol *hashtbl[HASHTBLSIZE]; /*
48  typedef struct stackitem_struct  typedef struct stackitem_struct
49  {  {
50    value *item;                  /* The value on the stack */    value *item;                  /* The value on the stack */
51                                    /* (This is never NULL) */
52    struct stackitem_struct *next; /* Next item */    struct stackitem_struct *next; /* Next item */
53  } stackitem;  } stackitem;
54    
# Line 99  void free_val(value *val){ Line 100  void free_val(value *val){
100        }        }
101        free(val);                /* Free the actual list value */        free(val);                /* Free the actual list value */
102        break;        break;
103      default:      case integer:
104        case func:
105        case symb:
106        break;        break;
107      }      }
108    }    }
# Line 344  extern void type(environment *env){ Line 347  extern void type(environment *env){
347    case list:    case list:
348      push_sym(env, "list");      push_sym(env, "list");
349      break;      break;
   default:  
     push_sym(env, "unknown");  
     break;  
350    }    }
351  }      }    
352    
# Line 358  void print_h(stackitem *stack_head) Line 358  void print_h(stackitem *stack_head)
358      printf("%d", stack_head->item->content.val);      printf("%d", stack_head->item->content.val);
359      break;      break;
360    case string:    case string:
361      printf("\"%s\"", (char*)stack_head->item->content.ptr);      printf("%s", (char*)stack_head->item->content.ptr);
362      break;      break;
363    case symb:    case symb:
364      printf("%s", ((symbol *)(stack_head->item->content.ptr))->id);      printf("%s", ((symbol *)(stack_head->item->content.ptr))->id);
# Line 377  void print_h(stackitem *stack_head) Line 377  void print_h(stackitem *stack_head)
377      }      }
378      printf("]");      printf("]");
379      break;      break;
   default:  
     printf("#<unknown %p>", (stack_head->item->content.ptr));  
     break;  
380    }    }
381  }  }
382    
# Line 436  extern void swap(environment *env) Line 433  extern void swap(environment *env)
433    env->head->next= temp;    env->head->next= temp;
434  }  }
435    
436    /* Rotate the first three elements on the stack. */
437    extern void rot(environment *env)
438    {
439      stackitem *temp= env->head;
440      
441      if(env->head==NULL || env->head->next==NULL
442          || env->head->next->next==NULL) {
443        printerr("Too Few Arguments");
444        env->err=1;
445        return;
446      }
447    
448      env->head= env->head->next->next;
449      temp->next->next= env->head->next;
450      env->head->next= temp;
451    }
452    
453  /* Recall a value from a symbol, if bound */  /* Recall a value from a symbol, if bound */
454  extern void rcl(environment *env)  extern void rcl(environment *env)
455  {  {
# Line 482  extern void eval(environment *env) Line 496  extern void eval(environment *env)
496      return;      return;
497    }    }
498    
499     eval_start:
500    
501    switch(env->head->item->type) {    switch(env->head->item->type) {
502      /* if it's a symbol */      /* if it's a symbol */
503    case symb:    case symb:
504      rcl(env);                   /* get its contents */      rcl(env);                   /* get its contents */
505      if(env->err) return;      if(env->err) return;
506      if(env->head->item->type!=symb){ /* don't recurse symbols */      if(env->head->item->type!=symb){ /* don't recurse symbols */
507        eval(env);                        /* evaluate the value */        goto eval_start;
       return;  
508      }      }
509      break;      return;
510    
511      /* If it's a lone function value, run it */      /* If it's a lone function value, run it */
512    case func:    case func:
513      in_func= (funcp)(env->head->item->content.ptr);      in_func= (funcp)(env->head->item->content.ptr);
514      toss(env);      toss(env);
515      if(env->err) return;      if(env->err) return;
516      (*in_func)(env);      return (*in_func)(env);
     break;  
517    
518      /* If it's a list */      /* If it's a list */
519    case list:    case list:
# Line 508  extern void eval(environment *env) Line 522  extern void eval(environment *env)
522      toss(env);      toss(env);
523      if(env->err) return;      if(env->err) return;
524      iterator= (stackitem*)temp_val->content.ptr;      iterator= (stackitem*)temp_val->content.ptr;
525      while(iterator!=NULL && iterator->item!=NULL) {      while(iterator!=NULL) {
526        push_val(&(env->head), iterator->item);        push_val(&(env->head), iterator->item);
527        if(env->head->item->type==symb        if(env->head->item->type==symb
528          && strcmp(";", ((symbol*)(env->head->item->content.ptr))->id)==0) {          && strcmp(";", ((symbol*)(env->head->item->content.ptr))->id)==0) {
529          toss(env);          toss(env);
530          if(env->err) return;          if(env->err) return;
531            if(iterator->next == NULL){
532              free_val(temp_val);
533              goto eval_start;
534            }
535          eval(env);          eval(env);
536          if(env->err) return;          if(env->err) return;
537        }        }
538        iterator= iterator->next;        iterator= iterator->next;
539      }      }
540      free_val(temp_val);      free_val(temp_val);
541      break;      return;
542    
543      /* If it's a string */      /* If it's a string */
544    case string:    case string:
# Line 530  extern void eval(environment *env) Line 548  extern void eval(environment *env)
548      if(env->err) return;      if(env->err) return;
549      temp_string= malloc(strlen((char*)temp_val->content.ptr)+5);      temp_string= malloc(strlen((char*)temp_val->content.ptr)+5);
550      strcpy(temp_string, "[ ");      strcpy(temp_string, "[ ");
551      strcat(temp_string, (char*)temp_val->content.ptr);      strcpy(temp_string+2, (char*)temp_val->content.ptr);
552        free_val(temp_val);
553      strcat(temp_string, " ]");      strcat(temp_string, " ]");
554      stack_read(env, temp_string);      stack_read(env, temp_string);
     eval(env);  
     if(env->err) return;  
     free_val(temp_val);  
555      free(temp_string);      free(temp_string);
556      break;      goto eval_start;
557    
558    default:    case integer:
559        return;
560    }    }
561  }  }
562    
# Line 879  extern void errn(environment *env){ Line 896  extern void errn(environment *env){
896    push_int(&(env->head), env->err);    push_int(&(env->head), env->err);
897  }  }
898    
899    extern void read(environment*);
900    
901  int main()  int main()
902  {  {
903    environment myenv;    environment myenv;
   char in_string[100];  
904    
905    init_env(&myenv);    init_env(&myenv);
906    
907    printf("okidok\n ");    while(1) {
908        fprintf(stderr, "okidok\n ");
909    while(fgets(in_string, 100, stdin) != NULL) {      read(&myenv);
     stack_read(&myenv, in_string);  
910      if(myenv.err) {      if(myenv.err) {
911        printf("(error %d) ", myenv.err);        printf("(error %d) ", myenv.err);
912        myenv.err=0;        myenv.err=0;
913        } else if(myenv.head->item->type==symb
914                  && ((symbol*)(myenv.head->item->content.ptr))->id[0]==';') {
915          toss(&myenv);             /* No error check in main */
916          eval(&myenv);
917      }      }
     printf("okidok\n ");  
918    }    }
919    quit(&myenv);    quit(&myenv);
920    return EXIT_FAILURE;    return EXIT_FAILURE;
# Line 940  extern void sx_2b(environment *env) { Line 960  extern void sx_2b(environment *env) {
960    a=env->head->item->content.val;    a=env->head->item->content.val;
961    toss(env);    toss(env);
962    if(env->err) return;    if(env->err) return;
963    b=env->head->item->content.val;    if(env->head->item->refcount == 1)
964        env->head->item->content.val += a;
965      else {
966        b=env->head->item->content.val;
967        toss(env);
968        if(env->err) return;
969        push_int(&(env->head), a+b);
970      }
971    }
972    
973    /* - */
974    extern void sx_2d(environment *env) {
975      int a, b;
976    
977      if((env->head)==NULL || env->head->next==NULL) {
978        printerr("Too Few Arguments");
979        env->err=1;
980        return;
981      }
982      
983      if(env->head->item->type!=integer
984         || env->head->next->item->type!=integer) {
985        printerr("Bad Argument Type");
986        env->err=2;
987        return;
988      }
989      a=env->head->item->content.val;
990      toss(env);
991      if(env->err) return;
992      if(env->head->item->refcount == 1)
993        env->head->item->content.val -= a;
994      else {
995        b=env->head->item->content.val;
996        toss(env);
997        if(env->err) return;
998        push_int(&(env->head), b-a);
999      }
1000    }
1001    
1002    /* > */
1003    extern void sx_3e(environment *env) {
1004      int a, b;
1005    
1006      if((env->head)==NULL || env->head->next==NULL) {
1007        printerr("Too Few Arguments");
1008        env->err=1;
1009        return;
1010      }
1011      
1012      if(env->head->item->type!=integer
1013         || env->head->next->item->type!=integer) {
1014        printerr("Bad Argument Type");
1015        env->err=2;
1016        return;
1017      }
1018      a=env->head->item->content.val;
1019      toss(env);
1020      if(env->err) return;
1021      if(env->head->item->refcount == 1)
1022        env->head->item->content.val = (env->head->item->content.val > a);
1023      else {
1024        b=env->head->item->content.val;
1025        toss(env);
1026        if(env->err) return;
1027        push_int(&(env->head), b>a);
1028      }
1029    }
1030    
1031    /* Return copy of a value */
1032    value *copy_val(value *old_value){
1033      stackitem *old_item, *new_item, *prev_item;
1034    
1035      value *new_value=malloc(sizeof(value));
1036    
1037      new_value->type=old_value->type;
1038      new_value->refcount=0;        /* This is increased if/when this
1039                                       value is referenced somewhere, like
1040                                       in a stack item or a variable */
1041      switch(old_value->type){
1042      case integer:
1043        new_value->content.val=old_value->content.val;
1044        break;
1045      case string:
1046        (char *)(new_value->content.ptr)
1047          = strdup((char *)(old_value->content.ptr));
1048        break;
1049      case func:
1050      case symb:
1051        new_value->content.ptr=old_value->content.ptr;
1052        break;
1053      case list:
1054        new_value->content.ptr=NULL;
1055    
1056        prev_item=NULL;
1057        old_item=(stackitem *)(old_value->content.ptr);
1058    
1059        while(old_item != NULL) {   /* While list is not empty */
1060          new_item= malloc(sizeof(stackitem));
1061          new_item->item=copy_val(old_item->item); /* recurse */
1062          new_item->next=NULL;
1063          if(prev_item != NULL)     /* If this wasn't the first item */
1064            prev_item->next=new_item; /* point the previous item to the
1065                                         new item */
1066          else
1067            new_value->content.ptr=new_item;
1068          old_item=old_item->next;
1069          prev_item=new_item;
1070        }    
1071        break;
1072      }
1073      return new_value;
1074    }
1075    
1076    /* duplicates an item on the stack */
1077    extern void dup(environment *env) {
1078      if((env->head)==NULL) {
1079        printerr("Too Few Arguments");
1080        env->err=1;
1081        return;
1082      }
1083      push_val(&(env->head), copy_val(env->head->item));
1084    }
1085    
1086    /* "if", If-Then */
1087    extern void sx_6966(environment *env) {
1088    
1089      int truth;
1090    
1091      if((env->head)==NULL || env->head->next==NULL) {
1092        printerr("Too Few Arguments");
1093        env->err=1;
1094        return;
1095      }
1096    
1097      if(env->head->next->item->type != integer) {
1098        printerr("Bad Argument Type");
1099        env->err=2;
1100        return;
1101      }
1102      
1103      swap(env);
1104      if(env->err) return;
1105      
1106      truth=env->head->item->content.val;
1107    
1108      toss(env);
1109      if(env->err) return;
1110    
1111      if(truth)
1112        eval(env);
1113      else
1114        toss(env);
1115    }
1116    
1117    /* If-Then-Else */
1118    extern void ifelse(environment *env) {
1119    
1120      int truth;
1121    
1122      if((env->head)==NULL || env->head->next==NULL
1123         || env->head->next->next==NULL) {
1124        printerr("Too Few Arguments");
1125        env->err=1;
1126        return;
1127      }
1128    
1129      if(env->head->next->next->item->type != integer) {
1130        printerr("Bad Argument Type");
1131        env->err=2;
1132        return;
1133      }
1134      
1135      rot(env);
1136      if(env->err) return;
1137      
1138      truth=env->head->item->content.val;
1139    
1140    toss(env);    toss(env);
1141    if(env->err) return;    if(env->err) return;
1142    push_int(&(env->head), a+b);  
1143      if(!truth)
1144        swap(env);
1145      if(env->err) return;
1146    
1147      toss(env);
1148      if(env->err) return;
1149    
1150      eval(env);
1151    }
1152    
1153    /* while */
1154    extern void sx_7768696c65(environment *env) {
1155    
1156      int truth;
1157      value *loop, *test;
1158    
1159      if((env->head)==NULL || env->head->next==NULL) {
1160        printerr("Too Few Arguments");
1161        env->err=1;
1162        return;
1163      }
1164    
1165      loop= env->head->item;
1166      loop->refcount++;
1167      toss(env); if(env->err) return;
1168    
1169      test= env->head->item;
1170      test->refcount++;
1171      toss(env); if(env->err) return;
1172    
1173      do {
1174        push_val(&(env->head), test);
1175        eval(env);
1176        
1177        if(env->head->item->type != integer) {
1178          printerr("Bad Argument Type");
1179          env->err=2;
1180          return;
1181        }
1182        
1183        truth= env->head->item->content.val;
1184        toss(env); if(env->err) return;
1185        
1186        if(truth) {
1187          push_val(&(env->head), loop);
1188          eval(env);
1189        } else {
1190          toss(env);
1191        }
1192      
1193      } while(truth);
1194    
1195      free_val(test);
1196      free_val(loop);
1197    }
1198    
1199    /* For-loop */
1200    extern void sx_666f72(environment *env) {
1201      
1202      value *loop, *foo;
1203      stackitem *iterator;
1204      
1205      if((env->head)==NULL || env->head->next==NULL) {
1206        printerr("Too Few Arguments");
1207        env->err=1;
1208        return;
1209      }
1210    
1211      if(env->head->next->item->type != list) {
1212        printerr("Bad Argument Type");
1213        env->err=2;
1214        return;
1215      }
1216    
1217      loop= env->head->item;
1218      loop->refcount++;
1219      toss(env); if(env->err) return;
1220    
1221      foo= env->head->item;
1222      foo->refcount++;
1223      toss(env); if(env->err) return;
1224    
1225      iterator= foo->content.ptr;
1226    
1227      while(iterator!=NULL) {
1228        push_val(&(env->head), iterator->item);
1229        push_val(&(env->head), loop);
1230        eval(env); if(env->err) return;
1231        iterator= iterator->next;
1232      }
1233    
1234      free_val(loop);
1235      free_val(foo);
1236    }
1237    
1238    /* 'to' */
1239    extern void to(environment *env) {
1240      int i, start, ending;
1241      
1242      if((env->head)==NULL || env->head->next==NULL) {
1243        printerr("Too Few Arguments");
1244        env->err=1;
1245        return;
1246      }
1247    
1248      if(env->head->item->type!=integer
1249         || env->head->next->item->type!=integer) {
1250        printerr("Bad Argument Type");
1251        env->err=2;
1252        return;
1253      }
1254    
1255      ending= env->head->item->content.val;
1256      toss(env); if(env->err) return;
1257      start= env->head->item->content.val;
1258      toss(env); if(env->err) return;
1259    
1260      push_sym(env, "[");
1261    
1262      if(ending>=start) {
1263        for(i= start; i<=ending; i++)
1264          push_int(&(env->head), i);
1265      } else {
1266        for(i= start; i>=ending; i--)
1267          push_int(&(env->head), i);
1268      }
1269    
1270      push_sym(env, "[");
1271      pack(env); if(env->err) return;
1272    }
1273    
1274    /* Read a string */
1275    extern void readline(environment *env) {
1276      char in_string[101];
1277    
1278      fgets(in_string, 100, stdin);
1279      push_cstring(&(env->head), in_string);
1280    }
1281    
1282    /* Read a value and place on stack */
1283    extern void read(environment *env) {
1284      const char symbform[]= "%[a-zA-Z0-9!$%*+./:<=>?@^_~-]%100c";
1285      const char strform[]= "\"%[^\"]\"%100c";
1286      const char intform[]= "%i%100c";
1287      const char blankform[]= "%*[ \t]%100c";
1288      const char ebrackform[]= "%*1[]]%100c";
1289      const char semicform[]= "%*1[;]%100c";
1290      const char bbrackform[]= "%*1[[]%100c";
1291    
1292      int itemp, rerun= 0;
1293      static int depth= 0;
1294      char *rest, *match;
1295      static char *in_string= NULL;
1296      size_t inlength;
1297    
1298      if(in_string==NULL) {
1299        readline(env); if(env->err) return;
1300        
1301        in_string= malloc(strlen(env->head->item->content.ptr)+1);
1302        strcpy(in_string, env->head->item->content.ptr);
1303        toss(env); if(env->err) return;
1304      }
1305      
1306      inlength= strlen(in_string)+1;
1307      match= malloc(inlength);
1308      rest= malloc(inlength);
1309    
1310      if(sscanf(in_string, blankform, rest)) {
1311        rerun= 1;    
1312      } else if(sscanf(in_string, intform, &itemp, rest) > 0) {
1313        push_int(&(env->head), itemp);
1314      } else if(sscanf(in_string, strform, match, rest) > 0) {
1315        push_cstring(&(env->head), match);
1316      } else if(sscanf(in_string, symbform, match, rest) > 0) {
1317        push_sym(env, match);
1318      } else if(sscanf(in_string, ebrackform, rest) > 0) {
1319        push_sym(env, "[");
1320        pack(env); if(env->err) return;
1321        if(depth!=0) depth--;
1322      } else if(sscanf(in_string, semicform, rest) > 0) {
1323        push_sym(env, ";");
1324      } else if(sscanf(in_string, bbrackform, rest) > 0) {
1325        push_sym(env, "[");
1326        depth++;
1327      } else {
1328        free(rest);
1329        rest= NULL;
1330        rerun= 1;
1331      }
1332          
1333      free(in_string);
1334      free(match);
1335    
1336      in_string= rest;
1337    
1338      if(rerun || depth)
1339        return read(env);
1340  }  }

Legend:
Removed from v.1.53  
changed lines
  Added in v.1.69

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26