forked from AbleOS/holey-bytes
added example for struct patters
This commit is contained in:
parent
ab41d49a3d
commit
25bbe247e9
|
@ -228,24 +228,30 @@ note: values of global variables are evaluated at compile time
|
|||
|
||||
#### directives
|
||||
```hb
|
||||
Type := struct {
|
||||
brah: int,
|
||||
blah: int,
|
||||
}
|
||||
foo := @use("foo.hb");
|
||||
|
||||
main := fn(): int {
|
||||
byte := @as(u8, 10);
|
||||
same_type_as_byte := @as(@TypeOf(byte), 30);
|
||||
wide_uint := @as(u32, 40);
|
||||
truncated_uint := @as(u8, @intcast(wide_uint));
|
||||
size_of_Type_in_bytes := @sizeof(Type);
|
||||
align_of_Type_in_bytes := @alignof(Type);
|
||||
size_of_Type_in_bytes := @sizeof(foo.Type);
|
||||
align_of_Type_in_bytes := @alignof(foo.Type);
|
||||
hardcoded_pointer := @as(^u8, @bitcast(10));
|
||||
ecall_that_returns_int := @eca(int, 1, Type.(10, 20), 5, 6);
|
||||
ecall_that_returns_int := @eca(int, 1, foo.Type.(10, 20), 5, 6);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// in module: foo.hb
|
||||
|
||||
Type := struct {
|
||||
brah: int,
|
||||
blah: int,
|
||||
}
|
||||
```
|
||||
|
||||
- `@use(<string>)`: imports a module based of string, the string is passed to a loader that can be customized, default loader uses following syntax:
|
||||
- `((rel:|)(<path>)|git:<git-addr>:<path>)`: `rel:` and `''` prefixes both mean module is located at `path` relavive to the current file, `git:` takes a git url without `https://` passed as `git-addr`, `path` then refers to file within the repository
|
||||
- `@TypeOf(<expr>)`: results into literal type of whatever the type of `<expr>` is, `<expr>` is not included in final binary
|
||||
- `@as(<ty>, <expr>)`: hint to the compiler that `@TypeOf(<expr>) == <ty>`
|
||||
- `@intcast(<expr>)`: needs to be used when conversion of `@TypeOf(<expr>)` would loose precision (widening of integers is implicit)
|
||||
|
@ -255,7 +261,6 @@ main := fn(): int {
|
|||
|
||||
#### c_strings
|
||||
```hb
|
||||
|
||||
str_len := fn(str: ^u8): int {
|
||||
len := 0;
|
||||
loop if *str == 0 break else {
|
||||
|
@ -275,6 +280,38 @@ main := fn(): int {
|
|||
}
|
||||
```
|
||||
|
||||
#### struct_patterns
|
||||
```hb
|
||||
.{ fib, fib_iter, Fiber } := @use("fibs.hb");
|
||||
|
||||
main := fn(): int {
|
||||
.{ a, b } := Fiber.{ a: 10, b: 10 };
|
||||
return fib(a) - fib_iter(b);
|
||||
}
|
||||
|
||||
// in module: fibs.hb
|
||||
|
||||
Fiber := struct { a: u8, b: u8 };
|
||||
|
||||
fib := fn(n: int): int if n < 2 {
|
||||
return n;
|
||||
} else {
|
||||
return fib(n - 1) + fib(n - 2);
|
||||
};
|
||||
|
||||
fib_iter := fn(n: int): int {
|
||||
a := 0;
|
||||
b := 1;
|
||||
loop if n == 0 break else {
|
||||
c := a + b;
|
||||
a = b;
|
||||
b = c;
|
||||
n -= 1;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
```
|
||||
|
||||
### Incomplete Examples
|
||||
|
||||
#### generic_types
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
--fmt - format all source files
|
||||
--fmt-current - format mentioned file
|
||||
--fmt-stdout - dont write the formatted file but print it
|
||||
--threads <1...> - number of threads compiler can use [default: 1]
|
||||
|
|
|
@ -2841,7 +2841,8 @@ impl Codegen {
|
|||
mod tests {
|
||||
use {
|
||||
super::parser,
|
||||
crate::{codegen::LoggedMem, log},
|
||||
crate::{codegen::LoggedMem, log, parser::FileId},
|
||||
std::io,
|
||||
};
|
||||
|
||||
const README: &str = include_str!("../README.md");
|
||||
|
@ -2872,9 +2873,30 @@ mod tests {
|
|||
|
||||
let input = find_block(input, ident);
|
||||
|
||||
let path = "test";
|
||||
let mut module_map = Vec::new();
|
||||
let mut last_start = 0;
|
||||
let mut last_module_name = "test";
|
||||
for (i, m) in input.match_indices("// in module: ") {
|
||||
module_map.push((last_module_name, &input[last_start..i]));
|
||||
let (module_name, _) = input[i + m.len()..].split_once('\n').unwrap();
|
||||
last_module_name = module_name;
|
||||
last_start = i + m.len() + module_name.len() + 1;
|
||||
}
|
||||
module_map.push((last_module_name, &input[last_start..]));
|
||||
|
||||
let loader = |path: &str, _: &str| {
|
||||
module_map
|
||||
.iter()
|
||||
.position(|&(name, _)| name == path)
|
||||
.map(|i| i as FileId)
|
||||
.ok_or(io::Error::from(io::ErrorKind::NotFound))
|
||||
};
|
||||
|
||||
let mut codegen = super::Codegen {
|
||||
files: vec![parser::Ast::new(path, input, &parser::no_loader)],
|
||||
files: module_map
|
||||
.iter()
|
||||
.map(|&(path, content)| parser::Ast::new(path, content, &loader))
|
||||
.collect(),
|
||||
..Default::default()
|
||||
};
|
||||
codegen.generate();
|
||||
|
@ -2947,5 +2969,6 @@ mod tests {
|
|||
generic_types => README;
|
||||
generic_functions => README;
|
||||
c_strings => README;
|
||||
struct_patterns => README;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::num::NonZeroUsize;
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
let args = std::env::args().collect::<Vec<_>>();
|
||||
let args = args.iter().map(String::as_str).collect::<Vec<_>>();
|
||||
|
@ -13,6 +15,12 @@ fn main() -> std::io::Result<()> {
|
|||
hblang::Options {
|
||||
fmt: args.contains(&"--fmt"),
|
||||
fmt_current: args.contains(&"--fmt-current"),
|
||||
extra_threads: args
|
||||
.iter()
|
||||
.position(|&a| a == "--threads")
|
||||
.map(|i| args[i + 1].parse::<NonZeroUsize>().expect("--threads expects integer"))
|
||||
.map_or(1, NonZeroUsize::get)
|
||||
- 1,
|
||||
},
|
||||
&mut std::io::stdout(),
|
||||
)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
ev: Ecall
|
||||
code size: 235
|
||||
code size: 239
|
||||
ret: 0
|
||||
status: Ok(())
|
||||
|
|
3
hblang/tests/codegen_tests_struct_patterns.txt
Normal file
3
hblang/tests/codegen_tests_struct_patterns.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
code size: 533
|
||||
ret: 0
|
||||
status: Ok(())
|
Loading…
Reference in a new issue