Created
June 12, 2019 14:34
-
-
Save mbillingr/e314aae5e57994096bc09c7fd76efbc7 to your computer and use it in GitHub Desktop.
LISP-ish low level experiments in C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdbool.h> | |
#include <memory.h> | |
#define NIL 0 | |
#define POINTER 1 | |
#define NUMBER 2 | |
typedef struct TaggedCell TaggedCell; | |
struct TaggedCell { | |
unsigned char tag; | |
union { | |
void* ptr; | |
double fnum; | |
}; | |
}; | |
static TaggedCell memory[100]; | |
static TaggedCell* free = &memory[0]; | |
TaggedCell allocate_pair() { | |
TaggedCell pair; | |
pair.tag = POINTER; | |
pair.ptr = free; | |
free += 2; | |
return pair; | |
} | |
bool is_null(TaggedCell obj) { | |
return obj.tag == NIL; | |
} | |
TaggedCell nil() { | |
TaggedCell obj; | |
obj.tag = NIL; | |
return obj; | |
} | |
TaggedCell number(double f) { | |
TaggedCell obj; | |
obj.tag = NUMBER; | |
obj.fnum = f; | |
return obj; | |
} | |
TaggedCell* car(TaggedCell obj) { | |
return (TaggedCell*)obj.ptr; | |
} | |
TaggedCell* cdr(TaggedCell obj) { | |
return (TaggedCell*)(obj.ptr) + 1; | |
} | |
TaggedCell cons(TaggedCell car_value, TaggedCell cdr_value) { | |
TaggedCell obj = allocate_pair(); | |
*car(obj) = car_value; | |
*cdr(obj) = cdr_value; | |
return obj; | |
} | |
TaggedCell splice(TaggedCell seq1, TaggedCell seq2) { | |
if(is_null(seq1)) return seq2; | |
if(is_null(seq2)) return seq1; | |
return cons(*car(seq1), cons(*car(seq2), splice(*cdr(seq1), *cdr(seq2)))); | |
} | |
TaggedCell reverse(TaggedCell input, TaggedCell output) { | |
if(is_null(input)) | |
return output; | |
return reverse(*cdr(input), cons(*car(input), output)); | |
} | |
TaggedCell length(TaggedCell sequence, int accumulator) { | |
if(is_null(sequence)) | |
return number(accumulator); | |
return length(*cdr(sequence), accumulator + 1); | |
} | |
void length2(TaggedCell* output, TaggedCell sequence, int accumulator) { | |
if(is_null(sequence)) { | |
*output = number(accumulator); | |
return; | |
} | |
length2(output, *cdr(sequence), accumulator + 1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment