draw_rectangle

This commit is contained in:
me 2025-12-20 18:10:59 +02:00
parent 7302265436
commit dd62cecd50
5 changed files with 105 additions and 19 deletions

View file

@ -12,7 +12,7 @@ test:
.PHONY: run .PHONY: run
run: run:
RUST_BACKTRACE=1 cargo run -- game.ayin RUST_BACKTRACE=1 cargo run -- colorgame.ayin
.PHONY: review .PHONY: review
review: review:

32
colorgame.ayin Normal file
View file

@ -0,0 +1,32 @@
let setup = fn() {
return {
.color: {
.r: random_u8(),
.g: random_u8(),
.b: random_u8(),
},
.rect: {
.dimensions: {
.x: 100,
.y: 100,
.w: 100,
.h: 100,
},
.color: {
.r: random_u8(),
.g: random_u8(),
.b: random_u8(),
},
},
};
}
let update = fn(state, input) {
let delta = get_frame_time();
return state;
}
let draw = fn(state) {
frame_clear(state.color.r, state.color.g, state.color.b);
draw_rectangle(state.rect.dimensions, state.rect.color);
}

View file

@ -168,7 +168,8 @@ fn eval_expr(expr_env: &Env, state: &mut State, expr: &ast::Expr) -> Result<ast:
let mut argsvec = vec![]; let mut argsvec = vec![];
for arg in args.iter() { for arg in args.iter() {
let evalled = eval_expr(&expr_env, state, arg)?; let evalled = eval_expr(&expr_env, state, arg)?;
argsvec.push(evalled); let e = value_to_stadnalone_expr(state, evalled)?;
argsvec.push(e);
} }
if let Some(func) = state.primitive_funcs.get(&func) { if let Some(func) = state.primitive_funcs.get(&func) {
Ok(func(argsvec)) Ok(func(argsvec))
@ -422,7 +423,7 @@ fn defs_to_env(
Ok(()) Ok(())
} }
pub fn value_to_stadnalone_expr(state: &State, value: ast::Value) -> Result<ast::Expr, String> { pub fn value_to_stadnalone_expr(state: &State, value: ast::Value) -> Result<ast::Expr, Error> {
match value { match value {
ast::Value::Ref(reference) => { ast::Value::Ref(reference) => {
let value = state.variables.get(&reference).clone(); let value = state.variables.get(&reference).clone();
@ -444,7 +445,11 @@ pub fn value_to_stadnalone_expr(state: &State, value: ast::Value) -> Result<ast:
} }
Ok(ast::Expr::Record(map)) Ok(ast::Expr::Record(map))
} }
ast::Value::Closure { .. } => Err("Closure migration not supported".into()), ast::Value::Closure { .. } => Err(Error::MigrationError(
value.clone(),
"Closure migration not supported".into(),
Backtrace::capture(),
)),
_ => Ok(ast::Expr::Value(value)), _ => Ok(ast::Expr::Value(value)),
} }
} }

View file

@ -18,6 +18,7 @@ pub enum Error {
NotAReference(ast::Value, Backtrace), NotAReference(ast::Value, Backtrace),
NotABoolean(ast::Value, Backtrace), NotABoolean(ast::Value, Backtrace),
OpError(ast::Value, ast::Op, ast::Value, Backtrace), OpError(ast::Value, ast::Op, ast::Value, Backtrace),
MigrationError(ast::Value, String, Backtrace),
ArgumentsMismatch(Backtrace), ArgumentsMismatch(Backtrace),
} }
impl PartialEq for Error { impl PartialEq for Error {
@ -34,6 +35,9 @@ impl PartialEq for Error {
(Error::NotARecord(a1, _), Error::NotARecord(a2, _)) => a1 == a2, (Error::NotARecord(a1, _), Error::NotARecord(a2, _)) => a1 == a2,
(Error::NotAReference(a1, _), Error::NotAReference(a2, _)) => a1 == a2, (Error::NotAReference(a1, _), Error::NotAReference(a2, _)) => a1 == a2,
(Error::NotABoolean(a1, _), Error::NotABoolean(a2, _)) => a1 == a2, (Error::NotABoolean(a1, _), Error::NotABoolean(a2, _)) => a1 == a2,
(Error::MigrationError(a1, b1, _), Error::MigrationError(a2, b2, _)) => {
a1 == a2 && b1 == b2
}
(Error::ArgumentsMismatch(_), Error::ArgumentsMismatch(_)) => true, (Error::ArgumentsMismatch(_), Error::ArgumentsMismatch(_)) => true,
_ => false, _ => false,
} }
@ -62,6 +66,9 @@ impl std::fmt::Display for Error {
Error::NotABoolean(a, b) => write!(f, "Not a boolean {a:?}\n{b}"), Error::NotABoolean(a, b) => write!(f, "Not a boolean {a:?}\n{b}"),
Error::ArgumentsMismatch(a) => write!(f, "Arguments mismatch\n{a}"), Error::ArgumentsMismatch(a) => write!(f, "Arguments mismatch\n{a}"),
Error::OpError(a, b, c, d) => write!(f, "Op Error {a:?} {b:?} {c:?}\n{d}"), Error::OpError(a, b, c, d) => write!(f, "Op Error {a:?} {b:?} {c:?}\n{d}"),
Error::MigrationError(a, b, c) => {
write!(f, "Migration error for:\n{a:#?}\n{b:#?}\n{c}")
}
} }
} }
} }
@ -100,7 +107,7 @@ pub struct PrimitiveFuncs {
pub map: HashMap<ast::Name, PrimFunc>, pub map: HashMap<ast::Name, PrimFunc>,
} }
pub type PrimFunc = fn(Vec<ast::Value>) -> ast::Value; pub type PrimFunc = fn(Vec<ast::Expr>) -> ast::Value;
impl PrimitiveFuncs { impl PrimitiveFuncs {
pub fn new(prims: Vec<(&str, PrimFunc)>) -> Self { pub fn new(prims: Vec<(&str, PrimFunc)>) -> Self {

View file

@ -8,32 +8,74 @@ use macroquad::prelude as mq;
pub fn primitive_funcs() -> PrimitiveFuncs { pub fn primitive_funcs() -> PrimitiveFuncs {
PrimitiveFuncs::new(vec![ PrimitiveFuncs::new(vec![
("frame_clear", clear), ("frame_clear", clear),
("draw_rectangle", draw_rectangle),
("get_frame_time", frame_time), ("get_frame_time", frame_time),
("random_u8", random_u8), ("random_u8", random_u8),
]) ])
} }
fn clear(args: Vec<ast::Value>) -> ast::Value { fn clear(args: Vec<ast::Expr>) -> ast::Value {
let r = to_u32(args.get(0)); let r = to_u8(args.get(0));
let g = to_u32(args.get(1)); let g = to_u8(args.get(1));
let b = to_u32(args.get(2)); let b = to_u8(args.get(2));
mq::clear_background(mq::Color::from_rgba(r, g, b, 255)); mq::clear_background(mq::Color::from_rgba(r, g, b, 255));
ast::UNIT_VALUE ast::UNIT_VALUE
} }
fn to_u32(value: Option<&ast::Value>) -> u8 { fn random_u8(_args: Vec<ast::Expr>) -> ast::Value {
match value {
Some(ast::Value::Int(i)) => *i as u8,
Some(ast::Value::Float(f)) => *f as u8,
_ => 0,
}
}
fn random_u8(_args: Vec<ast::Value>) -> ast::Value {
let random: u8 = rand::rng().random::<u8>(); let random: u8 = rand::rng().random::<u8>();
ast::Value::Int(random as i32) ast::Value::Int(random as i32)
} }
fn frame_time(_args: Vec<ast::Value>) -> ast::Value { fn frame_time(_args: Vec<ast::Expr>) -> ast::Value {
ast::Value::Float(get_frame_time() as f32) ast::Value::Float(get_frame_time() as f32)
} }
struct Rectangle {
x: f32,
y: f32,
w: f32,
h: f32,
}
fn draw_rectangle(args: Vec<ast::Expr>) -> ast::Value {
let rectangle = match args.get(0) {
Some(ast::Expr::Record(record)) => {
let x = to_f32(record.get(&"x".into()));
let y = to_f32(record.get(&"y".into()));
let w = to_f32(record.get(&"w".into()));
let h = to_f32(record.get(&"h".into()));
Rectangle { x, y, w, h }
}
_ => todo!(),
};
let color = match args.get(1) {
Some(ast::Expr::Record(record)) => {
let r = to_u8(record.get(&"r".into()));
let g = to_u8(record.get(&"g".into()));
let b = to_u8(record.get(&"b".into()));
mq::Color::from_rgba(r, g, b, 255)
}
_ => todo!(),
};
mq::draw_rectangle(rectangle.x, rectangle.y, rectangle.w, rectangle.h, color);
ast::UNIT_VALUE
}
///////////////
fn to_u8(value: Option<&ast::Expr>) -> u8 {
match value {
Some(ast::Expr::Value(ast::Value::Int(i))) => *i as u8,
Some(ast::Expr::Value(ast::Value::Float(f))) => *f as u8,
_ => 0,
}
}
fn to_f32(value: Option<&ast::Expr>) -> f32 {
match value {
Some(ast::Expr::Value(ast::Value::Int(i))) => *i as f32,
Some(ast::Expr::Value(ast::Value::Float(f))) => *f as f32,
_ => 0.0,
}
}