Compare commits
3 Commits
58ba166392
...
45ed7b2ba4
Author | SHA1 | Date |
---|---|---|
Nat | 45ed7b2ba4 | |
Nat | e224e5ebef | |
Nat | cc392da7da |
|
@ -2,6 +2,7 @@
|
|||
name = "ponderosa"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
default-run = "ponderosa-cpu"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
use std::fs;
|
||||
use std::env;
|
||||
use std::io;
|
||||
|
||||
use std::collections::{HashMap, BTreeMap, VecDeque};
|
||||
|
||||
use ponderosa::state::{Land, Rule};
|
||||
|
||||
fn parse_number(string: &str) -> u16 {
|
||||
string.parse::<u16>().unwrap()
|
||||
}
|
||||
|
||||
fn stack_bit(c: char) -> Result<u16, String> {
|
||||
match c {
|
||||
'r' => Ok(0),
|
||||
't' => Ok(1),
|
||||
_ => Err(format!("Unknown stack reference: '{c}'. A valid stack code must be (r)oot or (t)runk.")),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_binary_math_format<'a>(tokens: &Vec<String>, opcode: u16, signed: bool) -> Result<u16, String> {
|
||||
if tokens.len() < 4 { Err("Too few arguments".to_owned()) }
|
||||
else if tokens.len() > 4 { Err("Too many arguments".to_owned()) }
|
||||
else {
|
||||
let left_parse = stack_bit(tokens[1].as_bytes()[0] as char);
|
||||
let right_parse = stack_bit(tokens[2].as_bytes()[0] as char);
|
||||
let dest_parse = stack_bit(tokens[3].as_bytes()[0] as char);
|
||||
|
||||
match (left_parse, right_parse, dest_parse) {
|
||||
(Ok(left), Ok(right), Ok(dest)) => Ok(
|
||||
opcode << 11 &
|
||||
left << 10 &
|
||||
right << 9 &
|
||||
dest << 8 &
|
||||
(signed as u16) << 7
|
||||
),
|
||||
(Err(e), _, _) => Err(e),
|
||||
(_, Err(e), _) => Err(e),
|
||||
(_, _, Err(e)) => Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let path = &args[1];
|
||||
let source_code = fs::read_to_string(path)?;
|
||||
|
||||
let mut land = Land {
|
||||
width: 0,
|
||||
height: 0,
|
||||
map: HashMap::new(),
|
||||
semaphores: HashMap::new(),
|
||||
};
|
||||
|
||||
let mut original_stack_size = 0;
|
||||
let mut seed_cell_position = (0, 0);
|
||||
let mut reading_land_values = false;
|
||||
|
||||
let mut rules: BTreeMap<String, Rule> = BTreeMap::new();
|
||||
let mut reading_rule = false;
|
||||
let mut current_rule_name: String = String::from("");
|
||||
let mut current_rule: Rule = VecDeque::new();
|
||||
|
||||
for source_line in source_code.lines() {
|
||||
let tokens: Vec<&str> = source_line
|
||||
.split_whitespace()
|
||||
.collect();
|
||||
|
||||
if tokens.len() == 0 || tokens[0].starts_with("--") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if reading_land_values {
|
||||
if tokens.len() < 3 {
|
||||
reading_land_values = false;
|
||||
break;
|
||||
} else {
|
||||
let (value, x_pos, y_pos) = (tokens[0].parse::<u16>(), tokens[1].parse::<u16>(), tokens[2].parse::<u16>());
|
||||
match (value, x_pos, y_pos) {
|
||||
(Ok(v), Ok(x), Ok(y)) => {
|
||||
land.sow(&(x, y), v);
|
||||
continue;
|
||||
},
|
||||
_ => {
|
||||
reading_land_values = false;
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if tokens[0].as_bytes()[0] as char == '.' {
|
||||
if reading_rule {
|
||||
// Save the now finished rule
|
||||
let mut new_rule: Rule = VecDeque::new();
|
||||
new_rule.append(&mut current_rule); // This empties current_rule
|
||||
rules.insert(current_rule_name, new_rule);
|
||||
}
|
||||
|
||||
current_rule_name = String::from(&tokens[0][1..]);
|
||||
}
|
||||
|
||||
if reading_rule {
|
||||
let parse_instruction_result = match tokens[0] {
|
||||
"add" => Ok(1),
|
||||
_ => Err(format!("Unknown instruction: {token}", token=tokens[0])),
|
||||
};
|
||||
}
|
||||
|
||||
match tokens[0] {
|
||||
"stack_size" => original_stack_size = parse_number(tokens[1]),
|
||||
"land_width" => land.width = parse_number(tokens[1]),
|
||||
"land_height" => land.height = parse_number(tokens[1]),
|
||||
"seed_cell" => seed_cell_position = (parse_number(tokens[1]), parse_number(tokens[2])),
|
||||
"land" => reading_land_values = true,
|
||||
_ => continue,
|
||||
};
|
||||
}
|
||||
|
||||
println!("Original stack size: {}", original_stack_size);
|
||||
println!("Land dimensions: {}x{}", land.width, land.height);
|
||||
println!("Seed tree position: ({}, {})", seed_cell_position.0, seed_cell_position.1);
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -4,11 +4,7 @@ use std::fs::File;
|
|||
use std::io::Read;
|
||||
use std::collections::{VecDeque, HashMap, BTreeSet};
|
||||
|
||||
mod math;
|
||||
mod stack;
|
||||
mod state;
|
||||
mod control;
|
||||
mod forestry;
|
||||
use ponderosa::{math, stack, state, control, forestry};
|
||||
|
||||
fn parse_rom(path: &String) -> io::Result<(state::Land, Vec<state::Rule>, HashMap<u16, state::Tree>)> {
|
||||
let mut rom_file = File::open(path)?;
|
||||
|
@ -66,7 +62,7 @@ fn parse_rom(path: &String) -> io::Result<(state::Land, Vec<state::Rule>, HashMa
|
|||
let x_pos = rom_words.pop_front().unwrap();
|
||||
let y_pos = rom_words.pop_front().unwrap();
|
||||
|
||||
land.map.insert((x_pos % land.width, y_pos % land.height), value);
|
||||
land.sow(&(x_pos, y_pos), value);
|
||||
}
|
||||
|
||||
println!("World\n=====");
|
|
@ -0,0 +1,5 @@
|
|||
pub mod math;
|
||||
pub mod stack;
|
||||
pub mod state;
|
||||
pub mod control;
|
||||
pub mod forestry;
|
|
@ -83,6 +83,14 @@ impl Land {
|
|||
|
||||
return self.semaphores.get_mut(position).unwrap();
|
||||
}
|
||||
|
||||
pub fn sow(&mut self, position: &(u16, u16), value: u16) {
|
||||
self.map.insert((position.0 % self.width, position.1 % self.height), value);
|
||||
}
|
||||
|
||||
pub fn reap(&mut self, position: &(u16, u16)) -> u16 {
|
||||
self.map.insert((position.0 % self.width, position.1 % self.height), 0).unwrap_or(0)
|
||||
}
|
||||
}
|
||||
|
||||
pub type Rule = VecDeque<u16>;
|
||||
|
|
Loading…
Reference in New Issue