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