many fixes on compiler
This commit is contained in:
parent
1b091e6ce8
commit
11d9d31c2f
@ -2,21 +2,25 @@ use oxc_ast::ast::*;
|
||||
use anyhow::{Result, anyhow};
|
||||
|
||||
pub fn get_callee_name(expr: &Expression) -> Result<String> {
|
||||
get_member_expr_name(expr)
|
||||
}
|
||||
|
||||
pub fn get_member_expr_name(expr: &Expression) -> Result<String> {
|
||||
match expr {
|
||||
Expression::Identifier(ident) => Ok(ident.name.to_string()),
|
||||
Expression::Identifier(ident) => {
|
||||
let name = ident.name.to_string();
|
||||
// Remove prefix 'P' if it's followed by an uppercase letter (e.g., PGfx -> Gfx)
|
||||
if name.len() > 1 && name.starts_with('P') && name.chars().nth(1).unwrap().is_uppercase() {
|
||||
Ok(name[1..].to_string())
|
||||
} else {
|
||||
Ok(name)
|
||||
}
|
||||
}
|
||||
Expression::StaticMemberExpression(member) => {
|
||||
let obj = get_callee_name_from_member_obj(&member.object)?;
|
||||
let obj = get_member_expr_name(&member.object)?;
|
||||
let prop = member.property.name.to_string();
|
||||
Ok(format!("{}.{}", obj, prop))
|
||||
}
|
||||
_ => Err(anyhow!("Unsupported callee expression")),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_callee_name_from_member_obj(expr: &Expression) -> Result<String> {
|
||||
if let Expression::Identifier(ident) = expr {
|
||||
Ok(ident.name.to_string())
|
||||
} else {
|
||||
Err(anyhow!("Unsupported member object expression"))
|
||||
_ => Err(anyhow!("Unsupported expression")),
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,9 +3,11 @@ use oxc_ast::ast::*;
|
||||
use oxc_span::{Span, GetSpan};
|
||||
use prometeu_bytecode::opcode::OpCode;
|
||||
use prometeu_bytecode::asm::{Asm, Operand, assemble};
|
||||
use prometeu_bytecode::pbc::{ConstantPoolEntry, PbcFile, write_pbc};
|
||||
use crate::compiler::Symbol;
|
||||
use crate::syscall_map;
|
||||
use crate::codegen::ast_util;
|
||||
use prometeu_core::prometeu_os::Syscall;
|
||||
use std::collections::HashMap;
|
||||
use prometeu_bytecode::asm;
|
||||
|
||||
@ -15,6 +17,7 @@ pub struct Codegen {
|
||||
pub symbols: Vec<Symbol>,
|
||||
instructions: Vec<(Asm, bool)>, // (Asm, has_symbol)
|
||||
locals: HashMap<String, u32>,
|
||||
constant_pool: Vec<ConstantPoolEntry>,
|
||||
next_local: u32,
|
||||
label_count: u32,
|
||||
}
|
||||
@ -27,11 +30,22 @@ impl Codegen {
|
||||
symbols: Vec::new(),
|
||||
instructions: Vec::new(),
|
||||
locals: HashMap::new(),
|
||||
constant_pool: vec![ConstantPoolEntry::Null], // Index 0 is always Null
|
||||
next_local: 0,
|
||||
label_count: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn add_constant(&mut self, entry: ConstantPoolEntry) -> u32 {
|
||||
if let Some(pos) = self.constant_pool.iter().position(|e| e == &entry) {
|
||||
pos as u32
|
||||
} else {
|
||||
let pos = self.constant_pool.len();
|
||||
self.constant_pool.push(entry);
|
||||
pos as u32
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compile_program(&mut self, program: &Program) -> Result<Vec<u8>> {
|
||||
// Find tick function
|
||||
let mut tick_fn = None;
|
||||
@ -63,12 +77,17 @@ impl Codegen {
|
||||
self.emit_op(OpCode::Ret, vec![], Span::default());
|
||||
|
||||
let asm_vec: Vec<Asm> = self.instructions.iter().map(|(a, _)| a.clone()).collect();
|
||||
let rom = assemble(&asm_vec).map_err(|e| anyhow!("Assemble error: {}", e))?;
|
||||
let bytecode = assemble(&asm_vec).map_err(|e| anyhow!("Assemble error: {}", e))?;
|
||||
|
||||
// Finalize symbols (associate PC)
|
||||
self.finalize_symbols();
|
||||
|
||||
Ok(rom)
|
||||
let pbc = PbcFile {
|
||||
cp: self.constant_pool.clone(),
|
||||
rom: bytecode,
|
||||
};
|
||||
|
||||
write_pbc(&pbc).map_err(|e| anyhow!("PBC Write error: {}", e))
|
||||
}
|
||||
|
||||
fn compile_function(&mut self, f: &Function) -> Result<()> {
|
||||
@ -150,6 +169,13 @@ impl Codegen {
|
||||
Expression::BooleanLiteral(b) => {
|
||||
self.emit_op(OpCode::PushBool, vec![Operand::Bool(b.value)], b.span);
|
||||
}
|
||||
Expression::StringLiteral(s) => {
|
||||
let idx = self.add_constant(ConstantPoolEntry::String(s.value.to_string()));
|
||||
self.emit_op(OpCode::PushConst, vec![Operand::U32(idx)], s.span);
|
||||
}
|
||||
Expression::NullLiteral(n) => {
|
||||
self.emit_op(OpCode::PushConst, vec![Operand::U32(0)], n.span);
|
||||
}
|
||||
Expression::Identifier(ident) => {
|
||||
let name = ident.name.to_string();
|
||||
if let Some(&id) = self.locals.get(&name) {
|
||||
@ -251,12 +277,6 @@ impl Codegen {
|
||||
|
||||
self.emit_op(OpCode::BitOr, vec![], call.span);
|
||||
|
||||
} else if name == "input.btnA" || name == "Input.btnA" {
|
||||
self.emit_op(OpCode::PushI32, vec![Operand::I32(syscall_map::BTN_A as i32)], call.span);
|
||||
self.emit_op(OpCode::Syscall, vec![Operand::U32(syscall_id)], call.span);
|
||||
} else if name == "input.btnB" || name == "Input.btnB" {
|
||||
self.emit_op(OpCode::PushI32, vec![Operand::I32(syscall_map::BTN_B as i32)], call.span);
|
||||
self.emit_op(OpCode::Syscall, vec![Operand::U32(syscall_id)], call.span);
|
||||
} else {
|
||||
for arg in &call.arguments {
|
||||
if let Some(expr) = arg.as_expression() {
|
||||
@ -270,20 +290,65 @@ impl Codegen {
|
||||
}
|
||||
}
|
||||
Expression::StaticMemberExpression(member) => {
|
||||
let obj = ast_util::get_callee_name_from_member_obj(&member.object)?;
|
||||
let prop = member.property.name.to_string();
|
||||
let full_name = format!("{}.{}", obj, prop);
|
||||
let full_name = ast_util::get_member_expr_name(expr)?;
|
||||
|
||||
match full_name.as_str() {
|
||||
"Color.black" | "color.black" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0x0000)], member.span),
|
||||
"Color.white" | "color.white" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0xffff)], member.span),
|
||||
"Color.red" | "color.red" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0xf800)], member.span),
|
||||
"Color.green" | "color.green" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0x07e0)], member.span),
|
||||
"Color.blue" | "color.blue" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0x001f)], member.span),
|
||||
"Color.yellow" | "color.yellow" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0xffe0)], member.span),
|
||||
"Color.cyan" | "color.cyan" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0x07ff)], member.span),
|
||||
"Color.magenta" | "color.magenta" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0xf81f)], member.span),
|
||||
_ => return Err(anyhow!("Member expression outside call not supported: {} at {:?}", full_name, member.span)),
|
||||
if full_name.to_lowercase().starts_with("color.") {
|
||||
match full_name.to_lowercase().as_str() {
|
||||
"color.black" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0x0000)], member.span),
|
||||
"color.white" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0xffff)], member.span),
|
||||
"color.red" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0xf800)], member.span),
|
||||
"color.green" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0x07e0)], member.span),
|
||||
"color.blue" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0x001f)], member.span),
|
||||
"color.yellow" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0xffe0)], member.span),
|
||||
"color.cyan" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0x07ff)], member.span),
|
||||
"color.magenta" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0xf81f)], member.span),
|
||||
_ => return Err(anyhow!("Unsupported color constant: {} at {:?}", full_name, member.span)),
|
||||
}
|
||||
} else if full_name.to_lowercase().starts_with("pad.") {
|
||||
let parts: Vec<&str> = full_name.split('.').collect();
|
||||
if parts.len() == 3 {
|
||||
let btn_name = parts[1];
|
||||
let state_name = parts[2];
|
||||
let btn_id = self.map_btn_name(btn_name)?;
|
||||
let syscall_id = match state_name {
|
||||
"down" => Syscall::InputGetPad as u32,
|
||||
"pressed" => Syscall::InputGetPadPressed as u32,
|
||||
"released" => Syscall::InputGetPadReleased as u32,
|
||||
"holdFrames" => Syscall::InputGetPadHold as u32,
|
||||
_ => return Err(anyhow!("Unsupported button state: {} at {:?}", state_name, member.span)),
|
||||
};
|
||||
self.emit_op(OpCode::PushI32, vec![Operand::I32(btn_id as i32)], member.span);
|
||||
self.emit_op(OpCode::Syscall, vec![Operand::U32(syscall_id)], member.span);
|
||||
} else {
|
||||
return Err(anyhow!("Partial Pad access not supported: {} at {:?}", full_name, member.span));
|
||||
}
|
||||
} else if full_name.to_lowercase().starts_with("touch.") {
|
||||
let parts: Vec<&str> = full_name.split('.').collect();
|
||||
match parts.len() {
|
||||
2 => {
|
||||
let prop = parts[1];
|
||||
let syscall_id = match prop {
|
||||
"x" => Syscall::TouchGetX as u32,
|
||||
"y" => Syscall::TouchGetY as u32,
|
||||
_ => return Err(anyhow!("Unsupported touch property: {} at {:?}", prop, member.span)),
|
||||
};
|
||||
self.emit_op(OpCode::Syscall, vec![Operand::U32(syscall_id)], member.span);
|
||||
}
|
||||
3 if parts[1] == "button" => {
|
||||
let state_name = parts[2];
|
||||
let syscall_id = match state_name {
|
||||
"down" => Syscall::TouchIsDown as u32,
|
||||
"pressed" => Syscall::TouchIsPressed as u32,
|
||||
"released" => Syscall::TouchIsReleased as u32,
|
||||
"holdFrames" => Syscall::TouchGetHold as u32,
|
||||
_ => return Err(anyhow!("Unsupported touch button state: {} at {:?}", state_name, member.span)),
|
||||
};
|
||||
self.emit_op(OpCode::Syscall, vec![Operand::U32(syscall_id)], member.span);
|
||||
}
|
||||
_ => return Err(anyhow!("Unsupported touch access: {} at {:?}", full_name, member.span)),
|
||||
}
|
||||
} else {
|
||||
return Err(anyhow!("Member expression outside call not supported: {} at {:?}", full_name, member.span));
|
||||
}
|
||||
}
|
||||
_ => return Err(anyhow!("Unsupported expression type at {:?}", expr.span())),
|
||||
@ -291,6 +356,24 @@ impl Codegen {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn map_btn_name(&self, btn_name: &str) -> Result<u32> {
|
||||
match btn_name.to_lowercase().as_str() {
|
||||
"up" => Ok(syscall_map::BTN_UP),
|
||||
"down" => Ok(syscall_map::BTN_DOWN),
|
||||
"left" => Ok(syscall_map::BTN_LEFT),
|
||||
"right" => Ok(syscall_map::BTN_RIGHT),
|
||||
"a" => Ok(syscall_map::BTN_A),
|
||||
"b" => Ok(syscall_map::BTN_B),
|
||||
"x" => Ok(syscall_map::BTN_X),
|
||||
"y" => Ok(syscall_map::BTN_Y),
|
||||
"l" => Ok(syscall_map::BTN_L),
|
||||
"r" => Ok(syscall_map::BTN_R),
|
||||
"start" => Ok(syscall_map::BTN_START),
|
||||
"select" => Ok(syscall_map::BTN_SELECT),
|
||||
_ => Err(anyhow!("Unsupported button: {}", btn_name)),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_label(&mut self, prefix: &str) -> String {
|
||||
let label = format!("{}_{}", prefix, self.label_count);
|
||||
self.label_count += 1;
|
||||
|
||||
@ -65,6 +65,8 @@ impl<'a> Visit<'a> for Validator {
|
||||
match expr {
|
||||
Expression::NumericLiteral(_) |
|
||||
Expression::BooleanLiteral(_) |
|
||||
Expression::StringLiteral(_) |
|
||||
Expression::NullLiteral(_) |
|
||||
Expression::Identifier(_) |
|
||||
Expression::AssignmentExpression(_) |
|
||||
Expression::BinaryExpression(_) |
|
||||
|
||||
@ -34,7 +34,15 @@ impl CompilationUnit {
|
||||
|
||||
if emit_disasm {
|
||||
let disasm_path = out.with_extension("disasm.txt");
|
||||
let instructions = disasm(&self.rom).map_err(|e| anyhow::anyhow!("Disassembly failed: {}", e))?;
|
||||
|
||||
// Try to parse as PBC, if fails use raw
|
||||
let rom_to_disasm = if let Ok(pbc) = prometeu_bytecode::pbc::parse_pbc(&self.rom) {
|
||||
pbc.rom
|
||||
} else {
|
||||
self.rom.clone()
|
||||
};
|
||||
|
||||
let instructions = disasm(&rom_to_disasm).map_err(|e| anyhow::anyhow!("Disassembly failed: {}", e))?;
|
||||
|
||||
let mut disasm_text = String::new();
|
||||
for instr in instructions {
|
||||
|
||||
@ -21,7 +21,6 @@ pub fn map_syscall(name: &str) -> Option<u32> {
|
||||
|
||||
// Fallback para nomes especiais do compilador
|
||||
match name {
|
||||
"input.btnA" | "input.btnB" | "Input.btnA" | "Input.btnB" => Some(Syscall::InputGetPad as u32),
|
||||
"Color.rgb" | "color.rgb" => Some(0xFFFF_FFFF), // ID especial para Color.rgb (não é um syscall real)
|
||||
_ => None,
|
||||
}
|
||||
|
||||
@ -331,6 +331,25 @@ impl PrometeuOS {
|
||||
}
|
||||
|
||||
// Helper para syscalls
|
||||
pub fn get_button<'a>(&self, id: u32, hw: &'a dyn HardwareBridge) -> Option<&'a crate::model::Button> {
|
||||
let pad = hw.pad();
|
||||
match id {
|
||||
0 => Some(&pad.up),
|
||||
1 => Some(&pad.down),
|
||||
2 => Some(&pad.left),
|
||||
3 => Some(&pad.right),
|
||||
4 => Some(&pad.a),
|
||||
5 => Some(&pad.b),
|
||||
6 => Some(&pad.x),
|
||||
7 => Some(&pad.y),
|
||||
8 => Some(&pad.l),
|
||||
9 => Some(&pad.r),
|
||||
10 => Some(&pad.start),
|
||||
11 => Some(&pad.select),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_button_down(&self, id: u32, hw: &mut dyn HardwareBridge) -> bool {
|
||||
match id {
|
||||
0 => hw.pad().up.down,
|
||||
@ -650,6 +669,49 @@ impl NativeInterface for PrometeuOS {
|
||||
vm.push(Value::Boolean(is_down));
|
||||
Ok(50)
|
||||
}
|
||||
Syscall::InputGetPadPressed => {
|
||||
let button_id = vm.pop_integer()? as u32;
|
||||
let val = self.get_button(button_id, hw).map(|b| b.pressed).unwrap_or(false);
|
||||
vm.push(Value::Boolean(val));
|
||||
Ok(50)
|
||||
}
|
||||
Syscall::InputGetPadReleased => {
|
||||
let button_id = vm.pop_integer()? as u32;
|
||||
let val = self.get_button(button_id, hw).map(|b| b.released).unwrap_or(false);
|
||||
vm.push(Value::Boolean(val));
|
||||
Ok(50)
|
||||
}
|
||||
Syscall::InputGetPadHold => {
|
||||
let button_id = vm.pop_integer()? as u32;
|
||||
let val = self.get_button(button_id, hw).map(|b| b.hold_frames).unwrap_or(0);
|
||||
vm.push(Value::Int32(val as i32));
|
||||
Ok(50)
|
||||
}
|
||||
|
||||
Syscall::TouchGetX => {
|
||||
vm.push(Value::Int32(hw.touch().x));
|
||||
Ok(50)
|
||||
}
|
||||
Syscall::TouchGetY => {
|
||||
vm.push(Value::Int32(hw.touch().y));
|
||||
Ok(50)
|
||||
}
|
||||
Syscall::TouchIsDown => {
|
||||
vm.push(Value::Boolean(hw.touch().f.down));
|
||||
Ok(50)
|
||||
}
|
||||
Syscall::TouchIsPressed => {
|
||||
vm.push(Value::Boolean(hw.touch().f.pressed));
|
||||
Ok(50)
|
||||
}
|
||||
Syscall::TouchIsReleased => {
|
||||
vm.push(Value::Boolean(hw.touch().f.released));
|
||||
Ok(50)
|
||||
}
|
||||
Syscall::TouchGetHold => {
|
||||
vm.push(Value::Int32(hw.touch().f.hold_frames as i32));
|
||||
Ok(50)
|
||||
}
|
||||
|
||||
// --- Audio Syscalls ---
|
||||
|
||||
|
||||
@ -15,6 +15,16 @@ pub enum Syscall {
|
||||
|
||||
// Input
|
||||
InputGetPad = 0x2001,
|
||||
InputGetPadPressed = 0x2002,
|
||||
InputGetPadReleased = 0x2003,
|
||||
InputGetPadHold = 0x2004,
|
||||
|
||||
TouchGetX = 0x2101,
|
||||
TouchGetY = 0x2102,
|
||||
TouchIsDown = 0x2103,
|
||||
TouchIsPressed = 0x2104,
|
||||
TouchIsReleased = 0x2105,
|
||||
TouchGetHold = 0x2106,
|
||||
|
||||
// Audio
|
||||
AudioPlaySample = 0x3001,
|
||||
@ -45,6 +55,15 @@ impl Syscall {
|
||||
0x1005 => Some(Self::GfxDrawDisc),
|
||||
0x1006 => Some(Self::GfxDrawSquare),
|
||||
0x2001 => Some(Self::InputGetPad),
|
||||
0x2002 => Some(Self::InputGetPadPressed),
|
||||
0x2003 => Some(Self::InputGetPadReleased),
|
||||
0x2004 => Some(Self::InputGetPadHold),
|
||||
0x2101 => Some(Self::TouchGetX),
|
||||
0x2102 => Some(Self::TouchGetY),
|
||||
0x2103 => Some(Self::TouchIsDown),
|
||||
0x2104 => Some(Self::TouchIsPressed),
|
||||
0x2105 => Some(Self::TouchIsReleased),
|
||||
0x2106 => Some(Self::TouchGetHold),
|
||||
0x3001 => Some(Self::AudioPlaySample),
|
||||
0x4001 => Some(Self::FsOpen),
|
||||
0x4002 => Some(Self::FsRead),
|
||||
@ -59,75 +78,70 @@ impl Syscall {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::SystemHasCart => "system.has_cart",
|
||||
Self::SystemRunCart => "system.run_cart",
|
||||
Self::GfxClear => "gfx.clear",
|
||||
Self::GfxFillRect => "gfx.fillRect",
|
||||
Self::GfxDrawLine => "gfx.drawLine",
|
||||
Self::GfxDrawCircle => "gfx.drawCircle",
|
||||
Self::GfxDrawDisc => "gfx.drawDisc",
|
||||
Self::GfxDrawSquare => "gfx.drawSquare",
|
||||
Self::InputGetPad => "input.get_pad",
|
||||
Self::AudioPlaySample => "audio.playSample",
|
||||
Self::FsOpen => "fs.open",
|
||||
Self::FsRead => "fs.read",
|
||||
Self::FsWrite => "fs.write",
|
||||
Self::FsClose => "fs.close",
|
||||
Self::FsListDir => "fs.listDir",
|
||||
Self::FsExists => "fs.exists",
|
||||
Self::FsDelete => "fs.delete",
|
||||
Self::LogWrite => "log.write",
|
||||
Self::LogWriteTag => "log.writeTag",
|
||||
}
|
||||
}
|
||||
// pub fn as_str(&self) -> &'static str {
|
||||
// match self {
|
||||
// Self::SystemHasCart => "system.has_cart",
|
||||
// Self::SystemRunCart => "system.run_cart",
|
||||
// Self::GfxClear => "gfx.clear",
|
||||
// Self::GfxFillRect => "gfx.fillRect",
|
||||
// Self::GfxDrawLine => "gfx.drawLine",
|
||||
// Self::GfxDrawCircle => "gfx.drawCircle",
|
||||
// Self::GfxDrawDisc => "gfx.drawDisc",
|
||||
// Self::GfxDrawSquare => "gfx.drawSquare",
|
||||
// Self::InputGetPad => "input.get_pad",
|
||||
// Self::InputGetPadPressed => "input.get_pad_pressed",
|
||||
// Self::InputGetPadReleased => "input.get_pad_released",
|
||||
// Self::InputGetPadHold => "input.get_pad_hold",
|
||||
// Self::TouchGetX => "touch.getX",
|
||||
// Self::TouchGetY => "touch.getY",
|
||||
// Self::TouchIsDown => "touch.isDown",
|
||||
// Self::TouchIsPressed => "touch.isPressed",
|
||||
// Self::TouchIsReleased => "touch.isReleased",
|
||||
// Self::TouchGetHold => "touch.getHold",
|
||||
// Self::AudioPlaySample => "audio.playSample",
|
||||
// Self::FsOpen => "fs.open",
|
||||
// Self::FsRead => "fs.read",
|
||||
// Self::FsWrite => "fs.write",
|
||||
// Self::FsClose => "fs.close",
|
||||
// Self::FsListDir => "fs.listDir",
|
||||
// Self::FsExists => "fs.exists",
|
||||
// Self::FsDelete => "fs.delete",
|
||||
// Self::LogWrite => "log.write",
|
||||
// Self::LogWriteTag => "log.writeTag",
|
||||
// }
|
||||
// }
|
||||
|
||||
pub fn from_name(name: &str) -> Option<Self> {
|
||||
let name_lower = name.to_lowercase();
|
||||
match name_lower.as_str() {
|
||||
"system.has_cart" => Some(Self::SystemHasCart),
|
||||
"system.run_cart" => Some(Self::SystemRunCart),
|
||||
match name {
|
||||
"system.hasCart" => Some(Self::SystemHasCart),
|
||||
"gfx.clear" => Some(Self::GfxClear),
|
||||
"gfx.fillrect" | "gfx.draw_rect" => Some(Self::GfxFillRect),
|
||||
"gfx.drawline" | "gfx.draw_line" => Some(Self::GfxDrawLine),
|
||||
"gfx.drawcircle" | "gfx.draw_circle" => Some(Self::GfxDrawCircle),
|
||||
"gfx.drawdisc" | "gfx.draw_disc" => Some(Self::GfxDrawDisc),
|
||||
"gfx.drawsquare" | "gfx.draw_square" => Some(Self::GfxDrawSquare),
|
||||
"input.get_pad" => Some(Self::InputGetPad),
|
||||
"audio.playsample" | "audio.play_sample" => Some(Self::AudioPlaySample),
|
||||
"gfx.fillRect" | "gfx.draw_rect" => Some(Self::GfxFillRect),
|
||||
"gfx.drawLine" | "gfx.draw_line" => Some(Self::GfxDrawLine),
|
||||
"gfx.drawCircle" | "gfx.draw_circle" => Some(Self::GfxDrawCircle),
|
||||
"fx.drawDisc" | "gfx.draw_disc" => Some(Self::GfxDrawDisc),
|
||||
"gfx.drawSquare" | "gfx.draw_square" => Some(Self::GfxDrawSquare),
|
||||
"input.getPad" => Some(Self::InputGetPad),
|
||||
"input.getPadPressed" | "input.get_pad_pressed" => Some(Self::InputGetPadPressed),
|
||||
"input.getPadReleased" | "input.get_pad_released" => Some(Self::InputGetPadReleased),
|
||||
"input.getPadHold" | "input.get_pad_hold" => Some(Self::InputGetPadHold),
|
||||
"touch.getX" | "touch.get_x" => Some(Self::TouchGetX),
|
||||
"touch.getY" | "touch.get_y" => Some(Self::TouchGetY),
|
||||
"touch.isDown" | "touch.is_down" => Some(Self::TouchIsDown),
|
||||
"touch.isPressed" | "touch.is_pressed" => Some(Self::TouchIsPressed),
|
||||
"touch.isReleased" | "touch.is_released" => Some(Self::TouchIsReleased),
|
||||
"touch.getHold" | "touch.get_hold" => Some(Self::TouchGetHold),
|
||||
"audio.playSample" | "audio.play_sample" => Some(Self::AudioPlaySample),
|
||||
"fs.open" => Some(Self::FsOpen),
|
||||
"fs.read" => Some(Self::FsRead),
|
||||
"fs.write" => Some(Self::FsWrite),
|
||||
"fs.close" => Some(Self::FsClose),
|
||||
"fs.listdir" => Some(Self::FsListDir),
|
||||
"fs.listDir" | "fs.list_dir" => Some(Self::FsListDir),
|
||||
"fs.exists" => Some(Self::FsExists),
|
||||
"fs.delete" => Some(Self::FsDelete),
|
||||
"log.write" => Some(Self::LogWrite),
|
||||
"log.writetag" | "log.write_tag" => Some(Self::LogWriteTag),
|
||||
"log.writeTag" | "log.write_tag" => Some(Self::LogWriteTag),
|
||||
_ => {
|
||||
// Tenta corresponder exatamente se o lowercase falhar (para camelCase original)
|
||||
match name {
|
||||
"gfx.fillRect" => Some(Self::GfxFillRect),
|
||||
"gfx.drawLine" => Some(Self::GfxDrawLine),
|
||||
"gfx.drawCircle" => Some(Self::GfxDrawCircle),
|
||||
"gfx.drawDisc" => Some(Self::GfxDrawDisc),
|
||||
"gfx.drawSquare" => Some(Self::GfxDrawSquare),
|
||||
"audio.playSample" => Some(Self::AudioPlaySample),
|
||||
"fs.listDir" => Some(Self::FsListDir),
|
||||
"log.writeTag" => Some(Self::LogWriteTag),
|
||||
"Gfx.fillRect" => Some(Self::GfxFillRect),
|
||||
"Gfx.drawLine" => Some(Self::GfxDrawLine),
|
||||
"Gfx.drawCircle" => Some(Self::GfxDrawCircle),
|
||||
"Gfx.drawDisc" => Some(Self::GfxDrawDisc),
|
||||
"Gfx.drawSquare" => Some(Self::GfxDrawSquare),
|
||||
"Audio.playSample" => Some(Self::AudioPlaySample),
|
||||
"Fs.listDir" => Some(Self::FsListDir),
|
||||
"Log.writeTag" => Some(Self::LogWriteTag),
|
||||
"System.hasCart" | "System.has_cart" => Some(Self::SystemHasCart),
|
||||
"System.runCart" | "System.run_cart" => Some(Self::SystemRunCart),
|
||||
_ => None,
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
export function tick(): void {
|
||||
let color = 0x07E0; // green
|
||||
|
||||
if (Input.btnA()) color = 0xF800; // red
|
||||
if (Input.btnB()) color = 0x001F; // blue
|
||||
if (PInput.btnA()) color = 0xF800; // red
|
||||
if (PInput.btnB()) color = 0x001F; // blue
|
||||
|
||||
Gfx.fillRect(60, 60, 40, 40, color);
|
||||
}
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user