Skip to content

Commit 09455b4

Browse files
committed
add the sizeof() built-in function
1 parent 059c6aa commit 09455b4

File tree

5 files changed

+82
-1
lines changed

5 files changed

+82
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "customasm"
3-
version = "0.13.8"
3+
version = "0.13.9"
44
edition = "2021"
55
authors = ["hlorenzi <https://hlorenzi.com>"]
66
description = "An assembler for custom, user-defined instruction sets!"

src/expr/builtin_fn.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub fn resolve_builtin_fn(
88
match name.as_ref()
99
{
1010
"assert" => Some(eval_builtin_assert),
11+
"sizeof" => Some(eval_builtin_sizeof),
1112
"le" => Some(eval_builtin_le),
1213
"ascii" => Some(eval_builtin_ascii),
1314
"utf8" => Some(eval_builtin_utf8),
@@ -30,6 +31,7 @@ pub fn get_static_size_builtin_fn(
3031
let get_static_size_fn = {
3132
match name.as_ref()
3233
{
34+
"sizeof" => get_static_size_builtin_sizeof,
3335
"le" => get_static_size_builtin_le,
3436
_ => return None,
3537
}
@@ -49,6 +51,7 @@ pub fn get_statically_known_value_builtin_fn(
4951
match name.as_ref()
5052
{
5153
"assert" => false,
54+
"sizeof" => true,
5255
"le" => true,
5356
"ascii" => true,
5457
"utf8" => true,
@@ -118,6 +121,20 @@ pub fn eval_builtin_assert(
118121
}
119122

120123

124+
pub fn eval_builtin_sizeof(
125+
query: &mut expr::EvalFunctionQuery)
126+
-> Result<expr::Value, ()>
127+
{
128+
query.ensure_arg_number(1)?;
129+
130+
let (_bigint, size) = query.args[0].value.expect_sized_integerlike(
131+
query.report,
132+
query.args[0].span)?;
133+
134+
Ok(expr::Value::make_integer(size))
135+
}
136+
137+
121138
pub fn eval_builtin_le(
122139
query: &mut expr::EvalFunctionQuery)
123140
-> Result<expr::Value, ()>
@@ -147,6 +164,22 @@ pub fn eval_builtin_le(
147164
}
148165

149166

167+
pub fn get_static_size_builtin_sizeof(
168+
provider: &expr::StaticallyKnownProvider,
169+
args: &Vec<expr::Expr>)
170+
-> Option<usize>
171+
{
172+
if args.len() == 1
173+
{
174+
args[0].get_static_size(provider)
175+
}
176+
else
177+
{
178+
None
179+
}
180+
}
181+
182+
150183
pub fn get_static_size_builtin_le(
151184
provider: &expr::StaticallyKnownProvider,
152185
args: &Vec<expr::Expr>)

src/expr/expression.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,34 @@ impl Value
269269
}
270270

271271

272+
pub fn expect_sized_integerlike(
273+
&self,
274+
report: &mut diagn::Report,
275+
span: diagn::Span)
276+
-> Result<(util::BigInt, usize), ()>
277+
{
278+
if let Some(bigint) = self.coallesce_to_integer().get_bigint()
279+
{
280+
if let Some(size) = bigint.size
281+
{
282+
return Ok((bigint, size));
283+
}
284+
285+
report.error_span(
286+
"value has no definite size",
287+
span);
288+
289+
return Err(());
290+
}
291+
292+
report.error_span(
293+
"expected integer-like value with definite size",
294+
span);
295+
296+
Err(())
297+
}
298+
299+
272300
pub fn expect_error_or_bigint(
273301
self,
274302
report: &mut diagn::Report,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#d sizeof(123) ; error: failed / error: definite size
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ruledef test
2+
{
3+
ld {x} => {
4+
(sizeof(x) > 8 ? 0xff : 0x00) @ x @ sizeof(x)`8
5+
}
6+
}
7+
8+
ld 0`0 ; = 0x00__00
9+
ld 0x0 ; = 0x00_0_04
10+
ld 0x00 ; = 0x00_00_08
11+
ld 0x12 ; = 0x00_12_08
12+
ld 0xff ; = 0x00_ff_08
13+
ld 0x100 ; = 0xff_100_0c
14+
ld 0x0100 ; = 0xff_0100_10
15+
ld 0x0000 ; = 0xff_0000_10
16+
ld 0xeeeee ; = 0xff_eeeee_14
17+
18+
#d8 sizeof(0x1234) ; = 0x10
19+
#d8 sizeof("hello") ; = 0x28

0 commit comments

Comments
 (0)