From d3e882cba039889585cae27f7d78cbd97814f3ab Mon Sep 17 00:00:00 2001 From: Dennis Ranke Date: Thu, 11 Nov 2021 21:20:18 +0100 Subject: [PATCH] add take left operator, sizecoded wasm4 skip ahead to 512 bytes --- examples/wasm4/skipahead.cwa | 73 +++++++++++++++++++++--------------- src/ast.rs | 4 ++ src/constfold.rs | 4 ++ src/emit.rs | 11 ++++++ src/parser.rs | 9 ++++- src/typecheck.rs | 5 +++ 6 files changed, 74 insertions(+), 32 deletions(-) diff --git a/examples/wasm4/skipahead.cwa b/examples/wasm4/skipahead.cwa index cca4c88..af980fc 100644 --- a/examples/wasm4/skipahead.cwa +++ b/examples/wasm4/skipahead.cwa @@ -1,59 +1,70 @@ +// Sizecoded port of my TIC-80 game "skip ahead" +// 512 bytes of uncompressed wasm + import "env.memory" memory(1); import "env.rect" fn rect(i32, i32, i32, i32); import "env.oval" fn oval(i32, i32, i32, i32); +import "env.text" fn text(i32, i32, i32); -global mut pz: f32 = 0.0; -global mut px: f32 = 2.0; +global mut pz: i32 = 30; +global mut px: f32 = 0.0; global mut py: f32 = 0.0; global mut s: f32 = 0.0; global mut f: f32 = 0.0; -fn xorshift(state: i32) -> i32 { - 100902443 * ( - (state := - (state := state ^ (state << 13)) - ^ (state >> 17)) - ^ (state << 5) - ) +fn rng(state: i32) -> i32 { + 94614859 * (state ^ (state >> 17)) +} + +fn set_color(color: i32) -> i32 { + ?20 = color; + 6 } export fn update() { let y: i32; + let score = pz; + let defer pad = ?22; + let defer zero = 0.0; + + let defer control_speed = 0.03; + s = s + 0.1 - (f + control_speed) * (pad & 1) as f32; + f = f * 0.7; + loop lines { - let defer z = (200 as f32 / (y := y + 1) as f32 + pz) as i32; - let defer x = (xorshift(xorshift(xorshift(z))) & 3) as f32 / 2 as f32 - px; - let defer w = 6 as f32 / sqrt(z as f32); + ?(8003-y) = (score := score / 10) % 10 + 48; + let defer z = (4000 / (y := y + 1) + pz) / 20; + let defer x = (rng(rng(rng(rng(z)))) >>> 30) as f32 - px; + let defer w = 9 as f32 / sqrt(z as f32); let defer rx = 80 + (y as f32 * x) as i32; let defer rw = (y as f32 * w) as i32; let defer c = ((z & 1) + 2) * 17; - ?20 = c; - rect(rx, y, rw, y / 9); - ?20 = c + 17; - rect(rx, y + 1, rw, y / 9); + rect(rx, y, rw, y / set_color(c + 17)); - if y == 120 & py > 0.0 { - if x < -w | x > 0.0 { + text(8000, set_color(c) <| rect(rx, y, rw, 1), set_color(4)); + + if y == 120 & py > zero { + if x < -w | x > zero { + if pad & 2 { // (*) + pz = 30; // (*) + px = zero; // (*) + } // (*) return; } - py = 0.0; - s = 0.0; + py = zero; + s = zero; f = 0.8; } branch_if y < 160: lines; - }; + } - ?20 = 50; - oval(80 - 11, 114 - 11 + py as i32, 22, 22); - ?20 = 17; - oval(80 - 6, 114 - 6 + py as i32, 6, 6); - let defer pad = ?22; - let defer control_speed = 0.03; - px = px + (((pad >> 5) & 1) - ((pad >> 4) & 1)) as f32 * control_speed; - s = s + 0.1 - (f + control_speed) * (pad & 1) as f32; + let defer sy = 114 - 11 + py as i32; + oval(80 - 6, sy + 5, (set_color(50) <| oval(80 - 11, sy, 22, 22)), set_color(17)); + + px = px + (!(pad & 16) - !(pad & 32)) as f32 * control_speed; py = py + s; - pz = pz + 0.05; - f = f * 0.7; + pz = pz + 1; } \ No newline at end of file diff --git a/src/ast.rs b/src/ast.rs index 588621f..9dd4455 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -141,6 +141,10 @@ pub enum Expr { Return { value: Option>, }, + First { + value: Box, + drop: Box + }, Error, } diff --git a/src/constfold.rs b/src/constfold.rs index 8ac1264..86aba5c 100644 --- a/src/constfold.rs +++ b/src/constfold.rs @@ -212,6 +212,10 @@ fn fold_expr(expr: &mut ast::Expression) { } ast::Expr::Return { value: Some(ref mut value) } => fold_expr(value), ast::Expr::Return { value: None } => (), + ast::Expr::First { ref mut value, ref mut drop } => { + fold_expr(value); + fold_expr(drop); + } ast::Expr::Error => unreachable!() } } diff --git a/src/emit.rs b/src/emit.rs index 78611e7..d283236 100644 --- a/src/emit.rs +++ b/src/emit.rs @@ -291,6 +291,10 @@ fn collect_locals_expr<'a>(expr: &ast::Expression, locals: &mut Vec<(String, ast } ast::Expr::Return { value: Some(value) } => collect_locals_expr(value, locals), ast::Expr::Return { value: None } => (), + ast::Expr::First { value, drop } => { + collect_locals_expr(value, locals); + collect_locals_expr(drop, locals); + } ast::Expr::Error => unreachable!(), } } @@ -622,6 +626,13 @@ fn emit_expression<'a>(ctx: &mut FunctionContext<'a>, expr: &'a ast::Expression) } ctx.function.instruction(&Instruction::Return); } + ast::Expr::First { value, drop } => { + emit_expression(ctx, value); + emit_expression(ctx, drop); + if drop.type_.is_some() { + ctx.function.instruction(&Instruction::Drop); + } + } ast::Expr::Error => unreachable!(), } } diff --git a/src/parser.rs b/src/parser.rs index ef8ce74..e8516d0 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -675,7 +675,14 @@ fn script_parser() -> impl Parser> + C }) .boxed(); - op_bit + let op_first = op_bit.clone().then( + just(Token::Op("<|".to_string())).ignore_then(op_bit).repeated() + ).foldl(|left, right| { + let span = left.span.start..right.span.end; + ast::Expr::First { value: Box::new(left), drop: Box::new(right) }.with_span(span) + }).boxed(); + + op_first }); expression_out = Some(expression.clone()); diff --git a/src/typecheck.rs b/src/typecheck.rs index 07a0a08..1095821 100644 --- a/src/typecheck.rs +++ b/src/typecheck.rs @@ -687,6 +687,11 @@ fn tc_expression(context: &mut Context, expr: &mut ast::Expression) -> Result<() } None } + ast::Expr::First { ref mut value, ref mut drop } => { + tc_expression(context, value)?; + tc_expression(context, drop)?; + value.type_ + } ast::Expr::Error => unreachable!(), }; Ok(())