Compare commits
3 Commits
58ba166392
...
45ed7b2ba4
Author | SHA1 | Date |
---|---|---|
Nat | 45ed7b2ba4 | |
Nat | e224e5ebef | |
Nat | cc392da7da |
|
@ -2,6 +2,7 @@
|
||||||
name = "ponderosa"
|
name = "ponderosa"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
default-run = "ponderosa-cpu"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# 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::io::Read;
|
||||||
use std::collections::{VecDeque, HashMap, BTreeSet};
|
use std::collections::{VecDeque, HashMap, BTreeSet};
|
||||||
|
|
||||||
mod math;
|
use ponderosa::{math, stack, state, control, forestry};
|
||||||
mod stack;
|
|
||||||
mod state;
|
|
||||||
mod control;
|
|
||||||
mod forestry;
|
|
||||||
|
|
||||||
fn parse_rom(path: &String) -> io::Result<(state::Land, Vec<state::Rule>, HashMap<u16, state::Tree>)> {
|
fn parse_rom(path: &String) -> io::Result<(state::Land, Vec<state::Rule>, HashMap<u16, state::Tree>)> {
|
||||||
let mut rom_file = File::open(path)?;
|
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 x_pos = rom_words.pop_front().unwrap();
|
||||||
let y_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=====");
|
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();
|
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>;
|
pub type Rule = VecDeque<u16>;
|
||||||
|
|
Loading…
Reference in New Issue