Code cleanup
This commit is contained in:
@@ -17,7 +17,10 @@ unsafe impl Send for AllocationEntry {}
|
|||||||
unsafe impl Sync for AllocationEntry {}
|
unsafe impl Sync for AllocationEntry {}
|
||||||
|
|
||||||
pub trait Allocator {
|
pub trait Allocator {
|
||||||
|
#[allow(clippy::missing_safety_doc)]
|
||||||
unsafe fn alloc_uninit(&self, layout: Layout, drop: DropFn) -> *mut u8;
|
unsafe fn alloc_uninit(&self, layout: Layout, drop: DropFn) -> *mut u8;
|
||||||
|
|
||||||
|
#[allow(clippy::missing_safety_doc)]
|
||||||
unsafe fn alloc_unsafe(&self, data: *const u8, layout: Layout, drop: DropFn) -> *mut u8;
|
unsafe fn alloc_unsafe(&self, data: *const u8, layout: Layout, drop: DropFn) -> *mut u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,6 +29,7 @@ pub trait SyncAllocator: Allocator + Send + Sync {}
|
|||||||
impl<T: Allocator + Send + Sync> SyncAllocator for T {}
|
impl<T: Allocator + Send + Sync> SyncAllocator for T {}
|
||||||
|
|
||||||
impl<'l> dyn Allocator + 'l {
|
impl<'l> dyn Allocator + 'l {
|
||||||
|
#[allow(clippy::mut_from_ref)]
|
||||||
pub fn alloc<T>(&'l self, value: T) -> &'l mut T {
|
pub fn alloc<T>(&'l self, value: T) -> &'l mut T {
|
||||||
unsafe {
|
unsafe {
|
||||||
let value = MaybeUninit::new(value);
|
let value = MaybeUninit::new(value);
|
||||||
@@ -49,7 +53,7 @@ impl<'l> dyn Allocator + 'l {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_slice<T>(&'l self, iter: impl Iterator<Item = T> + ExactSizeIterator) -> &'l [T] {
|
pub fn alloc_slice<T>(&'l self, iter: impl ExactSizeIterator<Item = T>) -> &'l [T] {
|
||||||
unsafe {
|
unsafe {
|
||||||
let len = iter.len();
|
let len = iter.len();
|
||||||
let layout = Layout::array::<T>(len).unwrap();
|
let layout = Layout::array::<T>(len).unwrap();
|
||||||
@@ -82,7 +86,7 @@ impl<'l> dyn SyncAllocator + 'l {
|
|||||||
<dyn Allocator>::alloc_str(self, value)
|
<dyn Allocator>::alloc_str(self, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_slice<T>(&'l self, iter: impl Iterator<Item = T> + ExactSizeIterator) -> &'l [T] {
|
pub fn alloc_slice<T>(&'l self, iter: impl ExactSizeIterator<Item = T>) -> &'l [T] {
|
||||||
<dyn Allocator>::alloc_slice(self, iter)
|
<dyn Allocator>::alloc_slice(self, iter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-12
@@ -6,7 +6,7 @@ use derive_more::{Debug, Display};
|
|||||||
use fxhash::FxBuildHasher;
|
use fxhash::FxBuildHasher;
|
||||||
use leaf_allocators::SyncAllocator;
|
use leaf_allocators::SyncAllocator;
|
||||||
use scc::HashMap;
|
use scc::HashMap;
|
||||||
use std::{borrow::Cow, fmt::Display, hash::Hash, sync::OnceLock};
|
use std::{borrow::Cow, hash::Hash, sync::OnceLock};
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
derive_more::Debug, Display, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
|
derive_more::Debug, Display, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
|
||||||
@@ -69,7 +69,7 @@ impl<'l> Context<'l> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_or_create_assembly(&'l self, ident: AssemblyIdentifier) -> &'l Assembly<'l> {
|
pub fn get_or_create_assembly(&'l self, ident: AssemblyIdentifier) -> &'l Assembly<'l> {
|
||||||
&*self
|
&self
|
||||||
.assemblies
|
.assemblies
|
||||||
.entry_sync(ident.clone())
|
.entry_sync(ident.clone())
|
||||||
.or_insert_with(|| Assembly::new(self, ident))
|
.or_insert_with(|| Assembly::new(self, ident))
|
||||||
@@ -77,7 +77,7 @@ impl<'l> Context<'l> {
|
|||||||
|
|
||||||
pub fn intern_str(&'l self, str: &str) -> &'l str {
|
pub fn intern_str(&'l self, str: &str) -> &'l str {
|
||||||
if let Some(value) = self.strings.get_sync(str) {
|
if let Some(value) = self.strings.get_sync(str) {
|
||||||
return (*value).into();
|
return *value;
|
||||||
}
|
}
|
||||||
let str = self.alloc.alloc_str(str);
|
let str = self.alloc.alloc_str(str);
|
||||||
let _ = self.strings.insert_sync(str, str);
|
let _ = self.strings.insert_sync(str, str);
|
||||||
@@ -109,12 +109,11 @@ impl Hash for Assembly<'_> {
|
|||||||
|
|
||||||
impl<'l> Assembly<'l> {
|
impl<'l> Assembly<'l> {
|
||||||
pub fn new(ctx: &'l Context<'l>, ident: AssemblyIdentifier) -> &'l Self {
|
pub fn new(ctx: &'l Context<'l>, ident: AssemblyIdentifier) -> &'l Self {
|
||||||
let assembly = ctx.alloc.alloc(Self {
|
(ctx.alloc.alloc(Self {
|
||||||
ctx,
|
ctx,
|
||||||
ident,
|
ident,
|
||||||
functions: boxcar::vec![],
|
functions: boxcar::vec![],
|
||||||
});
|
})) as _
|
||||||
assembly
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ctx(&self) -> Ctx<'l> {
|
pub fn ctx(&self) -> Ctx<'l> {
|
||||||
@@ -144,11 +143,10 @@ impl<'l> Assembly<'l> {
|
|||||||
&'l self,
|
&'l self,
|
||||||
filter: impl Fn(&'l Function<'l>) -> bool,
|
filter: impl Fn(&'l Function<'l>) -> bool,
|
||||||
) -> Option<&'l Function<'l>> {
|
) -> Option<&'l Function<'l>> {
|
||||||
for (_, func) in self.functions.iter() {
|
self.functions
|
||||||
if filter(func) {
|
.iter()
|
||||||
return Some(func);
|
.map(|(_, func)| func)
|
||||||
}
|
.find(|&func| filter(func))
|
||||||
}
|
.map(|v| v as _)
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,12 +161,7 @@ pub enum InstructionVariant<'l> {
|
|||||||
|
|
||||||
impl InstructionVariant<'_> {
|
impl InstructionVariant<'_> {
|
||||||
pub fn is_block_termination(&self) -> bool {
|
pub fn is_block_termination(&self) -> bool {
|
||||||
match self {
|
matches!(self, Self::Return(_) | Self::Jump(_) | Self::Branch { .. })
|
||||||
Self::Return(_) => true,
|
|
||||||
Self::Jump(_) => true,
|
|
||||||
Self::Branch { .. } => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +192,7 @@ impl std::fmt::Debug for InstructionVariant<'_> {
|
|||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"call {}(",
|
"call {}(",
|
||||||
func.name.get().unwrap_or(&"<anonymous function>".into())
|
func.name.get().unwrap_or(&"<anonymous function>")
|
||||||
)?;
|
)?;
|
||||||
let mut separator = "";
|
let mut separator = "";
|
||||||
for arg in args {
|
for arg in args {
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ pub struct FunctionBody<'l> {
|
|||||||
pub blocks: Vec<&'l Block<'l>>,
|
pub blocks: Vec<&'l Block<'l>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'l> FmtDebug for FunctionBody<'_> {
|
impl FmtDebug for FunctionBody<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
struct BlockDbg<'l>(&'l Block<'l>);
|
struct BlockDbg<'l>(&'l Block<'l>);
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ pub enum Type<'l> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'l> Type<'l> {
|
impl<'l> Type<'l> {
|
||||||
|
#[allow(clippy::missing_transmute_annotations)]
|
||||||
pub fn ctx(&self) -> &'l Context<'l> {
|
pub fn ctx(&self) -> &'l Context<'l> {
|
||||||
match self.non_default_ctx() {
|
match self.non_default_ctx() {
|
||||||
Some(ctx) => ctx,
|
Some(ctx) => ctx,
|
||||||
@@ -69,7 +70,7 @@ impl<'l> Type<'l> {
|
|||||||
static ALLOCATOR: OnceLock<SyncArenaAllocator> = OnceLock::new();
|
static ALLOCATOR: OnceLock<SyncArenaAllocator> = OnceLock::new();
|
||||||
let ctx: &'static Context = DEFAULT.get_or_init(|| {
|
let ctx: &'static Context = DEFAULT.get_or_init(|| {
|
||||||
let allocator: &'static SyncArenaAllocator =
|
let allocator: &'static SyncArenaAllocator =
|
||||||
ALLOCATOR.get_or_init(|| SyncArenaAllocator::default());
|
ALLOCATOR.get_or_init(SyncArenaAllocator::default);
|
||||||
Context::new(allocator)
|
Context::new(allocator)
|
||||||
});
|
});
|
||||||
std::mem::transmute(ctx)
|
std::mem::transmute(ctx)
|
||||||
|
|||||||
@@ -50,12 +50,12 @@ impl Hash for Float {
|
|||||||
#[display("{}", _0)]
|
#[display("{}", _0)]
|
||||||
pub struct Const<T>(T);
|
pub struct Const<T>(T);
|
||||||
|
|
||||||
impl<'l, T: 'l> Into<AnyConst<'l>> for &'l Const<T>
|
impl<'l, T: 'l> From<&'l Const<T>> for AnyConst<'l>
|
||||||
where
|
where
|
||||||
for<'a> &'a T: Into<AnyConst<'a>>,
|
for<'a> &'a T: Into<AnyConst<'a>>,
|
||||||
{
|
{
|
||||||
fn into(self) -> AnyConst<'l> {
|
fn from(val: &'l Const<T>) -> Self {
|
||||||
(&self.0).into()
|
(&val.0).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ impl<'l> AnyConst<'l> {
|
|||||||
|
|
||||||
pub fn flags(&self) -> super::ValueFlags {
|
pub fn flags(&self) -> super::ValueFlags {
|
||||||
match self {
|
match self {
|
||||||
AnyConst::Function(function) => ValueFlags::Function,
|
AnyConst::Function(_) => ValueFlags::Function,
|
||||||
AnyConst::Type(_) => ValueFlags::Type,
|
AnyConst::Type(_) => ValueFlags::Type,
|
||||||
_ => ValueFlags::Const,
|
_ => ValueFlags::Const,
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-13
@@ -42,16 +42,17 @@ impl<'l> CompilationContext<'l> {
|
|||||||
modules: HashMap::default(),
|
modules: HashMap::default(),
|
||||||
functions: HashMap::default(),
|
functions: HashMap::default(),
|
||||||
native_int_ty: match target.get_target_data().get_pointer_byte_size(None) {
|
native_int_ty: match target.get_target_data().get_pointer_byte_size(None) {
|
||||||
8 => ctx.i8_type().into(),
|
8 => ctx.i8_type(),
|
||||||
16 => ctx.i16_type().into(),
|
16 => ctx.i16_type(),
|
||||||
32 => ctx.i32_type().into(),
|
32 => ctx.i32_type(),
|
||||||
64 => ctx.i64_type().into(),
|
64 => ctx.i64_type(),
|
||||||
128 => ctx.i128_type().into(),
|
128 => ctx.i128_type(),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::mutable_key_type)]
|
||||||
pub fn compile(&self, assembly: &'l Assembly<'l>) -> LlvmModule<'l> {
|
pub fn compile(&self, assembly: &'l Assembly<'l>) -> LlvmModule<'l> {
|
||||||
let mut exists = true;
|
let mut exists = true;
|
||||||
let module = self
|
let module = self
|
||||||
@@ -79,8 +80,8 @@ impl<'l> CompilationContext<'l> {
|
|||||||
.or_insert_with(|| module.add_function(name, ty, None));
|
.or_insert_with(|| module.add_function(name, ty, None));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, func) in assembly.functions() {
|
for (_, func) in assembly.functions() {
|
||||||
let llvm_func = self.functions.get_sync(&(assembly, *func)).unwrap().clone();
|
let llvm_func = *self.functions.get_sync(&(assembly, *func)).unwrap();
|
||||||
|
|
||||||
let Some(body) = func.body() else {
|
let Some(body) = func.body() else {
|
||||||
continue;
|
continue;
|
||||||
@@ -128,7 +129,7 @@ impl<'l> CompilationContext<'l> {
|
|||||||
break 'val None;
|
break 'val None;
|
||||||
};
|
};
|
||||||
let ptr = value.into_pointer_value();
|
let ptr = value.into_pointer_value();
|
||||||
Some(builder.build_load(ty, ptr, "").unwrap().into())
|
Some(builder.build_load(ty, ptr, "").unwrap())
|
||||||
}
|
}
|
||||||
InstructionVariant::Store(target, value) => 'val: {
|
InstructionVariant::Store(target, value) => 'val: {
|
||||||
let Some(t_val) = self.get_value(&values, target) else {
|
let Some(t_val) = self.get_value(&values, target) else {
|
||||||
@@ -220,7 +221,7 @@ impl<'l> CompilationContext<'l> {
|
|||||||
|
|
||||||
InstructionVariant::Call(func, args) => {
|
InstructionVariant::Call(func, args) => {
|
||||||
// TODO This will fail with external assemblies. Fix this.
|
// TODO This will fail with external assemblies. Fix this.
|
||||||
let func = self.functions.get_sync(&(assembly, *func)).unwrap().clone();
|
let func = *self.functions.get_sync(&(assembly, *func)).unwrap();
|
||||||
let args: Vec<_> = args
|
let args: Vec<_> = args
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|a| self.get_value(&values, a).map(|a| a.into()))
|
.filter_map(|a| self.get_value(&values, a).map(|a| a.into()))
|
||||||
@@ -334,13 +335,14 @@ impl<'l> CompilationContext<'l> {
|
|||||||
llvm_ty
|
llvm_ty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::mutable_key_type)]
|
||||||
fn get_value(
|
fn get_value(
|
||||||
&self,
|
&self,
|
||||||
map: &FxHashMap<Value<'l>, Option<BasicValueEnum<'l>>>,
|
map: &FxHashMap<Value<'l>, Option<BasicValueEnum<'l>>>,
|
||||||
val: &Value<'l>,
|
val: &Value<'l>,
|
||||||
) -> Option<BasicValueEnum<'l>> {
|
) -> Option<BasicValueEnum<'l>> {
|
||||||
if let Some(value) = map.get(val) {
|
if let Some(value) = map.get(val) {
|
||||||
return value.clone();
|
return *value;
|
||||||
}
|
}
|
||||||
match val {
|
match val {
|
||||||
Value::Constant(val) => match val {
|
Value::Constant(val) => match val {
|
||||||
@@ -353,9 +355,7 @@ impl<'l> CompilationContext<'l> {
|
|||||||
AnyConst::Int(Int::U32(v)) => {
|
AnyConst::Int(Int::U32(v)) => {
|
||||||
Some(self.ctx.i32_type().const_int(*v as u64, false).into())
|
Some(self.ctx.i32_type().const_int(*v as u64, false).into())
|
||||||
}
|
}
|
||||||
AnyConst::Int(Int::U64(v)) => {
|
AnyConst::Int(Int::U64(v)) => Some(self.ctx.i64_type().const_int(*v, false).into()),
|
||||||
Some(self.ctx.i64_type().const_int(*v as u64, false).into())
|
|
||||||
}
|
|
||||||
AnyConst::Int(Int::USize(v)) => {
|
AnyConst::Int(Int::USize(v)) => {
|
||||||
Some(self.native_int_ty.const_int(*v as u64, false).into())
|
Some(self.native_int_ty.const_int(*v as u64, false).into())
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-25
@@ -5,7 +5,7 @@ use leaf_assembly::{
|
|||||||
Function,
|
Function,
|
||||||
ir::{Cmp, FunctionBodyBuilder},
|
ir::{Cmp, FunctionBodyBuilder},
|
||||||
},
|
},
|
||||||
types::{IntT, Type, derivations::PtrT},
|
types::{Type, derivations::PtrT},
|
||||||
values::{AnyConst, Int, Value, ValueFlags},
|
values::{AnyConst, Int, Value, ValueFlags},
|
||||||
};
|
};
|
||||||
use leaf_parser::{
|
use leaf_parser::{
|
||||||
@@ -118,7 +118,7 @@ impl<'l> Scope<'l> {
|
|||||||
.map(|f| Value::Constant(AnyConst::Function(f)))
|
.map(|f| Value::Constant(AnyConst::Function(f)))
|
||||||
.map_err(|err| CompilationError {
|
.map_err(|err| CompilationError {
|
||||||
kind: Kind::FunctionCompilationFailed,
|
kind: Kind::FunctionCompilationFailed,
|
||||||
message: format!("Could not compile function."),
|
message: "Could not compile function.".to_string(),
|
||||||
location: Location::Range {
|
location: Location::Range {
|
||||||
file: self.source.clone(),
|
file: self.source.clone(),
|
||||||
range: func.text.range(),
|
range: func.text.range(),
|
||||||
@@ -135,7 +135,7 @@ impl<'l> Scope<'l> {
|
|||||||
match n.text.split_at_checked(2) {
|
match n.text.split_at_checked(2) {
|
||||||
Some(("0b", value)) => <$ty>::from_str_radix(value, 2),
|
Some(("0b", value)) => <$ty>::from_str_radix(value, 2),
|
||||||
Some(("0x", value)) => <$ty>::from_str_radix(value, 16),
|
Some(("0x", value)) => <$ty>::from_str_radix(value, 16),
|
||||||
_ => <$ty>::from_str_radix(&n.text, 10),
|
_ => n.text.parse::<$ty>(),
|
||||||
}
|
}
|
||||||
.map(|v| Value::Constant(AnyConst::Int(Int::$id(v))))
|
.map(|v| Value::Constant(AnyConst::Int(Int::$id(v))))
|
||||||
.map_err(|_| CompilationError {
|
.map_err(|_| CompilationError {
|
||||||
@@ -163,17 +163,15 @@ impl<'l> Scope<'l> {
|
|||||||
Some("u64") => parse_number!(u64, U64),
|
Some("u64") => parse_number!(u64, U64),
|
||||||
Some("u128") => parse_number!(u128, U128),
|
Some("u128") => parse_number!(u128, U128),
|
||||||
Some("usize") => parse_number!(u128, USize),
|
Some("usize") => parse_number!(u128, USize),
|
||||||
Some(ty) => {
|
Some(ty) => Err(CompilationError {
|
||||||
return Err(CompilationError {
|
kind: Kind::InvalidIntegerType,
|
||||||
kind: Kind::InvalidIntegerType,
|
message: format!("`{ty}` is not a valid integer type."),
|
||||||
message: format!("`{ty}` is not a valid integer type."),
|
location: Location::Range {
|
||||||
location: Location::Range {
|
file: self.source.clone(),
|
||||||
file: self.source.clone(),
|
range: n.text.range(),
|
||||||
range: n.text.range(),
|
},
|
||||||
},
|
cause: None,
|
||||||
cause: None,
|
}),
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,14 +245,14 @@ impl<'l> Scope<'l> {
|
|||||||
let Value::Constant(AnyConst::Type(dst_ty)) = rhs else {
|
let Value::Constant(AnyConst::Type(dst_ty)) = rhs else {
|
||||||
return Err(CompilationError {
|
return Err(CompilationError {
|
||||||
kind: Kind::NotAType,
|
kind: Kind::NotAType,
|
||||||
message: format!("Cannot perform cast."),
|
message: "Cannot perform cast.".to_string(),
|
||||||
location: Location::Range {
|
location: Location::Range {
|
||||||
file: self.source.clone(),
|
file: self.source.clone(),
|
||||||
range: expr.range(),
|
range: expr.range(),
|
||||||
},
|
},
|
||||||
cause: Some(Box::new(CompilationError {
|
cause: Some(Box::new(CompilationError {
|
||||||
kind: Kind::NotAType,
|
kind: Kind::NotAType,
|
||||||
message: format!("Cast target is not a type."),
|
message: "Cast target is not a type.".to_string(),
|
||||||
location: Location::Range {
|
location: Location::Range {
|
||||||
file: self.source.clone(),
|
file: self.source.clone(),
|
||||||
range: rhs_expr.range(),
|
range: rhs_expr.range(),
|
||||||
@@ -266,7 +264,7 @@ impl<'l> Scope<'l> {
|
|||||||
match (src_ty, dst_ty) {
|
match (src_ty, dst_ty) {
|
||||||
(Type::Int(src_ty), Type::Int(dst_ty)) => {
|
(Type::Int(src_ty), Type::Int(dst_ty)) => {
|
||||||
if dst_ty.precision < src_ty.precision {
|
if dst_ty.precision < src_ty.precision {
|
||||||
return Ok(builder.trunc(lhs, dst_ty).unwrap().into());
|
return Ok(builder.trunc(lhs, dst_ty).unwrap());
|
||||||
}
|
}
|
||||||
todo!("{src_ty} as {dst_ty}");
|
todo!("{src_ty} as {dst_ty}");
|
||||||
}
|
}
|
||||||
@@ -373,8 +371,7 @@ impl<'l> Scope<'l> {
|
|||||||
unsafe {
|
unsafe {
|
||||||
Ok(builder
|
Ok(builder
|
||||||
.reinterpret(Value::Instruction(inst), ptr, flags)
|
.reinterpret(Value::Instruction(inst), ptr, flags)
|
||||||
.unwrap()
|
.unwrap())
|
||||||
.into())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v => todo!("{v:?}"),
|
v => todo!("{v:?}"),
|
||||||
@@ -509,10 +506,10 @@ impl<'l> Scope<'l> {
|
|||||||
match func.ty.ret_t {
|
match func.ty.ret_t {
|
||||||
Type::Void => builder.ret(None).unwrap(),
|
Type::Void => builder.ret(None).unwrap(),
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(expr) = last_expr.as_mut() {
|
if let Some(expr) = last_expr.as_mut()
|
||||||
if expr.flags().contains(ValueFlags::LValue) {
|
&& expr.flags().contains(ValueFlags::LValue)
|
||||||
*expr = builder.load(*expr).unwrap();
|
{
|
||||||
}
|
*expr = builder.load(*expr).unwrap();
|
||||||
}
|
}
|
||||||
builder.ret(last_expr).unwrap()
|
builder.ret(last_expr).unwrap()
|
||||||
}
|
}
|
||||||
@@ -533,7 +530,7 @@ impl<'l> Scope<'l> {
|
|||||||
) -> Result<Value<'l>, CompilationError> {
|
) -> Result<Value<'l>, CompilationError> {
|
||||||
let mut sub_ctx = ExpressionContext {
|
let mut sub_ctx = ExpressionContext {
|
||||||
decl_names: Some(names),
|
decl_names: Some(names),
|
||||||
builder: ctx.builder.as_mut().map(|v| &mut **v),
|
builder: ctx.builder.as_deref_mut(),
|
||||||
};
|
};
|
||||||
let mut value = self.compile_expression(value, &mut sub_ctx)?;
|
let mut value = self.compile_expression(value, &mut sub_ctx)?;
|
||||||
if mutable {
|
if mutable {
|
||||||
@@ -558,7 +555,7 @@ impl<'l> Scope<'l> {
|
|||||||
Value::Constant(AnyConst::Type(ty)) => Ok(ty),
|
Value::Constant(AnyConst::Type(ty)) => Ok(ty),
|
||||||
_ => Err(CompilationError {
|
_ => Err(CompilationError {
|
||||||
kind: Kind::NotAType,
|
kind: Kind::NotAType,
|
||||||
message: format!("Value is not a type."),
|
message: "Value is not a type.".to_string(),
|
||||||
location: Location::None,
|
location: Location::None,
|
||||||
cause: None,
|
cause: None,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -8,17 +8,17 @@ impl Parse for SourceCode {
|
|||||||
type PositionRepr = LineCol;
|
type PositionRepr = LineCol;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn start<'input>(&'input self) -> usize {
|
fn start(&self) -> usize {
|
||||||
self.text.as_str().start()
|
self.text.as_str().start()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_eof<'input>(&'input self, p: usize) -> bool {
|
fn is_eof(&self, p: usize) -> bool {
|
||||||
self.text.as_str().is_eof(p)
|
self.text.as_str().is_eof(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn position_repr<'input>(&'input self, p: usize) -> Self::PositionRepr {
|
fn position_repr(&self, p: usize) -> Self::PositionRepr {
|
||||||
self.text.as_str().position_repr(p)
|
self.text.as_str().position_repr(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user