add FILE* to parser
This commit is contained in:
parent
0e6bc88cab
commit
3ae8c663e7
1
error.c
1
error.c
@ -1,7 +1,6 @@
|
||||
#include "dat.h"
|
||||
#include "fn.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
|
||||
5
fn.h
5
fn.h
@ -1,6 +1,7 @@
|
||||
#include <stdio.h>
|
||||
/* parser.c */
|
||||
Object* nextexpr(void);
|
||||
void skipline(void);
|
||||
Object* nextexpr(FILE*);
|
||||
void skipline(FILE*);
|
||||
|
||||
/* eval.c */
|
||||
Object* eval(Object *env, Object *expr);
|
||||
|
||||
1
gc.c
1
gc.c
@ -3,7 +3,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
15
main.c
15
main.c
@ -1,7 +1,6 @@
|
||||
#include "dat.h"
|
||||
#include "fn.h"
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
|
||||
jmp_buf *errptr;
|
||||
GC *gc;
|
||||
@ -63,16 +62,17 @@ printexpr(Object *obj)
|
||||
}
|
||||
|
||||
static void
|
||||
loop(void)
|
||||
loop(Object *env, FILE *f)
|
||||
{
|
||||
Object *env = newenv(gc, &Nil, &Nil, &Nil);
|
||||
jmp_buf buf;
|
||||
errptr = &buf;
|
||||
if(setjmp(buf) == 1){
|
||||
skipline();
|
||||
if(feof(f))
|
||||
return;
|
||||
skipline(f);
|
||||
}
|
||||
while(1){
|
||||
Object *res = nextexpr();
|
||||
Object *res = nextexpr(f);
|
||||
printexpr(res);
|
||||
res = eval(env, res);
|
||||
printgc("status", gc);
|
||||
@ -87,6 +87,7 @@ loop(void)
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
gc = newgc(&argc, 4000);
|
||||
loop();
|
||||
gc = newgc(&argc, 400);
|
||||
Object *env = newenv(gc, &Nil, &Nil, &Nil);
|
||||
loop(env, stdin);
|
||||
}
|
||||
|
||||
121
parser.c
121
parser.c
@ -1,6 +1,5 @@
|
||||
#include "dat.h"
|
||||
#include "fn.h"
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -8,177 +7,177 @@
|
||||
|
||||
const char symbolchars[] = "!*/%-=+<>'";
|
||||
|
||||
static Object* lparlist(void);
|
||||
static Object* list(void);
|
||||
static Object* lparlist(FILE *);
|
||||
static Object* list(FILE *);
|
||||
|
||||
static char
|
||||
get(void)
|
||||
get(FILE *f)
|
||||
{
|
||||
char c = getchar();
|
||||
char c = fgetc(f);
|
||||
if(c == EOF)
|
||||
panic("EOF");
|
||||
error("EOF");
|
||||
return c;
|
||||
}
|
||||
|
||||
static void
|
||||
expect(char x)
|
||||
expect(FILE *f, char x)
|
||||
{
|
||||
char y = get();
|
||||
char y = get(f);
|
||||
if(x != y)
|
||||
error("expected '%c', actual '%c'", x, y);
|
||||
}
|
||||
|
||||
static char
|
||||
lookup(void)
|
||||
lookup(FILE *f)
|
||||
{
|
||||
char c = get();
|
||||
ungetc(c, stdin);
|
||||
char c = get(f);
|
||||
ungetc(c, f);
|
||||
return c;
|
||||
}
|
||||
|
||||
/* skip space */
|
||||
static char
|
||||
slookup(void)
|
||||
slookup(FILE *f)
|
||||
{
|
||||
char c = -1;
|
||||
while(1){
|
||||
c = get();
|
||||
c = get(f);
|
||||
if(isspace(c) == 0)
|
||||
break;
|
||||
}
|
||||
ungetc(c, stdin);
|
||||
ungetc(c, f);
|
||||
return c;
|
||||
}
|
||||
|
||||
static Object*
|
||||
symbol(char c)
|
||||
symbol(FILE *f, char c)
|
||||
{
|
||||
char buf[SYMBOL_LEN+1] = {0,};
|
||||
int len = 0;
|
||||
buf[len++] = c;
|
||||
while(isalnum(lookup()) || strchr(symbolchars, lookup())){
|
||||
while(isalnum(lookup(f)) || strchr(symbolchars, lookup(f))){
|
||||
if(len >= sizeof(buf)-1)
|
||||
error("Symbol too long");
|
||||
buf[len++] = get();
|
||||
buf[len++] = get(f);
|
||||
}
|
||||
buf[len] = 0;
|
||||
return newsymbol(gc, buf, len);
|
||||
}
|
||||
|
||||
static long
|
||||
number(void)
|
||||
number(FILE *f)
|
||||
{
|
||||
long val = get() - '0';
|
||||
while(isdigit(lookup()))
|
||||
val = val * 10 + (get() - '0');
|
||||
long val = get(f) - '0';
|
||||
while(isdigit(lookup(f)))
|
||||
val = val * 10 + (get(f) - '0');
|
||||
return val;
|
||||
}
|
||||
|
||||
static Object*
|
||||
quote(void)
|
||||
quote(FILE *f)
|
||||
{
|
||||
Object *car = &Quote;
|
||||
Object *ccdr = list();
|
||||
Object *ccdr = list(f);
|
||||
Object *cdr = newcons(gc, ccdr, &Nil);
|
||||
return newcons(gc, car, cdr);
|
||||
}
|
||||
|
||||
static Object*
|
||||
string(void)
|
||||
string(FILE *f)
|
||||
{
|
||||
Object *str = newstr(gc, 16);
|
||||
while(lookup() != '\"'){
|
||||
str = strputc(str, get());
|
||||
while(lookup(f) != '\"'){
|
||||
str = strputc(str, get(f));
|
||||
}
|
||||
expect('\"');
|
||||
expect(f, '\"');
|
||||
return str;
|
||||
}
|
||||
|
||||
static Object*
|
||||
atom(char c)
|
||||
atom(FILE *f, char c)
|
||||
{
|
||||
if(isdigit(c))
|
||||
return newint(gc, number());
|
||||
get();
|
||||
return newint(gc, number(f));
|
||||
get(f);
|
||||
if(c == '-'){
|
||||
if(isdigit(lookup()))
|
||||
return newint(gc, -number());
|
||||
if(isdigit(lookup(f)))
|
||||
return newint(gc, -number(f));
|
||||
else
|
||||
return symbol('-');
|
||||
return symbol(f, '-');
|
||||
}
|
||||
if(c == '"'){
|
||||
return string();
|
||||
return string(f);
|
||||
}
|
||||
if(isalpha(c) || strchr(symbolchars, c)){
|
||||
return symbol(c);
|
||||
return symbol(f, c);
|
||||
}
|
||||
error("bad char in list '%c'", c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Object*
|
||||
lparlist(void)
|
||||
lparlist(FILE *f)
|
||||
{
|
||||
Object *car = 0;
|
||||
Object *cdr = 0;
|
||||
char c = slookup();
|
||||
char c = slookup(f);
|
||||
switch(c){
|
||||
case '\'':
|
||||
get();
|
||||
car = quote();
|
||||
cdr = lparlist();
|
||||
get(f);
|
||||
car = quote(f);
|
||||
cdr = lparlist(f);
|
||||
return newcons(gc, car, cdr);
|
||||
case '.':
|
||||
get();
|
||||
return list();
|
||||
get(f);
|
||||
return list(f);
|
||||
case '(':
|
||||
car = list();
|
||||
cdr = lparlist();
|
||||
car = list(f);
|
||||
cdr = lparlist(f);
|
||||
return newcons(gc, car, cdr);
|
||||
case ')':
|
||||
return &Nil;
|
||||
}
|
||||
car = atom(c);
|
||||
cdr = lparlist();
|
||||
car = atom(f, c);
|
||||
cdr = lparlist(f);
|
||||
return newcons(gc, car ,cdr);
|
||||
}
|
||||
|
||||
static Object*
|
||||
list(void)
|
||||
list(FILE *f)
|
||||
{
|
||||
char c = slookup();
|
||||
char c = slookup(f);
|
||||
switch(c){
|
||||
case '\'':
|
||||
get();
|
||||
return quote();
|
||||
get(f);
|
||||
return quote(f);
|
||||
case '(':{
|
||||
get();
|
||||
Object *obj = lparlist();
|
||||
slookup();
|
||||
expect(')');
|
||||
get(f);
|
||||
Object *obj = lparlist(f);
|
||||
slookup(f);
|
||||
expect(f, ')');
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return atom(c);
|
||||
return atom(f, c);
|
||||
}
|
||||
|
||||
void
|
||||
skipline(void)
|
||||
skipline(FILE *f)
|
||||
{
|
||||
for(;;){
|
||||
switch(get()){
|
||||
switch(get(f)){
|
||||
case '\n':
|
||||
return;
|
||||
case '\r':
|
||||
if(lookup() == '\n')
|
||||
get();
|
||||
if(lookup(f) == '\n')
|
||||
get(f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object*
|
||||
nextexpr(void)
|
||||
nextexpr(FILE *f)
|
||||
{
|
||||
return list();
|
||||
return list(f);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user