Skip to content

Instantly share code, notes, and snippets.

Per Vognsen pervognsen

Block or report user

Report or block pervognsen

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
View coll.h
// stretchy buffer, works directly on typed c pointers
afree(a)
apush(a, x)
alen(a) // lvalue, so you can do things like a[i] = a[--alen(a)]
aend(a) // a + alen(a)
areserve(a, n)
aresize(a, n)
// uint64 -> uint64 hash table
hinit(h, n)
View BTree.cpp
enum { BMAX = 32, BCUT = BMAX / 2, BHEIGHT = 6 };
typedef uint8_t BIndex;
struct BNode {
BIndex length;
Key keys[BMAX];
union {
BNode *children[BMAX];
Value values[BMAX];
View dbg-test.el
(require 'dbg)
(global-set-key (kbd "<C-S-f5>") 'dbg-restart)
(global-set-key (kbd "<f5>") 'dbg-continue)
(global-set-key (kbd "<f9>") 'dbg-toggle-breakpoint)
(global-set-key (kbd "<f8>") 'dbg-watch)
(global-set-key (kbd "<f10>") 'dbg-next)
(global-set-key (kbd "<C-f10>") 'dbg-continue-to-here)
(global-set-key (kbd "<f11>") 'dbg-step)
(global-set-key (kbd "<C-S-f10>") 'dbg-jump)
View Xeno.cpp
// Xeno
enum Xeno_Kind {
XENO_POINTER,
XENO_AGGREGATE,
XENO_FIRST_PRIMITIVE_TYPE,
XENO_UINT8 = XENO_FIRST_PRIMITIVE_TYPE,
XENO_UINT16,
XENO_UINT32,
XENO_UINT64,
View c_standard_spelunking.md

I've been trying to get clarity on to what extent the position-independent data structure tricks in Gob (https://gist.github.com/pervognsen/c25a039fcf8c256141ef0778a1b32a88) are legal or illegal according to the C standard. I always had the impression it would run afoul of strict aliasing or pointer casting restrictions, but I've been digging into the standard, and now I'm no longer so sure. It might be perfectly legal after all?

Here's section 6.3.2.3 on pointer conversions from the C99 draft standard. I'll be referencing the C99 standard throughout this article, but I've verified that the C11 standard hasn't changed in the relevant areas.

"5 An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation. [56]

6 Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined

View rad.py
# Reverse-mode automatic differentiation
import math
# d(-x) = -dx
def func_neg(x):
return -x, [-1]
# d(x + y) = dx + dy
def func_add(x, y):
@pervognsen
pervognsen / mu.cpp
Last active Oct 28, 2019
Mu as of the second stream
View mu.cpp
#include "mu.h"
#define _CRT_SECURE_NO_WARNINGS
#include <malloc.h>
#define _USE_MATH_DEFINES
#include <math.h>
#define _NO_CRT_STDIO_INLINE
#include <stdio.h>
#include <stdarg.h>
#define NO_STRICT
View asan_clang_cl.md

I was told by @mmozeiko that Address Sanitizer (ASAN) works on Windows now. I'd tried it a few years ago with no luck, so this was exciting news to hear.

It was a pretty smooth experience, but with a few gotchas I wanted to document.

First, download and run the LLVM installer for Windows: https://llvm.org/builds/

Then download and install the VS extension if you're a Visual Studio 2017 user like I am.

It's now very easy to use Clang to build your existing MSVC projects since there's a cl compatible frontend:

View str.ion
import libc {...}
struct StrLinesIter {
next: char const*;
start: char const*;
end: char const*;
}
func str_lines(str: char const*): StrLinesIter {
return {next = str};
View input_bindings.md

Every emulator should have most of these input-related features but I haven't found anything with more than a small fraction:

Default and custom input profiles. Custom profiles can have game-specific input bindings. Bindings in custom profiles set to the 'default' value defer to the binding in the default profile; it's important that custom profiles aren't just initialized as a copy of the then-current default profile as this makes it impossible to later change some non-overridden binding in the default profile and have it automatically propagate to existing custom profiles.

The emulator should remember which custom profile was last used for which game, based on the ROM hash or filename. (The emulator should also automatically save any relevant per-game emulator settings, but I think you want that separate from input profiles. As an example of what not to do, if I set the CPU overclocking for Metal Slug in MAME to 200% to

You can’t perform that action at this time.