Add module_id for modules and metadata
This commit is contained in:
parent
e2dc1a3f85
commit
64e34ecf13
@ -161,6 +161,7 @@ fn main() {
|
||||
let mir_context = mir::Context {
|
||||
modules: vec![Module {
|
||||
name: "test module".to_owned(),
|
||||
module_id: SourceModuleId::default(),
|
||||
imports: vec![],
|
||||
functions: vec![fibonacci, main],
|
||||
typedefs: Vec::new(),
|
||||
|
@ -2,7 +2,7 @@ use std::path::PathBuf;
|
||||
|
||||
use crate::{
|
||||
ast::{self},
|
||||
mir::{self, NamedVariableRef, StmtKind, StructField, StructType},
|
||||
mir::{self, NamedVariableRef, SourceModuleId, StmtKind, StructField, StructType},
|
||||
};
|
||||
|
||||
impl mir::Context {
|
||||
@ -12,7 +12,7 @@ impl mir::Context {
|
||||
}
|
||||
|
||||
impl ast::Module {
|
||||
pub fn process(&self) -> mir::Module {
|
||||
pub fn process(&self, module_id: SourceModuleId) -> mir::Module {
|
||||
let mut imports = Vec::new();
|
||||
let mut functions = Vec::new();
|
||||
let mut typedefs = Vec::new();
|
||||
@ -21,7 +21,7 @@ impl ast::Module {
|
||||
for stmt in &self.top_level_statements {
|
||||
match stmt {
|
||||
Import(import) => {
|
||||
imports.push(mir::Import(import.0.clone(), import.1.into()));
|
||||
imports.push(mir::Import(import.0.clone(), import.1.as_meta(module_id)));
|
||||
}
|
||||
FunctionDefinition(ast::FunctionDefinition(signature, is_pub, block, range)) => {
|
||||
let def = mir::FunctionDefinition {
|
||||
@ -39,7 +39,10 @@ impl ast::Module {
|
||||
.cloned()
|
||||
.map(|p| (p.0, p.1.into()))
|
||||
.collect(),
|
||||
kind: mir::FunctionDefinitionKind::Local(block.into_mir(), (*range).into()),
|
||||
kind: mir::FunctionDefinitionKind::Local(
|
||||
block.into_mir(module_id),
|
||||
(*range).as_meta(module_id),
|
||||
),
|
||||
};
|
||||
functions.push(def);
|
||||
}
|
||||
@ -75,14 +78,14 @@ impl ast::Module {
|
||||
StructField(
|
||||
s.name.clone(),
|
||||
s.ty.clone().into(),
|
||||
s.range.into(),
|
||||
s.range.as_meta(module_id),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
))
|
||||
}
|
||||
},
|
||||
meta: (*range).into(),
|
||||
meta: (*range).as_meta(module_id),
|
||||
};
|
||||
typedefs.push(def);
|
||||
}
|
||||
@ -91,6 +94,7 @@ impl ast::Module {
|
||||
|
||||
mir::Module {
|
||||
name: self.name.clone(),
|
||||
module_id: module_id,
|
||||
imports,
|
||||
functions,
|
||||
path: self.path.clone(),
|
||||
@ -101,7 +105,7 @@ impl ast::Module {
|
||||
}
|
||||
|
||||
impl ast::Block {
|
||||
pub fn into_mir(&self) -> mir::Block {
|
||||
pub fn into_mir(&self, module_id: SourceModuleId) -> mir::Block {
|
||||
let mut mir_statements = Vec::new();
|
||||
|
||||
for statement in &self.0 {
|
||||
@ -115,27 +119,31 @@ impl ast::Block {
|
||||
.map(|t| t.0.into())
|
||||
.unwrap_or(mir::TypeKind::Vague(mir::VagueType::Unknown)),
|
||||
s_let.0.clone(),
|
||||
s_let.4.into(),
|
||||
s_let.4.as_meta(module_id),
|
||||
),
|
||||
s_let.2,
|
||||
s_let.3.process(),
|
||||
s_let.3.process(module_id),
|
||||
),
|
||||
s_let.4,
|
||||
),
|
||||
ast::BlockLevelStatement::Set(var_ref, expression, range) => (
|
||||
StmtKind::Set(var_ref.process(), expression.process()),
|
||||
StmtKind::Set(var_ref.process(module_id), expression.process(module_id)),
|
||||
*range,
|
||||
),
|
||||
ast::BlockLevelStatement::Import { _i } => todo!(),
|
||||
ast::BlockLevelStatement::Expression(e) => (StmtKind::Expression(e.process()), e.1),
|
||||
ast::BlockLevelStatement::Return(_, e) => (StmtKind::Expression(e.process()), e.1),
|
||||
ast::BlockLevelStatement::Expression(e) => {
|
||||
(StmtKind::Expression(e.process(module_id)), e.1)
|
||||
}
|
||||
ast::BlockLevelStatement::Return(_, e) => {
|
||||
(StmtKind::Expression(e.process(module_id)), e.1)
|
||||
}
|
||||
};
|
||||
|
||||
mir_statements.push(mir::Statement(kind, range.into()));
|
||||
mir_statements.push(mir::Statement(kind, range.as_meta(module_id)));
|
||||
}
|
||||
|
||||
let return_expression = if let Some(r) = &self.1 {
|
||||
Some((r.0.into(), Box::new(r.1.process())))
|
||||
Some((r.0.into(), Box::new(r.1.process(module_id))))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -143,7 +151,7 @@ impl ast::Block {
|
||||
mir::Block {
|
||||
statements: mir_statements,
|
||||
return_expression,
|
||||
meta: self.2.into(),
|
||||
meta: self.2.as_meta(module_id),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -158,61 +166,67 @@ impl From<ast::ReturnType> for mir::ReturnKind {
|
||||
}
|
||||
|
||||
impl ast::Expression {
|
||||
fn process(&self) -> mir::Expression {
|
||||
fn process(&self, module_id: SourceModuleId) -> mir::Expression {
|
||||
let kind = match &self.0 {
|
||||
ast::ExpressionKind::VariableName(name) => mir::ExprKind::Variable(NamedVariableRef(
|
||||
mir::TypeKind::Vague(mir::VagueType::Unknown),
|
||||
name.clone(),
|
||||
self.1.into(),
|
||||
self.1.as_meta(module_id),
|
||||
)),
|
||||
ast::ExpressionKind::Literal(literal) => mir::ExprKind::Literal(literal.mir()),
|
||||
ast::ExpressionKind::Binop(binary_operator, lhs, rhs) => mir::ExprKind::BinOp(
|
||||
binary_operator.mir(),
|
||||
Box::new(lhs.process()),
|
||||
Box::new(rhs.process()),
|
||||
Box::new(lhs.process(module_id)),
|
||||
Box::new(rhs.process(module_id)),
|
||||
),
|
||||
ast::ExpressionKind::FunctionCall(fn_call_expr) => {
|
||||
mir::ExprKind::FunctionCall(mir::FunctionCall {
|
||||
name: fn_call_expr.0.clone(),
|
||||
return_type: mir::TypeKind::Vague(mir::VagueType::Unknown),
|
||||
parameters: fn_call_expr.1.iter().map(|e| e.process()).collect(),
|
||||
parameters: fn_call_expr
|
||||
.1
|
||||
.iter()
|
||||
.map(|e| e.process(module_id))
|
||||
.collect(),
|
||||
})
|
||||
}
|
||||
ast::ExpressionKind::BlockExpr(block) => mir::ExprKind::Block(block.into_mir()),
|
||||
ast::ExpressionKind::BlockExpr(block) => {
|
||||
mir::ExprKind::Block(block.into_mir(module_id))
|
||||
}
|
||||
ast::ExpressionKind::IfExpr(if_expression) => {
|
||||
let cond = if_expression.0.process();
|
||||
let then_block = if_expression.1.into_mir();
|
||||
let cond = if_expression.0.process(module_id);
|
||||
let then_block = if_expression.1.into_mir(module_id);
|
||||
let else_block = if let Some(el) = &if_expression.2 {
|
||||
Some(el.into_mir())
|
||||
Some(el.into_mir(module_id))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
mir::ExprKind::If(mir::IfExpression(Box::new(cond), then_block, else_block))
|
||||
}
|
||||
ast::ExpressionKind::Array(expressions) => {
|
||||
mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect())
|
||||
mir::ExprKind::Array(expressions.iter().map(|e| e.process(module_id)).collect())
|
||||
}
|
||||
ast::ExpressionKind::Indexed(expression, idx_expr) => mir::ExprKind::Indexed(
|
||||
Box::new(expression.process()),
|
||||
Box::new(expression.process(module_id)),
|
||||
mir::TypeKind::Vague(mir::VagueType::Unknown),
|
||||
Box::new(idx_expr.process()),
|
||||
Box::new(idx_expr.process(module_id)),
|
||||
),
|
||||
ast::ExpressionKind::StructExpression(struct_init) => mir::ExprKind::Struct(
|
||||
struct_init.name.clone(),
|
||||
struct_init
|
||||
.fields
|
||||
.iter()
|
||||
.map(|(n, e)| (n.clone(), e.process()))
|
||||
.map(|(n, e)| (n.clone(), e.process(module_id)))
|
||||
.collect(),
|
||||
),
|
||||
ast::ExpressionKind::Accessed(expression, name) => mir::ExprKind::Accessed(
|
||||
Box::new(expression.process()),
|
||||
Box::new(expression.process(module_id)),
|
||||
mir::TypeKind::Vague(mir::VagueType::Unknown),
|
||||
name.clone(),
|
||||
),
|
||||
};
|
||||
|
||||
mir::Expression(kind, self.1.into())
|
||||
mir::Expression(kind, self.1.as_meta(module_id))
|
||||
}
|
||||
}
|
||||
|
||||
|
0
reid/src/error_raporting.rs
Normal file
0
reid/src/error_raporting.rs
Normal file
@ -45,6 +45,7 @@ use std::path::PathBuf;
|
||||
|
||||
use mir::{
|
||||
linker::LinkerPass, typecheck::TypeCheck, typeinference::TypeInference, typerefs::TypeRefs,
|
||||
SourceModuleId,
|
||||
};
|
||||
use reid_lib::{compile::CompileOutput, Context};
|
||||
|
||||
@ -75,6 +76,7 @@ pub enum ReidError {
|
||||
pub fn compile_module(
|
||||
source: &str,
|
||||
name: String,
|
||||
module_id: SourceModuleId,
|
||||
path: Option<PathBuf>,
|
||||
is_main: bool,
|
||||
) -> Result<mir::Module, ReidError> {
|
||||
@ -99,7 +101,7 @@ pub fn compile_module(
|
||||
is_main,
|
||||
};
|
||||
|
||||
Ok(ast_module.process())
|
||||
Ok(ast_module.process(module_id))
|
||||
}
|
||||
|
||||
pub fn perform_all_passes(context: &mut mir::Context) -> Result<(), ReidError> {
|
||||
@ -159,6 +161,7 @@ pub fn compile(source: &str, path: PathBuf) -> Result<CompileOutput, ReidError>
|
||||
vec![compile_module(
|
||||
source,
|
||||
path.file_name().unwrap().to_str().unwrap().to_owned(),
|
||||
SourceModuleId::default(),
|
||||
Some(path.clone()),
|
||||
true,
|
||||
)?],
|
||||
|
@ -289,7 +289,13 @@ impl Display for CmpOperator {
|
||||
|
||||
impl Display for Metadata {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{:?}", self.range)
|
||||
write!(f, "{:?} ({})", self.range, self.source_module_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for SourceModuleId {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Mod {}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
use super::{typecheck::ErrorKind, typerefs::TypeRefs, VagueType as Vague, *};
|
||||
use super::{
|
||||
typecheck::ErrorKind,
|
||||
typerefs::{ScopeTypeRefs, TypeRef, TypeRefs},
|
||||
VagueType as Vague, *,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ReturnTypeOther {
|
||||
|
@ -12,7 +12,7 @@ use crate::{compile_module, ReidError};
|
||||
use super::{
|
||||
pass::{Pass, PassState},
|
||||
r#impl::EqualsIssue,
|
||||
Context, FunctionDefinition, Import, Metadata, Module,
|
||||
Context, FunctionDefinition, Import, Metadata, Module, SourceModuleId,
|
||||
};
|
||||
|
||||
pub static STD_SOURCE: &str = include_str!("../../lib/std.reid");
|
||||
@ -41,8 +41,15 @@ pub enum ErrorKind {
|
||||
FunctionIsPrivate(String, String),
|
||||
}
|
||||
|
||||
pub fn compile_std() -> super::Module {
|
||||
let module = compile_module(STD_SOURCE, "standard_library".to_owned(), None, false).unwrap();
|
||||
pub fn compile_std(module_id: SourceModuleId) -> super::Module {
|
||||
let module = compile_module(
|
||||
STD_SOURCE,
|
||||
"standard_library".to_owned(),
|
||||
module_id,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut mir_context = super::Context::from(vec![module], Default::default());
|
||||
|
||||
@ -85,7 +92,16 @@ impl Pass for LinkerPass {
|
||||
modules.insert(module.name.clone(), Rc::new(RefCell::new(module)));
|
||||
}
|
||||
|
||||
modules.insert("std".to_owned(), Rc::new(RefCell::new(compile_std())));
|
||||
let mut module_counter = modules
|
||||
.values()
|
||||
.map(|m| m.borrow().module_id)
|
||||
.max()
|
||||
.unwrap();
|
||||
|
||||
modules.insert(
|
||||
"std".to_owned(),
|
||||
Rc::new(RefCell::new(compile_std(module_counter.increment()))),
|
||||
);
|
||||
|
||||
let mut modules_to_process: Vec<Rc<RefCell<Module>>> = modules.values().cloned().collect();
|
||||
|
||||
@ -117,7 +133,13 @@ impl Pass for LinkerPass {
|
||||
continue;
|
||||
};
|
||||
|
||||
match compile_module(&source, module_name.clone(), Some(file_path), false) {
|
||||
match compile_module(
|
||||
&source,
|
||||
module_name.clone(),
|
||||
module_counter.increment(),
|
||||
Some(file_path),
|
||||
false,
|
||||
) {
|
||||
Ok(imported_module) => {
|
||||
if imported_module.is_main {
|
||||
state.ok::<_, Infallible>(
|
||||
|
@ -14,24 +14,40 @@ pub mod typecheck;
|
||||
pub mod typeinference;
|
||||
pub mod typerefs;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
|
||||
pub struct SourceModuleId(u32);
|
||||
|
||||
impl SourceModuleId {
|
||||
pub fn increment(&mut self) -> SourceModuleId {
|
||||
self.0 += 1;
|
||||
SourceModuleId(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy)]
|
||||
pub struct Metadata {
|
||||
pub range: TokenRange,
|
||||
pub source_module_id: SourceModuleId,
|
||||
}
|
||||
|
||||
impl std::ops::Add for Metadata {
|
||||
type Output = Metadata;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
assert!(self.source_module_id == rhs.source_module_id);
|
||||
Metadata {
|
||||
range: self.range + rhs.range,
|
||||
source_module_id: self.source_module_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TokenRange> for Metadata {
|
||||
fn from(value: TokenRange) -> Self {
|
||||
Metadata { range: value }
|
||||
impl TokenRange {
|
||||
pub fn as_meta(self, module: SourceModuleId) -> Metadata {
|
||||
Metadata {
|
||||
range: self,
|
||||
source_module_id: module,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,14 +256,14 @@ pub enum FunctionDefinitionKind {
|
||||
impl FunctionDefinition {
|
||||
fn block_meta(&self) -> Metadata {
|
||||
match &self.kind {
|
||||
FunctionDefinitionKind::Local(block, _) => block.meta,
|
||||
FunctionDefinitionKind::Local(block, _) => block.meta.clone(),
|
||||
FunctionDefinitionKind::Extern(_) => Metadata::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn signature(&self) -> Metadata {
|
||||
match &self.kind {
|
||||
FunctionDefinitionKind::Local(_, metadata) => *metadata,
|
||||
FunctionDefinitionKind::Local(_, metadata) => metadata.clone(),
|
||||
FunctionDefinitionKind::Extern(_) => Metadata::default(),
|
||||
}
|
||||
}
|
||||
@ -288,6 +304,7 @@ pub enum TypeDefinitionKind {
|
||||
#[derive(Debug)]
|
||||
pub struct Module {
|
||||
pub name: String,
|
||||
pub module_id: SourceModuleId,
|
||||
pub imports: Vec<Import>,
|
||||
pub functions: Vec<FunctionDefinition>,
|
||||
pub typedefs: Vec<TypeDefinition>,
|
||||
|
@ -15,7 +15,13 @@ pub static STRINGS: &str = include_str!("../../reid_src/strings.reid");
|
||||
|
||||
#[test]
|
||||
fn array_compiles_well() {
|
||||
let module = assert_err(compile_module(ARRAY, "array".to_owned(), None, true));
|
||||
let module = assert_err(compile_module(
|
||||
ARRAY,
|
||||
"array".to_owned(),
|
||||
Default::default(),
|
||||
None,
|
||||
true,
|
||||
));
|
||||
|
||||
assert_err(perform_all_passes(&mut mir::Context {
|
||||
modules: vec![module],
|
||||
@ -28,6 +34,7 @@ fn fibonacci_compiles_well() {
|
||||
let module = assert_err(compile_module(
|
||||
FIBONACCI,
|
||||
"fibonacci".to_owned(),
|
||||
Default::default(),
|
||||
None,
|
||||
true,
|
||||
));
|
||||
@ -43,6 +50,7 @@ fn hello_world_compiles_well() {
|
||||
let module = assert_err(compile_module(
|
||||
HELLO_WORLD,
|
||||
"hello_world".to_owned(),
|
||||
Default::default(),
|
||||
None,
|
||||
true,
|
||||
));
|
||||
@ -55,7 +63,13 @@ fn hello_world_compiles_well() {
|
||||
|
||||
#[test]
|
||||
fn mutable_compiles_well() {
|
||||
let module = assert_err(compile_module(MUTABLE, "mutable".to_owned(), None, true));
|
||||
let module = assert_err(compile_module(
|
||||
MUTABLE,
|
||||
"mutable".to_owned(),
|
||||
Default::default(),
|
||||
None,
|
||||
true,
|
||||
));
|
||||
|
||||
assert_err(perform_all_passes(&mut mir::Context {
|
||||
modules: vec![module],
|
||||
@ -65,7 +79,13 @@ fn mutable_compiles_well() {
|
||||
|
||||
#[test]
|
||||
fn strings_compiles_well() {
|
||||
let module = assert_err(compile_module(STRINGS, "strings".to_owned(), None, true));
|
||||
let module = assert_err(compile_module(
|
||||
STRINGS,
|
||||
"strings".to_owned(),
|
||||
Default::default(),
|
||||
None,
|
||||
true,
|
||||
));
|
||||
|
||||
assert_err(perform_all_passes(&mut mir::Context {
|
||||
modules: vec![module],
|
||||
|
@ -8,12 +8,12 @@ mod util;
|
||||
|
||||
#[test]
|
||||
fn compiles() {
|
||||
let _ = compile_std();
|
||||
let _ = compile_std(Default::default());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn passes_all_passes() {
|
||||
let mut std = compile_std();
|
||||
let mut std = compile_std(Default::default());
|
||||
|
||||
// Needed to pass linker-pass
|
||||
std.is_main = true;
|
||||
|
Loading…
Reference in New Issue
Block a user