Skip to content

Instantly share code, notes, and snippets.

Avatar
🛰️
save-lisp-and-die

Ramsey Nasser nasser

🛰️
save-lisp-and-die
View GitHub Profile
@nasser
nasser / Program.cs
Last active Apr 19, 2021
ajeeb-style coroutines in C#
View Program.cs
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
int FRAME = 0;
var sched = new Schedule();
async Task DelayFrames(int frames)
{
while (frames-- > 0)
@nasser
nasser / waitfor.cs
Last active Apr 14, 2021
sketching yield* in c#
View waitfor.cs
// coroutines in c#/unity are missing something like javascript's yield* which both wait for another
// coroutine *and* returns a value when that coroutine is finished.
// i think we can reproduce it with roslyn source transformations or something similar
// the trick is a WaitFor static method that allows the type inference to line up
// the method is never meant to actually be called though, and will throw if it ever is
// instead calls to the method are replaced with a local variable store, a yield return, and a field access
public class Coroutines {
public static T WaitFor<T>(IEnumerator<T> ie) {
throw new NotImplementedException();
@nasser
nasser / hatch.js
Created Mar 15, 2021
SVG Hatch Fill Generator
View hatch.js
const distance = (x1, y1, x2, y2) =>
Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2))
const approx = (a, b) =>
Math.abs(a - b) < 0.00001
/**
* Compute the intersection of a line segment and a line
*
* @param x1 x coordinate of the first endpoint of the line segment
@nasser
nasser / pixi.html
Created Feb 22, 2021
a pixi.js boilerplate scene in a single 16 line self-contained html file
View pixi.html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset-css@5.0.1/reset.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.1.3/pixi.min.js"></script>
<script type="module">
let app = new PIXI.Application()
document.body.appendChild(app.view)
window.onresize = function() {
app.renderer.resize(window.innerWidth, window.innerHeight)
app.stage.position = { x:window.innerWidth/2, y:window.innerHeight/2 }
}
View index.html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset-css@5.0.1/reset.min.css">
<canvas></canvas>
<script>
const vertexShader = `#version 300 es
uniform vec2 screen;
in vec2 position;
in vec3 color;
out vec3 pcolor;
@nasser
nasser / render.js
Created Jan 7, 2021
Flat template rendering in node.js in two lines of code
View render.js
const render = (template, values) =>
template.replace(/\{\{([^}]+)\}\}/g, (_, key) => values[key]);
render("hello {{place}}", { place: "world" })
// => "hello world"
render("shell='{{SHELL}}', term='{{TERM}}'", process.env)
// => "shell='/bin/bash', term='xterm-256color'"
@nasser
nasser / three.html
Last active Mar 16, 2021
a three.js boilerplate scene in a single 30 line self-contained html file
View three.html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset-css@5.0.1/reset.min.css">
<script type="module">
import * as THREE from "https://cdn.jsdelivr.net/npm/three@0.124.0/build/three.module.js"
import { OrbitControls } from "https://cdn.jsdelivr.net/npm/three@0.124.0/examples/jsm/controls/OrbitControls.js"
var scene = new THREE.Scene()
var camera = new THREE.PerspectiveCamera(75)
camera.position.z = 4
@nasser
nasser / wrap.js
Created Nov 20, 2020
javascript coroutine wrap
View wrap.js
// based on coroutine.wrap in lua (https://www.lua.org/pil/9.3.html)
function wrap(generator) {
let g = null
return function(...args) {
if(!g)
g = generator(...args)
return g.next(...args).value
}
}
@nasser
nasser / operators.js
Created Nov 15, 2020
sketch of limited operator overloading in javascript
View operators.js
const esprima = require("esprima")
const escodegen = require("escodegen")
const THREE = require("three")
/// implementation
let opMap = {
"+=": "add",
"/": "divideScalar",
// ... more operators here ...
@nasser
nasser / pic.ts
Created Jul 4, 2020
Generic Functions + Polymorphic Inline Cache Callsites
View pic.ts
// multiple dispatch generic functions and polymorphic inline caches
class GenericFunction {
cache: any = {}
addMethod(signature: string[], method) {
let cacheObject = this.cache;
for (const typeName of signature) {
if (!cacheObject.hasOwnProperty(typeName)) {
cacheObject[typeName] = {}
}
cacheObject = cacheObject[typeName];