Files
alisp/src/reader.c

118 lines
2.6 KiB
C

/* reader.c: Stream reader implementation
* Created: 2026-02-04
* Author: Aryadev Chavali
* License: See end of file
* Commentary:
*/
#include <ctype.h>
#include <string.h>
#include <alisp/reader.h>
const char *read_err_to_cstr(read_err_t err)
{
switch (err)
{
case READ_ERR_OK:
return "OK";
case READ_ERR_EOF:
return "EOF";
case READ_ERR_UNKNOWN_CHAR:
return "UNKNOWN_CHAR";
default:
FAIL("Unreachable");
}
}
// Accepted characters for symbols.
static const char *SYMBOL_CHARS =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!$%&*+,-./"
":<=>?@\\^_`{|}~0123456789";
// Little predicate using SYMBOL_CHARS
bool is_sym(char c)
{
return strchr(SYMBOL_CHARS, c) != NULL;
}
void skip_comments_and_whitespace(stream_t *stream)
{
for (char c = stream_peek(stream); c != '\0' && (isspace(c) || c == ';');
c = stream_peek(stream))
{
stream_while(stream, " \t\n\0");
if (stream_peek(stream) == ';')
{
// Skip till newline
stream_till(stream, "\n");
}
}
}
read_err_t read_int(sys_t *, stream_t *, lisp_t **)
{
TODO("read_int: not implemented");
}
read_err_t read_sym(sys_t *, stream_t *, lisp_t **)
{
TODO("read_sym: not implemented");
}
read_err_t read_list(sys_t *, stream_t *, lisp_t **)
{
TODO("read_list: not implemented");
}
read_err_t read_vec(sys_t *, stream_t *, lisp_t **)
{
TODO("read_vec: not implemented");
}
read_err_t read_all(sys_t *sys, stream_t *stream, vec_t *out)
{
while (!stream_eoc(stream))
{
lisp_t *item = NIL;
read_err_t err = read(sys, stream, &item);
if (err)
return err;
else
vec_append(out, &item, sizeof(item));
}
return READ_ERR_OK;
}
read_err_t read(sys_t *sys, stream_t *stream, lisp_t **ret)
{
skip_comments_and_whitespace(stream);
if (stream_eoc(stream))
return READ_ERR_EOF;
char c = stream_peek(stream);
if (isdigit(c))
return read_int(sys, stream, ret);
else if (is_sym(c))
return read_sym(sys, stream, ret);
else if (c == '(')
return read_list(sys, stream, ret);
else if (c == '[')
return read_vec(sys, stream, ret);
else
return READ_ERR_UNKNOWN_CHAR;
}
/* Copyright (C) 2026 Aryadev Chavali
* 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 Version 2 for
* details.
* You may distribute and modify this code under the terms of the GNU General
* Public License Version 2, which you should have received a copy of along with
* this program. If not, please go to <https://www.gnu.org/licenses/>.
*/