lispreader.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356
  1. /* $Id: lispreader.cpp,v 1.19 2004/05/11 22:16:12 sik0fewl Exp $ */
  2. /*
  3. * lispreader.c
  4. *
  5. * Copyright (C) 1998-2000 Mark Probst
  6. * Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de>
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Library General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2 of the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Library General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Library General Public
  19. * License along with this library; if not, write to the
  20. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  21. * Boston, MA 02111-1307, USA.
  22. */
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include "lispreader.hpp"
  26. #define TOKEN_ERROR -1
  27. #define TOKEN_EOF 0
  28. #define TOKEN_OPEN_PAREN 1
  29. #define TOKEN_CLOSE_PAREN 2
  30. #define TOKEN_SYMBOL 3
  31. #define TOKEN_STRING 4
  32. #define TOKEN_INTEGER 5
  33. #define TOKEN_REAL 6
  34. #define TOKEN_PATTERN_OPEN_PAREN 7
  35. #define TOKEN_DOT 8
  36. #define TOKEN_TRUE 9
  37. #define TOKEN_FALSE 10
  38. #define MAX_TOKEN_LENGTH 1024
  39. static char token_string[MAX_TOKEN_LENGTH + 1] = "";
  40. static int token_length = 0;
  41. static lisp_object_t end_marker = { LISP_TYPE_EOF, {{0, 0}} };
  42. static lisp_object_t error_object = { LISP_TYPE_PARSE_ERROR , {{0,0}} };
  43. static lisp_object_t close_paren_marker = { LISP_TYPE_PARSE_ERROR , {{0,0}} };
  44. static lisp_object_t dot_marker = { LISP_TYPE_PARSE_ERROR , {{0,0}} };
  45. static void
  46. _token_clear (void)
  47. {
  48. token_string[0] = '\0';
  49. token_length = 0;
  50. }
  51. static void
  52. _token_append (char c)
  53. {
  54. if (token_length >= MAX_TOKEN_LENGTH)
  55. throw LispReaderException("_token_append()", __FILE__, __LINE__);
  56. token_string[token_length++] = c;
  57. token_string[token_length] = '\0';
  58. }
  59. static int
  60. _next_char (lisp_stream_t *stream)
  61. {
  62. switch (stream->type)
  63. {
  64. case LISP_STREAM_FILE :
  65. return getc(stream->v.file);
  66. case LISP_STREAM_STRING :
  67. {
  68. char c = stream->v.string.buf[stream->v.string.pos];
  69. if (c == 0)
  70. return EOF;
  71. ++stream->v.string.pos;
  72. return c;
  73. }
  74. case LISP_STREAM_ANY:
  75. return stream->v.any.next_char(stream->v.any.data);
  76. }
  77. throw LispReaderException("_next_char()", __FILE__, __LINE__);
  78. return EOF;
  79. }
  80. static void
  81. _unget_char (char c, lisp_stream_t *stream)
  82. {
  83. switch (stream->type)
  84. {
  85. case LISP_STREAM_FILE :
  86. ungetc(c, stream->v.file);
  87. break;
  88. case LISP_STREAM_STRING :
  89. --stream->v.string.pos;
  90. break;
  91. case LISP_STREAM_ANY:
  92. stream->v.any.unget_char(c, stream->v.any.data);
  93. break;
  94. default :
  95. throw LispReaderException("_unget_char()", __FILE__, __LINE__);
  96. }
  97. }
  98. static int
  99. _scan (lisp_stream_t *stream)
  100. {
  101. static const char *delims = "\"();";
  102. int c;
  103. _token_clear();
  104. do
  105. {
  106. c = _next_char(stream);
  107. if (c == EOF)
  108. return TOKEN_EOF;
  109. else if (c == ';') /* comment start */
  110. while (1)
  111. {
  112. c = _next_char(stream);
  113. if (c == EOF)
  114. return TOKEN_EOF;
  115. else if (c == '\n')
  116. break;
  117. }
  118. }
  119. while (isspace(c));
  120. switch (c)
  121. {
  122. case '(' :
  123. return TOKEN_OPEN_PAREN;
  124. case ')' :
  125. return TOKEN_CLOSE_PAREN;
  126. case '"' :
  127. while (1)
  128. {
  129. c = _next_char(stream);
  130. if (c == EOF)
  131. return TOKEN_ERROR;
  132. if (c == '"')
  133. break;
  134. if (c == '\\')
  135. {
  136. c = _next_char(stream);
  137. switch (c)
  138. {
  139. case EOF :
  140. return TOKEN_ERROR;
  141. case 'n' :
  142. c = '\n';
  143. break;
  144. case 't' :
  145. c = '\t';
  146. break;
  147. }
  148. }
  149. _token_append(c);
  150. }
  151. return TOKEN_STRING;
  152. case '#' :
  153. c = _next_char(stream);
  154. if (c == EOF)
  155. return TOKEN_ERROR;
  156. switch (c)
  157. {
  158. case 't' :
  159. return TOKEN_TRUE;
  160. case 'f' :
  161. return TOKEN_FALSE;
  162. case '?' :
  163. c = _next_char(stream);
  164. if (c == EOF)
  165. return TOKEN_ERROR;
  166. if (c == '(')
  167. return TOKEN_PATTERN_OPEN_PAREN;
  168. else
  169. return TOKEN_ERROR;
  170. }
  171. return TOKEN_ERROR;
  172. default :
  173. if (isdigit(c) || c == '-')
  174. {
  175. int have_nondigits = 0;
  176. int have_digits = 0;
  177. int have_floating_point = 0;
  178. do
  179. {
  180. if (isdigit(c))
  181. have_digits = 1;
  182. else if (c == '.')
  183. have_floating_point++;
  184. _token_append(c);
  185. c = _next_char(stream);
  186. if (c != EOF && !isdigit(c) && !isspace(c) && c != '.' && !strchr(delims, c))
  187. have_nondigits = 1;
  188. }
  189. while (c != EOF && !isspace(c) && !strchr(delims, c));
  190. if (c != EOF)
  191. _unget_char(c, stream);
  192. if (have_nondigits || !have_digits || have_floating_point > 1)
  193. return TOKEN_SYMBOL;
  194. else if (have_floating_point == 1)
  195. return TOKEN_REAL;
  196. else
  197. return TOKEN_INTEGER;
  198. }
  199. else
  200. {
  201. if (c == '.')
  202. {
  203. c = _next_char(stream);
  204. if (c != EOF && !isspace(c) && !strchr(delims, c))
  205. _token_append('.');
  206. else
  207. {
  208. _unget_char(c, stream);
  209. return TOKEN_DOT;
  210. }
  211. }
  212. do
  213. {
  214. _token_append(c);
  215. c = _next_char(stream);
  216. }
  217. while (c != EOF && !isspace(c) && !strchr(delims, c));
  218. if (c != EOF)
  219. _unget_char(c, stream);
  220. return TOKEN_SYMBOL;
  221. }
  222. }
  223. throw LispReaderException("_scan()", __FILE__, __LINE__);
  224. return TOKEN_ERROR;
  225. }
  226. static lisp_object_t*
  227. lisp_object_alloc (int type)
  228. {
  229. lisp_object_t *obj = (lisp_object_t*)malloc(sizeof(lisp_object_t));
  230. obj->type = type;
  231. return obj;
  232. }
  233. lisp_stream_t*
  234. lisp_stream_init_file (lisp_stream_t *stream, FILE *file)
  235. {
  236. stream->type = LISP_STREAM_FILE;
  237. stream->v.file = file;
  238. return stream;
  239. }
  240. lisp_stream_t*
  241. lisp_stream_init_string (lisp_stream_t *stream, char *buf)
  242. {
  243. stream->type = LISP_STREAM_STRING;
  244. stream->v.string.buf = buf;
  245. stream->v.string.pos = 0;
  246. return stream;
  247. }
  248. lisp_stream_t*
  249. lisp_stream_init_any (lisp_stream_t *stream, void *data,
  250. int (*next_char) (void *data),
  251. void (*unget_char) (char c, void *data))
  252. {
  253. if (next_char == 0 || unget_char == 0)
  254. throw LispReaderException("lisp_stream_init_any()", __FILE__, __LINE__);
  255. stream->type = LISP_STREAM_ANY;
  256. stream->v.any.data = data;
  257. stream->v.any.next_char= next_char;
  258. stream->v.any.unget_char = unget_char;
  259. return stream;
  260. }
  261. lisp_object_t*
  262. lisp_make_integer (int value)
  263. {
  264. lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_INTEGER);
  265. obj->v.integer = value;
  266. return obj;
  267. }
  268. lisp_object_t*
  269. lisp_make_real (float value)
  270. {
  271. lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_REAL);
  272. obj->v.real = value;
  273. return obj;
  274. }
  275. lisp_object_t*
  276. lisp_make_symbol (const char *value)
  277. {
  278. lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_SYMBOL);
  279. obj->v.string = strdup(value);
  280. return obj;
  281. }
  282. lisp_object_t*
  283. lisp_make_string (const char *value)
  284. {
  285. lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_STRING);
  286. obj->v.string = strdup(value);
  287. return obj;
  288. }
  289. lisp_object_t*
  290. lisp_make_cons (lisp_object_t *car, lisp_object_t *cdr)
  291. {
  292. lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_CONS);
  293. obj->v.cons.car = car;
  294. obj->v.cons.cdr = cdr;
  295. return obj;
  296. }
  297. lisp_object_t*
  298. lisp_make_boolean (int value)
  299. {
  300. lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_BOOLEAN);
  301. obj->v.integer = value ? 1 : 0;
  302. return obj;
  303. }
  304. static lisp_object_t*
  305. lisp_make_pattern_cons (lisp_object_t *car, lisp_object_t *cdr)
  306. {
  307. lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_PATTERN_CONS);
  308. obj->v.cons.car = car;
  309. obj->v.cons.cdr = cdr;
  310. return obj;
  311. }
  312. static lisp_object_t*
  313. lisp_make_pattern_var (int type, int index, lisp_object_t *sub)
  314. {
  315. lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_PATTERN_VAR);
  316. obj->v.pattern.type = type;
  317. obj->v.pattern.index = index;
  318. obj->v.pattern.sub = sub;
  319. return obj;
  320. }
  321. lisp_object_t*
  322. lisp_read (lisp_stream_t *in)
  323. {
  324. int token = _scan(in);
  325. lisp_object_t *obj = lisp_nil();
  326. if (token == TOKEN_EOF)
  327. return &end_marker;
  328. switch (token)
  329. {
  330. case TOKEN_ERROR :
  331. return &error_object;
  332. case TOKEN_EOF :
  333. return &end_marker;
  334. case TOKEN_OPEN_PAREN :
  335. case TOKEN_PATTERN_OPEN_PAREN :
  336. {
  337. lisp_object_t *last = lisp_nil(), *car;
  338. do
  339. {
  340. car = lisp_read(in);
  341. if (car == &error_object || car == &end_marker)
  342. {
  343. lisp_free(obj);
  344. return &error_object;
  345. }
  346. else if (car == &dot_marker)
  347. {
  348. if (lisp_nil_p(last))
  349. {
  350. lisp_free(obj);
  351. return &error_object;
  352. }
  353. car = lisp_read(in);
  354. if (car == &error_object || car == &end_marker)
  355. {
  356. lisp_free(obj);
  357. return car;
  358. }
  359. else
  360. {
  361. last->v.cons.cdr = car;
  362. if (_scan(in) != TOKEN_CLOSE_PAREN)
  363. {
  364. lisp_free(obj);
  365. return &error_object;
  366. }
  367. car = &close_paren_marker;
  368. }
  369. }
  370. else if (car != &close_paren_marker)
  371. {
  372. if (lisp_nil_p(last))
  373. obj = last = (token == TOKEN_OPEN_PAREN ? lisp_make_cons(car, lisp_nil()) : lisp_make_pattern_cons(car, lisp_nil()));
  374. else
  375. last = last->v.cons.cdr = lisp_make_cons(car, lisp_nil());
  376. }
  377. }
  378. while (car != &close_paren_marker);
  379. }
  380. return obj;
  381. case TOKEN_CLOSE_PAREN :
  382. return &close_paren_marker;
  383. case TOKEN_SYMBOL :
  384. return lisp_make_symbol(token_string);
  385. case TOKEN_STRING :
  386. return lisp_make_string(token_string);
  387. case TOKEN_INTEGER :
  388. return lisp_make_integer(atoi(token_string));
  389. case TOKEN_REAL :
  390. return lisp_make_real((float)atof(token_string));
  391. case TOKEN_DOT :
  392. return &dot_marker;
  393. case TOKEN_TRUE :
  394. return lisp_make_boolean(1);
  395. case TOKEN_FALSE :
  396. return lisp_make_boolean(0);
  397. }
  398. throw LispReaderException("lisp_read()", __FILE__, __LINE__);
  399. return &error_object;
  400. }
  401. void
  402. lisp_free (lisp_object_t *obj)
  403. {
  404. if (obj == 0)
  405. return;
  406. switch (obj->type)
  407. {
  408. case LISP_TYPE_INTERNAL :
  409. case LISP_TYPE_PARSE_ERROR :
  410. case LISP_TYPE_EOF :
  411. return;
  412. case LISP_TYPE_SYMBOL :
  413. case LISP_TYPE_STRING :
  414. free(obj->v.string);
  415. break;
  416. case LISP_TYPE_CONS :
  417. case LISP_TYPE_PATTERN_CONS :
  418. lisp_free(obj->v.cons.car);
  419. lisp_free(obj->v.cons.cdr);
  420. break;
  421. case LISP_TYPE_PATTERN_VAR :
  422. lisp_free(obj->v.pattern.sub);
  423. break;
  424. }
  425. free(obj);
  426. }
  427. lisp_object_t*
  428. lisp_read_from_string (const char *buf)
  429. {
  430. lisp_stream_t stream;
  431. lisp_stream_init_string(&stream, (char*)buf);
  432. return lisp_read(&stream);
  433. }
  434. static int
  435. _compile_pattern (lisp_object_t **obj, int *index)
  436. {
  437. if (*obj == 0)
  438. return 1;
  439. switch (lisp_type(*obj))
  440. {
  441. case LISP_TYPE_PATTERN_CONS :
  442. {
  443. struct
  444. {
  445. const char *name;
  446. int type;
  447. }
  448. types[] =
  449. {
  450. { "any", LISP_PATTERN_ANY },
  451. { "symbol", LISP_PATTERN_SYMBOL },
  452. { "string", LISP_PATTERN_STRING },
  453. { "integer", LISP_PATTERN_INTEGER },
  454. { "real", LISP_PATTERN_REAL },
  455. { "boolean", LISP_PATTERN_BOOLEAN },
  456. { "list", LISP_PATTERN_LIST },
  457. { "or", LISP_PATTERN_OR },
  458. { 0, 0 }
  459. };
  460. char *type_name;
  461. int type;
  462. int i;
  463. lisp_object_t *pattern;
  464. type = -1;
  465. if (lisp_type(lisp_car(*obj)) != LISP_TYPE_SYMBOL)
  466. return 0;
  467. type_name = lisp_symbol(lisp_car(*obj));
  468. for (i = 0; types[i].name != 0; ++i)
  469. {
  470. if (strcmp(types[i].name, type_name) == 0)
  471. {
  472. type = types[i].type;
  473. break;
  474. }
  475. }
  476. if (types[i].name == 0)
  477. return 0;
  478. if (type != LISP_PATTERN_OR && lisp_cdr(*obj) != 0)
  479. return 0;
  480. pattern = lisp_make_pattern_var(type, (*index)++, lisp_nil());
  481. if (type == LISP_PATTERN_OR)
  482. {
  483. lisp_object_t *cdr = lisp_cdr(*obj);
  484. if (!_compile_pattern(&cdr, index))
  485. {
  486. lisp_free(pattern);
  487. return 0;
  488. }
  489. pattern->v.pattern.sub = cdr;
  490. (*obj)->v.cons.cdr = lisp_nil();
  491. }
  492. lisp_free(*obj);
  493. *obj = pattern;
  494. }
  495. break;
  496. case LISP_TYPE_CONS :
  497. if (!_compile_pattern(&(*obj)->v.cons.car, index))
  498. return 0;
  499. if (!_compile_pattern(&(*obj)->v.cons.cdr, index))
  500. return 0;
  501. break;
  502. }
  503. return 1;
  504. }
  505. int
  506. lisp_compile_pattern (lisp_object_t **obj, int *num_subs)
  507. {
  508. int index = 0;
  509. int result;
  510. result = _compile_pattern(obj, &index);
  511. if (result && num_subs != 0)
  512. *num_subs = index;
  513. return result;
  514. }
  515. static int _match_pattern (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **vars);
  516. static int
  517. _match_pattern_var (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **vars)
  518. {
  519. if (lisp_type(pattern) != LISP_TYPE_PATTERN_VAR)
  520. throw LispReaderException("_match_pattern_var", __FILE__, __LINE__);
  521. switch (pattern->v.pattern.type)
  522. {
  523. case LISP_PATTERN_ANY :
  524. break;
  525. case LISP_PATTERN_SYMBOL :
  526. if (obj == 0 || lisp_type(obj) != LISP_TYPE_SYMBOL)
  527. return 0;
  528. break;
  529. case LISP_PATTERN_STRING :
  530. if (obj == 0 || lisp_type(obj) != LISP_TYPE_STRING)
  531. return 0;
  532. break;
  533. case LISP_PATTERN_INTEGER :
  534. if (obj == 0 || lisp_type(obj) != LISP_TYPE_INTEGER)
  535. return 0;
  536. break;
  537. case LISP_PATTERN_REAL :
  538. if (obj == 0 || lisp_type(obj) != LISP_TYPE_REAL)
  539. return 0;
  540. break;
  541. case LISP_PATTERN_BOOLEAN :
  542. if (obj == 0 || lisp_type(obj) != LISP_TYPE_BOOLEAN)
  543. return 0;
  544. break;
  545. case LISP_PATTERN_LIST :
  546. if (obj == 0 || lisp_type(obj) != LISP_TYPE_CONS)
  547. return 0;
  548. break;
  549. case LISP_PATTERN_OR :
  550. {
  551. lisp_object_t *sub;
  552. int matched = 0;
  553. for (sub = pattern->v.pattern.sub; sub != 0; sub = lisp_cdr(sub))
  554. {
  555. if (lisp_type(sub) != LISP_TYPE_CONS)
  556. throw LispReaderException("_match_pattern_var()", __FILE__, __LINE__);
  557. if (_match_pattern(lisp_car(sub), obj, vars))
  558. matched = 1;
  559. }
  560. if (!matched)
  561. return 0;
  562. }
  563. break;
  564. default :
  565. throw LispReaderException("_match_pattern_var()", __FILE__, __LINE__);
  566. }
  567. if (vars != 0)
  568. vars[pattern->v.pattern.index] = obj;
  569. return 1;
  570. }
  571. static int
  572. _match_pattern (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **vars)
  573. {
  574. if (pattern == 0)
  575. return obj == 0;
  576. if (obj == 0)
  577. return 0;
  578. if (lisp_type(pattern) == LISP_TYPE_PATTERN_VAR)
  579. return _match_pattern_var(pattern, obj, vars);
  580. if (lisp_type(pattern) != lisp_type(obj))
  581. return 0;
  582. switch (lisp_type(pattern))
  583. {
  584. case LISP_TYPE_SYMBOL :
  585. return strcmp(lisp_symbol(pattern), lisp_symbol(obj)) == 0;
  586. case LISP_TYPE_STRING :
  587. return strcmp(lisp_string(pattern), lisp_string(obj)) == 0;
  588. case LISP_TYPE_INTEGER :
  589. return lisp_integer(pattern) == lisp_integer(obj);
  590. case LISP_TYPE_REAL :
  591. return lisp_real(pattern) == lisp_real(obj);
  592. case LISP_TYPE_CONS :
  593. {
  594. int result1, result2;
  595. result1 = _match_pattern(lisp_car(pattern), lisp_car(obj), vars);
  596. result2 = _match_pattern(lisp_cdr(pattern), lisp_cdr(obj), vars);
  597. return result1 && result2;
  598. }
  599. break;
  600. default :
  601. throw LispReaderException("_match_pattern()", __FILE__, __LINE__);
  602. }
  603. return 0;
  604. }
  605. int
  606. lisp_match_pattern (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **vars, int num_subs)
  607. {
  608. int i;
  609. if (vars != 0)
  610. for (i = 0; i < num_subs; ++i)
  611. vars[i] = &error_object;
  612. return _match_pattern(pattern, obj, vars);
  613. }
  614. int
  615. lisp_match_string (const char *pattern_string, lisp_object_t *obj, lisp_object_t **vars)
  616. {
  617. lisp_object_t *pattern;
  618. int result;
  619. int num_subs;
  620. pattern = lisp_read_from_string(pattern_string);
  621. if (pattern != 0 && (lisp_type(pattern) == LISP_TYPE_EOF
  622. || lisp_type(pattern) == LISP_TYPE_PARSE_ERROR))
  623. return 0;
  624. if (!lisp_compile_pattern(&pattern, &num_subs))
  625. {
  626. lisp_free(pattern);
  627. return 0;
  628. }
  629. result = lisp_match_pattern(pattern, obj, vars, num_subs);
  630. lisp_free(pattern);
  631. return result;
  632. }
  633. int
  634. lisp_type (lisp_object_t *obj)
  635. {
  636. if (obj == 0)
  637. return LISP_TYPE_NIL;
  638. return obj->type;
  639. }
  640. int
  641. lisp_integer (lisp_object_t *obj)
  642. {
  643. if (obj->type != LISP_TYPE_INTEGER)
  644. throw LispReaderException("lisp_integer()", __FILE__, __LINE__);
  645. return obj->v.integer;
  646. }
  647. char*
  648. lisp_symbol (lisp_object_t *obj)
  649. {
  650. if (obj->type != LISP_TYPE_SYMBOL)
  651. throw LispReaderException("lisp_symbol()", __FILE__, __LINE__);
  652. return obj->v.string;
  653. }
  654. char*
  655. lisp_string (lisp_object_t *obj)
  656. {
  657. if (obj->type != LISP_TYPE_STRING)
  658. throw LispReaderException("lisp_string()", __FILE__, __LINE__);
  659. return obj->v.string;
  660. }
  661. int
  662. lisp_boolean (lisp_object_t *obj)
  663. {
  664. if (obj->type != LISP_TYPE_BOOLEAN)
  665. throw LispReaderException("lisp_boolean()", __FILE__, __LINE__);
  666. return obj->v.integer;
  667. }
  668. float
  669. lisp_real (lisp_object_t *obj)
  670. {
  671. if (obj->type != LISP_TYPE_REAL && obj->type != LISP_TYPE_INTEGER)
  672. throw LispReaderException("lisp_real()", __FILE__, __LINE__);
  673. if (obj->type == LISP_TYPE_INTEGER)
  674. return obj->v.integer;
  675. return obj->v.real;
  676. }
  677. lisp_object_t*
  678. lisp_car (lisp_object_t *obj)
  679. {
  680. if (obj->type != LISP_TYPE_CONS && obj->type != LISP_TYPE_PATTERN_CONS)
  681. throw LispReaderException("lisp_car()", __FILE__, __LINE__);
  682. return obj->v.cons.car;
  683. }
  684. lisp_object_t*
  685. lisp_cdr (lisp_object_t *obj)
  686. {
  687. if (obj->type != LISP_TYPE_CONS && obj->type != LISP_TYPE_PATTERN_CONS)
  688. throw LispReaderException("lisp_cdr()", __FILE__, __LINE__);
  689. return obj->v.cons.cdr;
  690. }
  691. lisp_object_t*
  692. lisp_cxr (lisp_object_t *obj, const char *x)
  693. {
  694. int i;
  695. for (i = strlen(x) - 1; i >= 0; --i)
  696. if (x[i] == 'a')
  697. obj = lisp_car(obj);
  698. else if (x[i] == 'd')
  699. obj = lisp_cdr(obj);
  700. else
  701. throw LispReaderException("lisp_cxr()", __FILE__, __LINE__);
  702. return obj;
  703. }
  704. int
  705. lisp_list_length (lisp_object_t *obj)
  706. {
  707. int length = 0;
  708. while (obj != 0)
  709. {
  710. if (obj->type != LISP_TYPE_CONS && obj->type != LISP_TYPE_PATTERN_CONS)
  711. throw LispReaderException("lisp_list_length()", __FILE__, __LINE__);
  712. ++length;
  713. obj = obj->v.cons.cdr;
  714. }
  715. return length;
  716. }
  717. lisp_object_t*
  718. lisp_list_nth_cdr (lisp_object_t *obj, int index)
  719. {
  720. while (index > 0)
  721. {
  722. if (obj == 0)
  723. throw LispReaderException("lisp_list_nth_cdr()", __FILE__, __LINE__);
  724. if (obj->type != LISP_TYPE_CONS && obj->type != LISP_TYPE_PATTERN_CONS)
  725. throw LispReaderException("lisp_list_nth_cdr()", __FILE__, __LINE__);
  726. --index;
  727. obj = obj->v.cons.cdr;
  728. }
  729. return obj;
  730. }
  731. lisp_object_t*
  732. lisp_list_nth (lisp_object_t *obj, int index)
  733. {
  734. obj = lisp_list_nth_cdr(obj, index);
  735. if (obj == 0)
  736. throw LispReaderException("lisp_list_nth()", __FILE__, __LINE__);
  737. return obj->v.cons.car;
  738. }
  739. void
  740. lisp_dump (lisp_object_t *obj, FILE *out)
  741. {
  742. if (obj == 0)
  743. {
  744. fprintf(out, "()");
  745. return;
  746. }
  747. switch (lisp_type(obj))
  748. {
  749. case LISP_TYPE_EOF :
  750. fputs("#<eof>", out);
  751. break;
  752. case LISP_TYPE_PARSE_ERROR :
  753. fputs("#<error>", out);
  754. break;
  755. case LISP_TYPE_INTEGER :
  756. fprintf(out, "%d", lisp_integer(obj));
  757. break;
  758. case LISP_TYPE_REAL :
  759. fprintf(out, "%f", lisp_real(obj));
  760. break;
  761. case LISP_TYPE_SYMBOL :
  762. fputs(lisp_symbol(obj), out);
  763. break;
  764. case LISP_TYPE_STRING :
  765. {
  766. char *p;
  767. fputc('"', out);
  768. for (p = lisp_string(obj); *p != 0; ++p)
  769. {
  770. if (*p == '"' || *p == '\\')
  771. fputc('\\', out);
  772. fputc(*p, out);
  773. }
  774. fputc('"', out);
  775. }
  776. break;
  777. case LISP_TYPE_CONS :
  778. case LISP_TYPE_PATTERN_CONS :
  779. fputs(lisp_type(obj) == LISP_TYPE_CONS ? "(" : "#?(", out);
  780. while (obj != 0)
  781. {
  782. lisp_dump(lisp_car(obj), out);
  783. obj = lisp_cdr(obj);
  784. if (obj != 0)
  785. {
  786. if (lisp_type(obj) != LISP_TYPE_CONS
  787. && lisp_type(obj) != LISP_TYPE_PATTERN_CONS)
  788. {
  789. fputs(" . ", out);
  790. lisp_dump(obj, out);
  791. break;
  792. }
  793. else
  794. fputc(' ', out);
  795. }
  796. }
  797. fputc(')', out);
  798. break;
  799. case LISP_TYPE_BOOLEAN :
  800. if (lisp_boolean(obj))
  801. fputs("#t", out);
  802. else
  803. fputs("#f", out);
  804. break;
  805. default :
  806. throw LispReaderException("lisp_dump()", __FILE__, __LINE__);
  807. }
  808. }
  809. using namespace std;
  810. LispReader::LispReader (lisp_object_t* l)
  811. : lst (l)
  812. {
  813. //std::cout << "LispReader: " << std::flush;
  814. //lisp_dump(lst, stdout);
  815. //std::cout << std::endl;
  816. }
  817. lisp_object_t*
  818. LispReader::search_for(const char* name)
  819. {
  820. //std::cout << "LispReader::search_for(" << name << ")" << std::endl;
  821. lisp_object_t* cursor = lst;
  822. while(!lisp_nil_p(cursor))
  823. {
  824. lisp_object_t* cur = lisp_car(cursor);
  825. if (!lisp_cons_p(cur) || !lisp_symbol_p (lisp_car(cur)))
  826. {
  827. lisp_dump(cur, stdout);
  828. //throw ConstruoError (std::string("LispReader: Read error in search_for ") + name);
  829. printf("LispReader: Read error in search\n");
  830. }
  831. else
  832. {
  833. if (strcmp(lisp_symbol(lisp_car(cur)), name) == 0)
  834. {
  835. return lisp_cdr(cur);
  836. }
  837. }
  838. cursor = lisp_cdr (cursor);
  839. }
  840. return 0;
  841. }
  842. bool
  843. LispReader::read_int (const char* name, int* i)
  844. {
  845. lisp_object_t* obj = search_for (name);
  846. if (obj)
  847. {
  848. if (!lisp_integer_p(lisp_car(obj)))
  849. {
  850. //st_abort("LispReader expected type integer at token: ", name); /* Instead of giving up, we return with false now. */
  851. return false;
  852. }
  853. *i = lisp_integer(lisp_car(obj));
  854. return true;
  855. }
  856. return false;
  857. }
  858. bool
  859. LispReader::read_lisp(const char* name, lisp_object_t** b)
  860. {
  861. lisp_object_t* obj = search_for (name);
  862. if (obj)
  863. {
  864. *b = obj;
  865. return true;
  866. }
  867. else
  868. return false;
  869. }
  870. bool
  871. LispReader::read_float (const char* name, float* f)
  872. {
  873. lisp_object_t* obj = search_for (name);
  874. if (obj)
  875. {
  876. if (!lisp_real_p(lisp_car(obj)) && !lisp_integer_p(lisp_car(obj)))
  877. throw LispReaderException("LispReader expected type real at token: ",
  878. __FILE__, __LINE__);
  879. *f = lisp_real(lisp_car(obj));
  880. return true;
  881. }
  882. return false;
  883. }
  884. bool
  885. LispReader::read_string_vector (const char* name, std::vector<std::string>* vec)
  886. {
  887. lisp_object_t* obj = search_for (name);
  888. if (obj)
  889. {
  890. while(!lisp_nil_p(obj))
  891. {
  892. if (!lisp_string_p(lisp_car(obj)))
  893. throw LispReaderException("LispReader expected type string at token: ", name);
  894. vec->push_back(lisp_string(lisp_car(obj)));
  895. obj = lisp_cdr(obj);
  896. }
  897. return true;
  898. }
  899. return false;
  900. }
  901. bool
  902. LispReader::read_int_vector (const char* name, std::vector<int>* vec)
  903. {
  904. lisp_object_t* obj = search_for (name);
  905. if (obj)
  906. {
  907. while(!lisp_nil_p(obj))
  908. {
  909. if (!lisp_integer_p(lisp_car(obj)))
  910. throw LispReaderException("LispReader expected type integer at token: ", name);
  911. vec->push_back(lisp_integer(lisp_car(obj)));
  912. obj = lisp_cdr(obj);
  913. }
  914. return true;
  915. }
  916. return false;
  917. }
  918. bool
  919. LispReader::read_char_vector (const char* name, std::vector<char>* vec)
  920. {
  921. lisp_object_t* obj = search_for (name);
  922. if (obj)
  923. {
  924. while(!lisp_nil_p(obj))
  925. {
  926. vec->push_back(*lisp_string(lisp_car(obj)));
  927. obj = lisp_cdr(obj);
  928. }
  929. return true;
  930. }
  931. return false;
  932. }
  933. bool
  934. LispReader::read_string (const char* name, std::string* str)
  935. {
  936. lisp_object_t* obj = search_for (name);
  937. if (obj)
  938. {
  939. if (!lisp_string_p(lisp_car(obj)))
  940. throw LispReaderException("LispReader expected type string at token: ", name);
  941. *str = lisp_string(lisp_car(obj));
  942. return true;
  943. }
  944. return false;
  945. }
  946. bool
  947. LispReader::read_bool (const char* name, bool* b)
  948. {
  949. lisp_object_t* obj = search_for (name);
  950. if (obj)
  951. {
  952. if (!lisp_boolean_p(lisp_car(obj)))
  953. throw LispReaderException("LispReader expected type bool at token: ");
  954. *b = lisp_boolean(lisp_car(obj));
  955. return true;
  956. }
  957. return false;
  958. }
  959. LispWriter::LispWriter (const char* name)
  960. {
  961. lisp_objs.push_back(lisp_make_symbol (name));
  962. }
  963. void
  964. LispWriter::append (lisp_object_t* obj)
  965. {
  966. lisp_objs.push_back(obj);
  967. }
  968. lisp_object_t*
  969. LispWriter::make_list3 (lisp_object_t* a, lisp_object_t* b, lisp_object_t* c)
  970. {
  971. return lisp_make_cons (a, lisp_make_cons(b, lisp_make_cons(c, lisp_nil())));
  972. }
  973. lisp_object_t*
  974. LispWriter::make_list2 (lisp_object_t* a, lisp_object_t* b)
  975. {
  976. return lisp_make_cons (a, lisp_make_cons(b, lisp_nil()));
  977. }
  978. void
  979. LispWriter::write_float (const char* name, float f)
  980. {
  981. append(make_list2 (lisp_make_symbol (name),
  982. lisp_make_real(f)));
  983. }
  984. void
  985. LispWriter::write_int (const char* name, int i)
  986. {
  987. append(make_list2 (lisp_make_symbol (name),
  988. lisp_make_integer(i)));
  989. }
  990. void
  991. LispWriter::write_string (const char* name, const char* str)
  992. {
  993. append(make_list2 (lisp_make_symbol (name),
  994. lisp_make_string(str)));
  995. }
  996. void
  997. LispWriter::write_symbol (const char* name, const char* symname)
  998. {
  999. append(make_list2 (lisp_make_symbol (name),
  1000. lisp_make_symbol(symname)));
  1001. }
  1002. void
  1003. LispWriter::write_lisp_obj(const char* name, lisp_object_t* lst)
  1004. {
  1005. append(make_list2 (lisp_make_symbol (name),
  1006. lst));
  1007. }
  1008. void
  1009. LispWriter::write_boolean (const char* name, bool b)
  1010. {
  1011. append(make_list2 (lisp_make_symbol (name),
  1012. lisp_make_boolean(b)));
  1013. }
  1014. lisp_object_t*
  1015. LispWriter::create_lisp ()
  1016. {
  1017. lisp_object_t* lisp_obj = lisp_nil();
  1018. for(std::vector<lisp_object_t*>::reverse_iterator i = lisp_objs.rbegin ();
  1019. i != lisp_objs.rend (); ++i)
  1020. {
  1021. lisp_obj = lisp_make_cons (*i, lisp_obj);
  1022. }
  1023. lisp_objs.clear();
  1024. return lisp_obj;
  1025. }
  1026. #if 0
  1027. void mygzungetc(char c, void* file)
  1028. {
  1029. gzungetc(c, file);
  1030. }
  1031. lisp_stream_t* lisp_stream_init_gzfile (lisp_stream_t *stream, gzFile file)
  1032. {
  1033. return lisp_stream_init_any (stream, file, gzgetc, mygzungetc);
  1034. }
  1035. #endif
  1036. lisp_object_t* lisp_read_from_gzfile(const char* filename)
  1037. {
  1038. bool done = false;
  1039. lisp_object_t* root_obj = 0;
  1040. int chunk_size = 128 * 1024;
  1041. int buf_pos = 0;
  1042. int try_number = 1;
  1043. char* buf = static_cast<char*>(malloc(chunk_size));
  1044. if (!buf)
  1045. throw LispReaderException("lisp_read_from_gzfile()", __FILE__, __LINE__);
  1046. gzFile in = gzopen(filename, "r");
  1047. while (!done)
  1048. {
  1049. int ret = gzread(in, buf + buf_pos, chunk_size);
  1050. if (ret == -1)
  1051. {
  1052. free (buf);
  1053. throw LispReaderException("Error while reading from file", __FILE__, __LINE__);
  1054. }
  1055. else if (ret == chunk_size) // buffer got full, eof not yet there so resize
  1056. {
  1057. buf_pos = chunk_size * try_number;
  1058. try_number += 1;
  1059. buf = static_cast<char*>(realloc(buf, chunk_size * try_number));
  1060. if (!buf)
  1061. throw LispReaderException("lisp_read_from_gzfile()", __FILE__, __LINE__);
  1062. }
  1063. else
  1064. {
  1065. // everything fine, encountered EOF
  1066. done = true;
  1067. }
  1068. }
  1069. lisp_stream_t stream;
  1070. lisp_stream_init_string (&stream, buf);
  1071. root_obj = lisp_read (&stream);
  1072. free(buf);
  1073. gzclose(in);
  1074. return root_obj;
  1075. }
  1076. bool has_suffix(const char* data, const char* suffix)
  1077. {
  1078. int suffix_len = strlen(suffix);
  1079. int data_len = strlen(data);
  1080. const char* data_suffix = (data + data_len - suffix_len);
  1081. if (data_suffix >= data)
  1082. {
  1083. return (strcmp(data_suffix, suffix) == 0);
  1084. }
  1085. else
  1086. {
  1087. return false;
  1088. }
  1089. }
  1090. lisp_object_t* lisp_read_from_file(const std::string& filename)
  1091. {
  1092. lisp_stream_t stream;
  1093. if (has_suffix(filename.c_str(), ".gz"))
  1094. {
  1095. return lisp_read_from_gzfile(filename.c_str());
  1096. }
  1097. else
  1098. {
  1099. lisp_object_t* obj = 0;
  1100. FILE* in = fopen(filename.c_str(), "r");
  1101. if (in)
  1102. {
  1103. lisp_stream_init_file(&stream, in);
  1104. obj = lisp_read(&stream);
  1105. fclose(in);
  1106. }
  1107. return obj;
  1108. }
  1109. }
  1110. // EOF //