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)) ecall_that_returns_uint := @as(uint, @eca(1, foo.Type.(10, 20), 5, 6))
embedded_array := @as([u8; 15], @embed("text.txt")) embedded_array := @as([u8; 15], @embed("text.txt"))
two_fields := @len(foo.Type) two_fields := @len(foo.Type)
string_length := @len("foo\0")
the_struct_kind := @kindof(foo.Type) the_struct_kind := @kindof(foo.Type)
return @inline(foo.foo) 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 - `@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 - `@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 - `@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]` - `@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 #### c_strings

View file

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