opt0.c3 (1764B) - raw


      1 module brainz::opt0;
      2 import std::io;
      3 
      4 fn void? interpret(
      5 	Program program,
      6 	char[] memory,
      7 	InStream rdr = io::stdin(),
      8 	OutStream wtr = io::stdout(),
      9 ) {
     10 	char[] instructions = program;
     11 	uint pc;
     12 	uint dataptr;
     13 
     14 	while (pc < instructions.len) {
     15 		char instruction = instructions[pc];
     16 
     17 		switch (instruction) {
     18 			case '>': dataptr += 1;
     19 			case '<': dataptr -= 1;
     20 			case '+': memory[dataptr] += 1;
     21 			case '-': memory[dataptr] -= 1;
     22 			case ',': memory[dataptr] = rdr.read_byte()!;
     23 			case '.': wtr.write_byte(memory[dataptr])!;
     24 			case '[':
     25 				// jumps to next matching ']' if curr_data == 0
     26 				if (memory[dataptr] != 0) {
     27 					break;
     28 				}
     29 
     30 				uint bracket_nesting = 1;
     31 				uint saved_pc = pc; // used for error message only
     32 
     33 				while (bracket_nesting != 0 && pc < instructions.len - 1) {
     34 					pc += 1;
     35 
     36 					if (instructions[pc] == ']') {
     37 						bracket_nesting -= 1;
     38 					} else if (instructions[pc] == '[') {
     39 						bracket_nesting += 1;
     40 					}
     41 				}
     42 
     43 				if (bracket_nesting != 0) {
     44 					io::eprintfn("unmatched '[' at pc=%d", saved_pc);
     45 					return UNMATCHED_LBRACKET?;
     46 				}
     47 			case ']':
     48 				// jumps to previous matching ']' if curr data != 0
     49 				if (memory[dataptr] == 0) {
     50 					break;
     51 				}
     52 
     53 				uint bracket_nesting = 1;
     54 				uint saved_pc = pc; // used for error message only
     55 
     56 				while (bracket_nesting != 0 && pc > 0) {
     57 					pc -= 1;
     58 
     59 					if (instructions[pc] == '[') {
     60 						bracket_nesting -= 1;
     61 					} else if (instructions[pc] == ']') {
     62 						bracket_nesting += 1;
     63 					}
     64 				}
     65 
     66 				if (bracket_nesting != 0) {
     67 					io::eprintfn("unmatched ']' at pc=%d", saved_pc);
     68 					return UNMATCHED_RBRACKET?;
     69 				}
     70 			default:
     71 				return UNREACHABLE_CHAR?;
     72 		}
     73 		pc += 1;
     74 	}
     75 }
     76 
     77 faultdef
     78 	UNMATCHED_LBRACKET,
     79 	UNMATCHED_RBRACKET,
     80 	UNREACHABLE_CHAR,
     81 ;