Get intrinsics to inline at codegen
This commit is contained in:
parent
436ab319b8
commit
8810d34d54
@ -5,5 +5,5 @@ fn main() -> u32 {
|
|||||||
let value = 6;
|
let value = 6;
|
||||||
let other = 15;
|
let other = 15;
|
||||||
|
|
||||||
return value + other;
|
return value * other + 7 * -value;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use llvm_sys::{
|
use llvm_sys::{
|
||||||
LLVMIntPredicate, LLVMLinkage, LLVMRealPredicate, LLVMValueKind,
|
LLVMAttributeIndex, LLVMIntPredicate, LLVMLinkage, LLVMRealPredicate, LLVMValueKind,
|
||||||
analysis::LLVMVerifyModule,
|
analysis::LLVMVerifyModule,
|
||||||
core::*,
|
core::*,
|
||||||
debuginfo::*,
|
debuginfo::*,
|
||||||
@ -86,7 +86,7 @@ impl CompiledModule {
|
|||||||
triple,
|
triple,
|
||||||
c"generic".as_ptr(),
|
c"generic".as_ptr(),
|
||||||
c"".as_ptr(),
|
c"".as_ptr(),
|
||||||
llvm_sys::target_machine::LLVMCodeGenOptLevel::LLVMCodeGenLevelNone,
|
llvm_sys::target_machine::LLVMCodeGenOptLevel::LLVMCodeGenLevelLess,
|
||||||
llvm_sys::target_machine::LLVMRelocMode::LLVMRelocDefault,
|
llvm_sys::target_machine::LLVMRelocMode::LLVMRelocDefault,
|
||||||
llvm_sys::target_machine::LLVMCodeModel::LLVMCodeModelDefault,
|
llvm_sys::target_machine::LLVMCodeModel::LLVMCodeModelDefault,
|
||||||
);
|
);
|
||||||
@ -601,6 +601,15 @@ impl FunctionHolder {
|
|||||||
let function_ref =
|
let function_ref =
|
||||||
LLVMAddFunction(module_ref, into_cstring(&self.data.name).as_ptr(), fn_type);
|
LLVMAddFunction(module_ref, into_cstring(&self.data.name).as_ptr(), fn_type);
|
||||||
|
|
||||||
|
if self.data.flags.inline {
|
||||||
|
let attribute = LLVMCreateEnumAttribute(
|
||||||
|
context.context_ref,
|
||||||
|
LLVMEnumAttribute::AlwaysInline as u32,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
LLVMAddAttributeAtIndex(function_ref, 0, attribute);
|
||||||
|
}
|
||||||
|
|
||||||
let metadata = if let Some(debug) = debug {
|
let metadata = if let Some(debug) = debug {
|
||||||
if let Some(value) = &self.data.debug {
|
if let Some(value) = &self.data.debug {
|
||||||
let subprogram = debug.debug.get_subprogram_data_unchecked(&value);
|
let subprogram = debug.debug.get_subprogram_data_unchecked(&value);
|
||||||
@ -1215,3 +1224,7 @@ impl Type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum LLVMEnumAttribute {
|
||||||
|
AlwaysInline = 3,
|
||||||
|
}
|
||||||
|
@ -148,6 +148,7 @@ pub struct FunctionFlags {
|
|||||||
pub is_main: bool,
|
pub is_main: bool,
|
||||||
pub is_pub: bool,
|
pub is_pub: bool,
|
||||||
pub is_imported: bool,
|
pub is_imported: bool,
|
||||||
|
pub inline: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FunctionFlags {
|
impl Default for FunctionFlags {
|
||||||
@ -157,6 +158,7 @@ impl Default for FunctionFlags {
|
|||||||
is_main: false,
|
is_main: false,
|
||||||
is_pub: false,
|
is_pub: false,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
|
inline: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ use reid_lib::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
allocator::{Allocator, AllocatorScope},
|
allocator::{Allocator, AllocatorScope},
|
||||||
|
intrinsics::IntrinsicFunction,
|
||||||
lexer::{FullToken, Position},
|
lexer::{FullToken, Position},
|
||||||
mir::{
|
mir::{
|
||||||
self,
|
self,
|
||||||
@ -137,7 +138,7 @@ pub struct Debug<'ctx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct StackValue(StackValueKind, TypeKind);
|
pub struct StackValue(pub(super) StackValueKind, pub(super) TypeKind);
|
||||||
|
|
||||||
impl StackValue {
|
impl StackValue {
|
||||||
fn instr(&self) -> InstructionValue {
|
fn instr(&self) -> InstructionValue {
|
||||||
@ -188,7 +189,12 @@ impl StackValueKind {
|
|||||||
pub struct StackBinopDefinition<'ctx> {
|
pub struct StackBinopDefinition<'ctx> {
|
||||||
parameters: ((String, TypeKind), (String, TypeKind)),
|
parameters: ((String, TypeKind), (String, TypeKind)),
|
||||||
return_ty: TypeKind,
|
return_ty: TypeKind,
|
||||||
ir: Function<'ctx>,
|
kind: StackBinopFunctionKind<'ctx>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum StackBinopFunctionKind<'ctx> {
|
||||||
|
UserGenerated(Function<'ctx>),
|
||||||
|
Intrinsic(&'ctx Box<dyn IntrinsicFunction>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> StackBinopDefinition<'ctx> {
|
impl<'ctx> StackBinopDefinition<'ctx> {
|
||||||
@ -197,20 +203,30 @@ impl<'ctx> StackBinopDefinition<'ctx> {
|
|||||||
lhs: &StackValue,
|
lhs: &StackValue,
|
||||||
rhs: &StackValue,
|
rhs: &StackValue,
|
||||||
scope: &mut Scope<'ctx, 'a>,
|
scope: &mut Scope<'ctx, 'a>,
|
||||||
) -> StackValue {
|
) -> Result<StackValue, ErrorKind> {
|
||||||
let (lhs, rhs) = if lhs.1 == self.parameters.0 .1 && rhs.1 == self.parameters.1 .1 {
|
let (lhs, rhs) = if lhs.1 == self.parameters.0 .1 && rhs.1 == self.parameters.1 .1 {
|
||||||
(lhs, rhs)
|
(lhs, rhs)
|
||||||
} else {
|
} else {
|
||||||
(rhs, lhs)
|
(rhs, lhs)
|
||||||
};
|
};
|
||||||
let instr = scope
|
match &self.kind {
|
||||||
.block
|
StackBinopFunctionKind::UserGenerated(ir) => {
|
||||||
.build(Instr::FunctionCall(
|
let instr = scope
|
||||||
self.ir.value(),
|
.block
|
||||||
vec![lhs.instr(), rhs.instr()],
|
.build(Instr::FunctionCall(
|
||||||
))
|
ir.value(),
|
||||||
.unwrap();
|
vec![lhs.instr(), rhs.instr()],
|
||||||
StackValue(StackValueKind::Immutable(instr), self.return_ty.clone())
|
))
|
||||||
|
.unwrap();
|
||||||
|
Ok(StackValue(
|
||||||
|
StackValueKind::Immutable(instr),
|
||||||
|
self.return_ty.clone(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
StackBinopFunctionKind::Intrinsic(fun) => {
|
||||||
|
fun.codegen(scope, &[lhs.instr(), rhs.instr()])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,7 +342,7 @@ impl mir::Module {
|
|||||||
|
|
||||||
let is_main = self.is_main && function.name == "main";
|
let is_main = self.is_main && function.name == "main";
|
||||||
let func = match &function.kind {
|
let func = match &function.kind {
|
||||||
mir::FunctionDefinitionKind::Local(_, _) => module.function(
|
mir::FunctionDefinitionKind::Local(_, _) => Some(module.function(
|
||||||
&function.name,
|
&function.name,
|
||||||
function.return_type.get_type(&type_values),
|
function.return_type.get_type(&type_values),
|
||||||
param_types,
|
param_types,
|
||||||
@ -336,8 +352,8 @@ impl mir::Module {
|
|||||||
is_imported: function.is_imported,
|
is_imported: function.is_imported,
|
||||||
..FunctionFlags::default()
|
..FunctionFlags::default()
|
||||||
},
|
},
|
||||||
),
|
)),
|
||||||
mir::FunctionDefinitionKind::Extern(imported) => module.function(
|
mir::FunctionDefinitionKind::Extern(imported) => Some(module.function(
|
||||||
&function.name,
|
&function.name,
|
||||||
function.return_type.get_type(&type_values),
|
function.return_type.get_type(&type_values),
|
||||||
param_types,
|
param_types,
|
||||||
@ -346,87 +362,17 @@ impl mir::Module {
|
|||||||
is_imported: *imported,
|
is_imported: *imported,
|
||||||
..FunctionFlags::default()
|
..FunctionFlags::default()
|
||||||
},
|
},
|
||||||
),
|
)),
|
||||||
mir::FunctionDefinitionKind::Intrinsic(_) => module.function(
|
mir::FunctionDefinitionKind::Intrinsic(_) => None,
|
||||||
&function.name,
|
|
||||||
function.return_type.get_type(&type_values),
|
|
||||||
param_types,
|
|
||||||
FunctionFlags {
|
|
||||||
..FunctionFlags::default()
|
|
||||||
},
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
functions.insert(function.name.clone(), func);
|
if let Some(func) = func {
|
||||||
|
functions.insert(function.name.clone(), func);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut binops = HashMap::new();
|
let mut binops = HashMap::new();
|
||||||
for binop in &self.binop_defs {
|
for binop in &self.binop_defs {
|
||||||
let binop_fn_name = format!(
|
|
||||||
"binop.{}.{:?}.{}.{}",
|
|
||||||
binop.lhs.1, binop.op, binop.rhs.1, binop.return_type
|
|
||||||
);
|
|
||||||
let ir_function = module.function(
|
|
||||||
&binop_fn_name,
|
|
||||||
binop.return_type.get_type(&type_values),
|
|
||||||
vec![
|
|
||||||
binop.lhs.1.get_type(&type_values),
|
|
||||||
binop.rhs.1.get_type(&type_values),
|
|
||||||
],
|
|
||||||
FunctionFlags::default(),
|
|
||||||
);
|
|
||||||
let mut entry = ir_function.block("entry");
|
|
||||||
|
|
||||||
let allocator = Allocator::from(
|
|
||||||
&binop.fn_kind,
|
|
||||||
&vec![binop.lhs.clone(), binop.rhs.clone()],
|
|
||||||
&mut AllocatorScope {
|
|
||||||
block: &mut entry,
|
|
||||||
module_id: self.module_id,
|
|
||||||
type_values: &type_values,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut scope = Scope {
|
|
||||||
context,
|
|
||||||
modules: &modules,
|
|
||||||
tokens,
|
|
||||||
module: &module,
|
|
||||||
module_id: self.module_id,
|
|
||||||
function: &ir_function,
|
|
||||||
block: entry,
|
|
||||||
functions: &functions,
|
|
||||||
types: &types,
|
|
||||||
type_values: &type_values,
|
|
||||||
stack_values: HashMap::new(),
|
|
||||||
debug: Some(Debug {
|
|
||||||
info: &debug,
|
|
||||||
scope: compile_unit,
|
|
||||||
types: &debug_types,
|
|
||||||
}),
|
|
||||||
binops: &binops,
|
|
||||||
allocator: Rc::new(RefCell::new(allocator)),
|
|
||||||
};
|
|
||||||
|
|
||||||
binop
|
|
||||||
.fn_kind
|
|
||||||
.codegen(
|
|
||||||
binop_fn_name.clone(),
|
|
||||||
false,
|
|
||||||
&mut scope,
|
|
||||||
&vec![binop.lhs.clone(), binop.rhs.clone()],
|
|
||||||
&binop.return_type,
|
|
||||||
&ir_function,
|
|
||||||
match &binop.fn_kind {
|
|
||||||
FunctionDefinitionKind::Local(_, meta) => {
|
|
||||||
meta.into_debug(tokens, compile_unit)
|
|
||||||
}
|
|
||||||
FunctionDefinitionKind::Extern(_) => None,
|
|
||||||
FunctionDefinitionKind::Intrinsic(_) => None,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
binops.insert(
|
binops.insert(
|
||||||
ScopeBinopKey {
|
ScopeBinopKey {
|
||||||
params: (binop.lhs.1.clone(), binop.rhs.1.clone()),
|
params: (binop.lhs.1.clone(), binop.rhs.1.clone()),
|
||||||
@ -435,7 +381,83 @@ impl mir::Module {
|
|||||||
StackBinopDefinition {
|
StackBinopDefinition {
|
||||||
parameters: (binop.lhs.clone(), binop.rhs.clone()),
|
parameters: (binop.lhs.clone(), binop.rhs.clone()),
|
||||||
return_ty: binop.return_type.clone(),
|
return_ty: binop.return_type.clone(),
|
||||||
ir: ir_function,
|
kind: match &binop.fn_kind {
|
||||||
|
FunctionDefinitionKind::Local(block, metadata) => {
|
||||||
|
let binop_fn_name = format!(
|
||||||
|
"binop.{}.{:?}.{}.{}",
|
||||||
|
binop.lhs.1, binop.op, binop.rhs.1, binop.return_type
|
||||||
|
);
|
||||||
|
let ir_function = module.function(
|
||||||
|
&binop_fn_name,
|
||||||
|
binop.return_type.get_type(&type_values),
|
||||||
|
vec![
|
||||||
|
binop.lhs.1.get_type(&type_values),
|
||||||
|
binop.rhs.1.get_type(&type_values),
|
||||||
|
],
|
||||||
|
FunctionFlags {
|
||||||
|
inline: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let mut entry = ir_function.block("entry");
|
||||||
|
|
||||||
|
let allocator = Allocator::from(
|
||||||
|
&binop.fn_kind,
|
||||||
|
&vec![binop.lhs.clone(), binop.rhs.clone()],
|
||||||
|
&mut AllocatorScope {
|
||||||
|
block: &mut entry,
|
||||||
|
module_id: self.module_id,
|
||||||
|
type_values: &type_values,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut scope = Scope {
|
||||||
|
context,
|
||||||
|
modules: &modules,
|
||||||
|
tokens,
|
||||||
|
module: &module,
|
||||||
|
module_id: self.module_id,
|
||||||
|
function: &ir_function,
|
||||||
|
block: entry,
|
||||||
|
functions: &functions,
|
||||||
|
types: &types,
|
||||||
|
type_values: &type_values,
|
||||||
|
stack_values: HashMap::new(),
|
||||||
|
debug: Some(Debug {
|
||||||
|
info: &debug,
|
||||||
|
scope: compile_unit,
|
||||||
|
types: &debug_types,
|
||||||
|
}),
|
||||||
|
binops: &binops,
|
||||||
|
allocator: Rc::new(RefCell::new(allocator)),
|
||||||
|
};
|
||||||
|
|
||||||
|
binop
|
||||||
|
.fn_kind
|
||||||
|
.codegen(
|
||||||
|
binop_fn_name.clone(),
|
||||||
|
false,
|
||||||
|
&mut scope,
|
||||||
|
&vec![binop.lhs.clone(), binop.rhs.clone()],
|
||||||
|
&binop.return_type,
|
||||||
|
&ir_function,
|
||||||
|
match &binop.fn_kind {
|
||||||
|
FunctionDefinitionKind::Local(_, meta) => {
|
||||||
|
meta.into_debug(tokens, compile_unit)
|
||||||
|
}
|
||||||
|
FunctionDefinitionKind::Extern(_) => None,
|
||||||
|
FunctionDefinitionKind::Intrinsic(_) => None,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
StackBinopFunctionKind::UserGenerated(ir_function)
|
||||||
|
}
|
||||||
|
FunctionDefinitionKind::Extern(_) => todo!(),
|
||||||
|
FunctionDefinitionKind::Intrinsic(intrinsic_function) => {
|
||||||
|
StackBinopFunctionKind::Intrinsic(intrinsic_function)
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -619,7 +641,7 @@ impl FunctionDefinitionKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
mir::FunctionDefinitionKind::Extern(_) => {}
|
mir::FunctionDefinitionKind::Extern(_) => {}
|
||||||
mir::FunctionDefinitionKind::Intrinsic(kind) => kind.codegen(scope)?,
|
mir::FunctionDefinitionKind::Intrinsic(_) => {}
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -877,7 +899,10 @@ impl mir::Expression {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if let Some(operation) = operation {
|
if let Some(operation) = operation {
|
||||||
Some(operation.codegen(&lhs_val, &rhs_val, scope))
|
let a = operation.codegen(&lhs_val, &rhs_val, scope)?;
|
||||||
|
dbg!(&scope.context);
|
||||||
|
dbg!(&a);
|
||||||
|
Some(a)
|
||||||
} else {
|
} else {
|
||||||
dbg!((lhs_val.1.clone(), rhs_val.1.clone()));
|
dbg!((lhs_val.1.clone(), rhs_val.1.clone()));
|
||||||
dbg!(&operation.map(|b| &b.return_ty));
|
dbg!(&operation.map(|b| &b.return_ty));
|
||||||
|
@ -1,20 +1,15 @@
|
|||||||
use reid_lib::Instr;
|
use reid_lib::{builder::InstructionValue, Instr};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
codegen::{ErrorKind, Scope},
|
codegen::{ErrorKind, Scope, StackValue, StackValueKind},
|
||||||
mir::{BinaryOperator, BinopDefinition, FunctionDefinition, FunctionDefinitionKind, TypeKind},
|
mir::{BinaryOperator, BinopDefinition, FunctionDefinition, FunctionDefinitionKind, TypeKind},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub enum InstrinsicKind {
|
|
||||||
IAdd,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn intrinsic(
|
fn intrinsic(
|
||||||
name: &str,
|
name: &str,
|
||||||
ret_ty: TypeKind,
|
ret_ty: TypeKind,
|
||||||
params: Vec<(&str, TypeKind)>,
|
params: Vec<(&str, TypeKind)>,
|
||||||
kind: InstrinsicKind,
|
fun: impl IntrinsicFunction + 'static,
|
||||||
) -> FunctionDefinition {
|
) -> FunctionDefinition {
|
||||||
FunctionDefinition {
|
FunctionDefinition {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
@ -22,7 +17,7 @@ fn intrinsic(
|
|||||||
is_imported: false,
|
is_imported: false,
|
||||||
return_type: ret_ty,
|
return_type: ret_ty,
|
||||||
parameters: params.into_iter().map(|(n, ty)| (n.into(), ty)).collect(),
|
parameters: params.into_iter().map(|(n, ty)| (n.into(), ty)).collect(),
|
||||||
kind: FunctionDefinitionKind::Intrinsic(kind),
|
kind: FunctionDefinitionKind::Intrinsic(Box::new(fun)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,20 +26,20 @@ fn intrinsic_binop(
|
|||||||
lhs: TypeKind,
|
lhs: TypeKind,
|
||||||
rhs: TypeKind,
|
rhs: TypeKind,
|
||||||
ret_ty: TypeKind,
|
ret_ty: TypeKind,
|
||||||
kind: InstrinsicKind,
|
fun: impl IntrinsicFunction + 'static,
|
||||||
) -> BinopDefinition {
|
) -> BinopDefinition {
|
||||||
BinopDefinition {
|
BinopDefinition {
|
||||||
lhs: ("lhs".to_string(), lhs),
|
lhs: ("lhs".to_string(), lhs),
|
||||||
op,
|
op,
|
||||||
rhs: ("rhs".to_owned(), rhs),
|
rhs: ("rhs".to_owned(), rhs),
|
||||||
return_type: ret_ty,
|
return_type: ret_ty,
|
||||||
fn_kind: FunctionDefinitionKind::Intrinsic(kind),
|
fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(fun)),
|
||||||
meta: Default::default(),
|
meta: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn form_intrinsics() -> Vec<FunctionDefinition> {
|
pub fn form_intrinsics() -> Vec<FunctionDefinition> {
|
||||||
let mut intrinsics = Vec::new();
|
let intrinsics = Vec::new();
|
||||||
|
|
||||||
intrinsics
|
intrinsics
|
||||||
}
|
}
|
||||||
@ -57,25 +52,32 @@ pub fn form_intrinsic_binops() -> Vec<BinopDefinition> {
|
|||||||
TypeKind::U32,
|
TypeKind::U32,
|
||||||
TypeKind::U32,
|
TypeKind::U32,
|
||||||
TypeKind::U32,
|
TypeKind::U32,
|
||||||
InstrinsicKind::IAdd,
|
IntrinsicIAdd(TypeKind::U32),
|
||||||
));
|
));
|
||||||
|
|
||||||
intrinsics
|
intrinsics
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InstrinsicKind {
|
pub trait IntrinsicFunction: std::fmt::Debug {
|
||||||
pub fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>) -> Result<(), ErrorKind> {
|
fn codegen<'ctx, 'a>(
|
||||||
match self {
|
&self,
|
||||||
InstrinsicKind::IAdd => {
|
scope: &mut Scope<'ctx, 'a>,
|
||||||
let lhs = scope.block.build(Instr::Param(0)).unwrap();
|
params: &[InstructionValue],
|
||||||
let rhs = scope.block.build(Instr::Param(1)).unwrap();
|
) -> Result<StackValue, ErrorKind>;
|
||||||
let add = scope.block.build(Instr::Add(lhs, rhs)).unwrap();
|
}
|
||||||
scope
|
|
||||||
.block
|
#[derive(Debug, Clone)]
|
||||||
.terminate(reid_lib::TerminatorKind::Ret(add))
|
pub struct IntrinsicIAdd(TypeKind);
|
||||||
.unwrap()
|
|
||||||
}
|
impl IntrinsicFunction for IntrinsicIAdd {
|
||||||
}
|
fn codegen<'ctx, 'a>(
|
||||||
Ok(())
|
&self,
|
||||||
|
scope: &mut Scope<'ctx, 'a>,
|
||||||
|
params: &[InstructionValue],
|
||||||
|
) -> Result<StackValue, ErrorKind> {
|
||||||
|
let lhs = params.get(0).unwrap();
|
||||||
|
let rhs = params.get(1).unwrap();
|
||||||
|
let add = scope.block.build(Instr::Add(*lhs, *rhs)).unwrap();
|
||||||
|
Ok(StackValue(StackValueKind::Literal(add), self.0.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
use std::{collections::HashMap, path::PathBuf};
|
use std::{collections::HashMap, path::PathBuf};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
intrinsics::InstrinsicKind,
|
intrinsics::IntrinsicFunction,
|
||||||
lexer::{FullToken, Position},
|
lexer::{FullToken, Position},
|
||||||
token_stream::TokenRange,
|
token_stream::TokenRange,
|
||||||
};
|
};
|
||||||
@ -303,7 +303,7 @@ pub enum FunctionDefinitionKind {
|
|||||||
/// True = imported from other module, False = Is user defined extern
|
/// True = imported from other module, False = Is user defined extern
|
||||||
Extern(bool),
|
Extern(bool),
|
||||||
/// Intrinsic definition, defined within the compiler
|
/// Intrinsic definition, defined within the compiler
|
||||||
Intrinsic(InstrinsicKind),
|
Intrinsic(Box<dyn IntrinsicFunction>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionDefinition {
|
impl FunctionDefinition {
|
||||||
|
Loading…
Reference in New Issue
Block a user