void(lval* v){/* Make a Copy of the string */char* escaped =malloc(strlen(v->str)+1);strcpy(escaped, v->str);/* Pass it through the escape function */
escaped =mpcf_escape(escaped);/* Print it between " characters */printf("\"%s\"", escaped);/* free the copied string */free(escaped);}
读取字符串
添加对字符串解析的支持。跟以往相同,添加名称为string的新语法规则到 Lispy 语法分析器中。我们将要使用的字符串表示规则与 C 相同。这意味着字符串实质上是两个引号 " 之间的一系列转义字符或普通字符组成。
lval*lval_read_str(mpc_ast_t* t){/* Cut off the final quote character */
t->contents[strlen(t->contents)-1]='\0';/* Copy the string missing out the first quote character */char* unescaped =malloc(strlen(t->contents+1)+1);strcpy(unescaped, t->contents+1);/* Pass through the unescape function */
unescaped =mpcf_unescape(unescaped);/* Construct a new lval using the string */
lval* str =lval_str(unescaped);/* Free the string and return */free(unescaped);return str;}
lval*builtin_load(lenv* e, lval* a){LASSERT_NUM("load", a,1);LASSERT_TYPE("load", a,0, LVAL_STR);/* Parse File given by string name */
mpc_result_t r;if(mpc_parse_contents(a->cell[0]->str, Lispy,&r)){/* Read contents */
lval* expr =lval_read(r.output);mpc_ast_delete(r.output);/* Evaluate each Expression */while(expr->count){
lval* x =lval_eval(e,lval_pop(expr,0));/* If Evaluation leads to error print it */if(x->type == LVAL_ERR){lval_println(x);}lval_del(x);}/* Delete expressions and arguments */lval_del(expr);lval_del(a);/* Return empty list */returnlval_sexpr();}else{/* Get Parse Error as String */char* err_msg =mpc_err_string(r.error);mpc_err_delete(r.error);/* Create new error message using it */
lval* err =lval_err("Could not load Library %s", err_msg);free(err_msg);lval_del(a);/* Cleanup and return error */return err;}}
/* Supplied with list of files */if(argc >=2){/* loop over each supplied filename (starting from 1) */for(int i =1; i < argc; i++){/* Argument list with a single argument, the filename */
lval* args =lval_add(lval_sexpr(),lval_str(argv[i]));/* Pass to builtin load and get the result */
lval* x =builtin_load(e, args);/* If the result is an error be sure to print it */if(x->type == LVAL_ERR){lval_println(x);}lval_del(x);}}
lval*builtin_print(lenv* e, lval* a){/* Print each argument followed by a space */for(int i =0; i < a->count; i++){lval_print(a->cell[i]);putchar(' ');}/* Print a newline and delete arguments */putchar('\n');lval_del(a);returnlval_sexpr();}
$ ./parsing
Lispy Version 0.1
Press Ctrl+c to Exit
lispy> print "Hello World!"
"Hello World!"
()
lispy> error "This is an error"
Error: This is an error
请发表评论