Skip to content

Instantly share code, notes, and snippets.

@tinaun
Last active November 21, 2018 06:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tinaun/8f692355c84debd58daa43b6a071b0df to your computer and use it in GitHub Desktop.
Save tinaun/8f692355c84debd58daa43b6a071b0df to your computer and use it in GitHub Desktop.
my_oldest_surviving_rust.rs
// 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