Skip to content

Instantly share code, notes, and snippets.

@bas080
Created July 6, 2016 14:31
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 bas080/22fa50785b2b5b435d2bdf0fe145f798 to your computer and use it in GitHub Desktop.
Save bas080/22fa50785b2b5b435d2bdf0fe145f798 to your computer and use it in GitHub Desktop.
/********
* CORE *
********/
function expand(list) {
console.log('-', list);
return list[0] && list[0].isMacro ? expand(first(list)(rest(list))) : list
}
function apply(list) {
return list.isQuoted ? list : first(list).apply(null,
rest(list).map(item => {
return Array.isArray(item) ? apply(item) : item;
})
);
}
/***********
* SPECIAL *
***********/
function macro(fn) {
let expand = (form) => {
return fn(form);
};
expand.isMacro = true;
return expand;
}
function quote(...items) {
items.isQuoted = true;
return items;
}
/**********
* MACROS *
**********/
let thread = macro(forms => {
let val = forms.splice(0, 1)[0];
return forms.reduce((acc, form) => {
return form.concat([acc]);
}, val);
});
let not = macro(function(form){
form.unshift((v) => !v);
return form;
});
let repeat = macro(forms => {
let result = [];
for (let i=first(forms); i > 0; i--) {
result.push(second(forms));
}
return result;
});
/*************
* FUNCTIONS *
*************/
function first(list) {
return list[0];
}
function second(list) {
return list[1];
}
function concat (a, b) {
return a.concat(b);
}
function rest(list) {
return Object.create(list).slice(1);
}
function sum (a,b) {
return a + b;
}
let code;
code = [concat, [quote, 1,2,3], [quote, 4,5,6]];
code = [thread,
1,
[sum, 2],
[sum, 3],
[sum, 4]
];
code = [not, true];
let result = apply(expand(code));
console.log(result);
//console.log(expand(code));
//console.log(apply(expand(code)));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment