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
run:
RUST_BACKTRACE=1 cargo run -- game.ayin
RUST_BACKTRACE=1 cargo run -- colorgame.ayin
.PHONY: 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![];
for arg in args.iter() {
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) {
Ok(func(argsvec))
@ -422,7 +423,7 @@ fn defs_to_env(
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 {
ast::Value::Ref(reference) => {
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))
}
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)),
}
}

View file

@ -18,6 +18,7 @@ pub enum Error {
NotAReference(ast::Value, Backtrace),
NotABoolean(ast::Value, Backtrace),
OpError(ast::Value, ast::Op, ast::Value, Backtrace),
MigrationError(ast::Value, String, Backtrace),
ArgumentsMismatch(Backtrace),
}
impl PartialEq for Error {
@ -34,6 +35,9 @@ impl PartialEq for Error {
(Error::NotARecord(a1, _), Error::NotARecord(a2, _)) => a1 == a2,
(Error::NotAReference(a1, _), Error::NotAReference(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,
_ => false,
}
@ -62,6 +66,9 @@ impl std::fmt::Display for Error {
Error::NotABoolean(a, b) => write!(f, "Not a boolean {a:?}\n{b}"),
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::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 type PrimFunc = fn(Vec<ast::Value>) -> ast::Value;
pub type PrimFunc = fn(Vec<ast::Expr>) -> ast::Value;
impl PrimitiveFuncs {
pub fn new(prims: Vec<(&str, PrimFunc)>) -> Self {

View file

@ -8,32 +8,74 @@ use macroquad::prelude as mq;
pub fn primitive_funcs() -> PrimitiveFuncs {
PrimitiveFuncs::new(vec![
("frame_clear", clear),
("draw_rectangle", draw_rectangle),
("get_frame_time", frame_time),
("random_u8", random_u8),
])
}
fn clear(args: Vec<ast::Value>) -> ast::Value {
let r = to_u32(args.get(0));
let g = to_u32(args.get(1));
let b = to_u32(args.get(2));
fn clear(args: Vec<ast::Expr>) -> ast::Value {
let r = to_u8(args.get(0));
let g = to_u8(args.get(1));
let b = to_u8(args.get(2));
mq::clear_background(mq::Color::from_rgba(r, g, b, 255));
ast::UNIT_VALUE
}
fn to_u32(value: Option<&ast::Value>) -> u8 {
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 {
fn random_u8(_args: Vec<ast::Expr>) -> ast::Value {
let random: u8 = rand::rng().random::<u8>();
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)
}
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,
}
}