Skip to content

Instantly share code, notes, and snippets.

@geoffrasb
Last active December 27, 2015 20:39
Show Gist options
  • Save geoffrasb/7385956 to your computer and use it in GitHub Desktop.
Save geoffrasb/7385956 to your computer and use it in GitHub Desktop.
little typing sys
/*
for each type:
1. Define in Type as "newtype_t".
2. Define constructors.
If struct is needed, name it "Newtype_t".
3. Define "_deNewtype", which typed as "Data -> void".
*/
#include<assert.h>
#define tc(d,t) assert((d).type == (t));
#define tc2(d1,d2,t) assert((d1).type == (t) && (d2).type == (t))
#define tc3(d1,d2,d3,t) assert((d1).type == (t) && (d2).type == (t) && (d3).type == (t))
#define nil NULL
typedef enum
{ bottom_t
, boolean_t
, pair_t
, int_t
, cons_t
} Type;
typedef struct Data{
Type type;
void* cont;
} Data;
void _dePair(Data);
void _deInt(Data);
void _deCons(Data);
void deData(Data d){
switch(d.type){
case int_t: _deInt(d); break;
case pair_t: _dePair(d); break;
case cons_t: _deCons(d); break;
default:
break; } }
Data Bot(){
Data res = { bottom_t, NULL };
return res; }
int isBot(Data d){
if(d.type==bottom_t) return 1;
else return 0; }
Data True(){
Data res = {boolean_t, (void*)1};
return res; }
Data False(){
Data res = {boolean_t, (void*)0};
return res; }
/*
int prop(Data d){ tc(d,boolean_t);
return (int)d.cont; }
*/
Data Int(int a){
int *i = (int*)malloc(sizeof(int));
*i = a;
Data res = {int_t, (void*)i};
return res; }
void _deInt(Data d){ tc(d,int_t);
free((int*)d.cont); }
int pureInt(Data d){ tc(d,int_t);
return *((int*)d.cont); }
typedef struct Pair_t{
Data fst;
Data snd;
} Pair_t;
Data Pair(Data fst,Data snd){
Pair_t*p = (Pair_t*)malloc(sizeof(Pair_t));
Data res = {pair_t, (void*)p};
return res; }
void _dePair(Data d){ tc(d,pair_t);
deData(((Pair_t*)(d.cont))->fst);
deData(((Pair_t*)(d.cont))->snd);
free((Pair_t*)(d.cont)); }
Data fst(Data p){ tc(p,pair_t);
return ((Pair_t*)p.cont) -> fst; }
Data snd(Data p){ tc(p,pair_t);
return ((Pair_t*)p.cont) -> snd; }
typedef struct Cons_t{
Data car;
Data cdr;
} Cons_t;
Data
Empty(){
Data res = { cons_t, nil };
return res; }
Data
Cons(Data a, Data c){ tc(c,cons_t);
Cons_t*nc = (Cons_t*)malloc(sizeof(Cons_t));
nc->car = a;
nc->cdr = c;
Data res = { cons_t, (void*)nc };
return res; }
int
isEmpty(Data c){ tc(c,cons_t);
if(c.cont==nil) return 1;
else return 0; }
Data
car(Data c){ tc(c,cons_t);
if(isEmpty(c)) return Bot();
else return ((Cons_t*)c.cont)->car; }
Data
cdr(Data c){ tc(c,cons_t);
if(isEmpty(c)) return Bot();
else return ((Cons_t*)c.cont)->cdr; }
void
_deCons(Data c){ tc(c,cons_t);
if(!isEmpty(c)){
deData(car(c));
free((Cons_t*)c.cont);
_deCons(cdr(c)); } }
Data
setAsLast(Data c){ tc(c,cons_t);
if(!isEmpty(c)){
((Cons_t*)c.cont)->cdr = Empty(); }
return c;}
Data
setCar(Data c,Data a){ tc(c,cons_t);
if(!isEmpty(c)){
((Cons_t*)c.cont)->car = a;}
return c; }
Data
setCdr(Data c, Data c1){ tc2(c,c1,cons_t);
if(!isEmpty(c)){
((Cons_t*)c.cont)->cdr = c1; }
return c; }
/* mapping and folding patterns*/
/* map f lst =>
while(!isEmpty(lst)){
***
lst = cdr(lst) }
*/
/* fold f seed lst =>
Data seed;
while(!isEmpty(lst)){
seed = f seed car(lst)
lst = cdr(lst) }
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment