initial bytevector support
This commit is contained in:
parent
1675ad9f52
commit
aebf7f00f7
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef BLOB_H__
|
||||||
|
#define BLOB_H__
|
||||||
|
|
||||||
|
struct pic_blob {
|
||||||
|
PIC_OBJECT_HEADER
|
||||||
|
char *data;
|
||||||
|
int len;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define pic_blob_p(v) (pic_type(v) == PIC_TT_BLOB)
|
||||||
|
#define pic_blob_ptr(v) ((struct pic_blob *)(v).u.data)
|
||||||
|
|
||||||
|
struct pic_blob *pic_blob_new(pic_state *, char *, int len);
|
||||||
|
|
||||||
|
#endif
|
|
@ -41,6 +41,7 @@ enum pic_tt {
|
||||||
PIC_TT_PAIR,
|
PIC_TT_PAIR,
|
||||||
PIC_TT_STRING,
|
PIC_TT_STRING,
|
||||||
PIC_TT_VECTOR,
|
PIC_TT_VECTOR,
|
||||||
|
PIC_TT_BLOB,
|
||||||
PIC_TT_PROC,
|
PIC_TT_PROC,
|
||||||
PIC_TT_PORT,
|
PIC_TT_PORT,
|
||||||
PIC_TT_ENV
|
PIC_TT_ENV
|
||||||
|
@ -73,6 +74,7 @@ struct pic_vector {
|
||||||
|
|
||||||
struct pic_proc;
|
struct pic_proc;
|
||||||
struct pic_port;
|
struct pic_port;
|
||||||
|
struct pic_blob;
|
||||||
|
|
||||||
#define pic_obj_ptr(o) ((struct pic_object *)(o).u.data)
|
#define pic_obj_ptr(o) ((struct pic_object *)(o).u.data)
|
||||||
#define pic_pair_ptr(o) ((struct pic_pair *)(o).u.data)
|
#define pic_pair_ptr(o) ((struct pic_pair *)(o).u.data)
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "picrin.h"
|
||||||
|
#include "picrin/blob.h"
|
||||||
|
|
||||||
|
struct pic_blob *
|
||||||
|
pic_blob_new(pic_state *pic, char *dat, int len)
|
||||||
|
{
|
||||||
|
struct pic_blob *bv;
|
||||||
|
|
||||||
|
bv = (struct pic_blob *)pic_obj_alloc(pic, sizeof(struct pic_blob), PIC_TT_BLOB);
|
||||||
|
bv->data = strndup(dat, len);
|
||||||
|
bv->len = len;
|
||||||
|
return bv;
|
||||||
|
}
|
|
@ -518,7 +518,8 @@ codegen(codegen_state *state, pic_value obj, bool tailpos)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PIC_TT_STRING:
|
case PIC_TT_STRING:
|
||||||
case PIC_TT_VECTOR: {
|
case PIC_TT_VECTOR:
|
||||||
|
case PIC_TT_BLOB: {
|
||||||
int pidx;
|
int pidx;
|
||||||
pidx = pic->plen++;
|
pidx = pic->plen++;
|
||||||
pic->pool[pidx] = obj;
|
pic->pool[pidx] = obj;
|
||||||
|
|
|
@ -134,7 +134,8 @@ expand(pic_state *pic, pic_value obj, struct syntactic_env *env)
|
||||||
case PIC_TT_CHAR:
|
case PIC_TT_CHAR:
|
||||||
case PIC_TT_EOF:
|
case PIC_TT_EOF:
|
||||||
case PIC_TT_STRING:
|
case PIC_TT_STRING:
|
||||||
case PIC_TT_VECTOR: {
|
case PIC_TT_VECTOR:
|
||||||
|
case PIC_TT_BLOB: {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
case PIC_TT_PROC:
|
case PIC_TT_PROC:
|
||||||
|
|
8
src/gc.c
8
src/gc.c
|
@ -5,6 +5,7 @@
|
||||||
#include "picrin/irep.h"
|
#include "picrin/irep.h"
|
||||||
#include "picrin/proc.h"
|
#include "picrin/proc.h"
|
||||||
#include "picrin/port.h"
|
#include "picrin/port.h"
|
||||||
|
#include "picrin/blob.h"
|
||||||
|
|
||||||
#if GC_DEBUG
|
#if GC_DEBUG
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
|
@ -187,6 +188,9 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PIC_TT_BLOB: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
case PIC_TT_NIL:
|
case PIC_TT_NIL:
|
||||||
case PIC_TT_BOOL:
|
case PIC_TT_BOOL:
|
||||||
case PIC_TT_FLOAT:
|
case PIC_TT_FLOAT:
|
||||||
|
@ -285,6 +289,10 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
|
||||||
pic_free(pic, ((struct pic_vector *)obj)->data);
|
pic_free(pic, ((struct pic_vector *)obj)->data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PIC_TT_BLOB: {
|
||||||
|
pic_free(pic, ((struct pic_blob *)obj)->data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case PIC_TT_STRING: {
|
case PIC_TT_STRING: {
|
||||||
pic_free(pic, (void*)((struct pic_string *)obj)->str);
|
pic_free(pic, (void*)((struct pic_string *)obj)->str);
|
||||||
break;
|
break;
|
||||||
|
|
11
src/parse.y
11
src/parse.y
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "picrin.h"
|
#include "picrin.h"
|
||||||
#include "picrin/pair.h"
|
#include "picrin/pair.h"
|
||||||
|
#include "picrin/blob.h"
|
||||||
|
|
||||||
#define YYERROR_VERBOSE 1
|
#define YYERROR_VERBOSE 1
|
||||||
|
|
||||||
|
@ -35,6 +36,10 @@ void yylex_destroy();
|
||||||
double f;
|
double f;
|
||||||
char *cstr;
|
char *cstr;
|
||||||
char c;
|
char c;
|
||||||
|
struct {
|
||||||
|
char *dat;
|
||||||
|
int len, capa;
|
||||||
|
} blob;
|
||||||
pic_value datum;
|
pic_value datum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +49,7 @@ void yylex_destroy();
|
||||||
%token <f> tFLOAT
|
%token <f> tFLOAT
|
||||||
%token <cstr> tSYMBOL tSTRING
|
%token <cstr> tSYMBOL tSTRING
|
||||||
%token <c> tCHAR
|
%token <c> tCHAR
|
||||||
|
%token <blob> tBYTEVECTOR
|
||||||
|
|
||||||
%type <datum> program_data
|
%type <datum> program_data
|
||||||
%type <datum> datum simple_datum compound_datum abbrev
|
%type <datum> datum simple_datum compound_datum abbrev
|
||||||
|
@ -111,6 +117,11 @@ simple_datum
|
||||||
{
|
{
|
||||||
$$ = pic_char_value($1);
|
$$ = pic_char_value($1);
|
||||||
}
|
}
|
||||||
|
| tBYTEVECTOR
|
||||||
|
{
|
||||||
|
$$ = pic_obj_value(pic_blob_new(p->pic, $1.dat, $1.len));
|
||||||
|
free($1.dat);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
compound_datum
|
compound_datum
|
||||||
|
|
11
src/port.c
11
src/port.c
|
@ -4,6 +4,7 @@
|
||||||
#include "picrin.h"
|
#include "picrin.h"
|
||||||
#include "picrin/proc.h"
|
#include "picrin/proc.h"
|
||||||
#include "picrin/port.h"
|
#include "picrin/port.h"
|
||||||
|
#include "picrin/blob.h"
|
||||||
|
|
||||||
static void write_pair(pic_state *pic, struct pic_pair *pair);
|
static void write_pair(pic_state *pic, struct pic_pair *pair);
|
||||||
static void write_str(pic_state *pic, struct pic_string *str);
|
static void write_str(pic_state *pic, struct pic_string *str);
|
||||||
|
@ -67,6 +68,16 @@ write(pic_state *pic, pic_value obj)
|
||||||
}
|
}
|
||||||
printf(")");
|
printf(")");
|
||||||
break;
|
break;
|
||||||
|
case PIC_TT_BLOB:
|
||||||
|
printf("#u8(");
|
||||||
|
for (i = 0; i < pic_blob_ptr(obj)->len; ++i) {
|
||||||
|
printf("%d", pic_blob_ptr(obj)->data[i]);
|
||||||
|
if (i + 1 < pic_blob_ptr(obj)->len) {
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf(")");
|
||||||
|
break;
|
||||||
case PIC_TT_ENV:
|
case PIC_TT_ENV:
|
||||||
printf("#<env %p>", pic_env_ptr(obj));
|
printf("#<env %p>", pic_env_ptr(obj));
|
||||||
break;
|
break;
|
||||||
|
|
25
src/scan.l
25
src/scan.l
|
@ -33,6 +33,9 @@ infnan "+inf.0"|"-inf.0"|"+nan.0"|"-nan.0"
|
||||||
/* string */
|
/* string */
|
||||||
%x STRING
|
%x STRING
|
||||||
|
|
||||||
|
/* bytevector */
|
||||||
|
%x BYTEVECTOR
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
[ \t\n\r] /* skip whitespace */
|
[ \t\n\r] /* skip whitespace */
|
||||||
|
@ -83,6 +86,28 @@ infnan "+inf.0"|"-inf.0"|"+nan.0"|"-nan.0"
|
||||||
return tCHAR;
|
return tCHAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"#u8(" {
|
||||||
|
BEGIN(BYTEVECTOR);
|
||||||
|
yylvalp->blob.len = 0;
|
||||||
|
yylvalp->blob.capa = 10;
|
||||||
|
yylvalp->blob.dat = calloc(10, 1);
|
||||||
|
}
|
||||||
|
<BYTEVECTOR>[ \r\n\t]
|
||||||
|
<BYTEVECTOR>{uinteger} {
|
||||||
|
int i = atoi(yytext);
|
||||||
|
if (0 > i || i > 255)
|
||||||
|
REJECT;
|
||||||
|
yylvalp->blob.dat[yylvalp->blob.len++] = (char)i;
|
||||||
|
if (yylvalp->blob.len > yylvalp->blob.capa) {
|
||||||
|
yylvalp->blob.capa *= 2;
|
||||||
|
yylvalp->blob.dat = realloc(yylvalp->blob.dat, yylvalp->blob.capa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<BYTEVECTOR>")" {
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
return tBYTEVECTOR;
|
||||||
|
}
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in New Issue