diff options
author | Ashelyn Rose <git@ashen.earth> | 2024-12-21 17:23:24 -0700 |
---|---|---|
committer | Ashelyn Rose <git@ashen.earth> | 2024-12-21 17:23:24 -0700 |
commit | 9a2c2bc2d9ff45b9bd96c570b8c5fc0b03067ccc (patch) | |
tree | 12f65bfca6e285911713c6699b4d2a534df88cd4 /opcode_proc/src/lib.rs | |
parent | fbbeed8c10dc9c9bdb34f946d5b844b537ebad7a (diff) |
Implement setiosys
Diffstat (limited to 'opcode_proc/src/lib.rs')
-rw-r--r-- | opcode_proc/src/lib.rs | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/opcode_proc/src/lib.rs b/opcode_proc/src/lib.rs index d777214..7c84f9a 100644 --- a/opcode_proc/src/lib.rs +++ b/opcode_proc/src/lib.rs @@ -19,7 +19,7 @@ pub fn generate_opcodes(item: TokenStream) -> TokenStream { let code = &field.byte_code; let variant = &field.name; quote! { - #code => Self::#variant, + #code => Some(Self::#variant), } }).collect::<Vec<_>>(); @@ -39,6 +39,14 @@ pub fn generate_opcodes(item: TokenStream) -> TokenStream { } }); + let gen_stub_arms = ops_def.codes.iter().map(|field| { + let variant = &field.name; + let value = &field.no_store; + quote! { + #enum_name::#variant => #value, + } + }); + let closure_match_arms = ops_def.codes.iter().map(|field| { let variant = &field.name; let closure_expr = &field.func_block; @@ -87,15 +95,16 @@ pub fn generate_opcodes(item: TokenStream) -> TokenStream { }); let tokens = quote! { + #[derive(Debug, Clone)] pub enum #enum_name { #(#field_names),* } impl #enum_name { - pub fn get_from_code(code: u32) -> Self { + pub fn get_from_code(code: u32) -> Option<Self> { match code { #(#getcode_match_arms)* - _ => panic!("Unknown opcode 0x{code:03x}") + _ => None } } @@ -111,6 +120,12 @@ pub fn generate_opcodes(item: TokenStream) -> TokenStream { } } + pub fn should_gen_return_stub(opcode: Self) -> bool { + match opcode { + #(#gen_stub_arms)* + } + } + pub fn call_opcode(interpreter: &mut crate::Interpreter, opcode: Self, input_params: Vec<u32>) -> Vec<u32> { match opcode { #(#closure_match_arms)* @@ -148,6 +163,15 @@ impl Parse for SingleOpcodeDefinition { parenthesized!(code in attr); let byte_code = code.parse::<LitInt>()?; + let mut no_store = false; + if attr.peek(Token![,]) { + attr.parse::<Token![,]>()?; + let extra_attr = attr.parse::<Ident>()?; + if extra_attr == "no_store" { + no_store = true; + } + } + input.parse::<Token![fn]>()?; let name = input.parse::<Ident>()?; @@ -186,6 +210,7 @@ impl Parse for SingleOpcodeDefinition { Ok(SingleOpcodeDefinition { byte_code, + no_store, name, input_params, interpreter_ident, @@ -204,6 +229,7 @@ struct OpcodeBlock { struct SingleOpcodeDefinition { pub byte_code: LitInt, + pub no_store: bool, pub name: Ident, pub interpreter_ident: Option<Ident>, pub input_params: Vec<PatType>, |