Last active
November 21, 2018 06:57
-
-
Save tinaun/8f692355c84debd58daa43b6a071b0df to your computer and use it in GitHub Desktop.
my_oldest_surviving_rust.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// july 2014 | |
use std::io; | |
use std::from_str::FromStr; | |
// [], argument is optional, defaults to rax | |
#[deriving(Show)] | |
enum Operator { | |
MOV, // conditional move - MOV reg_from,reg_to,reg_test | |
IDA, // array index - IDA reg_array,reg_offset,[reg_output] | |
ADA, // array amendment - ADA reg_value,reg_array,reg_offset | |
ADD, // addition - ADD reg_a,reg_b,[reg_output] | |
MUL, // multiplication - ADD reg_a,reg_b,[reg_output] | |
DIV, // division - ADD reg_a,reg_b,[reg_output] | |
NAND, // bitwise nand - NAND reg_a,reg_b,[reg_output] | |
HALT, // halt - HALT | |
ALLA, // allocate array - ALLA reg_length | |
KILA, // abandon array - KILA reg_identifier | |
PUTC, // output - PUTC reg_char | |
GETC, // input - GETC reg_input | |
LOAD, // load program - LOAD reg_program,reg_jmp -- jumps to location in current program | |
STOR // orthography - STOR reg, value | |
} | |
#[deriving(Show)] | |
enum Register {rax,rbx,rcx,rdx,rex,rfx,rgx,rhx} | |
impl FromStr for Register { | |
fn from_str(s: &str) -> Option<Register> { | |
match s { | |
"rax" => Some(rax), | |
"rbx" => Some(rbx), | |
"rcx" => Some(rcx), | |
"rdx" => Some(rdx), | |
"rex" => Some(rex), | |
"rfx" => Some(rfx), | |
"rgx" => Some(rgx), | |
"rhx" => Some(rhx), | |
_ => None | |
} | |
} | |
} | |
//eight registers, each pointing to a 32 bit value | |
//named rax - rhx | |
static mut registers : [u32, ..8] = [0, 0, 0, 0, 0, 0, 0, 0]; | |
//arrays for data storage | |
// '0' holds the program data | |
fn cond_move(reg_from: Register, reg_to: Register, reg_test: Register) { | |
println!("moving {} to {} if {} non-zero", reg_from, reg_to, reg_test); | |
unsafe { | |
if registers[reg_test as uint] == 0 { | |
registers[reg_to as uint] = registers[reg_from as uint]; | |
} | |
} | |
} | |
fn array_index(reg_array: Register, reg_offset: Register, reg_output: Register) { | |
println!("accessing array {} at offset {}", reg_array, reg_offset); | |
} | |
fn array_amend(reg_value: Register, reg_array: Register, reg_offset: Register) { | |
println!("setting value {} into array {} at offset {}", reg_value, reg_array, reg_offset); | |
} | |
fn math_op(oper: |u32,u32| -> u32 , reg_a: Register, reg_b: Register, reg_output: Register) { | |
println!("apply function to {} and {} place return val in {}", reg_a, reg_b, reg_output); | |
unsafe { | |
let a = registers[reg_a as uint]; | |
let b = registers[reg_b as uint]; | |
registers[reg_output as uint] = oper (a, b); | |
} | |
} | |
fn store(reg: Register, value: u32){ | |
println!("setting {} in register {}", value, reg); | |
unsafe { | |
registers[reg as uint] = value; | |
} | |
} | |
fn word_dispatch(word: u32) -> Result<uint, &'static str> { | |
let opcode = word >> (32 - 4); | |
print!("op: {} " , opcode); | |
if opcode == 13 { | |
let reg_a = word & 0x0fffffff >> 25; | |
let value = word & 0x01ffffff >> 0; | |
} else { | |
let reg_a = word & 0x000001c0 >> 6; | |
let reg_b = word & 0x00000038 >> 3; | |
let reg_c = word & 0x00000007 >> 0; | |
println!("regs: a: {} b: {}, c: {}", reg_a, reg_b, reg_c); | |
} | |
return Ok(0); | |
} | |
fn asm_dispatch(call: &str, args: Vec<Register>) -> Result<uint, &'static str> { | |
println!("args: {}", args.len()); | |
match call { | |
"MOV" => cond_move(rax,rax,rax), | |
"IDA" => array_index(rax,rbx,rcx), | |
"ADA" => array_amend(rcx,rdx,rex), | |
"STOR" => store(rcx, 67u32), | |
"PLAC" => store(rax, 37u32), | |
"ADD" => math_op((|x,y| {x + y}), rax, rcx, rbx), | |
"MUL" => math_op((|x,y| {x * y}), rax, rcx, rbx), | |
"HALT" => return Ok(-1), | |
_ => return Err("invalid operator") | |
} | |
return Ok(0); | |
} | |
fn exec_line(in_str: &str) -> Result<uint, &'static str> { | |
//remove comments | |
let cmd_str = in_str.split(';').next().unwrap().trim(); | |
println!("\ncmd: {}", cmd_str); | |
if cmd_str.len() == 0 { | |
return Ok(0); | |
} | |
let mut iter = cmd_str.split(' '); | |
let (call, args) = (iter.next(), iter.next()); | |
let arg_vec : Vec<Register> = match args { | |
Some(a) => a.split(',').filter_map( |x| from_str(x) ).collect(), | |
None => Vec::new() | |
}; | |
println!("{} : {}", call, arg_vec); | |
asm_dispatch(call.unwrap(), arg_vec) | |
} | |
fn main(){ | |
println!("{} {}", 4u.to_string(), HALT); | |
loop { | |
print!("> "); | |
let input = io::stdin().read_line().ok().expect("INPUT ERROR"); | |
let result = exec_line(input.as_slice().trim()); | |
match result { | |
Ok(-1) => break, | |
Err(a) => println!("{:s}", a), | |
_ => continue | |
} | |
} | |
word_dispatch(0xa0000f3f); | |
unsafe { | |
println!("rax is {}", registers[0]); | |
println!("rbx is {}", registers[1]); | |
println!("rcx is {}", registers[2]); | |
println!("rdx is {}", registers[3]); | |
println!("rex is {}", registers[4]); | |
println!("rfx is {}", registers[5]); | |
println!("rgx is {}", registers[6]); | |
println!("rhx is {}", registers[7]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment