Skip to content

Commit f618f61

Browse files
implement yielding
1 parent e410653 commit f618f61

40 files changed

+726
-473
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ If you experience runtime stack overflow errors in debug mode, try using the `-s
2828
To add a new block named `category_opcode`, if it cannot be reduced to simpler blocks:
2929
1. create `src/instructions/category/opcode.rs`. Make sure to `use super::super::prelude::*` and create the relevant `pub` items:
3030
- (optional) `pub struct Fields` (must be `Debug` and `Clone`)
31-
- `pub fn wasm(func: &StepFunc, inputs: Rc<[IrType]>, (fields: &Fields)?) -> HQResult<Vec<Instruction<'static>>>;`
31+
- `pub fn wasm(func: &StepFunc, inputs: Rc<[IrType]>, (fields: &Fields)?) -> HQResult<Vec<InternalInstruction>>;`
3232
- - wasm is generated using the `wasm_gen::wasm` macro. See [its README](./wasm-gen/README.md) for usage instructions, or e.g. [say.rs](./src/instructions/looks/say.rs) for an example.
3333
- `pub fn acceptable_inputs() -> Rc<[IrType]>;`
3434
- - these should really be base types (see BASE_TYPES in [types.rs](./src/ir/types.rs))

build.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,14 @@ fn main() {
3838
let fields_name =
3939
format!("{}_{}_fields", category, opcode).to_case(Case::Pascal);
4040
paths.push((
41-
format!("{}::{}", category, opcode),
41+
format!(
42+
"{}::{}",
43+
category,
44+
match opcode {
45+
"yield" | "loop" => format!("r#{opcode}"),
46+
_ => opcode.to_string(),
47+
}
48+
),
4249
format!("{}_{}", category, opcode,),
4350
fields,
4451
fields_name,
@@ -116,21 +123,28 @@ pub enum IrOpcode {{
116123
117124
impl IrOpcode {{
118125
/// maps an opcode to its acceptable input types
119-
pub fn acceptable_inputs(&self) -> Rc<[crate::ir::Type]> {{
126+
pub fn acceptable_inputs(&self) -> Rc<[crate::ir::Type]> {{
120127
match self {{
121128
{}
122129
}}
123130
}}
124131
125132
/// maps an opcode to its WASM instructions
126-
pub fn wasm(&self, step_func: &crate::wasm::StepFunc, inputs: Rc<[crate::ir::Type]>) -> HQResult<Vec<wasm_encoder::Instruction<'static>>> {{
133+
pub fn wasm(&self, step_func: &crate::wasm::StepFunc, inputs: Rc<[crate::ir::Type]>) -> HQResult<Vec<crate::wasm::InternalInstruction>> {{
127134
match self {{
128135
{}
129136
}}
130137
}}
131138
132139
/// maps an opcode to its output type
133-
pub fn output_type(&self, inputs: Rc<[crate::ir::Type]>) -> HQResult<Option<crate::ir::Type>> {{
140+
pub fn output_type(&self, inputs: Rc<[crate::ir::Type]>) -> HQResult<Option<crate::ir::Type>> {{
141+
match self {{
142+
{}
143+
}}
144+
}}
145+
146+
/// does this opcode request a screen refresh (and by extension yields)?
147+
pub const fn yields(&self) -> bool {{
134148
match self {{
135149
{}
136150
}}
@@ -170,6 +184,13 @@ pub use fields::*;
170184
format!("IrOpcode::{} => {}::output_type(inputs),", id, path)
171185
}
172186
}).collect::<Vec<_>>().join("\n\t\t\t"),
187+
paths.iter().map(|(path, id, fields, _)| {
188+
if *fields {
189+
format!("IrOpcode::{}(_) => {}::YIELDS,", id, path)
190+
} else {
191+
format!("IrOpcode::{} => {}::YIELDS,", id, path)
192+
}
193+
}).collect::<Vec<_>>().join("\n\t\t\t"),
173194
paths.iter().filter(|(_, _, fields, _)| *fields)
174195
.map(|(path, _, _, fields_name)|
175196
format!("pub use {}::Fields as {};", path, fields_name)

playground/views/HomeView.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ import ProjectInput from '../components/ProjectInput.vue'
5050
id: 1050568991,
5151
name: 'fibonacci benchmark',
5252
author: 'pufferfish_test',
53+
},
54+
{
55+
id: 1116438829,
56+
name: 'HQ test project 2.0',
57+
author: 'pufferfish_test'
5358
}
5459
];
5560
</script>

src/instructions.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ include!(concat!(env!("OUT_DIR"), "/ir-opcodes.rs"));
1818
mod input_switcher;
1919
pub use input_switcher::wrap_instruction;
2020

21-
pub use hq::_yield::YieldMode;
21+
pub use hq::r#yield::YieldMode;
2222

2323
mod prelude {
2424
pub(crate) use crate::ir::Type as IrType;
2525
pub use crate::prelude::*;
26-
pub(crate) use crate::wasm::StepFunc;
27-
pub use wasm_encoder::{Instruction, RefType, ValType};
26+
pub(crate) use crate::wasm::{InternalInstruction, StepFunc};
27+
pub use wasm_encoder::{RefType, ValType};
2828
pub use wasm_gen::wasm;
2929

3030
/// Canonical NaN + bit 33, + string pointer in bits 1-32

src/instructions/control.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
pub mod _if;
2-
pub mod repeat;
1+
pub mod if_else;
2+
pub mod r#loop;

src/instructions/control/_if.rs

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/instructions/control/repeat.rs

Lines changed: 0 additions & 45 deletions
This file was deleted.

src/instructions/data.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pub mod setvariableto;
2+
pub mod teevariable;
23
pub mod variable;

src/instructions/data/setvariableto.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub fn wasm(
88
func: &StepFunc,
99
inputs: Rc<[IrType]>,
1010
Fields(variable): &Fields,
11-
) -> HQResult<Vec<Instruction<'static>>> {
11+
) -> HQResult<Vec<InternalInstruction>> {
1212
let global_index: u32 = func
1313
.registries()
1414
.variables()
@@ -36,6 +36,8 @@ pub fn output_type(_inputs: Rc<[IrType]>, _fields: &Fields) -> HQResult<Option<I
3636
Ok(None)
3737
}
3838

39+
pub const YIELDS: bool = false;
40+
3941
crate::instructions_test!(
4042
any;
4143
data_setvariableto;

src/instructions/data/variable.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub fn wasm(
88
func: &StepFunc,
99
_inputs: Rc<[IrType]>,
1010
Fields(variable): &Fields,
11-
) -> HQResult<Vec<Instruction<'static>>> {
11+
) -> HQResult<Vec<InternalInstruction>> {
1212
let global_index: u32 = func
1313
.registries()
1414
.variables()
@@ -28,6 +28,8 @@ pub fn output_type(_inputs: Rc<[IrType]>, Fields(rcvar): &Fields) -> HQResult<Op
2828
}))
2929
}
3030

31+
pub const YIELDS: bool = false;
32+
3133
crate::instructions_test!(
3234
any;
3335
data_variable;

src/instructions/hq.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
pub mod _yield;
21
pub mod cast;
2+
pub mod drop;
33
pub mod float;
44
pub mod integer;
55
pub mod text;
6+
pub mod r#yield;

src/instructions/hq/_yield.rs

Lines changed: 0 additions & 91 deletions
This file was deleted.

src/instructions/hq/cast.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub fn wasm(
3232
func: &StepFunc,
3333
inputs: Rc<[IrType]>,
3434
&Fields(to): &Fields,
35-
) -> HQResult<Vec<Instruction<'static>>> {
35+
) -> HQResult<Vec<InternalInstruction>> {
3636
let from = inputs[0];
3737

3838
let target = best_cast_candidate(from, to)?;
@@ -104,6 +104,8 @@ pub fn output_type(inputs: Rc<[IrType]>, &Fields(to): &Fields) -> HQResult<Optio
104104
))
105105
}
106106

107+
pub const YIELDS: bool = false;
108+
107109
crate::instructions_test! {float; hq_cast; t @ super::Fields(IrType::Float)}
108110
crate::instructions_test! {string; hq_cast; t @ super::Fields(IrType::String)}
109111
crate::instructions_test! {int; hq_cast; t @ super::Fields(IrType::QuasiInt)}

src/instructions/hq/float.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pub fn wasm(
77
_func: &StepFunc,
88
_inputs: Rc<[IrType]>,
99
fields: &Fields,
10-
) -> HQResult<Vec<Instruction<'static>>> {
10+
) -> HQResult<Vec<InternalInstruction>> {
1111
Ok(wasm![F64Const(fields.0)])
1212
}
1313

@@ -29,4 +29,6 @@ pub fn output_type(_inputs: Rc<[IrType]>, &Fields(val): &Fields) -> HQResult<Opt
2929
}))
3030
}
3131

