prometeu-sdk scratch
This commit is contained in:
parent
b7425e5a20
commit
1b091e6ce8
@ -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())),
|
||||
}
|
||||
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user