add color RGBA8888 VM intrinsics
This commit is contained in:
parent
d2fbe62f7a
commit
ab0e577c6f
@ -1,5 +1,5 @@
|
|||||||
use prometeu_bytecode::Value;
|
use prometeu_bytecode::Value;
|
||||||
use prometeu_hal::HostContext;
|
use prometeu_hal::{HostContext, color::Color};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct BuiltinTypeKey {
|
pub struct BuiltinTypeKey {
|
||||||
@ -56,6 +56,7 @@ pub enum BuiltinScalarType {
|
|||||||
Int,
|
Int,
|
||||||
Float,
|
Float,
|
||||||
Bool,
|
Bool,
|
||||||
|
Str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
@ -362,12 +363,63 @@ const VEC2_ZERO_LAYOUT: [AbiType; 2] =
|
|||||||
[AbiType::Scalar(BuiltinScalarType::Float), AbiType::Scalar(BuiltinScalarType::Float)];
|
[AbiType::Scalar(BuiltinScalarType::Float), AbiType::Scalar(BuiltinScalarType::Float)];
|
||||||
const VEC2_ZERO_SLOTS: [BuiltinConstSlotValue; 2] =
|
const VEC2_ZERO_SLOTS: [BuiltinConstSlotValue; 2] =
|
||||||
[BuiltinConstSlotValue::Float(0.0), BuiltinConstSlotValue::Float(0.0)];
|
[BuiltinConstSlotValue::Float(0.0), BuiltinConstSlotValue::Float(0.0)];
|
||||||
const BUILTIN_CONSTS: [BuiltinConstMeta; 1] = [BuiltinConstMeta {
|
const COLOR_BLACK_SLOTS: [BuiltinConstSlotValue; 1] =
|
||||||
|
[BuiltinConstSlotValue::Int64(Color::BLACK.raw() as i64)];
|
||||||
|
const COLOR_WHITE_SLOTS: [BuiltinConstSlotValue; 1] =
|
||||||
|
[BuiltinConstSlotValue::Int64(Color::WHITE.raw() as i64)];
|
||||||
|
const COLOR_RED_SLOTS: [BuiltinConstSlotValue; 1] =
|
||||||
|
[BuiltinConstSlotValue::Int64(Color::RED.raw() as i64)];
|
||||||
|
const COLOR_GREEN_SLOTS: [BuiltinConstSlotValue; 1] =
|
||||||
|
[BuiltinConstSlotValue::Int64(Color::GREEN.raw() as i64)];
|
||||||
|
const COLOR_BLUE_SLOTS: [BuiltinConstSlotValue; 1] =
|
||||||
|
[BuiltinConstSlotValue::Int64(Color::BLUE.raw() as i64)];
|
||||||
|
const COLOR_YELLOW_SLOTS: [BuiltinConstSlotValue; 1] =
|
||||||
|
[BuiltinConstSlotValue::Int64(Color::YELLOW.raw() as i64)];
|
||||||
|
const COLOR_ORANGE_SLOTS: [BuiltinConstSlotValue; 1] =
|
||||||
|
[BuiltinConstSlotValue::Int64(Color::ORANGE.raw() as i64)];
|
||||||
|
const COLOR_INDIGO_SLOTS: [BuiltinConstSlotValue; 1] =
|
||||||
|
[BuiltinConstSlotValue::Int64(Color::INDIGO.raw() as i64)];
|
||||||
|
const COLOR_GRAY_SLOTS: [BuiltinConstSlotValue; 1] =
|
||||||
|
[BuiltinConstSlotValue::Int64(Color::GRAY.raw() as i64)];
|
||||||
|
const COLOR_CYAN_SLOTS: [BuiltinConstSlotValue; 1] =
|
||||||
|
[BuiltinConstSlotValue::Int64(Color::CYAN.raw() as i64)];
|
||||||
|
const COLOR_MAGENTA_SLOTS: [BuiltinConstSlotValue; 1] =
|
||||||
|
[BuiltinConstSlotValue::Int64(Color::MAGENTA.raw() as i64)];
|
||||||
|
const COLOR_TRANSPARENT_SLOTS: [BuiltinConstSlotValue; 1] =
|
||||||
|
[BuiltinConstSlotValue::Int64(Color::TRANSPARENT.raw() as i64)];
|
||||||
|
|
||||||
|
const BUILTIN_CONSTS: [BuiltinConstMeta; 13] = [
|
||||||
|
BuiltinConstMeta {
|
||||||
key: BuiltinConstKey::new("vec2", "zero", 1),
|
key: BuiltinConstKey::new("vec2", "zero", 1),
|
||||||
flat_slot_layout: &VEC2_ZERO_LAYOUT,
|
flat_slot_layout: &VEC2_ZERO_LAYOUT,
|
||||||
flat_slot_width: 2,
|
flat_slot_width: 2,
|
||||||
materializer: BuiltinConstMaterializer::Direct(&VEC2_ZERO_SLOTS),
|
materializer: BuiltinConstMaterializer::Direct(&VEC2_ZERO_SLOTS),
|
||||||
}];
|
},
|
||||||
|
color_const_meta("black", &COLOR_BLACK_SLOTS),
|
||||||
|
color_const_meta("white", &COLOR_WHITE_SLOTS),
|
||||||
|
color_const_meta("red", &COLOR_RED_SLOTS),
|
||||||
|
color_const_meta("green", &COLOR_GREEN_SLOTS),
|
||||||
|
color_const_meta("blue", &COLOR_BLUE_SLOTS),
|
||||||
|
color_const_meta("yellow", &COLOR_YELLOW_SLOTS),
|
||||||
|
color_const_meta("orange", &COLOR_ORANGE_SLOTS),
|
||||||
|
color_const_meta("indigo", &COLOR_INDIGO_SLOTS),
|
||||||
|
color_const_meta("gray", &COLOR_GRAY_SLOTS),
|
||||||
|
color_const_meta("cyan", &COLOR_CYAN_SLOTS),
|
||||||
|
color_const_meta("magenta", &COLOR_MAGENTA_SLOTS),
|
||||||
|
color_const_meta("transparent", &COLOR_TRANSPARENT_SLOTS),
|
||||||
|
];
|
||||||
|
|
||||||
|
const fn color_const_meta(
|
||||||
|
name: &'static str,
|
||||||
|
slots: &'static [BuiltinConstSlotValue],
|
||||||
|
) -> BuiltinConstMeta {
|
||||||
|
BuiltinConstMeta {
|
||||||
|
key: BuiltinConstKey::new("color", name, 1),
|
||||||
|
flat_slot_layout: &COLOR_LAYOUT,
|
||||||
|
flat_slot_width: 1,
|
||||||
|
materializer: BuiltinConstMaterializer::Direct(slots),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const VEC2_DOT_ARGS: [AbiType; 4] = [
|
const VEC2_DOT_ARGS: [AbiType; 4] = [
|
||||||
AbiType::Scalar(BuiltinScalarType::Float),
|
AbiType::Scalar(BuiltinScalarType::Float),
|
||||||
@ -379,6 +431,20 @@ const SINGLE_FLOAT_RET: [AbiType; 1] = [AbiType::Scalar(BuiltinScalarType::Float
|
|||||||
const VEC2_LENGTH_ARGS: [AbiType; 2] =
|
const VEC2_LENGTH_ARGS: [AbiType; 2] =
|
||||||
[AbiType::Scalar(BuiltinScalarType::Float), AbiType::Scalar(BuiltinScalarType::Float)];
|
[AbiType::Scalar(BuiltinScalarType::Float), AbiType::Scalar(BuiltinScalarType::Float)];
|
||||||
const NO_ARGS: [AbiType; 0] = [];
|
const NO_ARGS: [AbiType; 0] = [];
|
||||||
|
const COLOR_ARGS: [AbiType; 1] = [AbiType::Builtin(COLOR)];
|
||||||
|
const COLOR_RET: [AbiType; 1] = [AbiType::Builtin(COLOR)];
|
||||||
|
const COLOR_RGB_ARGS: [AbiType; 3] = [
|
||||||
|
AbiType::Scalar(BuiltinScalarType::Int),
|
||||||
|
AbiType::Scalar(BuiltinScalarType::Int),
|
||||||
|
AbiType::Scalar(BuiltinScalarType::Int),
|
||||||
|
];
|
||||||
|
const COLOR_RGBA_ARGS: [AbiType; 4] = [
|
||||||
|
AbiType::Scalar(BuiltinScalarType::Int),
|
||||||
|
AbiType::Scalar(BuiltinScalarType::Int),
|
||||||
|
AbiType::Scalar(BuiltinScalarType::Int),
|
||||||
|
AbiType::Scalar(BuiltinScalarType::Int),
|
||||||
|
];
|
||||||
|
const COLOR_HTML_RGBA_ARGS: [AbiType; 1] = [AbiType::Scalar(BuiltinScalarType::Str)];
|
||||||
const PAD_RET: [AbiType; 1] = [AbiType::Builtin(INPUT_PAD)];
|
const PAD_RET: [AbiType; 1] = [AbiType::Builtin(INPUT_PAD)];
|
||||||
const TOUCH_RET: [AbiType; 1] = [AbiType::Builtin(INPUT_TOUCH)];
|
const TOUCH_RET: [AbiType; 1] = [AbiType::Builtin(INPUT_TOUCH)];
|
||||||
const BUTTON_RET: [AbiType; 1] = [AbiType::Builtin(INPUT_BUTTON)];
|
const BUTTON_RET: [AbiType; 1] = [AbiType::Builtin(INPUT_BUTTON)];
|
||||||
@ -388,7 +454,7 @@ const BUTTON_ARGS: [AbiType; 1] = [AbiType::Builtin(INPUT_BUTTON)];
|
|||||||
const BOOL_RET: [AbiType; 1] = [AbiType::Scalar(BuiltinScalarType::Bool)];
|
const BOOL_RET: [AbiType; 1] = [AbiType::Scalar(BuiltinScalarType::Bool)];
|
||||||
const INT_RET: [AbiType; 1] = [AbiType::Scalar(BuiltinScalarType::Int)];
|
const INT_RET: [AbiType; 1] = [AbiType::Scalar(BuiltinScalarType::Int)];
|
||||||
|
|
||||||
const INTRINSICS: [IntrinsicMeta; 23] = [
|
const INTRINSICS: [IntrinsicMeta; 42] = [
|
||||||
IntrinsicMeta {
|
IntrinsicMeta {
|
||||||
id: 0x1000,
|
id: 0x1000,
|
||||||
owner: "vec2",
|
owner: "vec2",
|
||||||
@ -411,6 +477,215 @@ const INTRINSICS: [IntrinsicMeta; 23] = [
|
|||||||
may_allocate: false,
|
may_allocate: false,
|
||||||
implementation: vec2_length,
|
implementation: vec2_length,
|
||||||
},
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1100,
|
||||||
|
owner: "color",
|
||||||
|
name: "from_raw",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &INT_RET,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_from_raw,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1101,
|
||||||
|
owner: "color",
|
||||||
|
name: "rgb",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &COLOR_RGB_ARGS,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_rgb,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1102,
|
||||||
|
owner: "color",
|
||||||
|
name: "rgba",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &COLOR_RGBA_ARGS,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_rgba,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1103,
|
||||||
|
owner: "color",
|
||||||
|
name: "html_rgba",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &COLOR_HTML_RGBA_ARGS,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_html_rgba,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1104,
|
||||||
|
owner: "color",
|
||||||
|
name: "gray_scale",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &INT_RET,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_gray_scale,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1105,
|
||||||
|
owner: "color",
|
||||||
|
name: "hex",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &COLOR_ARGS,
|
||||||
|
ret_layout: &INT_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_hex,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1106,
|
||||||
|
owner: "color",
|
||||||
|
name: "alpha",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &COLOR_ARGS,
|
||||||
|
ret_layout: &INT_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_alpha,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1120,
|
||||||
|
owner: "color",
|
||||||
|
name: "black",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &NO_ARGS,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_black,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1121,
|
||||||
|
owner: "color",
|
||||||
|
name: "white",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &NO_ARGS,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_white,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1122,
|
||||||
|
owner: "color",
|
||||||
|
name: "red",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &NO_ARGS,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_red,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1123,
|
||||||
|
owner: "color",
|
||||||
|
name: "green",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &NO_ARGS,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_green,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1124,
|
||||||
|
owner: "color",
|
||||||
|
name: "blue",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &NO_ARGS,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_blue,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1125,
|
||||||
|
owner: "color",
|
||||||
|
name: "yellow",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &NO_ARGS,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_yellow,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1126,
|
||||||
|
owner: "color",
|
||||||
|
name: "orange",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &NO_ARGS,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_orange,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1127,
|
||||||
|
owner: "color",
|
||||||
|
name: "indigo",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &NO_ARGS,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_indigo,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1128,
|
||||||
|
owner: "color",
|
||||||
|
name: "gray",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &NO_ARGS,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_gray,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x1129,
|
||||||
|
owner: "color",
|
||||||
|
name: "cyan",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &NO_ARGS,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_cyan,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x112A,
|
||||||
|
owner: "color",
|
||||||
|
name: "magenta",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &NO_ARGS,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_magenta,
|
||||||
|
},
|
||||||
|
IntrinsicMeta {
|
||||||
|
id: 0x112B,
|
||||||
|
owner: "color",
|
||||||
|
name: "transparent",
|
||||||
|
version: 1,
|
||||||
|
arg_layout: &NO_ARGS,
|
||||||
|
ret_layout: &COLOR_RET,
|
||||||
|
deterministic: true,
|
||||||
|
may_allocate: false,
|
||||||
|
implementation: color_transparent,
|
||||||
|
},
|
||||||
IntrinsicMeta {
|
IntrinsicMeta {
|
||||||
id: 0x2000,
|
id: 0x2000,
|
||||||
owner: "input",
|
owner: "input",
|
||||||
@ -698,11 +973,35 @@ fn expect_float_arg(args: &[Value], index: usize) -> Result<f64, IntrinsicExecut
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn expect_int_arg(args: &[Value], index: usize) -> Result<i64, IntrinsicExecutionError> {
|
||||||
|
let value = args
|
||||||
|
.get(index)
|
||||||
|
.ok_or(IntrinsicExecutionError::ArityMismatch { expected: index + 1, got: args.len() })?;
|
||||||
|
value.as_integer().ok_or(IntrinsicExecutionError::TypeMismatch {
|
||||||
|
index,
|
||||||
|
expected: AbiType::Scalar(BuiltinScalarType::Int),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expect_string_arg(args: &[Value], index: usize) -> Result<&str, IntrinsicExecutionError> {
|
||||||
|
let value = args
|
||||||
|
.get(index)
|
||||||
|
.ok_or(IntrinsicExecutionError::ArityMismatch { expected: index + 1, got: args.len() })?;
|
||||||
|
match value {
|
||||||
|
Value::String(value) => Ok(value.as_ref()),
|
||||||
|
_ => Err(IntrinsicExecutionError::TypeMismatch {
|
||||||
|
index,
|
||||||
|
expected: AbiType::Scalar(BuiltinScalarType::Str),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn value_matches_abi_type(value: &Value, expected: AbiType) -> bool {
|
fn value_matches_abi_type(value: &Value, expected: AbiType) -> bool {
|
||||||
match expected {
|
match expected {
|
||||||
AbiType::Scalar(BuiltinScalarType::Int) => value.as_integer().is_some(),
|
AbiType::Scalar(BuiltinScalarType::Int) => value.as_integer().is_some(),
|
||||||
AbiType::Scalar(BuiltinScalarType::Float) => value.as_float().is_some(),
|
AbiType::Scalar(BuiltinScalarType::Float) => value.as_float().is_some(),
|
||||||
AbiType::Scalar(BuiltinScalarType::Bool) => matches!(value, Value::Boolean(_)),
|
AbiType::Scalar(BuiltinScalarType::Bool) => matches!(value, Value::Boolean(_)),
|
||||||
|
AbiType::Scalar(BuiltinScalarType::Str) => matches!(value, Value::String(_)),
|
||||||
AbiType::Builtin(_) => value.as_integer().is_some(),
|
AbiType::Builtin(_) => value.as_integer().is_some(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -755,6 +1054,179 @@ fn vec2_length(
|
|||||||
Ok(vec![Value::Float((x * x + y * y).sqrt())])
|
Ok(vec![Value::Float((x * x + y * y).sqrt())])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn color_value(color: Color) -> Vec<Value> {
|
||||||
|
vec![Value::Int64(color.raw() as i64)]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expect_color_arg(args: &[Value], index: usize) -> Result<Color, IntrinsicExecutionError> {
|
||||||
|
let raw = u32::try_from(expect_int_arg(args, index)?).map_err(|_| {
|
||||||
|
IntrinsicExecutionError::TypeMismatch { index, expected: AbiType::Builtin(COLOR) }
|
||||||
|
})?;
|
||||||
|
Ok(Color::from_raw(raw))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expect_channel(args: &[Value], index: usize) -> Result<u8, IntrinsicExecutionError> {
|
||||||
|
let value = expect_int_arg(args, index)?;
|
||||||
|
u8::try_from(value).map_err(|_| IntrinsicExecutionError::TypeMismatch {
|
||||||
|
index,
|
||||||
|
expected: AbiType::Scalar(BuiltinScalarType::Int),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_html_rgba(value: &str) -> Option<Color> {
|
||||||
|
let hex = value.strip_prefix('#').unwrap_or(value);
|
||||||
|
if hex.len() != 8 || !hex.as_bytes().iter().all(u8::is_ascii_hexdigit) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(Color::from_raw(u32::from_str_radix(hex, 16).ok()?))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_from_raw(
|
||||||
|
args: &[Value],
|
||||||
|
_ctx: &mut HostContext<'_>,
|
||||||
|
) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
let raw = u32::try_from(expect_int_arg(args, 0)?).map_err(|_| {
|
||||||
|
IntrinsicExecutionError::TypeMismatch {
|
||||||
|
index: 0,
|
||||||
|
expected: AbiType::Scalar(BuiltinScalarType::Int),
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
Ok(color_value(Color::from_raw(raw)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_rgb(
|
||||||
|
args: &[Value],
|
||||||
|
_ctx: &mut HostContext<'_>,
|
||||||
|
) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
Ok(color_value(Color::rgb(
|
||||||
|
expect_channel(args, 0)?,
|
||||||
|
expect_channel(args, 1)?,
|
||||||
|
expect_channel(args, 2)?,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_rgba(
|
||||||
|
args: &[Value],
|
||||||
|
_ctx: &mut HostContext<'_>,
|
||||||
|
) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
Ok(color_value(Color::rgba(
|
||||||
|
expect_channel(args, 0)?,
|
||||||
|
expect_channel(args, 1)?,
|
||||||
|
expect_channel(args, 2)?,
|
||||||
|
expect_channel(args, 3)?,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_html_rgba(
|
||||||
|
args: &[Value],
|
||||||
|
_ctx: &mut HostContext<'_>,
|
||||||
|
) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
let color = parse_html_rgba(expect_string_arg(args, 0)?).ok_or({
|
||||||
|
IntrinsicExecutionError::TypeMismatch {
|
||||||
|
index: 0,
|
||||||
|
expected: AbiType::Scalar(BuiltinScalarType::Str),
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
Ok(color_value(color))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_gray_scale(
|
||||||
|
args: &[Value],
|
||||||
|
_ctx: &mut HostContext<'_>,
|
||||||
|
) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
Ok(color_value(Color::gray_scale(expect_channel(args, 0)?)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_hex(
|
||||||
|
args: &[Value],
|
||||||
|
_ctx: &mut HostContext<'_>,
|
||||||
|
) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
Ok(vec![Value::Int64(expect_color_arg(args, 0)?.hex() as i64)])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_alpha(
|
||||||
|
args: &[Value],
|
||||||
|
_ctx: &mut HostContext<'_>,
|
||||||
|
) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
Ok(vec![Value::Int64(expect_color_arg(args, 0)?.alpha() as i64)])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_const(color: Color) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
Ok(color_value(color))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_black(
|
||||||
|
_: &[Value],
|
||||||
|
_: &mut HostContext<'_>,
|
||||||
|
) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
color_const(Color::BLACK)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_white(
|
||||||
|
_: &[Value],
|
||||||
|
_: &mut HostContext<'_>,
|
||||||
|
) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
color_const(Color::WHITE)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_red(_: &[Value], _: &mut HostContext<'_>) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
color_const(Color::RED)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_green(
|
||||||
|
_: &[Value],
|
||||||
|
_: &mut HostContext<'_>,
|
||||||
|
) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
color_const(Color::GREEN)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_blue(_: &[Value], _: &mut HostContext<'_>) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
color_const(Color::BLUE)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_yellow(
|
||||||
|
_: &[Value],
|
||||||
|
_: &mut HostContext<'_>,
|
||||||
|
) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
color_const(Color::YELLOW)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_orange(
|
||||||
|
_: &[Value],
|
||||||
|
_: &mut HostContext<'_>,
|
||||||
|
) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
color_const(Color::ORANGE)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_indigo(
|
||||||
|
_: &[Value],
|
||||||
|
_: &mut HostContext<'_>,
|
||||||
|
) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
color_const(Color::INDIGO)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_gray(_: &[Value], _: &mut HostContext<'_>) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
color_const(Color::GRAY)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_cyan(_: &[Value], _: &mut HostContext<'_>) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
color_const(Color::CYAN)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_magenta(
|
||||||
|
_: &[Value],
|
||||||
|
_: &mut HostContext<'_>,
|
||||||
|
) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
color_const(Color::MAGENTA)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_transparent(
|
||||||
|
_: &[Value],
|
||||||
|
_: &mut HostContext<'_>,
|
||||||
|
) -> Result<Vec<Value>, IntrinsicExecutionError> {
|
||||||
|
color_const(Color::TRANSPARENT)
|
||||||
|
}
|
||||||
|
|
||||||
fn input_pad(
|
fn input_pad(
|
||||||
_args: &[Value],
|
_args: &[Value],
|
||||||
_ctx: &mut HostContext<'_>,
|
_ctx: &mut HostContext<'_>,
|
||||||
@ -1067,6 +1539,19 @@ mod tests {
|
|||||||
assert_eq!(looked_up, materialized);
|
assert_eq!(looked_up, materialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn builtin_constant_materializes_color_values() {
|
||||||
|
let red = materialize_builtin_constant("color", "red", 1)
|
||||||
|
.expect("materialization lookup must succeed")
|
||||||
|
.expect("constant must exist");
|
||||||
|
assert_eq!(red, vec![Value::Int64(Color::RED.raw() as i64)]);
|
||||||
|
|
||||||
|
let transparent = materialize_builtin_constant("color", "transparent", 1)
|
||||||
|
.expect("materialization lookup must succeed")
|
||||||
|
.expect("constant must exist");
|
||||||
|
assert_eq!(transparent, vec![Value::Int64(Color::TRANSPARENT.raw() as i64)]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn intrinsic_metadata_exposes_arg_and_return_layouts() {
|
fn intrinsic_metadata_exposes_arg_and_return_layouts() {
|
||||||
let dot = lookup_intrinsic("vec2", "dot", 1).expect("vec2.dot must exist");
|
let dot = lookup_intrinsic("vec2", "dot", 1).expect("vec2.dot must exist");
|
||||||
@ -1105,6 +1590,29 @@ mod tests {
|
|||||||
assert_eq!(result, vec![Value::Float(5.0)]);
|
assert_eq!(result, vec![Value::Float(5.0)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn color_intrinsics_construct_and_project_rgba8888() {
|
||||||
|
let mut ctx = HostContext::new(None);
|
||||||
|
|
||||||
|
let rgba = lookup_intrinsic("color", "rgba", 1).expect("color.rgba must exist");
|
||||||
|
let result = (rgba.implementation)(
|
||||||
|
&[Value::Int64(0x11), Value::Int64(0x22), Value::Int64(0x33), Value::Int64(0x44)],
|
||||||
|
&mut ctx,
|
||||||
|
)
|
||||||
|
.expect("rgba implementation must execute");
|
||||||
|
assert_eq!(result, vec![Value::Int64(0x11223344)]);
|
||||||
|
|
||||||
|
let html = lookup_intrinsic("color", "html_rgba", 1).expect("color.html_rgba must exist");
|
||||||
|
let result = (html.implementation)(&[Value::String("#AABBCCDD".into())], &mut ctx)
|
||||||
|
.expect("html_rgba implementation must execute");
|
||||||
|
assert_eq!(result, vec![Value::Int64(0xAABBCCDD)]);
|
||||||
|
|
||||||
|
let alpha = lookup_intrinsic("color", "alpha", 1).expect("color.alpha must exist");
|
||||||
|
let result = (alpha.implementation)(&[Value::Int64(0xAABBCCDD)], &mut ctx)
|
||||||
|
.expect("alpha implementation must execute");
|
||||||
|
assert_eq!(result, vec![Value::Int64(0xDD)]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn input_intrinsic_requires_hardware_context() {
|
fn input_intrinsic_requires_hardware_context() {
|
||||||
let mut ctx = HostContext::new(None);
|
let mut ctx = HostContext::new(None);
|
||||||
|
|||||||
@ -1,6 +1,25 @@
|
|||||||
final_id_hex,final_id_dec,canonical_name,canonical_version,owner,name,arg_slots,ret_slots,arg_layout,ret_layout,deterministic,may_allocate
|
final_id_hex,final_id_dec,canonical_name,canonical_version,owner,name,arg_slots,ret_slots,arg_layout,ret_layout,deterministic,may_allocate
|
||||||
0x1000,4096,vec2.dot,1,vec2,dot,4,1,float|float|float|float,float,true,false
|
0x1000,4096,vec2.dot,1,vec2,dot,4,1,float|float|float|float,float,true,false
|
||||||
0x1001,4097,vec2.length,1,vec2,length,2,1,float|float,float,true,false
|
0x1001,4097,vec2.length,1,vec2,length,2,1,float|float,float,true,false
|
||||||
|
0x1100,4352,color.from_raw,1,color,from_raw,1,1,int,builtin:color,true,false
|
||||||
|
0x1101,4353,color.rgb,1,color,rgb,3,1,int|int|int,builtin:color,true,false
|
||||||
|
0x1102,4354,color.rgba,1,color,rgba,4,1,int|int|int|int,builtin:color,true,false
|
||||||
|
0x1103,4355,color.html_rgba,1,color,html_rgba,1,1,str,builtin:color,true,false
|
||||||
|
0x1104,4356,color.gray_scale,1,color,gray_scale,1,1,int,builtin:color,true,false
|
||||||
|
0x1105,4357,color.hex,1,color,hex,1,1,builtin:color,int,true,false
|
||||||
|
0x1106,4358,color.alpha,1,color,alpha,1,1,builtin:color,int,true,false
|
||||||
|
0x1120,4384,color.black,1,color,black,0,1,,builtin:color,true,false
|
||||||
|
0x1121,4385,color.white,1,color,white,0,1,,builtin:color,true,false
|
||||||
|
0x1122,4386,color.red,1,color,red,0,1,,builtin:color,true,false
|
||||||
|
0x1123,4387,color.green,1,color,green,0,1,,builtin:color,true,false
|
||||||
|
0x1124,4388,color.blue,1,color,blue,0,1,,builtin:color,true,false
|
||||||
|
0x1125,4389,color.yellow,1,color,yellow,0,1,,builtin:color,true,false
|
||||||
|
0x1126,4390,color.orange,1,color,orange,0,1,,builtin:color,true,false
|
||||||
|
0x1127,4391,color.indigo,1,color,indigo,0,1,,builtin:color,true,false
|
||||||
|
0x1128,4392,color.gray,1,color,gray,0,1,,builtin:color,true,false
|
||||||
|
0x1129,4393,color.cyan,1,color,cyan,0,1,,builtin:color,true,false
|
||||||
|
0x112A,4394,color.magenta,1,color,magenta,0,1,,builtin:color,true,false
|
||||||
|
0x112B,4395,color.transparent,1,color,transparent,0,1,,builtin:color,true,false
|
||||||
0x2000,8192,input.pad,1,input,pad,0,1,,builtin:input.pad,true,false
|
0x2000,8192,input.pad,1,input,pad,0,1,,builtin:input.pad,true,false
|
||||||
0x2001,8193,input.touch,1,input,touch,0,1,,builtin:input.touch,true,false
|
0x2001,8193,input.touch,1,input,touch,0,1,,builtin:input.touch,true,false
|
||||||
0x2010,8208,input.pad.up,1,input.pad,up,1,1,builtin:input.pad,builtin:input.button,true,false
|
0x2010,8208,input.pad.up,1,input.pad,up,1,1,builtin:input.pad,builtin:input.button,true,false
|
||||||
|
|||||||
|
Loading…
x
Reference in New Issue
Block a user