commit e8fac282b1f7d8e1d21dbb1ba7cf38eceac64441
parent 1113d55d7a6d63ea00d5162879c9c1fdfb318602
Author: Ed van Bruggen <edvb@uw.edu>
Date: Wed, 11 Dec 2019 23:32:42 -0800
Incorporate file string directly into Env struct
Remove need for Str struct
Diffstat:
main.c | | | 5 | ++--- |
test.c | | | 6 | +++--- |
tibs/io.c | | | 10 | +++++++--- |
tisp.c | | | 174 | +++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
tisp.h | | | 14 | ++++++++------ |
5 files changed, 110 insertions(+), 99 deletions(-)
diff --git a/main.c b/main.c
@@ -17,7 +17,6 @@ int
main(int argc, char *argv[])
{
int i;
- struct Str str = { NULL };
Val v = NULL;
Env env = tisp_env_init(64);
@@ -38,11 +37,11 @@ main(int argc, char *argv[])
for (i = 1; i < argc; i++, v = NULL) {
if (argv[i][0] == '-') {
if (argv[i][1] == 'c') { /* run next argument as tisp command */
- if (!(str.d = argv[++i])) {
+ if (!(env->file = argv[++i])) {
fputs("tisp: expected command after -c\n", stderr);
exit(2);
}
- if ((v = tisp_read(env, &str)))
+ if ((v = tisp_read(env)))
v = tisp_eval(env, v);
} else if (argv[i][1] == 'v') { /* version and copyright info */
fprintf(stderr, "tisp v%s (c) 2017-2019 Ed van Bruggen\n", VERSION);
diff --git a/test.c b/test.c
@@ -484,15 +484,15 @@ char *tests[][2] = {
int
tisp_test(Env env, const char *input, const char *expect, int output)
{
- struct Str str = { NULL };
Val v;
FILE *f;
size_t nread;
char buf[BUFSIZ] = {0};
- if (!(str.d = strdup(input)))
+ if (!(env->file = strdup(input)))
return 0;
- if (!(v = tisp_read(env, &str)))
+ env->filec = 0;
+ if (!(v = tisp_read(env)))
return 0;
if (!(v = tisp_eval(env, v))) {
if (output)
diff --git a/tibs/io.c b/tibs/io.c
@@ -82,15 +82,19 @@ static Val
prim_parse(Env env, Val args)
{
Val v;
- struct Str str = { NULL };
+ char *file = env->file;
+ size_t filec = env->filec;
tsp_arg_num(args, "parse", 1);
if (!(v = tisp_eval(env, car(args))))
return NULL;
if (nilp(v))
return mk_pair(mk_sym(env, "quit"), env->nil);
tsp_arg_type(v, "parse", STRING);
- str.d = v->v.s;
- v = tisp_read(env, &str);
+ env->file = v->v.s;
+ env->filec = 0;
+ v = tisp_read(env);
+ env->file = file;
+ env->filec = filec;
return v ? v : env->none;
}
diff --git a/tisp.c b/tisp.c
@@ -124,18 +124,19 @@ isnum(char *str)
static char
isdelim(int c)
{
+ /* add .{}[]`', */
return isspace(c) || c == '(' || c == ')' || c == '"' || c == ';';
}
/* skip over comments and white space */
static void
-skip_ws(Str str, int skipnl)
+skip_ws(Env env, int skipnl)
{
const char *s = skipnl ? " \t\n" : " \t";
- while (*str->d && (strchr(s, *str->d) || *str->d == ';')) {
- str->d += strspn(str->d, s); /* skip white space */
- for (; *str->d == ';'; str->d++) /* skip comments until newline */
- str->d += strcspn(str->d, "\n") - !skipnl;
+ while (tsp_fget(env) && (strchr(s, tsp_fget(env)) || tsp_fget(env) == ';')) {
+ env->filec += strspn(env->file+env->filec, s); /* skip white space */
+ for (; tsp_fget(env) == ';'; tsp_finc(env)) /* skip comments until newline */
+ env->filec += strcspn(env->file+env->filec, "\n") - !skipnl;
}
}
@@ -436,35 +437,35 @@ mk_list(Env env, int n, Val *a)
/* read first character of number to determine sign */
static int
-read_sign(Str str)
+read_sign(Env env)
{
- switch (*str->d) {
- case '-': ++str->d; return -1;
- case '+': ++str->d; return 1;
+ switch (tsp_fget(env)) {
+ case '-': tsp_finc(env); return -1;
+ case '+': tsp_finc(env); return 1;
default: return 1;
}
}
/* return read integer */
static int
-read_int(Str str)
+read_int(Env env)
{
- int ret;
- for (ret = 0; isdigit(*str->d); str->d++)
- ret = ret * 10 + *str->d - '0';
+ int ret = 0;
+ for (; tsp_fget(env) && isdigit(tsp_fget(env)); tsp_finc(env))
+ ret = ret * 10 + tsp_fget(env) - '0';
return ret;
}
/* return read scientific notation */
static Val
-read_sci(Str str, double val, int isint)
+read_sci(Env env, double val, int isint)
{
- if (tolower(*str->d) != 'e')
+ if (tolower(tsp_fget(env)) != 'e')
goto finish;
- str->d++;
- double sign = read_sign(str) == 1 ? 10.0 : 0.1;
- for (int expo = read_int(str); expo--; val *= sign) ;
+ tsp_finc(env);
+ double sign = read_sign(env) == 1 ? 10.0 : 0.1;
+ for (int expo = read_int(env); expo--; val *= sign) ;
finish:
if (isint)
@@ -474,29 +475,26 @@ finish:
/* return read number */
static Val
-read_num(Str str)
+read_num(Env env)
{
- int sign = read_sign(str);
- int num = read_int(str);
- Str s;
- switch (*str->d) {
+ int sign = read_sign(env);
+ int num = read_int(env);
+ size_t oldc;
+ switch (tsp_fget(env)) {
case '/':
- str->d++;
- if (!isnum(str->d))
+ if (!isnum(env->file + ++env->filec))
tsp_warn("incorrect ratio format, no denominator found");
- return mk_rat(sign * num, read_sign(str) * read_int(str));
+ return mk_rat(sign * num, read_sign(env) * read_int(env));
case '.':
- s = emalloc(sizeof(Str));
- s->d = ++str->d;
- double d = (double) read_int(s);
- int size = s->d - str->d;
- str->d = s->d;
- free(s);
+ tsp_finc(env);
+ oldc = env->filec;
+ double d = (double) read_int(env);
+ int size = env->filec - oldc;
while (size--)
d /= 10.0;
- return read_sci(str, sign * (num+d), 0);
+ return read_sci(env, sign * (num+d), 0);
default:
- return read_sci(str, sign * num, 1);
+ return read_sci(env, sign * num, 1);
}
}
@@ -530,28 +528,28 @@ esc_str(char *s)
/* return read string */
static Val
-read_str(Env env, Str str)
+read_str(Env env)
{
int len = 0;
- char *s = ++str->d; /* skip starting open quote */
- for (; *str->d != '"'; str->d++, len++)
- if (!*str->d)
+ char *s = env->file + ++env->filec; /* skip starting open quote */
+ for (; tsp_fget(env) != '"'; tsp_finc(env), len++)
+ if (!tsp_fget(env))
tsp_warn("reached end before closing double quote");
- else if (*str->d == '\\' && str->d[1] == '"')
- str->d++, len++;
- str->d++; /* skip last closing quote */
+ else if (tsp_fget(env) == '\\' && tsp_fgetat(env, 1) == '"')
+ tsp_finc(env), len++;
+ tsp_finc(env); /* skip last closing quote */
s[len] = '\0'; /* TODO remember string length */
return mk_str(env, esc_str(s));
}
/* return read symbol */
static Val
-read_sym(Env env, Str str)
+read_sym(Env env)
{
int n = 1, i = 0;
char *sym = emalloc(n);
- for (; *str->d && issym(*str->d); str->d++) {
- sym[i++] = *str->d;
+ for (; tsp_fget(env) && issym(tsp_fget(env)); tsp_finc(env)) {
+ sym[i++] = tsp_fget(env);
if (i == n) {
n *= 2;
sym = erealloc(sym, n);
@@ -563,30 +561,30 @@ read_sym(Env env, Str str)
/* return read string containing a list */
static Val
-read_pair(Env env, Str str)
+read_pair(Env env)
{
Val a, b;
- skip_ws(str, 1);
- if (*str->d == ')') {
- str->d++;
- skip_ws(str, 1);
+ skip_ws(env, 1);
+ if (tsp_fget(env) == ')') {
+ tsp_finc(env);
+ skip_ws(env, 1);
return env->nil;
}
/* TODO simplify read_pair by supporting (. x) => x */
- if (!(a = tisp_read(env, str)))
+ if (!(a = tisp_read(env)))
return NULL;
- skip_ws(str, 1);
- if (*str->d == '.' && isdelim(str->d[1])) {
- str->d++;
- if (!(b = tisp_read(env, str)))
+ skip_ws(env, 1);
+ if (tsp_fget(env) == '.' && isdelim(tsp_fgetat(env,1))) {
+ tsp_finc(env);
+ if (!(b = tisp_read(env)))
return NULL;
- skip_ws(str, 1);
- if (*str->d != ')')
+ skip_ws(env, 1);
+ if (tsp_fget(env) != ')')
tsp_warn("did not find closing ')'");
- str->d++;
- skip_ws(str, 1);
+ tsp_finc(env);
+ skip_ws(env, 1);
} else {
- if (!(b = read_pair(env, str)))
+ if (!(b = read_pair(env)))
return NULL;
}
return mk_pair(a, b);
@@ -594,37 +592,37 @@ read_pair(Env env, Str str)
/* reads given string returning its tisp value */
Val
-tisp_read(Env env, Str str)
+tisp_read(Env env)
{
char *shorthands[] = {
"'", "quote",
"`", "quasiquote",
",", "unquote",
};
- skip_ws(str, 1);
- if (strlen(str->d) == 0)
+ skip_ws(env, 1);
+ if (strlen(env->file+env->filec) == 0)
return env->none;
- if (isnum(str->d))
- return read_num(str);
- if (*str->d == '"')
- return read_str(env, str);
+ if (isnum(env->file+env->filec))
+ return read_num(env);
+ if (tsp_fget(env) == '"')
+ return read_str(env);
for (int i = 0; i < LEN(shorthands); i += 2) {
- if (*str->d == *shorthands[i]) {
+ if (tsp_fget(env) == *shorthands[i]) {
Val v;
- str->d++;
- if (!(v = tisp_read(env, str)))
+ tsp_finc(env);
+ if (!(v = tisp_read(env)))
return NULL;
return mk_pair(mk_sym(env, shorthands[i+1]),
mk_pair(v, env->nil));
}
}
- if (issym(*str->d))
- return read_sym(env, str);
- if (*str->d == '(') {
- str->d++;
- return read_pair(env, str);
+ if (issym(tsp_fget(env)))
+ return read_sym(env);
+ if (tsp_fget(env) == '(') {
+ tsp_finc(env);
+ return read_pair(env);
}
- tsp_warnf("could not read given input '%s'", str->d);
+ tsp_warnf("could not read given input '%s'", env->file+env->filec);
}
/* return string containing contents of file name */
@@ -656,15 +654,17 @@ tisp_read_file(char *fname)
Val
tisp_parse_file(Env env, char *fname)
{
- struct Str str = { NULL };
Val ret = mk_pair(NULL, env->nil);
Val v, last = ret;
- char *file;
- if (!(file = tisp_read_file(fname)))
+ char *file = env->file;
+ size_t filec = env->filec;
+ if (!(env->file = tisp_read_file(fname)))
return ret;
- for (str.d = file; *str.d && (v = tisp_read(env, &str)); last = cdr(last))
+ for (env->filec = 0; tsp_fget(env) && (v = tisp_read(env)); last = cdr(last))
cdr(last) = mk_pair(v, env->nil);
- free(file);
+ free(env->file);
+ env->file = file;
+ env->filec = filec;
return cdr(ret);
}
@@ -1085,6 +1085,9 @@ tisp_env_init(size_t cap)
{
Env env = emalloc(sizeof(struct Env));
+ env->file = NULL;
+ env->filec = 0;
+
env->nil = emalloc(sizeof(struct Val));
env->nil->t = NIL;
env->none = emalloc(sizeof(struct Val));
@@ -1124,12 +1127,15 @@ tisp_env_init(size_t cap)
void
tisp_env_lib(Env env, char* lib)
{
- struct Str s;
Val v;
- if (!(s.d = strndup(lib, strlen(lib))))
- return;
- if ((v = tisp_read(env, &s)))
+ char *file = env->file;
+ size_t filec = env->filec;
+ env->file = lib;
+ env->filec = 0;
+ if ((v = tisp_read(env)))
tisp_eval_list(env, v);
+ env->file = file;
+ env->filec = filec;
}
void
diff --git a/tisp.h b/tisp.h
@@ -60,6 +60,10 @@
#define tsp_env_fn(NAME) tsp_env_name_fn(NAME, NAME)
#define tsp_include_tib(NAME) void tib_env_##NAME(Env)
+#define tsp_finc(ENV) ENV->filec++
+#define tsp_fgetat(ENV, O) ENV->file[ENV->filec+O]
+#define tsp_fget(ENV) tsp_fgetat(ENV,0)
+
#define car(P) ((P)->v.p.car)
#define cdr(P) ((P)->v.p.cdr)
#define caar(P) car(car(P))
@@ -74,11 +78,6 @@ struct Val;
typedef struct Val *Val;
typedef struct Env *Env;
-/* improved interface for a pointer to a string */
-typedef struct Str {
- char *d;
-} *Str;
-
/* fraction */
typedef struct {
double num, den;
@@ -138,6 +137,8 @@ struct Val {
};
struct Env {
+ char *file;
+ size_t filec;
Val none, nil, t;
Hash h, strs, syms;
void **libh;
@@ -157,7 +158,8 @@ Val mk_func(Type t, Val args, Val body, Env env);
Val mk_pair(Val a, Val b);
Val mk_list(Env env, int n, Val *a);
-Val tisp_read(Env env, Str str);
+Val tisp_read(Env env);
+Val tisp_read_line(Env env);
Val tisp_eval_list(Env env, Val v);
Val tisp_eval(Env env, Val v);
void tisp_print(FILE *f, Val v);