forked from AbleOS/holey-bytes
adding target @target directive
Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
parent
d1bc70892b
commit
18e8a831ab
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Reference in a new issue