Skip to content

Commit 3888afd

Browse files
committed
fix 'cd' command
1 parent f2cc6a8 commit 3888afd

9 files changed

Lines changed: 369 additions & 243 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ a.out
1414
moshell
1515
*.bin
1616
completions
17+
sandbox

analyzer/src/hir.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use crate::module::Export;
2+
use crate::symbol::SymbolRegistry;
13
use crate::typing::registry::{FunctionId, SchemaId};
24
use crate::typing::user::{TypeId, ERROR_TYPE, UNIT_TYPE, UNKNOWN_TYPE};
35
use crate::typing::variable::{LocalEnvironment, LocalId, Var};
@@ -191,7 +193,7 @@ impl TypedExpr {
191193
}
192194
}
193195

194-
/// A unit of code.
196+
/// An unit of code.
195197
pub struct Chunk {
196198
/// The fully qualified name to access this chunk.
197199
pub fqn: PathBuf,

analyzer/src/hoist.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub(super) fn hoist_files(
6060
requires: Vec::new(),
6161
};
6262
hoist_type_names(root, checker, &mut table, &mut exports);
63-
hoist_functions(
63+
hoist_signatures(
6464
root,
6565
checker,
6666
&mut table,
@@ -154,8 +154,8 @@ fn hoist_type_names(
154154
}
155155
}
156156
}
157-
158-
fn hoist_functions(
157+
/// hoists functions, structures and implementations
158+
fn hoist_signatures(
159159
root: &[Expr],
160160
checker: &mut TypeChecker,
161161
table: &mut SymbolTable,
@@ -255,6 +255,7 @@ fn hoist_functions(
255255
}
256256
}
257257
}
258+
//TODO implement recursive operation
258259
Import::AllIn(_, _) => {}
259260
Import::Environment(_) => {}
260261
Import::List(_) => {}
@@ -269,9 +270,9 @@ fn hoist_functions(
269270
}
270271
}
271272

