making @len work on strings

Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
Jakub Doka 2024-12-17 18:30:19 +01:00
parent 86f7d70747
commit 95496116b0
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
2 changed files with 14 additions and 11 deletions

View file

@ -440,6 +440,7 @@ main := fn(): uint {
ecall_that_returns_uint := @as(uint, @eca(1, foo.Type.(10, 20), 5, 6))
embedded_array := @as([u8; 15], @embed("text.txt"))
two_fields := @len(foo.Type)
string_length := @len("foo\0")
the_struct_kind := @kindof(foo.Type)
return @inline(foo.foo)
}
@ -466,7 +467,7 @@ arbitrary text
- `@eca(...<expr>)`: invoke `eca` instruction, where return type is inferred and `<expr>...` are arguments passed to the call in the standard call convention
- `@embed(<string>)`: include relative file as an array of bytes
- `@inline(<func>, ...<args>)`: equivalent to `<func>(...<args>)` but function is guaranteed to inline, compiler will otherwise never inline
- `@len(<ty>)`: reports a length of the type of indexing purposes
- `@len(<ty>)`: reports a length of the type of indexing purposes or length ot a string constant
- `@kindof(<ty>)`: gives an u8 integer describing the kind of type as an index to array `[Builtin, Struct, Enum, Union, Ptr, Slice, Opt, Func, Template, Global, Const, Module]`
#### c_strings

View file

@ -1309,16 +1309,18 @@ impl<'a> Codegen<'a> {
self.gen_inferred_const(ctx, ty::Id::DINT, align)
}
Expr::Directive { name: "len", args: [ety], .. } => {
let ty = self.ty(ety);
let Some(len) = self.tys.len_of(ty) else {
return self.error(
ety.pos(),
fa!(
"'@len' only supports structs and arrays, \
'{}' is neither",
self.ty_display(ty)
),
);
let ty = self.expr(ety)?;
let len = match self.ci.nodes[ty.id].kind {
Kind::CInt { value }
if let Some(len) = self.tys.len_of(ty::Id::from(value as u64)) =>
{
len
}
Kind::Global { global } => self.tys.ins.globals[global].data.len() as u32 - 1,
_ => {
return self
.error(ety.pos(), "'@len' only supports structs and arrays or strings")
}
};
self.gen_inferred_const(ctx, ty::Id::DINT, len)
}