Compare commits
3 Commits
dc9450f64a
...
1acaa29a12
Author | SHA1 | Date | |
---|---|---|---|
1acaa29a12 | |||
6788ef1690 | |||
6f8c02ac04 |
@ -265,8 +265,15 @@ impl FunctionHolder {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.data.flags.is_imported && !in_main_module {
|
if self.data.flags.is_imported {
|
||||||
|
if self.data.flags.is_extern {
|
||||||
|
LLVMSetLinkage(
|
||||||
|
own_function.value_ref,
|
||||||
|
LLVMLinkage::LLVMAvailableExternallyLinkage,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
LLVMSetLinkage(own_function.value_ref, LLVMLinkage::LLVMExternalLinkage);
|
LLVMSetLinkage(own_function.value_ref, LLVMLinkage::LLVMExternalLinkage);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LLVMSetLinkage(own_function.value_ref, LLVMLinkage::LLVMPrivateLinkage);
|
LLVMSetLinkage(own_function.value_ref, LLVMLinkage::LLVMPrivateLinkage);
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ fn main() -> Result<(), std::io::Error> {
|
|||||||
let object_path = parent.with_extension("o");
|
let object_path = parent.with_extension("o");
|
||||||
let asm_path = parent.with_extension("asm");
|
let asm_path = parent.with_extension("asm");
|
||||||
|
|
||||||
|
let before = std::time::SystemTime::now();
|
||||||
|
|
||||||
let text = fs::read_to_string(&path)?;
|
let text = fs::read_to_string(&path)?;
|
||||||
match compile(&text, PathBuf::from(&path)) {
|
match compile(&text, PathBuf::from(&path)) {
|
||||||
Ok(CompileOutput {
|
Ok(CompileOutput {
|
||||||
@ -20,15 +22,20 @@ fn main() -> Result<(), std::io::Error> {
|
|||||||
obj_buffer,
|
obj_buffer,
|
||||||
llvm_ir,
|
llvm_ir,
|
||||||
}) => {
|
}) => {
|
||||||
println!("Compiled with triple: {}", &triple);
|
println!("{}", llvm_ir);
|
||||||
|
|
||||||
|
let after = std::time::SystemTime::now();
|
||||||
|
println!("Compiled with triple: {}\n", &triple);
|
||||||
fs::write(&llvm_ir_path, &llvm_ir).expect("Could not write LLVM IR -file!");
|
fs::write(&llvm_ir_path, &llvm_ir).expect("Could not write LLVM IR -file!");
|
||||||
println!("Output LLVM IR to {:?}", llvm_ir_path);
|
println!("Output LLVM IR to {:?}", llvm_ir_path);
|
||||||
fs::write(&asm_path, &assembly).expect("Could not write Assembly-file!");
|
fs::write(&asm_path, &assembly).expect("Could not write Assembly-file!");
|
||||||
println!("Output Assembly to {:?}", asm_path);
|
println!("Output Assembly to {:?}", asm_path);
|
||||||
fs::write(&object_path, &obj_buffer).expect("Could not write Object-file!");
|
fs::write(&object_path, &obj_buffer).expect("Could not write Object-file!");
|
||||||
println!("Output Object-file to {:?}", object_path);
|
println!("Output Object-file to {:?}\n", object_path);
|
||||||
|
println!(
|
||||||
println!("{}", llvm_ir);
|
"Compilation took: {:.2}ms\n",
|
||||||
|
(after.duration_since(before).unwrap().as_micros() as f32) / 1000.
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Err(e) => panic!("{}", e),
|
Err(e) => panic!("{}", e),
|
||||||
};
|
};
|
||||||
|
@ -58,7 +58,7 @@ impl ast::Module {
|
|||||||
.cloned()
|
.cloned()
|
||||||
.map(|p| (p.0, p.1.into()))
|
.map(|p| (p.0, p.1.into()))
|
||||||
.collect(),
|
.collect(),
|
||||||
kind: mir::FunctionDefinitionKind::Extern,
|
kind: mir::FunctionDefinitionKind::Extern(false),
|
||||||
};
|
};
|
||||||
functions.push(def);
|
functions.push(def);
|
||||||
}
|
}
|
||||||
|
@ -69,12 +69,13 @@ impl mir::Module {
|
|||||||
..FunctionFlags::default()
|
..FunctionFlags::default()
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
mir::FunctionDefinitionKind::Extern => module.function(
|
mir::FunctionDefinitionKind::Extern(imported) => module.function(
|
||||||
&function.name,
|
&function.name,
|
||||||
function.return_type.get_type(),
|
function.return_type.get_type(),
|
||||||
param_types,
|
param_types,
|
||||||
FunctionFlags {
|
FunctionFlags {
|
||||||
is_extern: true,
|
is_extern: true,
|
||||||
|
is_imported: *imported,
|
||||||
..FunctionFlags::default()
|
..FunctionFlags::default()
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -117,7 +118,7 @@ impl mir::Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mir::FunctionDefinitionKind::Extern => {}
|
mir::FunctionDefinitionKind::Extern(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,13 +103,18 @@ pub fn compile_module(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn perform_all_passes(context: &mut mir::Context) -> Result<(), ReidError> {
|
pub fn perform_all_passes(context: &mut mir::Context) -> Result<(), ReidError> {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
dbg!(&context);
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
println!("{}", &context);
|
println!("{}", &context);
|
||||||
|
|
||||||
let state = context.pass(&mut LinkerPass);
|
let state = context.pass(&mut LinkerPass);
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
println!("{:?}\n{}", &context, &context);
|
println!("{}", &context);
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
dbg!(&state);
|
||||||
|
|
||||||
if !state.errors.is_empty() {
|
if !state.errors.is_empty() {
|
||||||
return Err(ReidError::LinkerErrors(state.errors));
|
return Err(ReidError::LinkerErrors(state.errors));
|
||||||
@ -119,10 +124,10 @@ pub fn perform_all_passes(context: &mut mir::Context) -> Result<(), ReidError> {
|
|||||||
|
|
||||||
let state = context.pass(&mut TypeInference { refs: &refs });
|
let state = context.pass(&mut TypeInference { refs: &refs });
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
dbg!(&state, &refs);
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
println!("{}", &context);
|
println!("{}", &context);
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
dbg!(&state, &refs);
|
||||||
|
|
||||||
if !state.errors.is_empty() {
|
if !state.errors.is_empty() {
|
||||||
return Err(ReidError::TypeInferenceErrors(state.errors));
|
return Err(ReidError::TypeInferenceErrors(state.errors));
|
||||||
@ -130,10 +135,10 @@ pub fn perform_all_passes(context: &mut mir::Context) -> Result<(), ReidError> {
|
|||||||
|
|
||||||
let state = context.pass(&mut TypeCheck { refs: &refs });
|
let state = context.pass(&mut TypeCheck { refs: &refs });
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
dbg!(&state);
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
println!("{}", &context);
|
println!("{}", &context);
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
dbg!(&state);
|
||||||
|
|
||||||
if !state.errors.is_empty() {
|
if !state.errors.is_empty() {
|
||||||
return Err(ReidError::TypeCheckErrors(state.errors));
|
return Err(ReidError::TypeCheckErrors(state.errors));
|
||||||
|
@ -61,7 +61,8 @@ impl Display for FunctionDefinitionKind {
|
|||||||
write!(f, "{}", block)?;
|
write!(f, "{}", block)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Self::Extern => write!(f, "<External>"),
|
Self::Extern(true) => write!(f, "<Imported Extern>"),
|
||||||
|
Self::Extern(false) => write!(f, "<Linked Extern>"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ impl Pass for LinkerPass {
|
|||||||
is_imported: false,
|
is_imported: false,
|
||||||
return_type: func.return_type.clone(),
|
return_type: func.return_type.clone(),
|
||||||
parameters: func.parameters.clone(),
|
parameters: func.parameters.clone(),
|
||||||
kind: super::FunctionDefinitionKind::Extern,
|
kind: super::FunctionDefinitionKind::Extern(true),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,21 +254,22 @@ pub struct FunctionDefinition {
|
|||||||
pub enum FunctionDefinitionKind {
|
pub enum FunctionDefinitionKind {
|
||||||
/// Actual definition block and surrounding signature range
|
/// Actual definition block and surrounding signature range
|
||||||
Local(Block, Metadata),
|
Local(Block, Metadata),
|
||||||
Extern,
|
/// True = imported from other module, False = Is user defined extern
|
||||||
|
Extern(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionDefinition {
|
impl FunctionDefinition {
|
||||||
fn block_meta(&self) -> Metadata {
|
fn block_meta(&self) -> Metadata {
|
||||||
match &self.kind {
|
match &self.kind {
|
||||||
FunctionDefinitionKind::Local(block, _) => block.meta,
|
FunctionDefinitionKind::Local(block, _) => block.meta,
|
||||||
FunctionDefinitionKind::Extern => Metadata::default(),
|
FunctionDefinitionKind::Extern(_) => Metadata::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Metadata {
|
fn signature(&self) -> Metadata {
|
||||||
match &self.kind {
|
match &self.kind {
|
||||||
FunctionDefinitionKind::Local(_, metadata) => *metadata,
|
FunctionDefinitionKind::Local(_, metadata) => *metadata,
|
||||||
FunctionDefinitionKind::Extern => Metadata::default(),
|
FunctionDefinitionKind::Extern(_) => Metadata::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ impl Context {
|
|||||||
let mut scope = Scope::default();
|
let mut scope = Scope::default();
|
||||||
pass.context(self, PassState::from(&mut state, &mut scope));
|
pass.context(self, PassState::from(&mut state, &mut scope));
|
||||||
for module in &mut self.modules {
|
for module in &mut self.modules {
|
||||||
module.pass(pass, &mut state, &mut scope);
|
module.pass(pass, &mut state, &mut scope.inner());
|
||||||
}
|
}
|
||||||
state
|
state
|
||||||
}
|
}
|
||||||
@ -261,7 +261,7 @@ impl FunctionDefinition {
|
|||||||
scope.return_type_hint = Some(self.return_type.clone());
|
scope.return_type_hint = Some(self.return_type.clone());
|
||||||
block.pass(pass, state, scope);
|
block.pass(pass, state, scope);
|
||||||
}
|
}
|
||||||
FunctionDefinitionKind::Extern => {}
|
FunctionDefinitionKind::Extern(_) => {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ impl FunctionDefinition {
|
|||||||
state.scope.return_type_hint = Some(self.return_type.clone());
|
state.scope.return_type_hint = Some(self.return_type.clone());
|
||||||
block.typecheck(&mut state.inner(), &hints, Some(&return_type))
|
block.typecheck(&mut state.inner(), &hints, Some(&return_type))
|
||||||
}
|
}
|
||||||
FunctionDefinitionKind::Extern => {
|
FunctionDefinitionKind::Extern(_) => {
|
||||||
Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown)))
|
Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown)))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -64,7 +64,7 @@ impl FunctionDefinition {
|
|||||||
ret_ty.narrow(&scope_hints.from_type(&self.return_type).unwrap());
|
ret_ty.narrow(&scope_hints.from_type(&self.return_type).unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FunctionDefinitionKind::Extern => {}
|
FunctionDefinitionKind::Extern(_) => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -181,14 +181,16 @@ impl IndexedVariableReference {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, thiserror::Error)]
|
#[derive(Debug, Clone, thiserror::Error)]
|
||||||
pub enum EqualsIssue {
|
pub enum EqualsIssue {
|
||||||
#[error("Function is already defined locally at {:?}", (.0).range)]
|
#[error("Function is already defined locally at {:?}", (.0).range)]
|
||||||
ExistsLocally(Metadata),
|
ExistsLocally(Metadata),
|
||||||
#[error("asd")]
|
#[error("Equals")]
|
||||||
Equals,
|
Equals,
|
||||||
#[error("asd")]
|
#[error("Function {0} is already declared locally at {:?}", (.1).range)]
|
||||||
ConflictingImports,
|
AlreadyExtern(String, Metadata),
|
||||||
|
#[error("Function {0} is already imported from another module")]
|
||||||
|
ConflictWithImport(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionDefinition {
|
impl FunctionDefinition {
|
||||||
@ -197,7 +199,10 @@ impl FunctionDefinition {
|
|||||||
FunctionDefinitionKind::Local(_, metadata) => {
|
FunctionDefinitionKind::Local(_, metadata) => {
|
||||||
Err(EqualsIssue::ExistsLocally(*metadata))
|
Err(EqualsIssue::ExistsLocally(*metadata))
|
||||||
}
|
}
|
||||||
FunctionDefinitionKind::Extern => {
|
FunctionDefinitionKind::Extern(imported) => {
|
||||||
|
if *imported {
|
||||||
|
Err(EqualsIssue::ConflictWithImport(self.name.clone()))
|
||||||
|
} else {
|
||||||
if self.is_pub == other.is_pub
|
if self.is_pub == other.is_pub
|
||||||
&& self.name == other.name
|
&& self.name == other.name
|
||||||
&& self.parameters == other.parameters
|
&& self.parameters == other.parameters
|
||||||
@ -205,7 +210,11 @@ impl FunctionDefinition {
|
|||||||
{
|
{
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(EqualsIssue::ConflictingImports)
|
Err(EqualsIssue::AlreadyExtern(
|
||||||
|
self.name.clone(),
|
||||||
|
self.signature(),
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user