orangeduck/BuildYourOwnLisp

Print statement not working while evaluating file

Closed this issue · 3 comments

Hey, there! I really appreciate the work you've done for mpc and Build Your Own Lisp book. Recently, I read the book and tried it out myself. Yesterday, I completed the 14th chapter of book which deals with strings, adding comments and print, error and load function as builtin types. And I tried it out and everything seems to work fine except whenever I try to evaluate a file, it doesn't output any thing at all whereas I am using print function and doing same thing in interpreter does work fine. Here, I am attaching a screenshot too.

Screenshot from 2022-02-09 12-27-49

As you can see in the following screenshot, in terminal while evaluating file it doesn't output anything whereas in interpreter it does.

Here is what my code looks like:-

int main(int argc, char **argv) {
  if (argc == 1) {
    eval(); // Here eval function will open a command line interface to interact with language.
  } else if (!strcmp(argv[1], "--version") || !strcmp(argv[1], "-v")) {
    printf("%s %s\n", PROG_NAME, VERSION);
  } else if (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) {
    printf("%s %s\n%s\n", PROG_NAME, VERSION, HELP_TEXT);
  } else if (!strcmp(argv[1], "--file") || !strcmp(argv[1], "-f")) {
    eval_file(argc, argv);
  }

  return 0;
}
void eval_file(int argc, char **argv) {
  parser *p = parse();
  lenv *env = lenv_new();
  lenv_add_builtins(env);
  for (int i = 2; i < argc; ++i) {
    lval *args = lval_add(lval_sexpr(), lval_str(argv[i]));
    lval *x = builtin_load(env, args, p->Yippy);

    if (x->type == LVAL_ERR) {
      lval_println(x);
    }
    lval_del(x);
  }
  lenv_del(env);
  p = parse_clean(p);
}

Here my eval_file function calls parse, builtin_load and parse_clean functions and other than those functions, everything is same as book describes.

My parser struct:

typedef struct parser {
  mpc_parser_t *Comments;
  mpc_parser_t *Number;
  mpc_parser_t *String;
  mpc_parser_t *Symbol;
  mpc_parser_t *Sexpr;
  mpc_parser_t *Qexpr;
  mpc_parser_t *Expr;
  mpc_parser_t *Yippy;
} parser;

My grammer:

#define GRAMMER                                                                \
  "                                          \
    comments : /;[^\\r\\n]*/ ;						\
    number : /-?[0-9]+/ ;						\
    symbol : /[a-zA-Z0-9_+\\-*%&|\\/\\\\=<>!~\"]+/;			\
    string  : /\"(\\\\.|[^\"])*\"/ ;					\
    sexpr  : '(' <expr>* ')' ;						\
    qexpr  : '{' <expr>* '}' ;						\
    expr   : <comments> | <number> | <string>				\
            | <symbol> | <qexpr> | <sexpr> ;				\
    yippy  : /^/ <expr>* /$/ ;						\
  "

parse function:

parser *parse() {
  parser *to_parse = (parser *)malloc(sizeof(parser));
  to_parse->Comments = mpc_new("comments");
  to_parse->Number = mpc_new("number");
  to_parse->String = mpc_new("string");
  to_parse->Symbol = mpc_new("symbol");
  to_parse->Sexpr = mpc_new("sexpr");
  to_parse->Qexpr = mpc_new("qexpr");
  to_parse->Expr = mpc_new("expr");
  to_parse->Yippy = mpc_new("yippy");

  mpca_lang(MPCA_LANG_DEFAULT, GRAMMER, to_parse->Comments, to_parse->Number,
            to_parse->String, to_parse->Symbol, to_parse->Sexpr,
            to_parse->Qexpr, to_parse->Expr, to_parse->Yippy);

  return to_parse;
}

My parse_clean function:

parser *parse_clean(parser *to_free) {
  mpc_cleanup(8, to_free->Comments, to_free->Number, to_free->String,
              to_free->Symbol, to_free->Sexpr, to_free->Qexpr, to_free->Expr,
              to_free->Yippy);
  free(to_free);
  to_free = NULL;
  return to_free;
}

builtin_load function:

lval *builtin_load(lenv *env, lval *a, mpc_parser_t *yippy) {
  LASSERT_NUM("load", a, 1);
  LASSERT_TYPE("load", a, 0, LVAL_STR);

  mpc_result_t r;
  if (mpc_parse_contents(a->cell[0]->string, yippy, &r)) {

    lval *expr = lval_read(r.output);
    mpc_ast_delete(r.output);

    while (expr->count) {
      lval *x = lval_eval(env, lval_pop(expr, 0));
      if (x->type == LVAL_ERR) {
        lval_println(x);
      }
      lval_del(x);
    }

    lval_del(expr);
    lval_del(a);

    return lval_sexpr();
  } else {
    char *error_msg = mpc_err_string(r.error);
    mpc_err_delete(r.error);
    lval *err = lval_err("Could not load library %s", error_msg);
    free(error_msg);
    lval_del(a);

    return err;
  }
}

Hi, not sure what could be wrong. I would suggest checking out what the expression it parses looks like in case something is wrong there.

Actually, parsed expression is correct.

Thanks for your response, it was my silly mistakes. I just fixed it. 🖤