Skip to content

Instantly share code, notes, and snippets.

@sawaken
Created November 6, 2014 17:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sawaken/96a5b135d796796baa43 to your computer and use it in GitHub Desktop.
Save sawaken/96a5b135d796796baa43 to your computer and use it in GitHub Desktop.
An easy functional-reactive-programming sample written in C.
#include <stdio.h>
#include <stdlib.h>
#include "frp_sample_lib.h"
ReactiveIntList FRPCursor(ReactiveIntList input)
{
ReactiveInt up, down, left, right, x, y;
up = ReactiveLiftList(UpCount, input);
down = ReactiveLiftList(DownCount, input);
left = ReactiveLiftList(LeftCount, input);
right = ReactiveLiftList(RightCount, input);
x = ReactiveSub(right, left);
y = ReactiveSub(up, down);
return ReactivePair(x, y);
}
void main()
{
ReactiveIntList input = NewReactiveIntList(NULL, NULL);
ReactiveIntList output = FRPCursor(input);
char buf[100];
while (fgets(buf, 100, stdin) != NULL) {
AssignInput(input, StrToReactiveIntList(buf));
printf("(%d, %d)\n", PullFirst(output), PullSecond(output));
}
}
#include "frp_sample_lib.h"
ReactiveInt NewReactiveInt(int n, int (*operator)(List), ReactiveIntList rlist)
{
ReactiveInt ri = malloc(sizeof(struct ReactiveInt));
ri->n = n;
ri->operator = operator;
ri->rlist = rlist;
return ri;
}
ReactiveIntList NewReactiveIntList(ReactiveInt ri, ReactiveIntList next)
{
ReactiveIntList rip = malloc(sizeof(struct ReactiveIntList));
rip->ri = ri;
rip->next = next;
return rip;
}
List NewList(int n, List next)
{
List ls = malloc(sizeof(struct List));
ls->n = n;
ls->next = next;
return ls;
}
int PullValue(ReactiveInt a)
{
if (a->operator == NULL) {
return a->n;
} else {
return a->operator(ToList(a->rlist));
}
}
List ToList(ReactiveIntList rlist)
{
if (rlist == NULL)
return NULL;
else
return NewList(PullValue(rlist->ri), ToList(rlist->next));
}
ReactiveIntList StrToReactiveIntList(const char* buf)
{
if (*buf == '\0')
return NULL;
else
return NewReactiveIntList(ReactiveNum((int)(*buf)), StrToReactiveIntList(buf + 1));
}
void AssignInput(ReactiveIntList input, ReactiveIntList assigned)
{
input->ri = assigned->ri;
input->next = assigned->next;
}
int Sub(List ls)
{
return ls->n - ls->next->n;
}
int UpCount(List ls)
{
return ls == NULL ? 0 : ((char)ls->n == 'A') + UpCount(ls->next);
}
int DownCount(List ls)
{
return ls == NULL ? 0 : ((char)ls->n == 'B') + DownCount(ls->next);
}
int LeftCount(List ls)
{
return ls == NULL ? 0 : ((char)ls->n == 'D') + LeftCount(ls->next);
}
int RightCount(List ls)
{
return ls == NULL ? 0 : ((char)ls->n == 'C') + RightCount(ls->next);
}
#include <stdlib.h>
typedef struct ReactiveInt* ReactiveInt;
typedef struct ReactiveIntList* ReactiveIntList;
typedef struct List* List;
struct ReactiveInt
{
int n;
int (*operator)(List);
ReactiveIntList rlist;
};
struct ReactiveIntList
{
ReactiveInt ri;
ReactiveIntList next;
};
struct List
{
int n;
List next;
};
#define ReactiveNum(n) NewReactiveInt((n), NULL, NULL)
#define ReactiveSub(l, r) NewReactiveInt(0, Sub, NewReactiveIntList((l), NewReactiveIntList((r), NULL)))
#define ReactiveLiftList(f, ls) NewReactiveInt(0, (f), (ls))
#define ReactivePair(x, y) NewReactiveIntList((x), NewReactiveIntList((y), NULL))
#define PullFirst(pair) PullValue((pair)->ri)
#define PullSecond(pair) PullValue((pair)->next->ri)
ReactiveInt NewReactiveInt(int n, int (*operator)(List), ReactiveIntList rlist);
ReactiveIntList NewReactiveIntList(ReactiveInt ri, ReactiveIntList next);
List NewList(int n, List next);
int PullValue(ReactiveInt a);
List ToList(ReactiveIntList rlist);
ReactiveIntList StrToReactiveIntList(const char* buf);
void AssignInput(ReactiveIntList input, ReactiveIntList assigned);
int Sub(List ls);
int UpCount(List ls);
int DownCount(List ls);
int LeftCount(List ls);
int RightCount(List ls);
object_files = \
frp_sample.o \
frp_sample_lib.o
.SUFFIXES : .c
frp_sample: $(object_files)
gcc -Wall -o frp_sample $(object_files)
.PHONY: clean
clean:
rm -f frp_sample *.o
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment