asdf

Dependencies:   mbed

Fork of manworm_ticker_tv by Bayley Wang

lisp.cpp

Committer:
dicarloj
Date:
2018-03-10
Revision:
9:2a47b9ff8911
Child:
10:1163fb31b0a7

File content as of revision 9:2a47b9ff8911:

///* A minimal Lisp interpreter
//   Copyright 2004 Andru Luvisi
//
//   This program is free software; you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation; either version 2 of the License , or
//   (at your option) any later version.
//
//   This program is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with this program. If not, write to the Free Software
//   Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
// */
//
//
//#include <stdio.h>
//#include <stdlib.h>
//#include <stdarg.h>
//#include <string.h>
//#include <ctype.h>
//#include "main.h"
//
//#define error(X) do { printf("ERROR: %s\n", X); } while (0)
//#define out_buf_size 5000
//#define in_buf_size 5000
//
//int out_counter = 0;
//int in_counter = 0;
//char out_buf[out_buf_size];
//char in_buf [in_buf_size];
//
//char lisp_exit = 0;
//
//void init_buf()
//{
//    for(int i = 0; i < out_buf_size; i++)
//        out_buf[i] = 0;
//
//    for(int i = 0; i < in_buf_size; i++)
//        in_buf[i] = 0;
//
//    out_buf[out_buf_size - 1] = 0;
//    out_counter = 0;
//    in_counter = 0;
//}
//
//char getc_2()
//{
//    //draw_vincent_string("getc2");
//    in_counter++;
//    if(in_counter >= in_buf_size)
//    {
//        lisp_exit = 1;
//        return EOF;
//    }
//
//    char next_char = in_buf[in_counter - 1];
//
//    if(next_char == 0)
//    {
//        lisp_exit = 1;
//        return EOF;
//    }
//
//    return in_buf[in_counter-1];
//}
//
//void ungetc_2(char c)
//{
//    in_counter--;
//}
//
//
//char* strdup_2(char* in)
//{
//    char* new_string = (char*)malloc(strlen(in));
//    strcpy(new_string,in);
//    return new_string;
//}
//
//void write_out(char* str)
//{
//    printf("write_out: %s\n",str);
//
//    int len = strlen(str);
//
//    if(len + out_counter < out_buf_size)
//    {
//        printf("BUUFER OVERLFOW!\n");
//        return;
//    }
//
//    memcpy(out_buf + out_counter, str, len);
//}
//
//int line_num = 1;
//int total_malloc = 0;
//
///*** List Structured Memory ***/
//enum otype { INT, SYM, CONS, PROC, PRIMOP };
//typedef struct obj {
//  enum otype type;
//  int line_num;
//  struct obj *p[1];
//} obj;
//typedef obj * (*primop)(obj *);
//obj *all_symbols, *top_env, *nil, *tee, *quote, 
//    *s_if, *s_lambda, *s_define, *s_setb, *s_begin;
//
//#define cons(X, Y)            omake(CONS, 2, (X), (Y))
//
//obj *car(obj *X) {
//  if(X == 0) {
//    sprintf(out_buf + strlen(out_buf),"warning: car argument null on line %d\n", line_num);
//    return nil;
//  }
//  if(X == nil)
//    return nil;
//  if(X->type != CONS) {
//    sprintf(out_buf + strlen(out_buf),"warning: car argument not a list (%d) on line %d\n", X->p[0], X->line_num);
//    return nil;
//  }
//  return X->p[0];
//}
//
//obj *cdr(obj *X) {
//  if(X == nil)
//    return nil;
//  if(X->type != CONS) {
//    sprintf(out_buf + strlen(out_buf),"warning: cdr argument not a list on line %d\n", X->line_num); 
//    return nil;    
//  }
//  if(X->p[1] == 0) {
//    sprintf(out_buf + strlen(out_buf),"error: cdr list element is zero-pointer at %d\n", X->line_num);
//    return nil;
//  }
//  return X->p[1];
//}
//
//#define setcar(X,Y)           (((X)->p[0]) = (Y))
//#define setcdr(X,Y)           (((X)->p[1]) = (Y))
//#define mkint(X)              omake(INT, 1, (obj *)(X))
//#define intval(X)             ((int)((X)->type == INT ? (X)->p[0] : 0)) // intval for INT only
//#define mksym(X)              omake(SYM, 1, (obj *)(X))
//#define symname(X)            ((char *)((X)->p[0]))
//#define mkprimop(X)           omake(PRIMOP, 1, (obj *)(X))
//#define primopval(X)          ((primop)(X)->p[0])
//#define mkproc(X,Y,Z)         omake(PROC, 3, (X), (Y), (Z))
//#define procargs(X)           ((X)->p[0])
//#define proccode(X)           ((X)->p[1])
//#define procenv(X)            ((X)->p[2])
//#define isnil(X)              ((X) == nil)
//
//obj *omake(enum otype type, int count, ...) {
//  obj *ret;
//  va_list ap;
//  int i;
//  va_start(ap, count);
//  int object_size = sizeof(obj) + (count - 1)*sizeof(obj *);
//  total_malloc += object_size;
//  if(type == INT)
//      printf("malloc %d bytes for INT\r\n",object_size);
//    if(type == SYM)
//      printf("malloc %d bytes for SYM\r\n",object_size);
//        if(type == CONS)
//      printf("malloc %d bytes for CONS\r\n",object_size);
//    if(type == SYM)
//      printf("malloc %d bytes for PROC\r\n",object_size);
//        if(type == PRIMOP)
//      printf("malloc %d bytes for PRIMOP\r\n",object_size);
//
////enum otype { INT, SYM, CONS, PROC, PRIMOP };
//  ret = (obj *) malloc(object_size);
//  ret->type = type;
//  ret->line_num = line_num;
//  for(i = 0; i < count; i++) ret->p[i] = va_arg(ap, obj *);
//  va_end(ap);
//  return ret;
//}
//
//obj *findsym(char *name) {
//  obj *symlist;
//  for(symlist = all_symbols; !isnil(symlist); symlist = cdr(symlist))
//    if(!strcmp(name, symname(car(symlist))))
//      return symlist;
//  return nil;
//}
//
//obj *intern(char *name) {
//  obj *op = findsym(name);
//  if(!isnil(op)) return car(op);
//  op = mksym(name);
//  all_symbols = cons(op, all_symbols);
//  return op;
//}
//
///*** Environment ***/
//#define extend(ENV, SYM, VAL) (cons(cons((SYM), (VAL)), (ENV)))
//
//obj *multiple_extend(obj *env, obj *syms, obj *vals) {
//  return isnil(syms) ? 
//         env : 
//         multiple_extend(extend(env, car(syms), car(vals)),
//                         cdr(syms), cdr(vals));
//}
//
//obj *extend_top(obj *sym, obj *val) {
//  setcdr(top_env, cons(cons(sym, val), cdr(top_env)));
//  return val;
//}
//
//obj *assoc(obj *key, obj *alist) {
//  if(isnil(alist)) return nil;
//  if(car(car(alist)) == key) return car(alist);
//  return assoc(key, cdr(alist));
//}
//
///*** Input/Output ***/
////FILE *ifp;
//char *token_la;
//int la_valid = 0;
//#define MAXLEN 100
//char buf[MAXLEN];
//int bufused;
//
//void add_to_buf(char ch) { if(bufused < MAXLEN - 1) buf[bufused++] = ch; }
//char *buf2str()          { buf[bufused++] = '\0'; return strdup_2(buf); }
////void setinput(FILE *fp)  { ifp = fp; }
//void putback_token(char *token) { token_la = token; la_valid = 1; }
//
//void myexit(int code);
//
//char *gettoken() {
//  int ch;
//  char comment=0;
//
//  bufused = 0;
//  if(la_valid) { la_valid = 0; return token_la; }
//  do {
//    if((ch = getc_2()) == EOF) {myexit(0); return NULL;} // replace with serial
//    //draw_vincent_string("gettoken");
//    if(ch == ';')      comment = 1;
//    if(ch == '\n') {
//      comment = 0;
//      line_num++;
//    }
//
//  } while(isspace(ch) || comment);
//
//
//  add_to_buf(ch);
//  if(strchr("()\'", ch)) return buf2str();
//  for(;;) {
//    if(lisp_exit) { return NULL; }
//    if((ch = getc_2()) == EOF) {myexit(0); return NULL;}
//    if(strchr("()\'", ch) || isspace(ch)) {
//      ungetc_2(ch);
//      return buf2str();
//    }
//    add_to_buf(ch);
//  }
//}
//
//obj *readlist();
//
//obj *readobj() {
//  char *token;
//
//  token = gettoken();
//  if(token == NULL) return NULL;
//  if(!strcmp(token, "(")) return readlist();
//  if(!strcmp(token, "\'")) return cons(quote, cons(readobj(), nil));
//
//  if(token[strspn(token, "0123456789")] == '\0'
//     || (token[0] == '-' && strlen(token) > 1)) 
//    return mkint(atoi(token));
//  return intern(token);
//}
//
//obj *readlist() {
//  char *token = gettoken();
//  if(token == NULL) return NULL;
//  obj *tmp;
//  if(!strcmp(token, ")")) return nil;
//  if(!strcmp(token, ".")) {
//    tmp = readobj();
//    if(strcmp(gettoken(), ")")) myexit(1);
//    return tmp;
//  }
//  putback_token(token);
//  tmp = readobj(); /* Must force evaluation order */
//  return cons(tmp, readlist());
//}
//
//void writeobj(obj *op) {
//  
//  if(op == NULL) { return; }
//  switch(op->type) {
//    case INT:  sprintf(out_buf + strlen(out_buf),"%d", intval(op));  break;
//    case CONS: 
//    //draw_vincent_string("  write_cons  ");
//        sprintf(out_buf + strlen(out_buf),"(");
//        for(;;) {
//            writeobj(car(op));
//            if(isnil(cdr(op))) {
//                sprintf(out_buf + strlen(out_buf),")");
//                break;
//            }
//            op = cdr(op);
//            if(op->type != CONS) {
//                sprintf(out_buf + strlen(out_buf)," . ");
//                writeobj(op);
//                sprintf(out_buf + strlen(out_buf),")");
//                break;
//            }
//            sprintf(out_buf + strlen(out_buf)," ");
//        }
//        break;
//    case SYM:
//    
//        if(isnil(op)) sprintf(out_buf + strlen(out_buf),"()");
//        else          sprintf(out_buf + strlen(out_buf),"%s", symname(op));
//        break;
//    case PRIMOP: sprintf(out_buf + strlen(out_buf),"#<PRIMOP>"); break;
//    case PROC:   sprintf(out_buf + strlen(out_buf),"#<PROC>"); break;
//    default: myexit(1);
//  }
//}
//
///*** Evaluator (Eval/no Apply) ***/
//obj *evlis(obj *exps, obj *env);
//
//obj *eval(obj *exp, obj *env) {
//  if(lisp_exit) return NULL;
//  obj *tmp, *proc, *vals;
//
//  eval_start:
//  
//  if(exp == NULL) return nil;
//  if(exp == nil) return nil;
//
//
//  switch(exp->type) {
//    case INT:   return exp;
//    case SYM:   tmp = assoc(exp, env);
//
//      if(tmp == nil) {
//        sprintf(out_buf + strlen(out_buf), "Unbound symbol ");
//        writeobj(exp);
//        sprintf(out_buf + strlen(out_buf), "\n");
//        return nil;
//      }
//      return cdr(tmp);
//
//
//
//    case CONS: 
//      if(car(exp) == s_if) {
//        if(eval(car(cdr(exp)), env) != nil)
//          return eval(car(cdr(cdr(exp))), env);
//        else
//          return eval(car(cdr(cdr(cdr(exp)))), env);
//      }
//      if(car(exp) == s_lambda)
//        return mkproc(car(cdr(exp)), cdr(cdr(exp)), env);
//      if(car(exp) == quote)
//        return car(cdr(exp));
//      if(car(exp) == s_define)
//        return(extend_top(car(cdr(exp)),
//                          eval(car(cdr(cdr(exp))), env)));
//      if(car(exp) == s_setb) {
//        obj *pair   = assoc(car(cdr(exp)), env);
//        obj *newval = eval(car(cdr(cdr(exp))), env);
//        setcdr(pair, newval);
//        return newval;
//      }
//      if(car(exp) == s_begin) {
//        exp = cdr(exp);
//        if(exp == nil) return nil;
//        for(;;) {
//          if(cdr(exp) == nil) {
//            exp = car(exp);
//            goto eval_start;
//          }
//          eval(car(exp), env);
//          exp = cdr(exp);
//        }
//      }
//      proc = eval(car(exp), env);
//      vals = evlis(cdr(exp), env);
//      if(proc->type == PRIMOP)
//        return (*primopval(proc))(vals);
//      if(proc->type == PROC) {
//        /* For dynamic scope, use env instead of procenv(proc) */
//        env = multiple_extend(procenv(proc), procargs(proc), vals);
//        exp = cons(s_begin, proccode(proc));
//        goto eval_start;
//      }
//      sprintf(out_buf + strlen(out_buf),"Bad PROC type\n");
//      return nil;
//    case PRIMOP: return exp;
//    case PROC:   return exp;
//  }
//  /* Not reached */
//  return exp; 
//}
//
//obj *evlis(obj *exps, obj *env) {
//  if(exps == nil) return nil;
//  return cons(eval(car(exps), env), 
//              evlis(cdr(exps), env));
//}
//
///*** Primitives ***/
//obj *prim_sum(obj *args) {
//  int sum;
//  for(sum = 0; !isnil(args); sum += intval(car(args)), args = cdr(args));
//  return mkint(sum);
//}
//
//obj *prim_sub(obj *args) {
//  int sum;
//  for(sum = intval(car(args)), args = cdr(args); 
//      !isnil(args); 
//      sum -= intval(car(args)), args = cdr(args));
//  return mkint(sum);
//}
//
//obj *prim_prod(obj *args) {
//  int prod;
//  for(prod = 1; !isnil(args); prod *= intval(car(args)), args = cdr(args));
//  return mkint(prod);
//}
//obj *prim_divide(obj *args) {
//  int prod = intval(car(args));
//  args = cdr(args);
//  while(!isnil(args)) {
//    prod /= intval(car(args));
//    args = cdr(args);
//  }
//
//  return mkint(prod);
//}
//
//obj *prim_gt(obj *args) {
//  return intval(car(args)) > intval(car(cdr(args))) ? tee : nil;
//}
//
//obj *prim_lt(obj *args) {
//  return intval(car(args)) < intval(car(cdr(args))) ? tee : nil;
//}
//obj *prim_ge(obj *args) {
//  return intval(car(args)) >= intval(car(cdr(args))) ? tee : nil;
//}
//obj *prim_le(obj *args) {
//  return intval(car(args)) <= intval(car(cdr(args))) ? tee : nil;
//}
//obj *prim_numeq(obj *args) {
//  return intval(car(args)) == intval(car(cdr(args))) ? tee : nil;
//}
//
//obj *prim_cons(obj *args) { return cons(car(args), car(cdr(args))); }
//obj *prim_car(obj *args)  { return car(car(args)); }
//obj *prim_cdr(obj *args)  { return cdr(car(args)); }
//
//
///*** Helpers *****/
//
//obj *prim_print(obj *args) {
//  while(!isnil(args)) {
//    writeobj(car(args));
//    args = cdr(args);
//    sprintf(out_buf + strlen(out_buf)," ");
//  }
//  sprintf(out_buf + strlen(out_buf),"\n");
//  return nil;
//}
//
///*** Initialization ***/
//void init_sl3() {
//  nil = mksym("nil");
//  all_symbols = cons(nil, nil);
//  top_env  = cons(cons(nil, nil), nil);
//  tee      = intern("t");
//  extend_top(tee, tee);
//  quote    = intern("quote");
//  s_if     = intern("if");
//  s_lambda = intern("lambda");
//  s_define = intern("define");
//  s_setb   = intern("set!");
//  s_begin  = intern("begin");
//  extend_top(intern("+"), mkprimop(prim_sum));
//  extend_top(intern("-"), mkprimop(prim_sub));
//  extend_top(intern("*"), mkprimop(prim_prod));
//  extend_top(intern("/"), mkprimop(prim_divide));
//  extend_top(intern("="), mkprimop(prim_numeq));
//
//  extend_top(intern(">"), mkprimop(prim_gt));
//  extend_top(intern(">="), mkprimop(prim_ge));
//
//  extend_top(intern("<"), mkprimop(prim_lt));
//  extend_top(intern("<="), mkprimop(prim_le));
//
//  extend_top(intern("cons"), mkprimop(prim_cons));
//  extend_top(intern("car"),  mkprimop(prim_car));
//  extend_top(intern("cdr"),  mkprimop(prim_cdr));
//
//  extend_top(intern("print"),  mkprimop(prim_print));
//}
//
//char* get_output()
//{
//    return out_buf;
//}
//
//int lisp_init = 0;
//
///*** Main Driver ***/
//int run_lisp(char* input) {
//  if(!lisp_init)
//  { 
//    init_sl3();
//    lisp_init = 1;
//  }
//    
//    init_buf();
//      
//
//  lisp_exit = 0;
//  strcpy(in_buf, input);
//  if(!strncmp(input,"clear",4)){ clear_all_text(); return 0; }
//  if(!strncmp(input,"mem",3))
//  {
//     char memuse[40];
//     sprintf(memuse,"MEM: %d bytes",total_malloc);
//     draw_vincent_string(memuse);
//     return;
//  }
//  in_buf[in_buf_size - 1] = 0;
//  //new_line();
//  //draw_vincent_string(in_buf);
//  //new_line();
//  //print_vincent_string(in_buf);
////  if(argc == 2)
////  {
////      memcpy(in_buf,argv[1],strlen(argv[1]));
////      printf("%s\n",in_buf);
////  }
////  else
//    //sprintf(in_buf,"(+ 2 2)\n");
////  char test_in[] = "(+ 2 2)\n";
////  FILE* input_stream = open_memstream(test_in,8);
////  fprintf(input_stream,"(+ 2 3)\n");
////  char test_out[50];
////  FILE* output_stream = fmemopen(test_out,50,"w");
//  //setinput(input_stream);
//  int lisp_count = 0;
//  while(!lisp_exit) {
//    writeobj(eval(readobj(), top_env));
//    //fflush(output_stream);
//    printf("\n");
//    printf("%s\n",out_buf);
//    
//    lisp_count++;
//    if(lisp_count > 500) break;
//    //printf("outstream: %s\n",test_out);
//  }
//  draw_vincent_string(out_buf);
//  //draw_vincent_string("done!");
//  return 0;
//}
//
//void myexit(int code) {
//  printf("%d bytes left hanging\n", total_malloc);
//  lisp_exit = 1;
//}