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};
|
use anyhow::{Result, anyhow};
|
||||||
|
|
||||||
pub fn get_callee_name(expr: &Expression) -> Result<String> {
|
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 {
|
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) => {
|
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();
|
let prop = member.property.name.to_string();
|
||||||
Ok(format!("{}.{}", obj, prop))
|
Ok(format!("{}.{}", obj, prop))
|
||||||
}
|
}
|
||||||
_ => Err(anyhow!("Unsupported callee expression")),
|
_ => Err(anyhow!("Unsupported 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"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,9 +3,11 @@ use oxc_ast::ast::*;
|
|||||||
use oxc_span::{Span, GetSpan};
|
use oxc_span::{Span, GetSpan};
|
||||||
use prometeu_bytecode::opcode::OpCode;
|
use prometeu_bytecode::opcode::OpCode;
|
||||||
use prometeu_bytecode::asm::{Asm, Operand, assemble};
|
use prometeu_bytecode::asm::{Asm, Operand, assemble};
|
||||||
|
use prometeu_bytecode::pbc::{ConstantPoolEntry, PbcFile, write_pbc};
|
||||||
use crate::compiler::Symbol;
|
use crate::compiler::Symbol;
|
||||||
use crate::syscall_map;
|
use crate::syscall_map;
|
||||||
use crate::codegen::ast_util;
|
use crate::codegen::ast_util;
|
||||||
|
use prometeu_core::prometeu_os::Syscall;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use prometeu_bytecode::asm;
|
use prometeu_bytecode::asm;
|
||||||
|
|
||||||
@ -15,6 +17,7 @@ pub struct Codegen {
|
|||||||
pub symbols: Vec<Symbol>,
|
pub symbols: Vec<Symbol>,
|
||||||
instructions: Vec<(Asm, bool)>, // (Asm, has_symbol)
|
instructions: Vec<(Asm, bool)>, // (Asm, has_symbol)
|
||||||
locals: HashMap<String, u32>,
|
locals: HashMap<String, u32>,
|
||||||
|
constant_pool: Vec<ConstantPoolEntry>,
|
||||||
next_local: u32,
|
next_local: u32,
|
||||||
label_count: u32,
|
label_count: u32,
|
||||||
}
|
}
|
||||||
@ -27,11 +30,22 @@ impl Codegen {
|
|||||||
symbols: Vec::new(),
|
symbols: Vec::new(),
|
||||||
instructions: Vec::new(),
|
instructions: Vec::new(),
|
||||||
locals: HashMap::new(),
|
locals: HashMap::new(),
|
||||||
|
constant_pool: vec![ConstantPoolEntry::Null], // Index 0 is always Null
|
||||||
next_local: 0,
|
next_local: 0,
|
||||||
label_count: 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>> {
|
pub fn compile_program(&mut self, program: &Program) -> Result<Vec<u8>> {
|
||||||
// Find tick function
|
// Find tick function
|
||||||
let mut tick_fn = None;
|
let mut tick_fn = None;
|
||||||
@ -63,12 +77,17 @@ impl Codegen {
|
|||||||
self.emit_op(OpCode::Ret, vec![], Span::default());
|
self.emit_op(OpCode::Ret, vec![], Span::default());
|
||||||
|
|
||||||
let asm_vec: Vec<Asm> = self.instructions.iter().map(|(a, _)| a.clone()).collect();
|
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)
|
// Finalize symbols (associate PC)
|
||||||
self.finalize_symbols();
|
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<()> {
|
fn compile_function(&mut self, f: &Function) -> Result<()> {
|
||||||
@ -150,6 +169,13 @@ impl Codegen {
|
|||||||
Expression::BooleanLiteral(b) => {
|
Expression::BooleanLiteral(b) => {
|
||||||
self.emit_op(OpCode::PushBool, vec![Operand::Bool(b.value)], b.span);
|
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) => {
|
Expression::Identifier(ident) => {
|
||||||
let name = ident.name.to_string();
|
let name = ident.name.to_string();
|
||||||
if let Some(&id) = self.locals.get(&name) {
|
if let Some(&id) = self.locals.get(&name) {
|
||||||
@ -251,12 +277,6 @@ impl Codegen {
|
|||||||
|
|
||||||
self.emit_op(OpCode::BitOr, vec![], call.span);
|
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 {
|
} else {
|
||||||
for arg in &call.arguments {
|
for arg in &call.arguments {
|
||||||
if let Some(expr) = arg.as_expression() {
|
if let Some(expr) = arg.as_expression() {
|
||||||
@ -270,20 +290,65 @@ impl Codegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expression::StaticMemberExpression(member) => {
|
Expression::StaticMemberExpression(member) => {
|
||||||
let obj = ast_util::get_callee_name_from_member_obj(&member.object)?;
|
let full_name = ast_util::get_member_expr_name(expr)?;
|
||||||
let prop = member.property.name.to_string();
|
|
||||||
let full_name = format!("{}.{}", obj, prop);
|
|
||||||
|
|
||||||
match full_name.as_str() {
|
if full_name.to_lowercase().starts_with("color.") {
|
||||||
"Color.black" | "color.black" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0x0000)], member.span),
|
match full_name.to_lowercase().as_str() {
|
||||||
"Color.white" | "color.white" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0xffff)], member.span),
|
"color.black" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0x0000)], member.span),
|
||||||
"Color.red" | "color.red" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0xf800)], member.span),
|
"color.white" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0xffff)], member.span),
|
||||||
"Color.green" | "color.green" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0x07e0)], member.span),
|
"color.red" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0xf800)], member.span),
|
||||||
"Color.blue" | "color.blue" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0x001f)], member.span),
|
"color.green" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0x07e0)], member.span),
|
||||||
"Color.yellow" | "color.yellow" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0xffe0)], member.span),
|
"color.blue" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0x001f)], member.span),
|
||||||
"Color.cyan" | "color.cyan" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0x07ff)], member.span),
|
"color.yellow" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0xffe0)], member.span),
|
||||||
"Color.magenta" | "color.magenta" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0xf81f)], member.span),
|
"color.cyan" => self.emit_op(OpCode::PushI32, vec![Operand::I32(0x07ff)], member.span),
|
||||||
_ => return Err(anyhow!("Member expression outside call not supported: {} at {:?}", full_name, 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())),
|
_ => return Err(anyhow!("Unsupported expression type at {:?}", expr.span())),
|
||||||
@ -291,6 +356,24 @@ impl Codegen {
|
|||||||
Ok(())
|
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 {
|
fn new_label(&mut self, prefix: &str) -> String {
|
||||||
let label = format!("{}_{}", prefix, self.label_count);
|
let label = format!("{}_{}", prefix, self.label_count);
|
||||||
self.label_count += 1;
|
self.label_count += 1;
|
||||||
|
|||||||
@ -65,6 +65,8 @@ impl<'a> Visit<'a> for Validator {
|
|||||||
match expr {
|
match expr {
|
||||||
Expression::NumericLiteral(_) |
|
Expression::NumericLiteral(_) |
|
||||||
Expression::BooleanLiteral(_) |
|
Expression::BooleanLiteral(_) |
|
||||||
|
Expression::StringLiteral(_) |
|
||||||
|
Expression::NullLiteral(_) |
|
||||||
Expression::Identifier(_) |
|
Expression::Identifier(_) |
|
||||||
Expression::AssignmentExpression(_) |
|
Expression::AssignmentExpression(_) |
|
||||||
Expression::BinaryExpression(_) |
|
Expression::BinaryExpression(_) |
|
||||||
|
|||||||
@ -34,7 +34,15 @@ impl CompilationUnit {
|
|||||||
|
|
||||||
if emit_disasm {
|
if emit_disasm {
|
||||||
let disasm_path = out.with_extension("disasm.txt");
|
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();
|
let mut disasm_text = String::new();
|
||||||
for instr in instructions {
|
for instr in instructions {
|
||||||
|
|||||||
@ -21,7 +21,6 @@ pub fn map_syscall(name: &str) -> Option<u32> {
|
|||||||
|
|
||||||
// Fallback para nomes especiais do compilador
|
// Fallback para nomes especiais do compilador
|
||||||
match name {
|
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)
|
"Color.rgb" | "color.rgb" => Some(0xFFFF_FFFF), // ID especial para Color.rgb (não é um syscall real)
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -331,6 +331,25 @@ impl PrometeuOS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper para syscalls
|
// 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 {
|
pub fn is_button_down(&self, id: u32, hw: &mut dyn HardwareBridge) -> bool {
|
||||||
match id {
|
match id {
|
||||||
0 => hw.pad().up.down,
|
0 => hw.pad().up.down,
|
||||||
@ -650,6 +669,49 @@ impl NativeInterface for PrometeuOS {
|
|||||||
vm.push(Value::Boolean(is_down));
|
vm.push(Value::Boolean(is_down));
|
||||||
Ok(50)
|
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 ---
|
// --- Audio Syscalls ---
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,16 @@ pub enum Syscall {
|
|||||||
|
|
||||||
// Input
|
// Input
|
||||||
InputGetPad = 0x2001,
|
InputGetPad = 0x2001,
|
||||||
|
InputGetPadPressed = 0x2002,
|
||||||
|
InputGetPadReleased = 0x2003,
|
||||||
|
InputGetPadHold = 0x2004,
|
||||||
|
|
||||||
|
TouchGetX = 0x2101,
|
||||||
|
TouchGetY = 0x2102,
|
||||||
|
TouchIsDown = 0x2103,
|
||||||
|
TouchIsPressed = 0x2104,
|
||||||
|
TouchIsReleased = 0x2105,
|
||||||
|
TouchGetHold = 0x2106,
|
||||||
|
|
||||||
// Audio
|
// Audio
|
||||||
AudioPlaySample = 0x3001,
|
AudioPlaySample = 0x3001,
|
||||||
@ -45,6 +55,15 @@ impl Syscall {
|
|||||||
0x1005 => Some(Self::GfxDrawDisc),
|
0x1005 => Some(Self::GfxDrawDisc),
|
||||||
0x1006 => Some(Self::GfxDrawSquare),
|
0x1006 => Some(Self::GfxDrawSquare),
|
||||||
0x2001 => Some(Self::InputGetPad),
|
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),
|
0x3001 => Some(Self::AudioPlaySample),
|
||||||
0x4001 => Some(Self::FsOpen),
|
0x4001 => Some(Self::FsOpen),
|
||||||
0x4002 => Some(Self::FsRead),
|
0x4002 => Some(Self::FsRead),
|
||||||
@ -59,75 +78,70 @@ impl Syscall {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_str(&self) -> &'static str {
|
// pub fn as_str(&self) -> &'static str {
|
||||||
match self {
|
// match self {
|
||||||
Self::SystemHasCart => "system.has_cart",
|
// Self::SystemHasCart => "system.has_cart",
|
||||||
Self::SystemRunCart => "system.run_cart",
|
// Self::SystemRunCart => "system.run_cart",
|
||||||
Self::GfxClear => "gfx.clear",
|
// Self::GfxClear => "gfx.clear",
|
||||||
Self::GfxFillRect => "gfx.fillRect",
|
// Self::GfxFillRect => "gfx.fillRect",
|
||||||
Self::GfxDrawLine => "gfx.drawLine",
|
// Self::GfxDrawLine => "gfx.drawLine",
|
||||||
Self::GfxDrawCircle => "gfx.drawCircle",
|
// Self::GfxDrawCircle => "gfx.drawCircle",
|
||||||
Self::GfxDrawDisc => "gfx.drawDisc",
|
// Self::GfxDrawDisc => "gfx.drawDisc",
|
||||||
Self::GfxDrawSquare => "gfx.drawSquare",
|
// Self::GfxDrawSquare => "gfx.drawSquare",
|
||||||
Self::InputGetPad => "input.get_pad",
|
// Self::InputGetPad => "input.get_pad",
|
||||||
Self::AudioPlaySample => "audio.playSample",
|
// Self::InputGetPadPressed => "input.get_pad_pressed",
|
||||||
Self::FsOpen => "fs.open",
|
// Self::InputGetPadReleased => "input.get_pad_released",
|
||||||
Self::FsRead => "fs.read",
|
// Self::InputGetPadHold => "input.get_pad_hold",
|
||||||
Self::FsWrite => "fs.write",
|
// Self::TouchGetX => "touch.getX",
|
||||||
Self::FsClose => "fs.close",
|
// Self::TouchGetY => "touch.getY",
|
||||||
Self::FsListDir => "fs.listDir",
|
// Self::TouchIsDown => "touch.isDown",
|
||||||
Self::FsExists => "fs.exists",
|
// Self::TouchIsPressed => "touch.isPressed",
|
||||||
Self::FsDelete => "fs.delete",
|
// Self::TouchIsReleased => "touch.isReleased",
|
||||||
Self::LogWrite => "log.write",
|
// Self::TouchGetHold => "touch.getHold",
|
||||||
Self::LogWriteTag => "log.writeTag",
|
// 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> {
|
pub fn from_name(name: &str) -> Option<Self> {
|
||||||
let name_lower = name.to_lowercase();
|
match name {
|
||||||
match name_lower.as_str() {
|
"system.hasCart" => Some(Self::SystemHasCart),
|
||||||
"system.has_cart" => Some(Self::SystemHasCart),
|
|
||||||
"system.run_cart" => Some(Self::SystemRunCart),
|
|
||||||
"gfx.clear" => Some(Self::GfxClear),
|
"gfx.clear" => Some(Self::GfxClear),
|
||||||
"gfx.fillrect" | "gfx.draw_rect" => Some(Self::GfxFillRect),
|
"gfx.fillRect" | "gfx.draw_rect" => Some(Self::GfxFillRect),
|
||||||
"gfx.drawline" | "gfx.draw_line" => Some(Self::GfxDrawLine),
|
"gfx.drawLine" | "gfx.draw_line" => Some(Self::GfxDrawLine),
|
||||||
"gfx.drawcircle" | "gfx.draw_circle" => Some(Self::GfxDrawCircle),
|
"gfx.drawCircle" | "gfx.draw_circle" => Some(Self::GfxDrawCircle),
|
||||||
"gfx.drawdisc" | "gfx.draw_disc" => Some(Self::GfxDrawDisc),
|
"fx.drawDisc" | "gfx.draw_disc" => Some(Self::GfxDrawDisc),
|
||||||
"gfx.drawsquare" | "gfx.draw_square" => Some(Self::GfxDrawSquare),
|
"gfx.drawSquare" | "gfx.draw_square" => Some(Self::GfxDrawSquare),
|
||||||
"input.get_pad" => Some(Self::InputGetPad),
|
"input.getPad" => Some(Self::InputGetPad),
|
||||||
"audio.playsample" | "audio.play_sample" => Some(Self::AudioPlaySample),
|
"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.open" => Some(Self::FsOpen),
|
||||||
"fs.read" => Some(Self::FsRead),
|
"fs.read" => Some(Self::FsRead),
|
||||||
"fs.write" => Some(Self::FsWrite),
|
"fs.write" => Some(Self::FsWrite),
|
||||||
"fs.close" => Some(Self::FsClose),
|
"fs.close" => Some(Self::FsClose),
|
||||||
"fs.listdir" => Some(Self::FsListDir),
|
"fs.listDir" | "fs.list_dir" => Some(Self::FsListDir),
|
||||||
"fs.exists" => Some(Self::FsExists),
|
"fs.exists" => Some(Self::FsExists),
|
||||||
"fs.delete" => Some(Self::FsDelete),
|
"fs.delete" => Some(Self::FsDelete),
|
||||||
"log.write" => Some(Self::LogWrite),
|
"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)
|
None
|
||||||
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,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
export function tick(): void {
|
export function tick(): void {
|
||||||
let color = 0x07E0; // green
|
let color = 0x07E0; // green
|
||||||
|
|
||||||
if (Input.btnA()) color = 0xF800; // red
|
if (PInput.btnA()) color = 0xF800; // red
|
||||||
if (Input.btnB()) color = 0x001F; // blue
|
if (PInput.btnB()) color = 0x001F; // blue
|
||||||
|
|
||||||
Gfx.fillRect(60, 60, 40, 40, color);
|
Gfx.fillRect(60, 60, 40, 40, color);
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user