Skip to content

Instantly share code, notes, and snippets.

@jdh30
jdh30 / SimpleParser1.fs
Created March 4, 2018 16:33
Port of an camlp4-based inline parser to vanilla ML
// See: https://gist.github.com/jdh30/6130c615b5945fd57fc0ea74fcb87e05
open System.Text.RegularExpressions
type BinOp = Add | Sub | Le
type expr =
| Int of int
| Var of string
| BinOp of expr * BinOp * expr
@jdh30
jdh30 / Camlp4LikeParser.fs
Created March 12, 2018 23:40
A parser definition in F# written in the style of a Camlp4 parser
let reint = R(Regex "[0-9]+")
let relident = R(Regex "[a-z][a-zA-Z0-9]*")
let grammar : Grammar<Entry> =
[
Expr,
[ [ S"if"; C Expr; S"then"; C Expr; S"else"; C Expr ], fun [E p; E t; E f] -> E(If(p, t, f))
[ C Expr; S"<="; C Expr ], fun [E e1; E e2] -> E(BinOp(e1, Le, e2))
[ C Expr; S"+"; C Expr ], fun [E e1; E e2] -> E(BinOp(e1, Add, e2))
[ C Expr; S"-"; C Expr ], fun [E e1; E e2] -> E(BinOp(e1, Sub, e2))
@jdh30
jdh30 / j.c
Created April 6, 2017 01:01
Arthur Whitney's mini J interpreter in C from "Remembering Ken Iverson" http://keiapl.org/rhui/remember.htm
typedef char C;typedef long I;
typedef struct a{I t,r,d[3],p[2];}*A;
#define P printf
#define R return
#define V1(f) A f(w)A w;
#define V2(f) A f(a,w)A a,w;
#define DO(n,x) {I i=0,_n=(n);for(;i<_n;++i){x;}}
I *ma(n){R(I*)malloc(n*4);}mv(d,s,n)I *d,*s;{DO(n,d[i]=s[i]);}
tr(r,d)I *d;{I z=1;DO(r,z=z*d[i]);R z;}
A ga(t,r,d)I *d;{A z=(A)ma(5+tr(r,d));z->t=t,z->r=r,mv(z->d,d,r);
@jdh30
jdh30 / Q_rsqrt.fs
Last active October 13, 2018 14:01
Fast inverse sqrt in F#
// The famous fast inverse square root approximation from
// Quake ported to F#.
// Note: this algorithm is not fast on modern computers
// and this implementation of it is extremely inefficient:
// for educational purposes only!
open System
let isqrt y =
let x2 = y * 0.5f
@jdh30
jdh30 / promptness.fs
Last active February 28, 2019 03:12
A program for which prompt collection is practically impossible
(*
The resizable array xs is required for the first half of the execution of
this "test" function but not the last half. Collecting xs as early as possible
would mean collecting it halfway through the execution of "test" but this
is practically impossible. Doing so in general is equivalent to solving the
halting problem.
*)
let next n =
6364136223846793005UL*n + 1442695040888963407UL
@jdh30
jdh30 / Eddy.fs
Created February 28, 2019 09:27
Memory management benchmark - shedding Eddys
(*
This benchmark maintains an array of roots and randomly either pushes
onto them and relinks them or empties them. If I designed it correctly
then this should rapidly create unreachable subgraphs, some of which
are cyclic.
This is a torture test for any kind of reference counting.
*)
type Vertex = { mutable Dst: Vertex }
@jdh30
jdh30 / gist:bc1794232ac584db9baa
Created August 29, 2015 22:54
List-based n-queens solver with mark-sweep GC written in C++
#include <vector>
#include <iostream>
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include "Allocator.h"
#include "MarkSweep.h"
#define OPTIMIZED
#define SHADOWSTACK
@jdh30
jdh30 / gist:438afaed15d3bb7af3bfaedf54c4852b
Created April 28, 2019 23:01
McCarthy's definition of LISP 1.5 in itself
; 20LOC to define a useful language
; However, no strings, IO, closure semantics or GC.
apply[fn;x;a] =
[atom[fn] -> [eq[fn;CAR] -> caar[x];
eq[fn;CDR] -> cdar[x];
eq[fn;CONS] -> cons[car[x];cadr[x]];
eq[fn;ATOM] -> atom[car[x]];
eq[fn;EQ] -> eq[car[x];cadr[x]];
T -> apply[eval[fn;a];x;a]];
@jdh30
jdh30 / binarytrees.cpp
Created May 9, 2019 10:06
Hans Boehm's binary trees benchmark in C++ using the default new+delete
#include <algorithm>
#include <iostream>
#include <chrono>
struct Node {
Node *l, *r;
Node() : l(0), r(0) {}
Node(Node* l2, Node* r2) : l(l2), r(r2) {}
~Node() { delete l; delete r; }
int check() const {
@jdh30
jdh30 / binarytrees.fs
Created May 9, 2019 10:07
Hans Boehm's binary trees benchmark in F#
[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
type Tree = Empty | Node of Tree * Tree
let rec make depth =
if depth=0 then Empty else Node(make (depth-1), make (depth-1))
let rec check = function
| Empty -> 1
| Node(l, r) -> 1 + check l + check r