adding target @target directive

Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
Jakub Doka 2025-01-01 22:56:40 +01:00
parent d1bc70892b
commit 18e8a831ab
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
5 changed files with 69 additions and 1 deletions

View file

@ -67,6 +67,10 @@ impl Backend {
}
impl hblang::backend::Backend for Backend {
fn triple(&self) -> String {
self.module.as_ref().unwrap().isa().triple().to_string()
}
fn assemble_reachable(
&mut self,
from: hbty::Func,

View file

@ -454,6 +454,8 @@ main := fn(): uint {
embedded_array := @as([15]u8, @embed("text.txt"))
two_fields := @lenof(foo.Type)
the_struct_kind := @kindof(foo.Type)
if @target("compile-time") die
if !@target("*-virt-unknown") die
return @inline(foo.foo)
}
@ -486,6 +488,7 @@ arbitrary text
- `@Any()`: generic parameter based on inference, TBD: this will ake arguments in the future that restrict what is accepted
- `@error(...<expr>)`: emit compiler error, if reachable, and use arguments to construct a message, can display strings and types
- `@ChildOf(<ty>)`: returns the child type of the `<ty>`, works for pointers and optionals (`@ChildOf(?u8) == u8`)
- `@target("<pat>")`: if the supplied pattern matches the target triple code is compiled to this returns `true`, compile time target is `"compile-time"`
#### c_strings
```hb

View file

@ -11,6 +11,7 @@ use {
core::{assert_matches::debug_assert_matches, error, mem, ops::Range},
hbbytecode::{self as instrs, *},
reg::Reg,
std::borrow::ToOwned,
};
mod regalloc;
@ -115,6 +116,10 @@ impl HbvmBackend {
}
impl Backend for HbvmBackend {
fn triple(&self) -> String {
TARGET_TRIPLE.to_owned()
}
fn assemble_bin(
&mut self,
entry: ty::Func,

View file

@ -1,5 +1,6 @@
#![feature(
iter_array_chunks,
str_split_remainder,
assert_matches,
let_chains,
if_let_guard,
@ -75,9 +76,51 @@ pub mod backend {
utils::EntSlice,
},
alloc::{string::String, vec::Vec},
core::error,
core::{error, mem::take},
};
pub fn match_triple(pattern: &str, triple: &str) -> Result<bool, &'static str> {
if pattern == "*" {
return Err("you can replace this with 'true'");
}
if pattern.ends_with("-*") {
return Err("trailing '*' is redundant");
}
let mut matcher = pattern.split('-');
let mut matchee = triple.split('-');
let mut eat_start = false;
loop {
match matcher.next() {
Some("*") if eat_start => return Err("consecutive '*' are redundant"),
Some("*") if matchee.next().is_none() => return Ok(false),
Some("*") => eat_start = true,
Some(pat) if take(&mut eat_start) => {
if matchee.by_ref().all(|v| v != pat) {
return Ok(false);
}
}
Some(pat) if matchee.next() != Some(pat) => return Ok(false),
Some(_) => {}
None => return Ok(true),
}
}
}
#[test]
fn sanity_match_triple() {
assert!(match_triple("a-b-c", "a-b-c").unwrap());
assert!(match_triple("*-b-c", "a-b-c").unwrap());
assert!(match_triple("*-c", "a-b-c").unwrap());
assert!(match_triple("a", "a-b-c").unwrap());
assert!(!match_triple("*-a", "a-b-c").unwrap());
assert!(!match_triple("*-a", "a-b-c").unwrap());
assert!(match_triple("*-*", "a-b-c").is_err());
assert!(match_triple("*-b-*", "a-b-c").is_err());
}
pub mod hbvm;
pub struct AssemblySpec {
@ -87,6 +130,7 @@ pub mod backend {
}
pub trait Backend {
fn triple(&self) -> String;
fn assemble_reachable(
&mut self,
from: ty::Func,

View file

@ -564,6 +564,7 @@ pub struct Codegen<'a> {
pub files: &'a EntSlice<Module, parser::Ast>,
pub errors: &'a RefCell<String>,
pub warnings: &'a RefCell<String>,
backend_triple: String,
tys: &'a mut Types,
ci: ItemCtx,
pool: &'a mut Pool,
@ -596,6 +597,7 @@ impl<'a> Codegen<'a> {
files: files.into(),
errors: &ctx.parser.errors,
warnings: &ctx.parser.warnings,
backend_triple: backend.triple(),
tys: &mut ctx.tys,
ci: Default::default(),
pool: &mut ctx.pool,
@ -1446,6 +1448,16 @@ impl<'a> Codegen<'a> {
self.ci.nodes.new_node(glob.ty, Kind::Global { global: id }, [VOID], self.tys);
Some(Value::ptr(g).ty(glob.ty))
}
Expr::Directive { name: "target", args: &[Expr::String { pos, literal }], .. } => {
let value = match crate::backend::match_triple(
&literal[1..literal.len() - 1],
if self.ct.active() { "compile-time" } else { &self.backend_triple },
) {
Ok(v) => v,
Err(msg) => return self.error(pos, msg),
};
self.gen_inferred_const(ctx, ty::Id::BOOL, value)
}
Expr::Directive { name: "kindof", args: [ty], .. } => {
let ty = self.ty(ty);
self.gen_inferred_const(ctx, ty::Id::U8, ty.kind())