Skip to content

Instantly share code, notes, and snippets.

@aemmitt-ns
Last active October 14, 2023 19:36
Show Gist options
  • Save aemmitt-ns/4b6f234b13818558ab1cc0de253f6973 to your computer and use it in GitHub Desktop.
Save aemmitt-ns/4b6f234b13818558ab1cc0de253f6973 to your computer and use it in GitHub Desktop.
a brainfuck interpreter made with an NSExpression that evaluates on itself. idk.
// yields brainfuck when quined
char *h = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]"
">>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."; // -> Hello World!
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
NSString *program = [NSString stringWithUTF8String: argc > 1 ? argv[1] : h];
NSMutableArray *prog = [NSMutableArray array]; // make the program into an array cuz its easier
for (int i = 0; i < program.length; i++) {
NSString *c = [program substringWithRange: NSMakeRange(i, 1)];
if ([@".,<>-+[]" rangeOfString: c].location != NSNotFound) [prog addObject: c];
}
NSMutableDictionary *context = [@{@"prog": prog, @"pc": @0} mutableCopy];
NSExpression *expr = [NSExpression expressionWithFormat: @"{"
"ternary($pc == 0, {" // if at the start, initialize input, output, mem ...
"$inp := cast('NSFileHandle', 'Class').fileHandleWithStandardInput," // stdin
"$out := cast('NSFileHandle', 'Class').fileHandleWithStandardOutput," // stdout
"$m := {0,0}, $p := 0, $e := 1, $ign := 0, $ind := {0,0}},1),"
"ternary($prog[size] > $pc, {" // check whether the end has been reached
"ternary($e == 1 && $prog[$pc] == '.', now(" // perform putchar
"$b := function('','stringByAppendingFormat:','%p/<%02x>',function($m[$p],'charValue')),"
"function($out, 'writeData:error:', $b.lastPathComponent.propertyList, nil)),1),"
"ternary($e == 1 && $prog[$pc] == ',', now(" // perform getchar
"$b := function($inp, 'readDataOfLength:', function(1, 'intValue')).asciiDescription,"
"$b := function(1.superclass,'numberWithShort:',function($b,'characterAtIndex:',nil)),"
"function($m,'replaceObjectAtIndex:withObject:',function($p,'intValue'),$b)),1),"
"ternary($e == 1 && $prog[$pc] == '<' && $p > 0, $p := $p - 1, 1),"
"ternary($e == 1 && $prog[$pc] == '>', {$p := $p + 1," // if its out of bounds just add a 0
"ternary($p >= $m[size], now(1,function($m, 'addObject:', 0)),1)},1),"
"ternary($e == 1 && $prog[$pc] == '+', now(1," // increment data
"function($m,'replaceObjectAtIndex:withObject:',function($p,'intValue'),($m[$p]+1))),1),"
"ternary($e == 1 && $prog[$pc] == '-', now(1," // decrement data
"function($m,'replaceObjectAtIndex:withObject:',function($p,'intValue'),($m[$p]-1))),1),"
"ternary($prog[$pc] == '[', now(function($ind, 'addObject:', $pc)," // start loop
"ternary($e == 0, $ign := $ign + 1,1), ternary($m[$p] == 0, $e := 0,1)),1),"
"ternary($prog[$pc] == ']', now(" // end loop
"ternary($e == 1 && $m[$p]!=0,$pc:=$ind[last],now(1,function($ind,'removeLastObject'))),"
"ternary($e == 0, ternary($ign == 0, $e := 1, $ign := $ign-1),1)),1),"
"$pc := $pc + 1, function(self, 'expressionValueWithObject:context:', self, %@)"
"},1)}", context];
[expr expressionValueWithObject: expr context: context];
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment