Compare commits

..

No commits in common. "384703fbd2c7e2fa7d36ca7335973c78f071cd35" and "84233c8f49a560664e04c11571c50ba53857d3c9" have entirely different histories.

18 changed files with 18 additions and 466 deletions

View File

@ -1,10 +0,0 @@
// Arithmetic, function calls and imports!
fn test<T>(value: T) -> T {
let b: T = value;
return b;
}
fn main() -> u32 {
return test<u64>(15) as u32 + test<u32>(5);
}

View File

@ -16,7 +16,7 @@ BINARY="$(echo $1 | cut -d'.' -f1)"".out"
echo $1 echo $1
cargo run -p reid -- run $@ && \ cargo run -p reid -- $@ && \
./$BINARY ; echo "Return value: ""$?" ./$BINARY ; echo "Return value: ""$?"
## Command from: clang -v hello.o -o test ## Command from: clang -v hello.o -o test

View File

@ -1,6 +1,6 @@
# Change Log # Change Log
All notable changes to the "reid-language-server" extension will be documented in this file. All notable changes to the "reid-lsp" extension will be documented in this file.
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.

View File

@ -13,13 +13,6 @@
"Other" "Other"
], ],
"main": "./dist/extension.js", "main": "./dist/extension.js",
"icon": "./reid.png",
"publisher": "Teascade",
"author": {
"email": "teascade@teascade.net",
"name": "Teascade",
"url": "https://teascade.net"
},
"contributes": { "contributes": {
"languages": [ "languages": [
{ {
@ -49,7 +42,7 @@
"reid-language-server.language-server-path": { "reid-language-server.language-server-path": {
"type": "string", "type": "string",
"scope": "window", "scope": "window",
"default": "$HOME/.cargo/bin/reid-language-server", "default": "$HOME/.cargo/bin/reid-lsp",
"description": "Path to the Reid Language Server executable" "description": "Path to the Reid Language Server executable"
} }
} }

View File

@ -162,7 +162,6 @@ impl BinaryOperator {
pub struct FunctionCallExpression { pub struct FunctionCallExpression {
pub name: String, pub name: String,
pub params: Vec<Expression>, pub params: Vec<Expression>,
pub generics: Vec<Type>,
pub range: TokenRange, pub range: TokenRange,
pub is_macro: bool, pub is_macro: bool,
} }
@ -193,7 +192,6 @@ pub struct FunctionDefinition(pub FunctionSignature, pub bool, pub Block, pub To
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct FunctionSignature { pub struct FunctionSignature {
pub name: String, pub name: String,
pub generics: Vec<String>,
pub documentation: Option<String>, pub documentation: Option<String>,
pub self_kind: SelfKind, pub self_kind: SelfKind,
pub params: Vec<(String, Type, TokenRange)>, pub params: Vec<(String, Type, TokenRange)>,

View File

@ -182,7 +182,6 @@ impl Parse for AssociatedFunctionCall {
ty, ty,
FunctionCallExpression { FunctionCallExpression {
name: String::new(), name: String::new(),
generics: Vec::new(),
params: Vec::new(), params: Vec::new(),
range: stream.get_range_prev_curr().unwrap(), range: stream.get_range_prev_curr().unwrap(),
is_macro: false, is_macro: false,
@ -201,7 +200,6 @@ impl Parse for AssociatedFunctionCall {
ty, ty,
FunctionCallExpression { FunctionCallExpression {
name: fn_name, name: fn_name,
generics: Vec::new(),
params: Vec::new(), params: Vec::new(),
range: stream.get_range_prev_curr().unwrap(), range: stream.get_range_prev_curr().unwrap(),
is_macro: false, is_macro: false,
@ -213,7 +211,6 @@ impl Parse for AssociatedFunctionCall {
ty, ty,
FunctionCallExpression { FunctionCallExpression {
name: String::new(), name: String::new(),
generics: Vec::new(),
params: Vec::new(), params: Vec::new(),
range: stream.get_range_prev_curr().unwrap(), range: stream.get_range_prev_curr().unwrap(),
is_macro: false, is_macro: false,
@ -594,8 +591,7 @@ impl Parse for FunctionCallExpression {
let args = stream.parse::<FunctionArgs>()?; let args = stream.parse::<FunctionArgs>()?;
Ok(FunctionCallExpression { Ok(FunctionCallExpression {
name, name,
generics: args.0, params: args.0,
params: args.1,
range: stream.get_range().unwrap(), range: stream.get_range().unwrap(),
is_macro, is_macro,
}) })
@ -606,23 +602,10 @@ impl Parse for FunctionCallExpression {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct FunctionArgs(Vec<Type>, Vec<Expression>); pub struct FunctionArgs(Vec<Expression>);
impl Parse for FunctionArgs { impl Parse for FunctionArgs {
fn parse(mut stream: TokenStream) -> Result<Self, Error> { fn parse(mut stream: TokenStream) -> Result<Self, Error> {
let mut generics: Vec<Type> = Vec::new();
if let Some(Token::LessThan) = stream.peek() {
stream.next();
if let Ok(ty) = stream.parse() {
generics.push(ty);
while let Some(Token::Comma) = stream.peek() {
stream.next();
generics.push(stream.parse()?);
}
}
stream.expect(Token::GreaterThan)?;
}
stream.expect(Token::ParenOpen)?; stream.expect(Token::ParenOpen)?;
let mut params = Vec::new(); let mut params = Vec::new();
@ -635,7 +618,7 @@ impl Parse for FunctionArgs {
} }
stream.expect(Token::ParenClose)?; stream.expect(Token::ParenClose)?;
Ok(FunctionArgs(generics, params)) Ok(FunctionArgs(params))
} }
} }
@ -797,18 +780,6 @@ impl Parse for SelfParam {
impl Parse for FunctionSignature { impl Parse for FunctionSignature {
fn parse(mut stream: TokenStream) -> Result<Self, Error> { fn parse(mut stream: TokenStream) -> Result<Self, Error> {
if let Some(Token::Identifier(name)) = stream.next() { if let Some(Token::Identifier(name)) = stream.next() {
let mut generics = Vec::new();
if let Some(Token::LessThan) = stream.peek() {
stream.next();
while let Some(Token::Identifier(ident)) = stream.peek() {
stream.next();
generics.push(ident);
}
stream.expect(Token::GreaterThan)?;
}
stream.expect(Token::ParenOpen)?; stream.expect(Token::ParenOpen)?;
let mut params = Vec::new(); let mut params = Vec::new();
@ -843,7 +814,6 @@ impl Parse for FunctionSignature {
Ok(FunctionSignature { Ok(FunctionSignature {
name, name,
generics,
documentation: None, documentation: None,
params, params,
self_kind, self_kind,
@ -991,8 +961,7 @@ impl Parse for DotIndexKind {
if let Ok(args) = stream.parse::<FunctionArgs>() { if let Ok(args) = stream.parse::<FunctionArgs>() {
Ok(Self::FunctionCall(FunctionCallExpression { Ok(Self::FunctionCall(FunctionCallExpression {
name, name,
generics: args.0, params: args.0,
params: args.1,
range: stream.get_range_prev().unwrap(), range: stream.get_range_prev().unwrap(),
is_macro: false, is_macro: false,
})) }))

View File

@ -1,7 +1,7 @@
use std::{collections::HashMap, path::PathBuf}; use std::path::PathBuf;
use crate::{ use crate::{
ast::{self, ReturnType, TypeKind}, ast::{self, ReturnType},
mir::{ mir::{
self, CustomTypeKey, FunctionParam, ModuleMap, NamedVariableRef, ReturnKind, SourceModuleId, StmtKind, self, CustomTypeKey, FunctionParam, ModuleMap, NamedVariableRef, ReturnKind, SourceModuleId, StmtKind,
StructField, StructType, WhileStatement, StructField, StructType, WhileStatement,
@ -44,11 +44,6 @@ impl ast::Module {
let def = mir::FunctionDefinition { let def = mir::FunctionDefinition {
name: signature.name.clone(), name: signature.name.clone(),
documentation: signature.documentation.clone(), documentation: signature.documentation.clone(),
generics: signature
.generics
.iter()
.map(|g| (g.clone(), mir::TypeKind::Vague(mir::VagueType::Unknown)))
.collect(),
linkage_name: None, linkage_name: None,
is_pub: false, is_pub: false,
is_imported: false, is_imported: false,
@ -180,15 +175,9 @@ impl ast::FunctionDefinition {
ty: p.1 .0.into_mir(module_id), ty: p.1 .0.into_mir(module_id),
meta: p.2.as_meta(module_id), meta: p.2.as_meta(module_id),
})); }));
mir::FunctionDefinition { mir::FunctionDefinition {
name: signature.name.clone(), name: signature.name.clone(),
documentation: signature.documentation.clone(), documentation: signature.documentation.clone(),
generics: signature
.generics
.iter()
.map(|g| (g.clone(), mir::TypeKind::Vague(mir::VagueType::Unknown)))
.collect(),
linkage_name: None, linkage_name: None,
is_pub: *is_pub, is_pub: *is_pub,
is_imported: false, is_imported: false,
@ -390,7 +379,6 @@ impl ast::Expression {
), ),
ast::ExpressionKind::FunctionCall(fn_call_expr) => mir::ExprKind::FunctionCall(mir::FunctionCall { ast::ExpressionKind::FunctionCall(fn_call_expr) => mir::ExprKind::FunctionCall(mir::FunctionCall {
name: fn_call_expr.name.clone(), name: fn_call_expr.name.clone(),
generics: fn_call_expr.generics.iter().map(|g| g.0.into_mir(module_id)).collect(),
return_type: mir::TypeKind::Vague(mir::VagueType::Unknown), return_type: mir::TypeKind::Vague(mir::VagueType::Unknown),
parameters: fn_call_expr.params.iter().map(|e| e.process(module_id)).collect(), parameters: fn_call_expr.params.iter().map(|e| e.process(module_id)).collect(),
meta: fn_call_expr.range.as_meta(module_id), meta: fn_call_expr.range.as_meta(module_id),
@ -480,7 +468,6 @@ impl ast::Expression {
ty.0.into_mir(module_id), ty.0.into_mir(module_id),
mir::FunctionCall { mir::FunctionCall {
name: fn_call_expr.name.clone(), name: fn_call_expr.name.clone(),
generics: fn_call_expr.generics.iter().map(|g| g.0.into_mir(module_id)).collect(),
return_type: mir::TypeKind::Vague(mir::VagueType::Unknown), return_type: mir::TypeKind::Vague(mir::VagueType::Unknown),
parameters: fn_call_expr.params.iter().map(|e| e.process(module_id)).collect(), parameters: fn_call_expr.params.iter().map(|e| e.process(module_id)).collect(),
meta: fn_call_expr.range.as_meta(module_id), meta: fn_call_expr.range.as_meta(module_id),
@ -504,7 +491,6 @@ impl ast::Expression {
mir::TypeKind::Vague(mir::VagueType::Unknown), mir::TypeKind::Vague(mir::VagueType::Unknown),
mir::FunctionCall { mir::FunctionCall {
name: fn_call_expr.name.clone(), name: fn_call_expr.name.clone(),
generics: fn_call_expr.generics.iter().map(|g| g.0.into_mir(module_id)).collect(),
return_type: mir::TypeKind::Vague(mir::VagueType::Unknown), return_type: mir::TypeKind::Vague(mir::VagueType::Unknown),
parameters: params, parameters: params,
meta: fn_call_expr.range.as_meta(module_id), meta: fn_call_expr.range.as_meta(module_id),

View File

@ -77,7 +77,6 @@ pub fn form_intrinsics() -> Vec<FunctionDefinition> {
intrinsics.push(FunctionDefinition { intrinsics.push(FunctionDefinition {
name: MALLOC_IDENT.to_owned(), name: MALLOC_IDENT.to_owned(),
generics: Vec::new(),
documentation: doc!("Allocates `size` bytes and returns a `u8`-pointer."), documentation: doc!("Allocates `size` bytes and returns a `u8`-pointer."),
linkage_name: Some("malloc".to_owned()), linkage_name: Some("malloc".to_owned()),
is_pub: false, is_pub: false,
@ -105,7 +104,6 @@ pub fn simple_intrinsic<T: Into<String> + Clone>(
) -> FunctionDefinition { ) -> FunctionDefinition {
FunctionDefinition { FunctionDefinition {
name: name.into(), name: name.into(),
generics: Vec::new(),
documentation: Some(doc.into()), documentation: Some(doc.into()),
linkage_name: None, linkage_name: None,
is_pub: true, is_pub: true,
@ -126,7 +124,6 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
if let TypeKind::Array(_, len) = ty { if let TypeKind::Array(_, len) = ty {
intrinsics.push(FunctionDefinition { intrinsics.push(FunctionDefinition {
name: "length".to_owned(), name: "length".to_owned(),
generics: Vec::new(),
documentation: doc!("Returns the length of this given array"), documentation: doc!("Returns the length of this given array"),
linkage_name: None, linkage_name: None,
is_pub: true, is_pub: true,
@ -285,7 +282,6 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
)); ));
intrinsics.push(FunctionDefinition { intrinsics.push(FunctionDefinition {
name: "powi".to_owned(), name: "powi".to_owned(),
generics: Vec::new(),
documentation: doc!("Returns `value` raised to the exponent of `exponent`."), documentation: doc!("Returns `value` raised to the exponent of `exponent`."),
linkage_name: None, linkage_name: None,
is_pub: true, is_pub: true,
@ -330,7 +326,6 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
if ty.signed() { if ty.signed() {
intrinsics.push(FunctionDefinition { intrinsics.push(FunctionDefinition {
name: "abs".to_owned(), name: "abs".to_owned(),
generics: Vec::new(),
documentation: doc!("Returns the absolute value of `value`."), documentation: doc!("Returns the absolute value of `value`."),
linkage_name: None, linkage_name: None,
is_pub: true, is_pub: true,
@ -362,7 +357,6 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
} }
intrinsics.push(FunctionDefinition { intrinsics.push(FunctionDefinition {
name: "sizeof".to_owned(), name: "sizeof".to_owned(),
generics: Vec::new(),
documentation: doc!("Simply returns the size of type `T` in bytes."), documentation: doc!("Simply returns the size of type `T` in bytes."),
linkage_name: None, linkage_name: None,
is_pub: true, is_pub: true,
@ -375,7 +369,6 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
}); });
intrinsics.push(FunctionDefinition { intrinsics.push(FunctionDefinition {
name: "malloc".to_owned(), name: "malloc".to_owned(),
generics: Vec::new(),
documentation: doc!("Allocates `T::sizeof() * size` bytes and returns a pointer to `T`."), documentation: doc!("Allocates `T::sizeof() * size` bytes and returns a pointer to `T`."),
linkage_name: None, linkage_name: None,
is_pub: true, is_pub: true,
@ -393,7 +386,6 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
intrinsics.push(FunctionDefinition { intrinsics.push(FunctionDefinition {
name: "memcpy".to_owned(), name: "memcpy".to_owned(),
generics: Vec::new(),
documentation: doc!( documentation: doc!(
"Copies `T::sizeof() * size` bytes from pointer `source` to pointer "Copies `T::sizeof() * size` bytes from pointer `source` to pointer
`destination`." `destination`."
@ -426,7 +418,6 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
intrinsics.push(FunctionDefinition { intrinsics.push(FunctionDefinition {
name: "null".to_owned(), name: "null".to_owned(),
generics: Vec::new(),
documentation: doc!("Returns a null-pointer of type `T`."), documentation: doc!("Returns a null-pointer of type `T`."),
linkage_name: None, linkage_name: None,
is_pub: true, is_pub: true,
@ -440,7 +431,6 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
intrinsics.push(FunctionDefinition { intrinsics.push(FunctionDefinition {
name: "is_null".to_owned(), name: "is_null".to_owned(),
generics: Vec::new(),
documentation: doc!("Returns a boolean representing if `val` is a nullptr or not."), documentation: doc!("Returns a boolean representing if `val` is a nullptr or not."),
linkage_name: None, linkage_name: None,
is_pub: true, is_pub: true,

View File

@ -1218,9 +1218,7 @@ impl mir::Expression {
let TypeKind::CustomType(key) = *inner.clone() else { let TypeKind::CustomType(key) = *inner.clone() else {
panic!("tried accessing non-custom-type"); panic!("tried accessing non-custom-type");
}; };
let TypeDefinitionKind::Struct(struct_ty) = scope.get_typedef(&key).unwrap().kind.clone() else { let TypeDefinitionKind::Struct(struct_ty) = scope.get_typedef(&key).unwrap().kind.clone();
panic!();
};
let idx = struct_ty.find_index(field).unwrap(); let idx = struct_ty.find_index(field).unwrap();
let gep_n = format!("{}.{}.gep", key.0, field); let gep_n = format!("{}.{}.gep", key.0, field);
@ -1261,10 +1259,7 @@ impl mir::Expression {
let TypeDefinition { let TypeDefinition {
kind: TypeDefinitionKind::Struct(struct_ty), kind: TypeDefinitionKind::Struct(struct_ty),
.. ..
} = scope.types.get(scope.type_values.get(&key).unwrap()).unwrap() } = scope.types.get(scope.type_values.get(&key).unwrap()).unwrap();
else {
panic!()
};
let indices = struct_ty.0.iter().enumerate(); let indices = struct_ty.0.iter().enumerate();

View File

@ -8,7 +8,7 @@ use crate::{
ast::token_stream::{self, TokenRange}, ast::token_stream::{self, TokenRange},
codegen, codegen,
lexer::{self, Cursor, FullToken, Position}, lexer::{self, Cursor, FullToken, Position},
mir::{self, generics, macros, pass, typecheck, Metadata, SourceModuleId}, mir::{self, macros, pass, typecheck, Metadata, SourceModuleId},
}; };
use crate::mir::typecheck::ErrorKind as TypecheckError; use crate::mir::typecheck::ErrorKind as TypecheckError;
@ -36,8 +36,6 @@ pub enum ErrorKind {
LinkerError(#[from] mir::pass::Error<mir::linker::ErrorKind>), LinkerError(#[from] mir::pass::Error<mir::linker::ErrorKind>),
#[error("{}{}", label("(Macro) "), .0)] #[error("{}{}", label("(Macro) "), .0)]
MacroError(#[from] mir::pass::Error<macros::ErrorKind>), MacroError(#[from] mir::pass::Error<macros::ErrorKind>),
#[error("{}{}", label("(Generics) "), .0)]
GenericsError(#[from] mir::pass::Error<generics::ErrorKind>),
#[error("{}{}", label("(Codegen) "), .0)] #[error("{}{}", label("(Codegen) "), .0)]
CodegenError(#[from] codegen::ErrorKind), CodegenError(#[from] codegen::ErrorKind),
} }
@ -64,7 +62,6 @@ impl ErrorKind {
codegen::ErrorKind::Null => Default::default(), codegen::ErrorKind::Null => Default::default(),
}, },
ErrorKind::MacroError(error) => error.metadata, ErrorKind::MacroError(error) => error.metadata,
ErrorKind::GenericsError(error) => error.metadata,
} }
} }
@ -77,7 +74,6 @@ impl ErrorKind {
ErrorKind::LinkerError(_) => "linker", ErrorKind::LinkerError(_) => "linker",
ErrorKind::MacroError(_) => "macro-pass", ErrorKind::MacroError(_) => "macro-pass",
ErrorKind::CodegenError(_) => "codegen", ErrorKind::CodegenError(_) => "codegen",
ErrorKind::GenericsError(_) => "generics",
} }
} }
} }

View File

@ -70,7 +70,6 @@ use reid_lib::{compile::CompileOutput, Context};
use crate::{ use crate::{
ast::TopLevelStatement, ast::TopLevelStatement,
mir::{ mir::{
generics::GenericsPass,
macros::{form_macros, MacroModule, MacroPass}, macros::{form_macros, MacroModule, MacroPass},
SourceModuleId, SourceModuleId,
}, },
@ -178,24 +177,6 @@ pub fn perform_all_passes<'map>(
is_lib: true, is_lib: true,
})?; })?;
#[cfg(debug_assertions)]
log::trace!("{:-^100}", "LINKER OUTPUT");
#[cfg(debug_assertions)]
log::trace!("{:#}", &context);
#[cfg(debug_assertions)]
log::trace!("{:#?}", &state);
if !state.errors.is_empty() {
return Err(ReidError::from_kind(
state.errors.iter().map(|e| e.clone().into()).collect(),
module_map.clone(),
));
}
let state = context.pass(&mut GenericsPass {
function_map: HashMap::new(),
})?;
for module in &mut context.modules { for module in &mut context.modules {
for intrinsic in form_intrinsics() { for intrinsic in form_intrinsics() {
module.1.functions.insert(0, intrinsic); module.1.functions.insert(0, intrinsic);
@ -203,7 +184,7 @@ pub fn perform_all_passes<'map>(
} }
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
log::trace!("{:-^100}", "GENERICS OUTPUT"); log::trace!("{:-^100}", "LINKER OUTPUT");
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
log::trace!("{:#}", &context); log::trace!("{:#}", &context);
#[cfg(debug_assertions)] #[cfg(debug_assertions)]

View File

@ -157,14 +157,9 @@ impl Display for FunctionDefinition {
} }
write!( write!(
f, f,
"{}fn {}<{}>({}) -> {:#} ", "{}fn {}({}) -> {:#} ",
if self.is_pub { "pub " } else { "" }, if self.is_pub { "pub " } else { "" },
self.name, self.name,
self.generics
.iter()
.map(|(n, t)| format!("{n} = {:?}", t))
.collect::<Vec<_>>()
.join(", "),
self.parameters self.parameters
.iter() .iter()
.map(|FunctionParam { name, ty, .. }| format!("{}: {:#}", name, ty)) .map(|FunctionParam { name, ty, .. }| format!("{}: {:#}", name, ty))
@ -494,14 +489,12 @@ impl Display for VagueType {
VagueType::Integer => write!(f, "Number"), VagueType::Integer => write!(f, "Number"),
VagueType::TypeRef(id) => write!(f, "TypeRef({0})", id), VagueType::TypeRef(id) => write!(f, "TypeRef({0})", id),
VagueType::Decimal => write!(f, "Decimal"), VagueType::Decimal => write!(f, "Decimal"),
VagueType::Named(name) => write!(f, "Named<{name}>"),
} }
} else { } else {
match self { match self {
VagueType::Unknown => write!(f, "{{unknown}}"), VagueType::Unknown => write!(f, "{{unknown}}"),
VagueType::Integer => write!(f, "Number"), VagueType::Integer => write!(f, "Number"),
VagueType::TypeRef(_) => write!(f, "{{unknown}}"), VagueType::TypeRef(_) => write!(f, "{{unknown}}"),
VagueType::Named(name) => write!(f, "{name}"),
VagueType::Decimal => write!(f, "Decimal"), VagueType::Decimal => write!(f, "Decimal"),
} }
} }

View File

@ -1,296 +0,0 @@
use std::{collections::HashMap, path::PathBuf};
use log::Metadata;
use crate::mir::{
self, generics, CustomTypeKey, FunctionCall, FunctionDefinition, FunctionParam, GlobalKind, GlobalValue,
IfExpression, Literal, Module, SourceModuleId, TypeKind, WhileStatement,
};
use super::pass::{Pass, PassResult, PassState};
#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum ErrorKind {
#[error("Should never be encountered!")]
Null,
#[error("Expected {0} type-arguments, got {1}!")]
InvalidNumberTypeArguments(u32, u32),
}
type Calls = Vec<(Vec<TypeKind>, mir::Metadata)>;
pub struct GenericsPass {
pub function_map: HashMap<SourceModuleId, Functions>,
}
#[derive(Debug)]
pub struct Functions {
calls: HashMap<String, Calls>,
assoc_calls: HashMap<(TypeKind, String), Calls>,
}
#[derive(Default, Clone)]
pub struct GenericsPassData {
generic_types: HashMap<String, TypeKind>,
}
type GenericsPassState<'map, 'st, 'sc> = PassState<'st, 'sc, GenericsPassData, ErrorKind>;
impl Pass for GenericsPass {
type Data = GenericsPassData;
type TError = ErrorKind;
fn context(&mut self, context: &mut mir::Context, mut _state: PassState<Self::Data, Self::TError>) -> PassResult {
let mut function_map = HashMap::new();
for module in &context.modules {
function_map.insert(
module.0.clone(),
Functions {
calls: HashMap::new(),
assoc_calls: HashMap::new(),
},
);
}
for module in &mut context.modules {
let mut calls = HashMap::new();
let mut assoc_calls = HashMap::new();
for function in &mut module.1.associated_functions {
match &mut function.1.kind {
mir::FunctionDefinitionKind::Local(block, _) => block.find_calls(&mut calls, &mut assoc_calls),
mir::FunctionDefinitionKind::Extern(_) => {}
mir::FunctionDefinitionKind::Intrinsic(_) => {}
}
}
for function in &mut module.1.functions {
match &mut function.kind {
mir::FunctionDefinitionKind::Local(block, _) => block.find_calls(&mut calls, &mut assoc_calls),
mir::FunctionDefinitionKind::Extern(_) => {}
mir::FunctionDefinitionKind::Intrinsic(_) => {}
}
}
for function in &module.1.associated_functions {
if let Some(source) = function.1.source {
let key = (function.0.clone(), function.1.name.clone());
function_map
.get_mut(&source)
.unwrap()
.assoc_calls
.insert(key.clone(), assoc_calls.get(&key).cloned().unwrap_or_default());
}
}
for function in &module.1.functions {
if let Some(source) = function.source {
function_map.get_mut(&source).unwrap().calls.insert(
function.name.clone(),
calls.get(&function.name).cloned().unwrap_or_default(),
);
}
}
}
self.function_map = function_map;
Ok(())
}
fn module(&mut self, module: &mut mir::Module, mut state: PassState<Self::Data, Self::TError>) -> PassResult {
for function in module.functions.drain(..).collect::<Vec<_>>() {
if let Some(source) = function.source {
let functions = self.function_map.get(&source).unwrap();
let calls = functions.calls.get(&function.name).unwrap();
for call in calls {
if call.0.len() != function.generics.len() {
state.note_errors(
&vec![ErrorKind::InvalidNumberTypeArguments(
function.generics.len() as u32,
call.0.len() as u32,
)],
call.1,
);
}
}
if function.generics.len() > 0 {
for call in calls {
if let Some(clone) = function.try_clone() {
let generics = function
.generics
.iter()
.zip(call.0.clone())
.map(|((n, _), t)| (n.clone(), t.clone()))
.collect();
module.functions.push(FunctionDefinition {
name: name_fmt(function.name.clone(), call.0.clone()),
return_type: function.return_type.replace_generic(&generics),
parameters: function
.parameters
.iter()
.map(|p| FunctionParam {
ty: p.ty.replace_generic(&generics),
..p.clone()
})
.collect(),
generics,
..clone
});
}
}
} else {
module.functions.push(function);
}
} else {
module.functions.push(function);
}
}
Ok(())
}
fn function(
&mut self,
func: &mut FunctionDefinition,
mut state: PassState<Self::Data, Self::TError>,
) -> PassResult {
for (name, ty) in &func.generics {
state.scope.data.generic_types.insert(name.clone(), ty.clone());
}
Ok(())
}
fn stmt(&mut self, stmt: &mut mir::Statement, mut state: PassState<Self::Data, Self::TError>) -> PassResult {
match &mut stmt.0 {
mir::StmtKind::Let(var_ref, _, _) => match var_ref.0.clone() {
TypeKind::CustomType(custom_type_key) => {
if let Some(ty) = state.scope.data.generic_types.get(&custom_type_key.0) {
var_ref.0 = ty.clone();
}
}
_ => {}
},
_ => {}
}
Ok(())
}
}
impl mir::Block {
fn find_calls(&mut self, calls: &mut HashMap<String, Calls>, assoc_calls: &mut HashMap<(TypeKind, String), Calls>) {
for statement in &mut self.statements {
statement.find_calls(calls, assoc_calls);
}
if let Some((_, Some(e))) = &mut self.return_expression {
e.find_calls(calls, assoc_calls);
}
}
}
impl mir::Statement {
fn find_calls(&mut self, calls: &mut HashMap<String, Calls>, assoc_calls: &mut HashMap<(TypeKind, String), Calls>) {
match &mut self.0 {
mir::StmtKind::Let(_, _, expression) => expression.find_calls(calls, assoc_calls),
mir::StmtKind::Set(expression, expression1) => {
expression.find_calls(calls, assoc_calls);
expression1.find_calls(calls, assoc_calls);
}
mir::StmtKind::Import(_) => {}
mir::StmtKind::Expression(expression) => expression.find_calls(calls, assoc_calls),
mir::StmtKind::While(WhileStatement { condition, block, .. }) => {
condition.find_calls(calls, assoc_calls);
block.find_calls(calls, assoc_calls);
}
}
}
}
impl mir::Expression {
fn find_calls(&mut self, calls: &mut HashMap<String, Calls>, assoc_calls: &mut HashMap<(TypeKind, String), Calls>) {
match &mut self.0 {
mir::ExprKind::Variable(_) => {}
mir::ExprKind::Indexed(expression, _, expression1) => {
expression.find_calls(calls, assoc_calls);
expression1.find_calls(calls, assoc_calls);
}
mir::ExprKind::Accessed(expression, _, _, _) => {
expression.find_calls(calls, assoc_calls);
}
mir::ExprKind::Array(expressions) => {
for expression in expressions {
expression.find_calls(calls, assoc_calls);
}
}
mir::ExprKind::Struct(_, items) => {
for item in items {
item.1.find_calls(calls, assoc_calls);
}
}
mir::ExprKind::Literal(_) => {}
mir::ExprKind::BinOp(_, lhs, rhs, _) => {
lhs.find_calls(calls, assoc_calls);
rhs.find_calls(calls, assoc_calls);
}
mir::ExprKind::FunctionCall(function_call) => {
if let Some(calls) = calls.get_mut(&function_call.name) {
calls.push((function_call.generics.clone(), self.1));
} else {
calls.insert(
function_call.name.clone(),
vec![(function_call.generics.clone(), self.1)],
);
}
if function_call.generics.len() > 0 {
function_call.name = name_fmt(function_call.name.clone(), function_call.generics.clone())
}
}
mir::ExprKind::AssociatedFunctionCall(ty, function_call) => {
if let Some(calls) = assoc_calls.get_mut(&(ty.clone(), function_call.name.clone())) {
calls.push((function_call.generics.clone(), self.1));
} else {
assoc_calls.insert(
(ty.clone(), function_call.name.clone()),
vec![(function_call.generics.clone(), self.1)],
);
}
if function_call.generics.len() > 0 {
function_call.name = name_fmt(function_call.name.clone(), function_call.generics.clone())
}
}
mir::ExprKind::If(IfExpression(cond, then_e, else_e)) => {
cond.find_calls(calls, assoc_calls);
then_e.find_calls(calls, assoc_calls);
if let Some(else_e) = else_e.as_mut() {
else_e.find_calls(calls, assoc_calls);
}
}
mir::ExprKind::Block(block) => block.find_calls(calls, assoc_calls),
mir::ExprKind::Borrow(expression, _) => expression.find_calls(calls, assoc_calls),
mir::ExprKind::Deref(expression) => expression.find_calls(calls, assoc_calls),
mir::ExprKind::CastTo(expression, _) => expression.find_calls(calls, assoc_calls),
mir::ExprKind::GlobalRef(_, _) => {}
}
}
}
fn name_fmt(name: String, generics: Vec<TypeKind>) -> String {
format!(
"{}.{}",
name,
generics.iter().map(|t| t.to_string()).collect::<Vec<_>>().join(".")
)
}
impl TypeKind {
fn replace_generic(&self, generics: &Vec<(String, TypeKind)>) -> TypeKind {
match self {
TypeKind::CustomType(CustomTypeKey(name, _)) => {
if let Some((_, inner)) = generics.iter().find(|(n, _)| n == name) {
inner.clone()
} else {
self.clone()
}
}
_ => self.clone(),
}
}
}

View File

@ -171,7 +171,6 @@ impl TypeKind {
VagueType::Integer => TypeCategory::Integer, VagueType::Integer => TypeCategory::Integer,
VagueType::Decimal => TypeCategory::Real, VagueType::Decimal => TypeCategory::Real,
VagueType::TypeRef(_) => TypeCategory::TypeRef, VagueType::TypeRef(_) => TypeCategory::TypeRef,
VagueType::Named(_) => TypeCategory::Other,
}, },
} }
} }

View File

@ -311,7 +311,6 @@ impl<'map> Pass for LinkerPass<'map> {
importer_module.functions.push(FunctionDefinition { importer_module.functions.push(FunctionDefinition {
name: function.name.clone(), name: function.name.clone(),
generics: function.generics.clone(),
documentation: function.documentation.clone(), documentation: function.documentation.clone(),
linkage_name: None, linkage_name: None,
is_pub: false, is_pub: false,
@ -461,7 +460,6 @@ impl<'map> Pass for LinkerPass<'map> {
FunctionDefinition { FunctionDefinition {
name: func_name.clone(), name: func_name.clone(),
documentation: func.documentation.clone(), documentation: func.documentation.clone(),
generics: func.generics.clone(),
linkage_name: Some(format!("{}::{}", ty, func_name)), linkage_name: Some(format!("{}::{}", ty, func_name)),
is_pub: false, is_pub: false,
is_imported: false, is_imported: false,

View File

@ -11,7 +11,6 @@ use crate::{
}; };
mod fmt; mod fmt;
pub mod generics;
pub mod implement; pub mod implement;
pub mod linker; pub mod linker;
pub mod macros; pub mod macros;
@ -136,14 +135,13 @@ pub enum TypeKind {
Vague(VagueType), Vague(VagueType),
} }
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum VagueType { pub enum VagueType {
Unknown, Unknown,
/// Some integer value (e.g. 5) /// Some integer value (e.g. 5)
Integer, Integer,
/// Some decimal fractional value (e.g. 1.5) /// Some decimal fractional value (e.g. 1.5)
Decimal, Decimal,
Named(String),
TypeRef(usize), TypeRef(usize),
} }
@ -166,7 +164,7 @@ impl StructType {
impl TypeKind { impl TypeKind {
pub fn known(&self) -> Result<TypeKind, VagueType> { pub fn known(&self) -> Result<TypeKind, VagueType> {
if let TypeKind::Vague(vague) = self { if let TypeKind::Vague(vague) = self {
Err(vague.clone()) Err(*vague)
} else { } else {
Ok(self.clone()) Ok(self.clone())
} }
@ -311,7 +309,6 @@ pub struct IfExpression(pub Box<Expression>, pub Box<Expression>, pub Box<Option
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct FunctionCall { pub struct FunctionCall {
pub name: String, pub name: String,
pub generics: Vec<TypeKind>,
pub return_type: TypeKind, pub return_type: TypeKind,
pub parameters: Vec<Expression>, pub parameters: Vec<Expression>,
pub is_macro: bool, pub is_macro: bool,
@ -323,7 +320,6 @@ pub struct FunctionDefinition {
pub name: String, pub name: String,
pub documentation: Option<String>, pub documentation: Option<String>,
pub linkage_name: Option<String>, pub linkage_name: Option<String>,
pub generics: Vec<(String, TypeKind)>,
/// Whether this function is visible to outside modules /// Whether this function is visible to outside modules
pub is_pub: bool, pub is_pub: bool,
/// Whether this module is from an external module, and has been imported /// Whether this module is from an external module, and has been imported
@ -335,40 +331,6 @@ pub struct FunctionDefinition {
pub signature_meta: Metadata, pub signature_meta: Metadata,
} }
impl FunctionDefinition {
pub fn try_clone(&self) -> Option<FunctionDefinition> {
match &self.kind {
FunctionDefinitionKind::Local(block, metadata) => Some(FunctionDefinition {
name: self.name.clone(),
documentation: self.documentation.clone(),
linkage_name: self.linkage_name.clone(),
generics: self.generics.clone(),
is_pub: self.is_pub.clone(),
is_imported: self.is_imported.clone(),
return_type: self.return_type.clone(),
parameters: self.parameters.clone(),
kind: FunctionDefinitionKind::Local(block.clone(), metadata.clone()),
source: self.source.clone(),
signature_meta: self.signature_meta.clone(),
}),
FunctionDefinitionKind::Extern(e) => Some(FunctionDefinition {
name: self.name.clone(),
documentation: self.documentation.clone(),
linkage_name: self.linkage_name.clone(),
generics: self.generics.clone(),
is_pub: self.is_pub.clone(),
is_imported: self.is_imported.clone(),
return_type: self.return_type.clone(),
parameters: self.parameters.clone(),
kind: FunctionDefinitionKind::Extern(*e),
source: self.source.clone(),
signature_meta: self.signature_meta.clone(),
}),
FunctionDefinitionKind::Intrinsic(intrinsic_function) => None,
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd)] #[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct FunctionParam { pub struct FunctionParam {
pub name: String, pub name: String,

View File

@ -290,11 +290,10 @@ impl TypeKind {
pub(super) fn or_default(&self) -> Result<TypeKind, ErrorKind> { pub(super) fn or_default(&self) -> Result<TypeKind, ErrorKind> {
Ok(match self { Ok(match self {
TypeKind::Vague(vague_type) => match &vague_type { TypeKind::Vague(vague_type) => match &vague_type {
Vague::Unknown => Err(ErrorKind::TypeIsVague(vague_type.clone()))?, Vague::Unknown => Err(ErrorKind::TypeIsVague(*vague_type))?,
Vague::Integer => TypeKind::I32, Vague::Integer => TypeKind::I32,
Vague::TypeRef(_) => panic!("Hinted default!"), Vague::TypeRef(_) => panic!("Hinted default!"),
VagueType::Decimal => TypeKind::F32, VagueType::Decimal => TypeKind::F32,
VagueType::Named(_) => panic!("Defaulted unknown named!"),
}, },
TypeKind::Array(type_kind, len) => TypeKind::Array(Box::new(type_kind.or_default()?), *len), TypeKind::Array(type_kind, len) => TypeKind::Array(Box::new(type_kind.or_default()?), *len),
TypeKind::Borrow(type_kind, mutable) => TypeKind::Borrow(Box::new(type_kind.or_default()?), *mutable), TypeKind::Borrow(type_kind, mutable) => TypeKind::Borrow(Box::new(type_kind.or_default()?), *mutable),
@ -340,7 +339,7 @@ impl TypeKind {
TypeKind::Borrow(type_kind, _) => type_kind.is_known(state), TypeKind::Borrow(type_kind, _) => type_kind.is_known(state),
TypeKind::UserPtr(type_kind) => type_kind.is_known(state), TypeKind::UserPtr(type_kind) => type_kind.is_known(state),
TypeKind::CodegenPtr(type_kind) => type_kind.is_known(state), TypeKind::CodegenPtr(type_kind) => type_kind.is_known(state),
TypeKind::Vague(vague_type) => Err(ErrorKind::TypeIsVague(vague_type.clone())), TypeKind::Vague(vague_type) => Err(ErrorKind::TypeIsVague(*vague_type)),
_ => Ok(()), _ => Ok(()),
} }
} }

View File

@ -368,7 +368,6 @@ impl<'outer> ScopeTypeRefs<'outer> {
self.narrow_to_type(&typeref, &self.try_default_deep(&typeref.resolve_deep()?)?)? self.narrow_to_type(&typeref, &self.try_default_deep(&typeref.resolve_deep()?)?)?
.resolve_deep()? .resolve_deep()?
} }
VagueType::Named(_) => ty.clone(),
}, },
_ => ty.clone(), _ => ty.clone(),
}) })