prometeu-sdk scratch

This commit is contained in:
Nilton Constantino 2026-01-21 07:01:09 +00:00
parent b7425e5a20
commit 1b091e6ce8
No known key found for this signature in database
3 changed files with 91 additions and 16 deletions

View File

@ -213,18 +213,58 @@ impl Codegen {
Expression::CallExpression(call) => {
let name = ast_util::get_callee_name(&call.callee)?;
if let Some(syscall_id) = syscall_map::map_syscall(&name) {
if name == "input.btnA" {
if syscall_id == 0xFFFF_FFFF {
// Color.rgb(r, g, b)
if call.arguments.len() != 3 {
return Err(anyhow!("Color.rgb expects 3 arguments at {:?}", call.span));
}
// We'll emit the bit manipulation logic here or just a special syscall if we had one.
// Since we have bitwise opcodes, let's use them!
// ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)
// Argument 0: r
if let Some(expr) = call.arguments[0].as_expression() {
self.compile_expr(expr)?;
self.emit_op(OpCode::PushI32, vec![Operand::I32(3)], call.span);
self.emit_op(OpCode::Shr, vec![], call.span);
self.emit_op(OpCode::PushI32, vec![Operand::I32(11)], call.span);
self.emit_op(OpCode::Shl, vec![], call.span);
}
// Argument 1: g
if let Some(expr) = call.arguments[1].as_expression() {
self.compile_expr(expr)?;
self.emit_op(OpCode::PushI32, vec![Operand::I32(2)], call.span);
self.emit_op(OpCode::Shr, vec![], call.span);
self.emit_op(OpCode::PushI32, vec![Operand::I32(5)], call.span);
self.emit_op(OpCode::Shl, vec![], call.span);
}
self.emit_op(OpCode::BitOr, vec![], call.span);
// Argument 2: b
if let Some(expr) = call.arguments[2].as_expression() {
self.compile_expr(expr)?;
self.emit_op(OpCode::PushI32, vec![Operand::I32(3)], call.span);
self.emit_op(OpCode::Shr, 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);
} else if name == "input.btnB" {
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() {
self.compile_expr(expr)?;
}
}
self.emit_op(OpCode::Syscall, vec![Operand::U32(syscall_id)], call.span);
}
self.emit_op(OpCode::Syscall, vec![Operand::U32(syscall_id)], call.span);
} else {
return Err(anyhow!("Unsupported function call: {} at {:?}", name, call.span));
}
@ -233,8 +273,18 @@ impl Codegen {
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);
// If it's used as a value (GetGlobal/GetLocal?), but for now we only support it in calls
return Err(anyhow!("Member expression outside call not supported: {} at {:?}", full_name, member.span));
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)),
}
}
_ => return Err(anyhow!("Unsupported expression type at {:?}", expr.span())),
}

View File

@ -21,7 +21,8 @@ pub fn map_syscall(name: &str) -> Option<u32> {
// Fallback para nomes especiais do compilador
match name {
"input.btnA" | "input.btnB" => Some(Syscall::InputGetPad as u32),
"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,
}
}

View File

@ -84,27 +84,51 @@ impl Syscall {
}
pub fn from_name(name: &str) -> Option<Self> {
match name {
let name_lower = name.to_lowercase();
match name_lower.as_str() {
"system.has_cart" => Some(Self::SystemHasCart),
"system.run_cart" => Some(Self::SystemRunCart),
"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),
"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),
"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" => Some(Self::FsListDir),
"fs.exists" => Some(Self::FsExists),
"fs.delete" => Some(Self::FsDelete),
"log.write" => Some(Self::LogWrite),
"log.writeTag" => Some(Self::LogWriteTag),
_ => None,
"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,
}
}
}
}
}