Compare commits
No commits in common. "89002f34e4ae2d7cfe9eb53fbb0ba2c774f60501" and "3404f0fb6ee848211991e3fb3c116f70e38cc298" have entirely different histories.
89002f34e4
...
3404f0fb6e
@ -47,7 +47,7 @@ Currently missing big features (TODOs) are:
|
|||||||
- Debug Information (PARTIALLY DONE)
|
- Debug Information (PARTIALLY DONE)
|
||||||
- Ability to specify types in literals and variable definitions
|
- Ability to specify types in literals and variable definitions
|
||||||
- Intrinsic functions
|
- Intrinsic functions
|
||||||
- Not-Unary and NEQ-binary
|
- Not-Unary
|
||||||
|
|
||||||
Big features that I want later but are not necessary:
|
Big features that I want later but are not necessary:
|
||||||
- Associated functions
|
- Associated functions
|
||||||
|
@ -7,7 +7,7 @@ import std::new_string;
|
|||||||
import std::add_num_to_str;
|
import std::add_num_to_str;
|
||||||
import std::concat_strings;
|
import std::concat_strings;
|
||||||
|
|
||||||
fn main() -> u8 {
|
fn main() -> i32 {
|
||||||
let mut test = from_str("hello");
|
let mut test = from_str("hello");
|
||||||
|
|
||||||
concat_strings(&mut test, from_str(" world"));
|
concat_strings(&mut test, from_str(" world"));
|
||||||
@ -21,5 +21,5 @@ fn main() -> u8 {
|
|||||||
|
|
||||||
free_string(&test);
|
free_string(&test);
|
||||||
|
|
||||||
return addition(5, 3);
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ impl Default for FunctionFlags {
|
|||||||
FunctionFlags {
|
FunctionFlags {
|
||||||
is_extern: false,
|
is_extern: false,
|
||||||
is_main: false,
|
is_main: false,
|
||||||
is_pub: false,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,16 +18,11 @@ pub struct Allocator {
|
|||||||
pub struct AllocatorScope<'ctx, 'a> {
|
pub struct AllocatorScope<'ctx, 'a> {
|
||||||
pub(super) block: &'a mut Block<'ctx>,
|
pub(super) block: &'a mut Block<'ctx>,
|
||||||
pub(super) module_id: SourceModuleId,
|
pub(super) module_id: SourceModuleId,
|
||||||
|
pub(super) types: &'a HashMap<TypeValue, TypeDefinition>,
|
||||||
pub(super) type_values: &'a HashMap<CustomTypeKey, TypeValue>,
|
pub(super) type_values: &'a HashMap<CustomTypeKey, TypeValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Allocator {
|
impl Allocator {
|
||||||
pub fn empty() -> Allocator {
|
|
||||||
Allocator {
|
|
||||||
allocations: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from(func: &FunctionDefinition, scope: &mut AllocatorScope) -> Allocator {
|
pub fn from(func: &FunctionDefinition, scope: &mut AllocatorScope) -> Allocator {
|
||||||
func.allocate(scope)
|
func.allocate(scope)
|
||||||
}
|
}
|
||||||
@ -49,21 +44,22 @@ impl mir::FunctionDefinition {
|
|||||||
fn allocate<'ctx, 'a>(&self, scope: &mut AllocatorScope<'ctx, 'a>) -> Allocator {
|
fn allocate<'ctx, 'a>(&self, scope: &mut AllocatorScope<'ctx, 'a>) -> Allocator {
|
||||||
let mut allocated = Vec::new();
|
let mut allocated = Vec::new();
|
||||||
match &self.kind {
|
match &self.kind {
|
||||||
mir::FunctionDefinitionKind::Local(block, _) => {
|
crate::mir::FunctionDefinitionKind::Local(block, _) => {
|
||||||
for param in &self.parameters {
|
for param in &self.parameters {
|
||||||
let allocation = scope
|
let allocation = scope
|
||||||
.block
|
.block
|
||||||
.build_named(
|
.build_named(
|
||||||
param.0.clone(),
|
param.0.clone(),
|
||||||
reid_lib::Instr::Alloca(param.1.get_type(scope.type_values)),
|
reid_lib::Instr::Alloca(
|
||||||
|
param.1.get_type(scope.type_values, scope.types),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
allocated.push(Allocation(param.0.clone(), param.1.clone(), allocation));
|
allocated.push(Allocation(param.0.clone(), param.1.clone(), allocation));
|
||||||
}
|
}
|
||||||
allocated.extend(block.allocate(scope));
|
allocated.extend(block.allocate(scope));
|
||||||
}
|
}
|
||||||
mir::FunctionDefinitionKind::Extern(_) => {}
|
crate::mir::FunctionDefinitionKind::Extern(_) => {}
|
||||||
mir::FunctionDefinitionKind::Intrinsic(_) => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Allocator {
|
Allocator {
|
||||||
@ -99,7 +95,11 @@ impl mir::Statement {
|
|||||||
.block
|
.block
|
||||||
.build_named(
|
.build_named(
|
||||||
named_variable_ref.1.clone(),
|
named_variable_ref.1.clone(),
|
||||||
reid_lib::Instr::Alloca(named_variable_ref.0.get_type(scope.type_values)),
|
reid_lib::Instr::Alloca(
|
||||||
|
named_variable_ref
|
||||||
|
.0
|
||||||
|
.get_type(scope.type_values, scope.types),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
allocated.push(Allocation(
|
allocated.push(Allocation(
|
||||||
|
@ -50,6 +50,7 @@ impl ast::Module {
|
|||||||
block.into_mir(module_id),
|
block.into_mir(module_id),
|
||||||
(*range).as_meta(module_id),
|
(*range).as_meta(module_id),
|
||||||
),
|
),
|
||||||
|
source: module_id,
|
||||||
};
|
};
|
||||||
functions.push(def);
|
functions.push(def);
|
||||||
}
|
}
|
||||||
@ -70,6 +71,7 @@ impl ast::Module {
|
|||||||
.map(|p| (p.0, p.1 .0.into_mir(module_id)))
|
.map(|p| (p.0, p.1 .0.into_mir(module_id)))
|
||||||
.collect(),
|
.collect(),
|
||||||
kind: mir::FunctionDefinitionKind::Extern(false),
|
kind: mir::FunctionDefinitionKind::Extern(false),
|
||||||
|
source: module_id,
|
||||||
};
|
};
|
||||||
functions.push(def);
|
functions.push(def);
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ impl mir::Module {
|
|||||||
// TODO: Reorder custom-type definitions such that
|
// TODO: Reorder custom-type definitions such that
|
||||||
// inner types get evaluated first. Otherwise this
|
// inner types get evaluated first. Otherwise this
|
||||||
// will cause a panic!
|
// will cause a panic!
|
||||||
.map(|StructField(_, t, _)| t.get_type(&type_values))
|
.map(|StructField(_, t, _)| t.get_type(&type_values, &types))
|
||||||
.collect(),
|
.collect(),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
@ -291,14 +291,14 @@ impl mir::Module {
|
|||||||
let param_types: Vec<Type> = function
|
let param_types: Vec<Type> = function
|
||||||
.parameters
|
.parameters
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(_, p)| p.get_type(&type_values))
|
.map(|(_, p)| p.get_type(&type_values, &types))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
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(_, _) => module.function(
|
||||||
&function.name,
|
&function.name,
|
||||||
function.return_type.get_type(&type_values),
|
function.return_type.get_type(&type_values, &types),
|
||||||
param_types,
|
param_types,
|
||||||
FunctionFlags {
|
FunctionFlags {
|
||||||
is_pub: function.is_pub || is_main,
|
is_pub: function.is_pub || is_main,
|
||||||
@ -309,7 +309,7 @@ impl mir::Module {
|
|||||||
),
|
),
|
||||||
mir::FunctionDefinitionKind::Extern(imported) => module.function(
|
mir::FunctionDefinitionKind::Extern(imported) => module.function(
|
||||||
&function.name,
|
&function.name,
|
||||||
function.return_type.get_type(&type_values),
|
function.return_type.get_type(&type_values, &types),
|
||||||
param_types,
|
param_types,
|
||||||
FunctionFlags {
|
FunctionFlags {
|
||||||
is_extern: true,
|
is_extern: true,
|
||||||
@ -317,14 +317,6 @@ impl mir::Module {
|
|||||||
..FunctionFlags::default()
|
..FunctionFlags::default()
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
mir::FunctionDefinitionKind::Intrinsic(_) => module.function(
|
|
||||||
&function.name,
|
|
||||||
function.return_type.get_type(&type_values),
|
|
||||||
param_types,
|
|
||||||
FunctionFlags {
|
|
||||||
..FunctionFlags::default()
|
|
||||||
},
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
functions.insert(function.name.clone(), StackFunction { ir: func });
|
functions.insert(function.name.clone(), StackFunction { ir: func });
|
||||||
@ -341,6 +333,7 @@ impl mir::Module {
|
|||||||
&mut AllocatorScope {
|
&mut AllocatorScope {
|
||||||
block: &mut entry,
|
block: &mut entry,
|
||||||
module_id: self.module_id,
|
module_id: self.module_id,
|
||||||
|
types: &types,
|
||||||
type_values: &type_values,
|
type_values: &type_values,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -477,26 +470,6 @@ impl mir::Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
mir::FunctionDefinitionKind::Extern(_) => {}
|
mir::FunctionDefinitionKind::Extern(_) => {}
|
||||||
mir::FunctionDefinitionKind::Intrinsic(kind) => {
|
|
||||||
let entry = function.ir.block("entry");
|
|
||||||
let mut scope = Scope {
|
|
||||||
context,
|
|
||||||
modules: &modules,
|
|
||||||
tokens,
|
|
||||||
module: &module,
|
|
||||||
module_id: self.module_id,
|
|
||||||
function,
|
|
||||||
block: entry,
|
|
||||||
functions: &functions,
|
|
||||||
types: &types,
|
|
||||||
type_values: &type_values,
|
|
||||||
stack_values: Default::default(),
|
|
||||||
debug: None,
|
|
||||||
allocator: Rc::new(RefCell::new(Allocator::empty())),
|
|
||||||
};
|
|
||||||
|
|
||||||
kind.codegen(&mut scope)?
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,7 +694,7 @@ impl mir::Expression {
|
|||||||
format!("{}", varref.1),
|
format!("{}", varref.1),
|
||||||
Instr::Load(
|
Instr::Load(
|
||||||
v.0.instr(),
|
v.0.instr(),
|
||||||
inner.get_type(scope.type_values),
|
inner.get_type(scope.type_values, scope.types),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
@ -827,7 +800,7 @@ impl mir::Expression {
|
|||||||
.known()
|
.known()
|
||||||
.expect("function return type unknown");
|
.expect("function return type unknown");
|
||||||
|
|
||||||
let ret_type = ret_type_kind.get_type(scope.type_values);
|
let ret_type = ret_type_kind.get_type(scope.type_values, scope.types);
|
||||||
|
|
||||||
let params = try_all(
|
let params = try_all(
|
||||||
call.parameters
|
call.parameters
|
||||||
@ -930,7 +903,10 @@ impl mir::Expression {
|
|||||||
.block
|
.block
|
||||||
.build_named(
|
.build_named(
|
||||||
"load",
|
"load",
|
||||||
Instr::Load(kind.instr(), inner.get_type(scope.type_values)),
|
Instr::Load(
|
||||||
|
kind.instr(),
|
||||||
|
inner.get_type(scope.type_values, scope.types),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
(
|
(
|
||||||
@ -986,7 +962,10 @@ impl mir::Expression {
|
|||||||
.block
|
.block
|
||||||
.build_named(
|
.build_named(
|
||||||
"array.load",
|
"array.load",
|
||||||
Instr::Load(ptr, contained_ty.get_type(scope.type_values)),
|
Instr::Load(
|
||||||
|
ptr,
|
||||||
|
contained_ty.get_type(scope.type_values, scope.types),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_location(&mut scope.block, location),
|
.maybe_location(&mut scope.block, location),
|
||||||
@ -1024,7 +1003,7 @@ impl mir::Expression {
|
|||||||
.unwrap_or(TypeKind::Void);
|
.unwrap_or(TypeKind::Void);
|
||||||
|
|
||||||
let array_ty = Type::Array(
|
let array_ty = Type::Array(
|
||||||
Box::new(elem_ty_kind.get_type(scope.type_values)),
|
Box::new(elem_ty_kind.get_type(scope.type_values, scope.types)),
|
||||||
instr_list.len() as u64,
|
instr_list.len() as u64,
|
||||||
);
|
);
|
||||||
let array_name = format!("{}.{}", elem_ty_kind, instr_list.len());
|
let array_name = format!("{}.{}", elem_ty_kind, instr_list.len());
|
||||||
@ -1107,7 +1086,10 @@ impl mir::Expression {
|
|||||||
.block
|
.block
|
||||||
.build_named(
|
.build_named(
|
||||||
load_n,
|
load_n,
|
||||||
Instr::Load(value, type_kind.get_type(scope.type_values)),
|
Instr::Load(
|
||||||
|
value,
|
||||||
|
type_kind.get_type(scope.type_values, scope.types),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
),
|
),
|
||||||
@ -1198,7 +1180,10 @@ impl mir::Expression {
|
|||||||
.block
|
.block
|
||||||
.build_named(
|
.build_named(
|
||||||
format!("{}.deref", varref.1),
|
format!("{}.deref", varref.1),
|
||||||
Instr::Load(v.0.instr(), ptr_inner.get_type(scope.type_values)),
|
Instr::Load(
|
||||||
|
v.0.instr(),
|
||||||
|
ptr_inner.get_type(scope.type_values, scope.types),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -1213,7 +1198,7 @@ impl mir::Expression {
|
|||||||
format!("{}.deref.inner", varref.1),
|
format!("{}.deref.inner", varref.1),
|
||||||
Instr::Load(
|
Instr::Load(
|
||||||
var_ptr_instr,
|
var_ptr_instr,
|
||||||
inner.get_type(scope.type_values),
|
inner.get_type(scope.type_values, scope.types),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
@ -1251,7 +1236,7 @@ impl mir::Expression {
|
|||||||
.build(Instr::BitCast(
|
.build(Instr::BitCast(
|
||||||
val.instr(),
|
val.instr(),
|
||||||
Type::Ptr(Box::new(
|
Type::Ptr(Box::new(
|
||||||
type_kind.get_type(scope.type_values),
|
type_kind.get_type(scope.type_values, scope.types),
|
||||||
)),
|
)),
|
||||||
))
|
))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
@ -1269,7 +1254,7 @@ impl mir::Expression {
|
|||||||
.block
|
.block
|
||||||
.build(Instr::BitCast(
|
.build(Instr::BitCast(
|
||||||
val.instr(),
|
val.instr(),
|
||||||
type_kind.get_type(scope.type_values),
|
type_kind.get_type(scope.type_values, scope.types),
|
||||||
))
|
))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
),
|
),
|
||||||
@ -1278,10 +1263,10 @@ impl mir::Expression {
|
|||||||
_ => {
|
_ => {
|
||||||
let cast_instr = val
|
let cast_instr = val
|
||||||
.1
|
.1
|
||||||
.get_type(scope.type_values)
|
.get_type(scope.type_values, scope.types)
|
||||||
.cast_instruction(
|
.cast_instruction(
|
||||||
val.instr(),
|
val.instr(),
|
||||||
&type_kind.get_type(scope.type_values),
|
&type_kind.get_type(scope.type_values, scope.types),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -1453,7 +1438,11 @@ impl mir::Literal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TypeKind {
|
impl TypeKind {
|
||||||
pub(super) fn get_type(&self, type_vals: &HashMap<CustomTypeKey, TypeValue>) -> Type {
|
pub(super) fn get_type(
|
||||||
|
&self,
|
||||||
|
type_vals: &HashMap<CustomTypeKey, TypeValue>,
|
||||||
|
typedefs: &HashMap<TypeValue, TypeDefinition>,
|
||||||
|
) -> Type {
|
||||||
match &self {
|
match &self {
|
||||||
TypeKind::I8 => Type::I8,
|
TypeKind::I8 => Type::I8,
|
||||||
TypeKind::I16 => Type::I16,
|
TypeKind::I16 => Type::I16,
|
||||||
@ -1474,16 +1463,24 @@ impl TypeKind {
|
|||||||
TypeKind::F80 => Type::F80,
|
TypeKind::F80 => Type::F80,
|
||||||
TypeKind::F128PPC => Type::F128PPC,
|
TypeKind::F128PPC => Type::F128PPC,
|
||||||
TypeKind::Char => Type::U8,
|
TypeKind::Char => Type::U8,
|
||||||
TypeKind::Array(elem_t, len) => Type::Array(Box::new(elem_t.get_type(type_vals)), *len),
|
TypeKind::Array(elem_t, len) => {
|
||||||
|
Type::Array(Box::new(elem_t.get_type(type_vals, typedefs)), *len)
|
||||||
|
}
|
||||||
TypeKind::Void => Type::Void,
|
TypeKind::Void => Type::Void,
|
||||||
TypeKind::Vague(_) => panic!("Tried to compile a vague type!"),
|
TypeKind::Vague(_) => panic!("Tried to compile a vague type!"),
|
||||||
TypeKind::CustomType(n) => {
|
TypeKind::CustomType(n) => {
|
||||||
let type_val = type_vals.get(n).unwrap().clone();
|
let type_val = type_vals.get(n).unwrap().clone();
|
||||||
Type::CustomType(type_val)
|
Type::CustomType(type_val)
|
||||||
}
|
}
|
||||||
TypeKind::UserPtr(type_kind) => Type::Ptr(Box::new(type_kind.get_type(type_vals))),
|
TypeKind::UserPtr(type_kind) => {
|
||||||
TypeKind::CodegenPtr(type_kind) => Type::Ptr(Box::new(type_kind.get_type(type_vals))),
|
Type::Ptr(Box::new(type_kind.get_type(type_vals, typedefs)))
|
||||||
TypeKind::Borrow(type_kind, _) => Type::Ptr(Box::new(type_kind.get_type(type_vals))),
|
}
|
||||||
|
TypeKind::CodegenPtr(type_kind) => {
|
||||||
|
Type::Ptr(Box::new(type_kind.get_type(type_vals, typedefs)))
|
||||||
|
}
|
||||||
|
TypeKind::Borrow(type_kind, _) => {
|
||||||
|
Type::Ptr(Box::new(type_kind.get_type(type_vals, typedefs)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,57 +0,0 @@
|
|||||||
use reid_lib::Instr;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
codegen::{ErrorKind, Scope},
|
|
||||||
mir::{FunctionDefinition, FunctionDefinitionKind, TypeKind},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub enum InstrinsicKind {
|
|
||||||
IAdd,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn intrinsic(
|
|
||||||
name: &str,
|
|
||||||
ret_ty: TypeKind,
|
|
||||||
params: Vec<(&str, TypeKind)>,
|
|
||||||
kind: InstrinsicKind,
|
|
||||||
) -> FunctionDefinition {
|
|
||||||
FunctionDefinition {
|
|
||||||
name: name.into(),
|
|
||||||
is_pub: false,
|
|
||||||
is_imported: false,
|
|
||||||
return_type: ret_ty,
|
|
||||||
parameters: params.into_iter().map(|(n, ty)| (n.into(), ty)).collect(),
|
|
||||||
kind: FunctionDefinitionKind::Intrinsic(kind),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn form_intrinsics() -> Vec<FunctionDefinition> {
|
|
||||||
let mut intrinsics = Vec::new();
|
|
||||||
|
|
||||||
intrinsics.push(intrinsic(
|
|
||||||
"addition",
|
|
||||||
TypeKind::U8,
|
|
||||||
vec![("lhs".into(), TypeKind::U8), ("rhs".into(), TypeKind::U8)],
|
|
||||||
InstrinsicKind::IAdd,
|
|
||||||
));
|
|
||||||
|
|
||||||
intrinsics
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InstrinsicKind {
|
|
||||||
pub fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>) -> Result<(), ErrorKind> {
|
|
||||||
match self {
|
|
||||||
InstrinsicKind::IAdd => {
|
|
||||||
let lhs = scope.block.build(Instr::Param(0)).unwrap();
|
|
||||||
let rhs = scope.block.build(Instr::Param(1)).unwrap();
|
|
||||||
let add = scope.block.build(Instr::Add(lhs, rhs)).unwrap();
|
|
||||||
scope
|
|
||||||
.block
|
|
||||||
.terminate(reid_lib::TerminatorKind::Ret(add))
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
@ -44,7 +44,6 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use error_raporting::{ErrorKind as ErrorRapKind, ErrorModules, ReidError};
|
use error_raporting::{ErrorKind as ErrorRapKind, ErrorModules, ReidError};
|
||||||
use intrinsics::form_intrinsics;
|
|
||||||
use lexer::FullToken;
|
use lexer::FullToken;
|
||||||
use mir::{
|
use mir::{
|
||||||
linker::LinkerPass, typecheck::TypeCheck, typeinference::TypeInference, typerefs::TypeRefs,
|
linker::LinkerPass, typecheck::TypeCheck, typeinference::TypeInference, typerefs::TypeRefs,
|
||||||
@ -57,7 +56,6 @@ mod allocator;
|
|||||||
mod ast;
|
mod ast;
|
||||||
mod codegen;
|
mod codegen;
|
||||||
pub mod error_raporting;
|
pub mod error_raporting;
|
||||||
pub mod intrinsics;
|
|
||||||
pub mod ld;
|
pub mod ld;
|
||||||
mod lexer;
|
mod lexer;
|
||||||
pub mod mir;
|
pub mod mir;
|
||||||
@ -128,12 +126,6 @@ pub fn perform_all_passes<'map>(
|
|||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
dbg!(&context);
|
dbg!(&context);
|
||||||
|
|
||||||
for module in &mut context.modules {
|
|
||||||
for intrinsic in form_intrinsics() {
|
|
||||||
module.1.functions.insert(0, intrinsic);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
println!("{}", &context);
|
println!("{}", &context);
|
||||||
|
|
||||||
|
@ -108,13 +108,12 @@ impl Display for FunctionDefinition {
|
|||||||
impl Display for FunctionDefinitionKind {
|
impl Display for FunctionDefinitionKind {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
FunctionDefinitionKind::Local(block, _) => {
|
Self::Local(block, _) => {
|
||||||
write!(f, "{}", block)?;
|
write!(f, "{}", block)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
FunctionDefinitionKind::Extern(true) => write!(f, "<Imported Extern>"),
|
Self::Extern(true) => write!(f, "<Imported Extern>"),
|
||||||
FunctionDefinitionKind::Extern(false) => write!(f, "<Linked Extern>"),
|
Self::Extern(false) => write!(f, "<Linked Extern>"),
|
||||||
FunctionDefinitionKind::Intrinsic(_) => write!(f, "<Intrinsic>"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -675,8 +675,6 @@ pub enum EqualsIssue {
|
|||||||
AlreadyExtern(String, Metadata),
|
AlreadyExtern(String, Metadata),
|
||||||
#[error("Function {0} is already imported from another module")]
|
#[error("Function {0} is already imported from another module")]
|
||||||
ConflictWithImport(String),
|
ConflictWithImport(String),
|
||||||
#[error("Function is defined as an intrinsic")]
|
|
||||||
ExistsAsIntrinsic,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionDefinition {
|
impl FunctionDefinition {
|
||||||
@ -703,7 +701,6 @@ impl FunctionDefinition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FunctionDefinitionKind::Intrinsic(_) => Err(EqualsIssue::ExistsAsIntrinsic),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,6 +331,7 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
return_type,
|
return_type,
|
||||||
parameters: param_tys,
|
parameters: param_tys,
|
||||||
kind: super::FunctionDefinitionKind::Extern(true),
|
kind: super::FunctionDefinitionKind::Extern(true),
|
||||||
|
source: imported_mod_id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
use std::{collections::HashMap, path::PathBuf};
|
use std::{collections::HashMap, path::PathBuf};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
intrinsics::InstrinsicKind,
|
|
||||||
lexer::{FullToken, Position},
|
lexer::{FullToken, Position},
|
||||||
token_stream::TokenRange,
|
token_stream::TokenRange,
|
||||||
};
|
};
|
||||||
@ -294,6 +293,7 @@ pub struct FunctionDefinition {
|
|||||||
pub return_type: TypeKind,
|
pub return_type: TypeKind,
|
||||||
pub parameters: Vec<(String, TypeKind)>,
|
pub parameters: Vec<(String, TypeKind)>,
|
||||||
pub kind: FunctionDefinitionKind,
|
pub kind: FunctionDefinitionKind,
|
||||||
|
pub source: SourceModuleId,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -302,8 +302,6 @@ pub enum FunctionDefinitionKind {
|
|||||||
Local(Block, Metadata),
|
Local(Block, Metadata),
|
||||||
/// 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(InstrinsicKind),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionDefinition {
|
impl FunctionDefinition {
|
||||||
@ -311,7 +309,6 @@ impl FunctionDefinition {
|
|||||||
match &self.kind {
|
match &self.kind {
|
||||||
FunctionDefinitionKind::Local(block, _) => block.meta.clone(),
|
FunctionDefinitionKind::Local(block, _) => block.meta.clone(),
|
||||||
FunctionDefinitionKind::Extern(_) => Metadata::default(),
|
FunctionDefinitionKind::Extern(_) => Metadata::default(),
|
||||||
FunctionDefinitionKind::Intrinsic(_) => Metadata::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,7 +316,6 @@ impl FunctionDefinition {
|
|||||||
match &self.kind {
|
match &self.kind {
|
||||||
FunctionDefinitionKind::Local(_, metadata) => metadata.clone(),
|
FunctionDefinitionKind::Local(_, metadata) => metadata.clone(),
|
||||||
FunctionDefinitionKind::Extern(_) => Metadata::default(),
|
FunctionDefinitionKind::Extern(_) => Metadata::default(),
|
||||||
FunctionDefinitionKind::Intrinsic(_) => Metadata::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,7 +352,6 @@ impl FunctionDefinition {
|
|||||||
block.pass(pass, state, scope, mod_id)?;
|
block.pass(pass, state, scope, mod_id)?;
|
||||||
}
|
}
|
||||||
FunctionDefinitionKind::Extern(_) => {}
|
FunctionDefinitionKind::Extern(_) => {}
|
||||||
FunctionDefinitionKind::Intrinsic(..) => {}
|
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,8 @@ pub enum ErrorKind {
|
|||||||
FunctionNotDefined(String),
|
FunctionNotDefined(String),
|
||||||
#[error("Expected a return type of {0}, got {1} instead")]
|
#[error("Expected a return type of {0}, got {1} instead")]
|
||||||
ReturnTypeMismatch(TypeKind, TypeKind),
|
ReturnTypeMismatch(TypeKind, TypeKind),
|
||||||
#[error("Function {0} already defined {1}")]
|
#[error("Function already defined: {0}")]
|
||||||
FunctionAlreadyDefined(String, ErrorTypedefKind),
|
FunctionAlreadyDefined(String),
|
||||||
#[error("Variable already defined: {0}")]
|
#[error("Variable already defined: {0}")]
|
||||||
VariableAlreadyDefined(String),
|
VariableAlreadyDefined(String),
|
||||||
#[error("Variable {0} is not declared as mutable")]
|
#[error("Variable {0} is not declared as mutable")]
|
||||||
@ -80,16 +80,6 @@ pub struct TypeCheck<'t> {
|
|||||||
|
|
||||||
type TypecheckPassState<'st, 'sc> = PassState<'st, 'sc, (), ErrorKind>;
|
type TypecheckPassState<'st, 'sc> = PassState<'st, 'sc, (), ErrorKind>;
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
|
||||||
pub enum ErrorTypedefKind {
|
|
||||||
#[error("locally")]
|
|
||||||
Local,
|
|
||||||
#[error("as an extern")]
|
|
||||||
Extern,
|
|
||||||
#[error("as an intrinsic")]
|
|
||||||
Intrinsic,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'t> Pass for TypeCheck<'t> {
|
impl<'t> Pass for TypeCheck<'t> {
|
||||||
type Data = ();
|
type Data = ();
|
||||||
type TError = ErrorKind;
|
type TError = ErrorKind;
|
||||||
@ -126,9 +116,10 @@ impl<'t> Pass for TypeCheck<'t> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let seen = HashSet::new();
|
||||||
for typedef in defmap.values() {
|
for typedef in defmap.values() {
|
||||||
let mut seen_types = HashSet::new();
|
let mut curr = seen.clone();
|
||||||
seen_types.insert(typedef.name.clone());
|
curr.insert(typedef.name.clone());
|
||||||
check_typedefs_for_recursion(&defmap, typedef, HashSet::new(), &mut state);
|
check_typedefs_for_recursion(&defmap, typedef, HashSet::new(), &mut state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,9 +196,6 @@ impl FunctionDefinition {
|
|||||||
FunctionDefinitionKind::Extern(_) => {
|
FunctionDefinitionKind::Extern(_) => {
|
||||||
Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown)))
|
Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown)))
|
||||||
}
|
}
|
||||||
FunctionDefinitionKind::Intrinsic(..) => {
|
|
||||||
Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown)))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match inferred {
|
match inferred {
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
//! must then be passed through TypeCheck with the same [`TypeRefs`] in order to
|
//! must then be passed through TypeCheck with the same [`TypeRefs`] in order to
|
||||||
//! place the correct types from the IDs and check that there are no issues.
|
//! place the correct types from the IDs and check that there are no issues.
|
||||||
|
|
||||||
use std::{collections::HashMap, convert::Infallible, iter};
|
use std::{convert::Infallible, iter};
|
||||||
|
|
||||||
use crate::{mir::TypeKind, util::try_all};
|
use crate::{mir::TypeKind, util::try_all};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
pass::{Pass, PassResult, PassState},
|
pass::{Pass, PassResult, PassState},
|
||||||
typecheck::{ErrorKind, ErrorTypedefKind},
|
typecheck::ErrorKind,
|
||||||
typerefs::{ScopeTypeRefs, TypeRef, TypeRefs},
|
typerefs::{ScopeTypeRefs, TypeRef, TypeRefs},
|
||||||
Block, CustomTypeKey, ExprKind, Expression, FunctionDefinition, FunctionDefinitionKind,
|
Block, CustomTypeKey, ExprKind, Expression, FunctionDefinition, FunctionDefinitionKind,
|
||||||
IfExpression, Module, ReturnKind, StmtKind,
|
IfExpression, Module, ReturnKind, StmtKind,
|
||||||
@ -33,28 +33,6 @@ impl<'t> Pass for TypeInference<'t> {
|
|||||||
type TError = ErrorKind;
|
type TError = ErrorKind;
|
||||||
|
|
||||||
fn module(&mut self, module: &mut Module, mut state: TypeInferencePassState) -> PassResult {
|
fn module(&mut self, module: &mut Module, mut state: TypeInferencePassState) -> PassResult {
|
||||||
let mut seen_functions = HashMap::new();
|
|
||||||
for function in &mut module.functions {
|
|
||||||
if let Some(kind) = seen_functions.get(&function.name) {
|
|
||||||
state.note_errors(
|
|
||||||
&vec![ErrorKind::FunctionAlreadyDefined(
|
|
||||||
function.name.clone(),
|
|
||||||
*kind,
|
|
||||||
)],
|
|
||||||
function.signature(),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
seen_functions.insert(
|
|
||||||
function.name.clone(),
|
|
||||||
match function.kind {
|
|
||||||
FunctionDefinitionKind::Local(..) => ErrorTypedefKind::Local,
|
|
||||||
FunctionDefinitionKind::Extern(..) => ErrorTypedefKind::Extern,
|
|
||||||
FunctionDefinitionKind::Intrinsic(..) => ErrorTypedefKind::Intrinsic,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for function in &mut module.functions {
|
for function in &mut module.functions {
|
||||||
let res = function.infer_types(&self.refs, &mut state.inner());
|
let res = function.infer_types(&self.refs, &mut state.inner());
|
||||||
state.ok(res, function.block_meta());
|
state.ok(res, function.block_meta());
|
||||||
@ -91,7 +69,6 @@ impl FunctionDefinition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
FunctionDefinitionKind::Extern(_) => {}
|
FunctionDefinitionKind::Extern(_) => {}
|
||||||
FunctionDefinitionKind::Intrinsic(_) => {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -98,7 +98,7 @@ fn float_compiles_well() {
|
|||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn hello_world_compiles_well() {
|
fn hello_world_compiles_well() {
|
||||||
test(include_str!("../../examples/hello_world.reid"), "test", 8);
|
test(include_str!("../../examples/hello_world.reid"), "test", 0);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn mutable_compiles_well() {
|
fn mutable_compiles_well() {
|
||||||
|
Loading…
Reference in New Issue
Block a user