32+
pub const YIELDS: bool = false;
33+
3234
crate::instructions_test! {tests; hq_float; @ super::Fields(0.0)}

src/instructions/hq/integer.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pub fn wasm(
77
_func: &StepFunc,
88
_inputs: Rc<[IrType]>,
99
fields: &Fields,
10-
) -> HQResult<Vec<Instruction<'static>>> {
10+
) -> HQResult<Vec<InternalInstruction>> {
1111
Ok(wasm![I32Const(fields.0)])
1212
}
1313

@@ -24,4 +24,6 @@ pub fn output_type(_inputs: Rc<[IrType]>, &Fields(val): &Fields) -> HQResult<Opt
2424
}))
2525
}
2626

27+
pub const YIELDS: bool = false;
28+
2729
crate::instructions_test! {tests; hq_integer; @ super::Fields(0)}

src/instructions/hq/text.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub fn wasm(
88
func: &StepFunc,
99
_inputs: Rc<[IrType]>,
1010
fields: &Fields,
11-
) -> HQResult<Vec<Instruction<'static>>> {
11+
) -> HQResult<Vec<InternalInstruction>> {
1212
let string_idx = func
1313
.registries()
1414
.strings()
@@ -43,4 +43,6 @@ pub fn output_type(_inputs: Rc<[IrType]>, Fields(val): &Fields) -> HQResult<Opti
4343
}))
4444
}
4545

46+
pub const YIELDS: bool = false;
47+
4648
crate::instructions_test! {tests; hq_text; @ super::Fields("hello, world!".into())}

0 commit comments

Comments
 (0)