Skip to content

Instantly share code, notes, and snippets.

View nasser's full-sized avatar
🛰️
save-lisp-and-die

Ramsey Nasser nasser

🛰️
save-lisp-and-die
View GitHub Profile
@nasser
nasser / Program.cs
Last active April 19, 2021 19:13
ajeeb-style coroutines in C#
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 April 14, 2021 18:36
sketching yield* in c#
// 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 March 15, 2021 00:08
SVG Hatch Fill Generator
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
Last active November 17, 2021 15:09
a pixi.js boilerplate scene in a single 16 line self-contained html file
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset-css@5.0.1/reset.min.css">
<script type="module">
import * as PIXI from "https://cdnjs.cloudflare.com/ajax/libs/pixi.js/6.2.0/browser/pixi.min.mjs"
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 }
}
@nasser
nasser / index.html
Last active January 15, 2021 14:36
lines
<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 January 7, 2021 18:10
Flat template rendering in node.js in two lines of code
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 March 16, 2021 15:40
a three.js boilerplate scene in a single 30 line self-contained html file
<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 November 20, 2020 02:26
javascript coroutine wrap
// 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 November 15, 2020 21:49
sketch of limited operator overloading in javascript
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 July 4, 2020 20:18
Generic Functions + Polymorphic Inline Cache Callsites
// 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];