Insert is a programming language for self-modifying code

trenchgun1 pts0 comments

GitHub - uellenberg/Insert: Insert is a programming language for self-modifying code. · GitHub

/" data-turbo-transient="true" />

Skip to content

Search or jump to...

Search code, repositories, users, issues, pull requests...

-->

Search

Clear

Search syntax tips

Provide feedback

--><br>We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Cancel

Submit feedback

Saved searches

Use saved searches to filter your results more quickly

-->

Name

Query

To see all available qualifiers, see our documentation.

Cancel

Create saved search

Sign in

/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up

Appearance settings

Resetting focus

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

uellenberg

Insert

Public

Notifications<br>You must be signed in to change notification settings

Fork

Star<br>61

master

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>209 Commits<br>209 Commits

.idea

.idea

docs

docs

src

src

std

std

test

test

.gitattributes

.gitattributes

.gitignore

.gitignore

Cargo.lock

Cargo.lock

Cargo.toml

Cargo.toml

Insert.iml

Insert.iml

README.md

README.md

pong.avif

pong.avif

quineRun.sh

quineRun.sh

rust-toolchain.toml

rust-toolchain.toml

test.mjs

test.mjs

View all files

Repository files navigation

Insert

Insert is a programming language for self-modifying code.

It can be used to create programs that produce modified versions of themselves. For example, the pong game<br>above (which was one of the winners of IOCCC29) can be found<br>at test/snapshots/pong-target.stdout, with the source code used to create it<br>at test/src/pong.int and a helper script to run it at quineRun.sh.

Each iteration of this program produces the source code to create the next frame, with the current frame (display and<br>game state) rendered inside the source code itself. For a high-level overview of how this all works, check out<br>the IOCCC writeup.

A simple quine

This program prints a copy of itself with an embedded counter incremented each time it runs:

i32 {<br>quineStr[incrValMarker] = string(incrVal + 1);<br>printQuine(quineStr, $quineLen);<br>}">static incrVal: i32 = binding incrValMarker (0);

static quineStr: &[string] = $quine;

import "std/quine.int";

function main() -> i32 {<br>quineStr[incrValMarker] = string(incrVal + 1);<br>printQuine(quineStr, $quineLen);

$quine gives you your own source as an array of string fragments, binding marks a specific value in that array so<br>you can find and overwrite it, and printQuine prints the result.<br>See docs/self-modifying-code.md for how this works.

Getting started

Make sure you're using rustup, as this project requires a nightly toolchain (specified<br>in rust-toolchain.toml).

main.c

# Build and run the C program.<br>gcc main.c -o a.out && ./a.out

# Or use the included script to iterate it.<br>./quineRun.sh"># Compile an Insert program to C.<br>cargo run -- test/src/pong.int > main.c

# Build and run the C program.<br>gcc main.c -o a.out && ./a.out

# Or use the included script to iterate it.<br>./quineRun.sh

For a full walkthrough, including how to run a self-modifying program,<br>see docs/getting-started.md.

Documentation

Getting started - install, build, and run your<br>first program.

Language guide - types, functions, control flow,<br>and the rest of the syntax.

Self-modifying code - markers, bindings, and<br>quines.

Architecture - how the compiler is put together.

High-level architecture

The compiler has three main stages, and you can inspect the output using --stage. For a deeper look, including how<br>quines are emitted, see docs/architecture.md.

AST

First, the input text is transformed into an AST. This step is performed by the pest library, and can be found<br>under src/parser/program.pest.

Then, this AST is converted into MIR (this should really just be IR, although the name is a remnant from an older<br>version of the compiler that had two levels of IR). This conversion can be found<br>under src/parser/mod.rs. This conversion is mostly one-to-one, although a small amount of syntax<br>sugar is removed.

Here, we declare markers which maintain their order in the program all the way down to the output. We can also declare<br>bindings, which wrap an expression in two markers (before and after) to modify it specifically.

MIR

The MIR (mid-level intermediate representation) is where most of the compilation work is done. You can see a high-level<br>view of what happens in src/mir/mod.rs (under visit_mir). Initially, the MIR looks like the AST,<br>and is gradually transformed as more compiler passes run. This transformation includes things like type checking,<br>constant evaluation, and expression simplification.

After these transformations,...

insert code program test self modifying

Related Articles