272-
struct CurrentType {
273-
current_ty: TypeId,
274-
current_generics: Vec<TypeId>,
273+
struct SelfType {
274+
self_ty: TypeId,
275+
self_generics: Vec<TypeId>,
275276
}
276277

277278
fn hoist_fn_decl(
@@ -283,17 +284,17 @@ fn hoist_fn_decl(
283284
return_type,
284285
..
285286
}: &FunctionDeclaration,
286-
current_ty: Option<CurrentType>,
287+
self_ty: Option<SelfType>,
287288
checker: &mut TypeChecker,
288289
table: &mut SymbolTable,
289290
exports: &mut [Export],
290291
errors: &mut Vec<TypeError>,
291292
) {
292293
table.enter_scope();
293-
let (current_ty, mut generic_variables) = match current_ty {
294-
Some(CurrentType {
295-
current_ty,
296-
current_generics,
294+
let (current_ty, mut generic_variables) = match self_ty {
295+
Some(SelfType {
296+
self_ty: current_ty,
297+
self_generics: current_generics,
297298
}) => (Some(current_ty), current_generics),
298299
None => (None, Vec::new()),
299300
};
@@ -510,9 +511,9 @@ fn hoist_impl_decl(
510511
};
511512
if impl_ty.is_ok() {
512513
for function in functions {
513-
let current = CurrentType {
514-
current_ty: impl_ty,
515-
current_generics: generic_variables.clone(),
514+
let current = SelfType {
515+
self_ty: impl_ty,
516+
self_generics: generic_variables.clone(),
516517
};
517518
hoist_fn_decl(function, Some(current), checker, table, exports, errors);
518519
}

analyzer/src/module.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::{Filesystem, PipelineError, Reef, SourceLocation, UnitKey};
2121
use ast::call::ProgrammaticCall;
2222
use ast::function::FunctionDeclaration;
2323
use ast::r#use::{Import as ImportExpr, ImportList, ImportedSymbol, InclusionPathItem, Use};
24-
use ast::variable::VarDeclaration;
24+
use ast::variable::{Identifier, VarDeclaration};
2525
use ast::Expr;
2626
use context::source::{SourceSegment, SourceSegmentHolder, Span};
2727
use parser::err::ParseError;
@@ -242,6 +242,12 @@ impl ModuleTree {
242242
}
243243
std::mem::take(&mut current.exports)
244244
}
245+
246+
pub fn find_export(&self, name: &str, symbol_registry: SymbolRegistry) -> Option<&Export> {
247+
self.exports
248+
.iter()
249+
.find(|e| e.name == name && e.registry == symbol_registry)
250+
}
245251
}
246252

247253
pub(crate) struct ImportResult {
@@ -278,6 +284,15 @@ impl<'a> ModuleView<'a> {
278284
}
279285
Some(tree)
280286
}
287+
288+
pub(crate) fn get_foreign(&self, path: &[&str]) -> Option<&ModuleTree> {
289+
let (first, rest) = path.split_first().expect("path should not be empty");
290+
let tree = self.foreign.get(OsStr::new(first))?;
291+
292+
rest.iter().fold(Some(tree), |acc, it| {
293+
acc.and_then(|tree| tree.get(OsStr::new(it)))
294+
})
295+
}
281296
}
282297

283298
/// Access all related files starting from the entrypoint.

analyzer/src/typing.rs

Lines changed: 3 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ mod flow;
33
pub mod function;
44
mod lower;
55
mod operator;
6+
mod pfc;
67
pub mod registry;
78
pub mod schema;
89
mod shell;
@@ -19,6 +20,7 @@ use crate::typing::flow::{ascribe_control, ascribe_while};
1920
use crate::typing::function::Function;
2021
use crate::typing::lower::{ascribe_template_string, coerce_condition};
2122
use crate::typing::operator::ascribe_binary;
23+
use crate::typing::pfc::ascribe_pfc;
2224
use crate::typing::registry::{FunctionId, Registry, SchemaId};
2325
use crate::typing::schema::Schema;
2426
use crate::typing::shell::{
@@ -490,186 +492,8 @@ fn ascribe_type(
490492
Expr::Parenthesis(paren) => {
491493
ascribe_type(&paren.expression, table, checker, storage, ctx, errors)
492494
}
493-
Expr::ProgrammaticCall(ProgrammaticCall {
494-
path,
495-
arguments,
496-
type_parameters,
497-
segment: span,
498-
}) => {
499-
let arguments = arguments
500-
.iter()
501-
.map(|expr| ascribe_type(expr, table, checker, storage, ctx, errors))
502-
.collect::<Vec<_>>();
503-
let ty = lookup_path(
504-
path,
505-
SymbolRegistry::Function,
506-
table,
507-
checker,
508-
modules,
509-
errors,
510-
);
511-
if ty.is_err() {
512-
return TypedExpr {
513-
kind: ExprKind::Noop,
514-
span: span.clone(),
515-
ty: ERROR_TYPE,
516-
};
517-
}
518-
let mut type_parameters = type_parameters
519-
.iter()
520-
.map(|type_param| lookup_type(type_param, table, checker, modules, errors))
521-
.collect::<Vec<TypeId>>();
522-
let UserType::Function(function) = checker.types[ty] else {
523-
panic!(
524-
"function should have a function type {ty:?} {:?}",
525-
&checker.types[ty]
526-
);
527-
};
528-
let Function {
529-
ref declared_at,
530-
fqn: _,
531-
ref generic_variables,
532-
ref param_types,
533-
return_type,
534-
kind: _,
535-
} = checker.registry[function];
536-
let mut return_type = return_type;
537-
if type_parameters.is_empty() && !generic_variables.is_empty() {
538-
// Try to infer the generic types from the actual arguments
539-
type_parameters = vec![UNKNOWN_TYPE; generic_variables.len()];
540-
for (arg, param) in arguments.iter().zip(param_types.iter()) {
541-
if let Some(generic_variable) =
542-
generic_variables.iter().position(|&ty| ty == param.ty)
543-
{
544-
if type_parameters[generic_variable] != UNKNOWN_TYPE
545-
&& type_parameters[generic_variable] != arg.ty
546-
{
547-
errors.push(TypeError::new(
548-
TypeErrorKind::TypeMismatch {
549-
expected: checker.display(type_parameters[generic_variable]),
550-
expected_due_to: None,
551-
actual: checker.display(arg.ty),
552-
},
553-
SourceLocation::new(table.path().to_owned(), arg.span.clone()),
554-
));
555-
} else {
556-
type_parameters[generic_variable] = arg.ty;
557-
}
558-
} else if let UserType::Parametrized {
559-
schema: param_schema,
560-
params: param_params,
561-
..
562-
} = &checker.types[param.ty]
563-
{
564-
if let UserType::Parametrized {
565-
schema,
566-
params: arg_params,
567-
} = &checker.types[arg.ty]
568-
{
569-
if schema == param_schema {
570-
for param_param in param_params {
571-
if let Some(idx) =
572-
generic_variables.iter().position(|&ty| ty == *param_param)
573-
{
574-
type_parameters[idx].define_if_absent(arg_params[idx]);
575-
}
576-
}
577-
}
578-
}
579-
}
580-
}
581-
if let TypeHint::Required(expected_return_ty) = hint {
582-
if let Some(idx) = generic_variables.iter().position(|&ty| ty == return_type) {
583-
type_parameters[idx].define_if_absent(expected_return_ty);
584-
} else if let UserType::Parametrized {
585-
schema: expected_schema,
586-
params: expected_params,
587-
..
588-
} = &checker.types[expected_return_ty]
589-
{
590-
if let UserType::Parametrized {
591-
schema,
592-
params: fn_return_params,
593-
} = &checker.types[return_type]
594-
{
595-
if schema == expected_schema {
596-
// First, get the index of the generic_variables in the return_params list
597-
for (fn_return_param, fn_actual) in
598-
fn_return_params.iter().zip(expected_params)
599-
{
600-
if let Some(generic_idx) = generic_variables
601-
.iter()
602-
.position(|&ty| ty == *fn_return_param)
603-
{
604-
type_parameters[generic_idx].define_if_absent(*fn_actual);
605-
}
606-
}
607-
}
608-
}
609-
}
610-
}
611-
if type_parameters.iter().any(|ty| *ty == UNKNOWN_TYPE) {
612-
errors.push(TypeError::new(
613-
TypeErrorKind::TypeAnnotationRequired {
614-
types: generic_variables
615-
.iter()
616-
.map(|ty| checker.display(*ty))
617-
.collect(),
618-
insert_at: path
619-
.last()
620-
.expect("path should have at least one item")
621-
.segment()
622-
.end,
623-
},
624-
SourceLocation::new(table.path().to_owned(), span.clone()),
625-
));
626-
return_type = ERROR_TYPE;
627-
}
628-
}
629-
630-
if arguments.len() != param_types.len() {
631-
errors.push(TypeError::new(
632-
TypeErrorKind::ArityMismatch {
633-
expected: param_types.len(),
634-
received: arguments.len(),
635-
},
636-
SourceLocation::new(table.path().to_owned(), span.clone()),
637-
));
638-
} else {
639-
for (arg, param) in arguments.iter().zip(param_types.iter()) {
640-
let param_ty =
641-
checker
642-
.types
643-
.concretize(param.ty, generic_variables, &type_parameters);
644-
if let Err(_) = checker.types.unify(arg.ty, param_ty) {
645-
errors.push(TypeError::new(
646-
TypeErrorKind::TypeMismatch {
647-
expected: checker.display(param_ty),
648-
expected_due_to: Some(SourceLocation::new(
649-
declared_at.clone(),
650-
param.span.clone(),
651-
)),
652-
actual: checker.display(arg.ty),
653-
},
654-
SourceLocation::new(table.path().to_owned(), arg.span.clone()),
655-
));
656-
}
657-
}
658-
}
659-
return_type =
660-
checker
661-
.types
662-
.concretize(return_type, generic_variables, &type_parameters);
663-
TypedExpr {
664-
kind: ExprKind::FunctionCall(FunctionCall {
665-
arguments,
666-
function_id: function,
667-
}),
668-
span: span.clone(),
669-
ty: return_type,
670-
}
671-
}
672495
Expr::StructDeclaration(decl) => TypedExpr::noop(decl.segment.clone()),
496+
Expr::ProgrammaticCall(call) => ascribe_pfc(call, table, checker, storage, ctx, errors),
673497
Expr::FieldAccess(FieldAccess {
674498
expr,
675499
field,

0 commit comments

Comments
 (0)