add vectors.

This commit is contained in:
Jan Nieuwenhuizen 2016-07-11 10:38:02 +02:00
parent 9a699da5c5
commit 081cb4a94f
6 changed files with 147 additions and 20 deletions

View file

@ -1,6 +1,6 @@
.PHONY: all check default .PHONY: all check default
CFLAGS=-std=c99 -O3 -finline-functions CFLAGS=-std=c99 -O3 -finline-functions
#CFLAGS=-g #CFLAGS=-std=c99 -g
default: all default: all
@ -15,7 +15,7 @@ mes.h: mes.c GNUmakefile
while read f; do\ while read f; do\
fun=$$(echo $$f | sed -e 's,^scm [*],,' -e 's,{.*,,');\ fun=$$(echo $$f | sed -e 's,^scm [*],,' -e 's,{.*,,');\
name=$$(echo $$fun | sed -e 's,^scm [\*],,' | grep -o '^[^ ]*');\ name=$$(echo $$fun | sed -e 's,^scm [\*],,' | grep -o '^[^ ]*');\
scm_name=$$(echo $$name | sed -e 's,_p$$,?,' -e 's,_x$$,!,' -e 's,^builtin_,,' -re 's,(.*)_$$,c:\1,' | sed \ scm_name=$$(echo $$name | sed -e 's,_to_,->,' -e 's,_p$$,?,' -e 's,_x$$,!,' -e 's,^builtin_,,' -re 's,(.*)_$$,c:\1,' | sed \
-e 's,^divide$$,/,'\ -e 's,^divide$$,/,'\
-e 's,^is?$$,=,'\ -e 's,^is?$$,=,'\
-e 's,^less?$$,<,'\ -e 's,^less?$$,<,'\

18
TODO
View file

@ -10,27 +10,27 @@ quote
set! set!
** implement minimal needed rsr3/rsr4: ** implement minimal needed rsr3/rsr4:
v "string" v "string"
#(v e c t o r) v #(v e c t o r)
#\CHAR #\CHAR
assq assq
call-with-values call-with-values
v char? v char?
v length v length
v list v list
list->vector v list->vector
make-vector v make-vector
memv memv
v string v string
v string-append v string-append
v string? v string?
v symbol? v symbol?
values values
vector v vector
vector->list v vector->list
vector-length v vector-length
vector-ref v vector-ref
vector-set! v vector-set!
vector? v vector?
... possibly also: any, each, unquote-splicing, ... ... possibly also: any, each, unquote-splicing, ...
** implement extras: (gensym) ** implement extras: (gensym)
** hook-up sc-expand, see guile-1.0?: scheme:eval-transformer ** hook-up sc-expand, see guile-1.0?: scheme:eval-transformer

101
mes.c
View file

@ -42,7 +42,7 @@
#define QUOTE_SUGAR 1 #define QUOTE_SUGAR 1
#endif #endif
enum type {STRING, SYMBOL, CHAR, NUMBER, PAIR, enum type {CHAR, NUMBER, PAIR, STRING, SYMBOL, VECTOR,
FUNCTION0, FUNCTION1, FUNCTION2, FUNCTION3, FUNCTIONn}; FUNCTION0, FUNCTION1, FUNCTION2, FUNCTION3, FUNCTIONn};
struct scm_t; struct scm_t;
typedef struct scm_t* (*function0_t) (void); typedef struct scm_t* (*function0_t) (void);
@ -56,6 +56,7 @@ typedef struct scm_t {
union { union {
char *name; char *name;
struct scm_t* car; struct scm_t* car;
int length;
}; };
union { union {
int value; int value;
@ -65,6 +66,7 @@ typedef struct scm_t {
function3_t function3; function3_t function3;
functionn_t functionn; functionn_t functionn;
struct scm_t* cdr; struct scm_t* cdr;
struct scm_t** vector;
}; };
} scm; } scm;
@ -150,6 +152,8 @@ eq_p (scm *x, scm *y)
&& y->type != CHAR && y->type != CHAR
&& x->type != NUMBER && x->type != NUMBER
&& y->type != NUMBER && y->type != NUMBER
&& x->type != VECTOR
&& y->type != VECTOR
&& atom_p (y) == &scm_t && atom_p (y) == &scm_t
&& !strcmp (x->name, y->name))) && !strcmp (x->name, y->name)))
? &scm_t : &scm_f; ? &scm_t : &scm_f;
@ -308,6 +312,8 @@ eval_ (scm *e, scm *a)
return e; return e;
else if (e->type == STRING) else if (e->type == STRING)
return e; return e;
else if (e->type == VECTOR)
return e;
else if (atom_p (e) == &scm_t) { else if (atom_p (e) == &scm_t) {
scm *y = assoc (e, a); scm *y = assoc (e, a);
if (y == &scm_f) { if (y == &scm_f) {
@ -445,6 +451,12 @@ symbol_p (scm *x)
return x->type == SYMBOL ? &scm_t : &scm_f; return x->type == SYMBOL ? &scm_t : &scm_f;
} }
scm *
vector_p (scm *x)
{
return x->type == VECTOR ? &scm_t : &scm_f;
}
scm * scm *
display (scm *x) display (scm *x)
{ {
@ -523,6 +535,16 @@ make_symbol (char const *s)
return p; return p;
} }
scm *
make_vector (int n)
{
scm *p = malloc (sizeof (scm));
p->type = VECTOR;
p->length = n;
p->vector = malloc (n * sizeof (scm*));
return p;
}
scm * scm *
string (scm *x/*...*/) string (scm *x/*...*/)
{ {
@ -572,6 +594,44 @@ length (scm *x)
return make_number (n); return make_number (n);
} }
#if 0
scm *
builtin_list (scm *x/*...*/) // int
{
return x;
}
scm *
vector (scm *x/*...*/) // int
{
return list_to_vector (x);
}
#endif
scm *
vector_length (scm *x)
{
assert (x->type == VECTOR);
return make_number (x->length);
}
scm *
vector_ref (scm *x, scm *i)
{
assert (x->type == VECTOR);
assert (i->value < x->length);
return x->vector[i->value];
}
scm *
vector_set_x (scm *x, scm *i, scm *e)
{
assert (x->type == VECTOR);
assert (i->value < x->length);
x->vector[i->value] = e;
return &scm_unspecified;
}
scm * scm *
lookup (char *x, scm *a) lookup (char *x, scm *a)
{ {
@ -620,6 +680,29 @@ list2str (scm *l)
return buf; return buf;
} }
scm*
list_to_vector (scm *x)
{
int n = length (x)->value;
scm *v = make_vector (n);
scm **p = v->vector;
while (x != &scm_nil)
{
*p++ = car (x);
x = cdr (x);
}
return v;
}
scm*
vector_to_list (scm *v)
{
scm *x = &scm_nil;
for (int i = 0; i < v->length; i++)
x = append (x, cons (v->vector[i], &scm_nil));
return x;
}
scm * scm *
builtin_lookup (scm *l, scm *a) builtin_lookup (scm *l, scm *a)
{ {
@ -678,6 +761,12 @@ display_helper (scm *x, bool cont, char *sep, bool quote)
} }
if (!cont) printf (")"); if (!cont) printf (")");
} }
else if (x->type == VECTOR) {
printf ("#(");
for (int i = 0; i < x->length; i++)
display_helper (x->vector[i], true, i ? " " : "", false);
printf (")");
}
else if (atom_p (x) == &scm_t) printf ("%s", x->name); else if (atom_p (x) == &scm_t) printf ("%s", x->name);
return &scm_unspecified; return &scm_unspecified;
@ -743,7 +832,7 @@ readword (int c, char* w, scm *a)
if (c == ' ') return readword ('\n', w, a); if (c == ' ') return readword ('\n', w, a);
if (c == '"' && !w) return readstring (); if (c == '"' && !w) return readstring ();
if (c == '"') {ungetchar (c); return lookup (w, a);} if (c == '"') {ungetchar (c); return lookup (w, a);}
if (c == '(' && !w) return readlis (a); if (c == '(' && !w) return readlist (a);
if (c == '(') {ungetchar (c); return lookup (w, a);} if (c == '(') {ungetchar (c); return lookup (w, a);}
if (c == ')' && !w) {ungetchar (c); return &scm_nil;} if (c == ')' && !w) {ungetchar (c); return &scm_nil;}
if (c == ')') {ungetchar (c); return lookup (w, a);} if (c == ')') {ungetchar (c); return lookup (w, a);}
@ -758,6 +847,8 @@ readword (int c, char* w, scm *a)
&scm_nil));} &scm_nil));}
if (c == ';') {readcomment (c); return readword ('\n', w, a);} if (c == ';') {readcomment (c); return readword ('\n', w, a);}
if (c == '#' && peekchar () == '\\') {getchar (); return readchar ();} if (c == '#' && peekchar () == '\\') {getchar (); return readchar ();}
if (c == '#' && !w && peekchar () == '(') {getchar (); return list_to_vector (readlist (a));}
if (c == '#' && peekchar () == '(') {ungetchar (c); return lookup (w, a);}
if (c == '#' && peekchar () == '!') {getchar (); readblock (getchar ()); return readword (getchar (), w, a);} if (c == '#' && peekchar () == '!') {getchar (); readblock (getchar ()); return readword (getchar (), w, a);}
char buf[256] = {0}; char buf[256] = {0};
char ch = c; char ch = c;
@ -822,15 +913,15 @@ eat_whitespace (int c)
} }
scm * scm *
readlis (scm *a) readlist (scm *a)
{ {
int c = getchar (); int c = getchar ();
c = eat_whitespace (c); c = eat_whitespace (c);
if (c == ')') return &scm_nil; if (c == ')') return &scm_nil;
scm *w = readword (c, 0, a); scm *w = readword (c, 0, a);
if (w == &scm_dot) if (w == &scm_dot)
return car (readlis (a)); return car (readlist (a));
return cons (w, readlis (a)); return cons (w, readlist (a));
} }
scm * scm *

