Compare commits

...

3 Commits

6 changed files with 153 additions and 6 deletions

View File

@ -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

125
src/bin/ponderosa-asm.rs Normal file
View File

@ -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(())
}

View File

@ -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=====");

5
src/lib.rs Normal file
View File

@ -0,0 +1,5 @@
pub mod math;
pub mod stack;
pub mod state;
pub mod control;
pub mod forestry;

View File

@ -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>;

12
test.rosa Normal file
View File

@ -0,0 +1,12 @@
stack_size 20
land_width 8
land_height 8
seed_cell 0 0
land
8 0 0
.seed
reap r 0 0
push r 2
mult r r t
sow t 0 0