add color RGBA8888 VM intrinsics
This commit is contained in:
parent
d2fbe62f7a
commit
ab0e577c6f
@ -1,5 +1,5 @@
|
||||
use prometeu_bytecode::Value;
|
||||
use prometeu_hal::HostContext;
|
||||
use prometeu_hal::{HostContext, color::Color};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct BuiltinTypeKey {
|
||||
@ -56,6 +56,7 @@ pub enum BuiltinScalarType {
|
||||
Int,
|
||||
Float,
|
||||
Bool,
|
||||
Str,
|
||||
}
|
||||
|
||||
#[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)];
|
||||
const VEC2_ZERO_SLOTS: [BuiltinConstSlotValue; 2] =
|
||||
[BuiltinConstSlotValue::Float(0.0), BuiltinConstSlotValue::Float(0.0)];
|
||||
const BUILTIN_CONSTS: [BuiltinConstMeta; 1] = [BuiltinConstMeta {
|
||||
key: BuiltinConstKey::new("vec2", "zero", 1),
|
||||
flat_slot_layout: &VEC2_ZERO_LAYOUT,
|
||||
flat_slot_width: 2,
|
||||
materializer: BuiltinConstMaterializer::Direct(&VEC2_ZERO_SLOTS),
|
||||
}];
|
||||
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),
|
||||
flat_slot_layout: &VEC2_ZERO_LAYOUT,
|
||||
flat_slot_width: 2,
|
||||
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] = [
|
||||
AbiType::Scalar(BuiltinScalarType::Float),
|
||||
@ -379,6 +431,20 @@ const SINGLE_FLOAT_RET: [AbiType; 1] = [AbiType::Scalar(BuiltinScalarType::Float
|
||||
const VEC2_LENGTH_ARGS: [AbiType; 2] =
|
||||
[AbiType::Scalar(BuiltinScalarType::Float), AbiType::Scalar(BuiltinScalarType::Float)];
|
||||
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 TOUCH_RET: [AbiType; 1] = [AbiType::Builtin(INPUT_TOUCH)];
|
||||
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 INT_RET: [AbiType; 1] = [AbiType::Scalar(BuiltinScalarType::Int)];
|
||||
|
||||
const INTRINSICS: [IntrinsicMeta; 23] = [
|
||||
const INTRINSICS: [IntrinsicMeta; 42] = [
|
||||
IntrinsicMeta {
|
||||
id: 0x1000,
|
||||
owner: "vec2",
|
||||
@ -411,6 +477,215 @@ const INTRINSICS: [IntrinsicMeta; 23] = [
|
||||
may_allocate: false,
|
||||
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 {
|
||||
id: 0x2000,
|
||||
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 {
|
||||
match expected {
|
||||
AbiType::Scalar(BuiltinScalarType::Int) => value.as_integer().is_some(),
|
||||
AbiType::Scalar(BuiltinScalarType::Float) => value.as_float().is_some(),
|
||||
AbiType::Scalar(BuiltinScalarType::Bool) => matches!(value, Value::Boolean(_)),
|
||||
AbiType::Scalar(BuiltinScalarType::Str) => matches!(value, Value::String(_)),
|
||||
AbiType::Builtin(_) => value.as_integer().is_some(),
|
||||
}
|
||||
}
|
||||
@ -755,6 +1054,179 @@ fn vec2_length(
|
||||
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(
|
||||
_args: &[Value],
|
||||
_ctx: &mut HostContext<'_>,
|
||||
@ -1067,6 +1539,19 @@ mod tests {
|
||||
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]
|
||||
fn intrinsic_metadata_exposes_arg_and_return_layouts() {
|
||||
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)]);
|
||||
}
|
||||
|
||||
#[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]
|
||||
fn input_intrinsic_requires_hardware_context() {
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user