10
mes.mes
View file

@ -126,6 +126,7 @@
((char? e) e) ((char? e) e)
((number? e) e) ((number? e) e)
((string? e) e) ((string? e) e)
((vector? e) e)
((atom? e) (cdr (assoc e a))) ((atom? e) (cdr (assoc e a)))
((builtin? e) e) ((builtin? e) e)
((atom? (car e)) ((atom? (car e))
@ -176,7 +177,7 @@
((eq? c 32) ;; \space ((eq? c 32) ;; \space
(readword 10 w a)) (readword 10 w a))
((eq? c 40) ;; ( ((eq? c 40) ;; (
(cond ((eq? w '()) (readlis a)) (cond ((eq? w '()) (readlist a))
(#t (ungetchar c) (lookup w a)))) (#t (ungetchar c) (lookup w a))))
((eq? c 41) ;; ) ((eq? c 41) ;; )
(cond ((eq? w '()) (ungetchar c) w) (cond ((eq? w '()) (ungetchar c) w)
@ -194,6 +195,7 @@
(getchar) (getchar)
(readblock (getchar)) (readblock (getchar))
(readword 10 w a)) (readword 10 w a))
;; TODO: char, vector
(#t (readword (getchar) (append w (cons c '())) a)))) (#t (readword (getchar) (append w (cons c '())) a))))
(#t (readword (getchar) (append w (cons c '())) a)))) (#t (readword (getchar) (append w (cons c '())) a))))
@ -211,15 +213,15 @@
((eq? (peekchar) 35) (getchar) (eat-whitespace)) ((eq? (peekchar) 35) (getchar) (eat-whitespace))
(#t #t))) (#t #t)))
(define (readlis a) (define (readlist a)
;; (display 'mes-readlis:) ;; (display 'mes-readlist:)
;; (newline) ;; (newline)
(eat-whitespace) (eat-whitespace)
(cond ((eq? (peekchar) 41) ;; ) (cond ((eq? (peekchar) 41) ;; )
(getchar) (getchar)
'()) '())
;; TODO *dot* ;; TODO *dot*
(#t (cons (readword (getchar) '() a) (readlis a))))) (#t (cons (readword (getchar) '() a) (readlist a)))))
(define (readcomment c) (define (readcomment c)
(cond ((eq? c 10) ;; \n (cond ((eq? c 10) ;; \n

View file

@ -22,6 +22,7 @@
;; http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf ;; http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf
(define (list . rest) rest) (define (list . rest) rest)
(define (vector . rest) (list->vector rest))
(define (+ x y) (- x (- 0 y))) (define (+ x y) (- x (- 0 y)))

View file

@ -189,4 +189,37 @@
(display (length '(a b c))) (display (length '(a b c)))
(newline) (newline)
#(a b c)
(display #(0 1 2))
(newline)
(define v #("a" "b" "c"))
(display "vector?: ")
(display (vector? v))
(newline)
(display "length of ")
(display v)
(display ": ")
(display (vector-length v))
(newline)
(display "as list: ")
(define lv (vector->list v))
(display lv)
(newline)
(display "again as vector: ")
(display (list->vector lv))
(newline)
(display "(vector 0 1 2): ")
(display (vector 0 1 2))
(newline)
(display "v[1]: ")
(display (vector-ref v 1))
(newline)
(display "v[1]=q: ")
(vector-set! v 1 'q)
(display v)
(newline)
'() '()