Skip to content

Commit

Permalink
Merge pull request #93 from lambdaclass/add_structs_ir
Browse files Browse the repository at this point in the history
Implement structs and more type checks
  • Loading branch information
igaray authored Mar 7, 2024
2 parents a2be823 + 3de8742 commit 8daf8cb
Show file tree
Hide file tree
Showing 31 changed files with 954 additions and 304 deletions.
223 changes: 120 additions & 103 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ test: check-deps
cargo test --workspace --all-targets --all-features

coverage: check-deps
cargo llvm-cov --verbose --all-features --workspace --lcov --output-path lcov.info
cargo llvm-cov --verbose --all-features --all-targets --workspace --lcov --output-path lcov.info
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,30 @@ mod Fibonacci {
}
```

```rust
mod StructExample {
struct Foo {
bar: i32,
baz: i64,
}

fn main() -> i32 {
let mut foo: Foo = Foo {
bar: 2,
baz: 3,
};

foo.bar = foo.bar * 2;

return get_foo_field_by_borrow(&foo) + foo.bar;
}

fn get_foo_field_by_borrow(x: &Foo) -> i32 {
return x.bar;
}
}
```

```rust
mod Option {
pub enum Option<T> {
Expand Down Expand Up @@ -205,8 +229,8 @@ Features:
- imports ✔️
- floats ✔️
- borrowing ✔️
- structs 🏗
- arrays :x:
- structs
- arrays 🏗️
- iterators :x:
- for :x:
- match :x:
Expand Down
7 changes: 5 additions & 2 deletions crates/concrete_ast/src/common.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::ops::Range;

use crate::types::TypeSpec;

#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Span {
pub from: usize,
Expand Down Expand Up @@ -29,8 +31,9 @@ pub struct Ident {
pub span: Span,
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct GenericParam {
pub name: Ident,
pub params: Vec<Ident>,
pub params: Vec<TypeSpec>,
pub span: Span,
}
29 changes: 25 additions & 4 deletions crates/concrete_ast/src/expressions.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
use std::collections::HashMap;

use crate::{
common::Ident,
common::{Ident, Span},
statements::Statement,
types::{RefType, TypeSpec},
};

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Expression {
Value(ValueExpr),
Value(ValueExpr, Span),
FnCall(FnCallOp),
Match(MatchExpr),
If(IfExpr),
UnaryOp(UnaryOp, Box<Self>),
BinaryOp(Box<Self>, BinaryOp, Box<Self>),
StructInit(StructInitExpr),
Deref(Box<Self>),
AsRef(Box<Self>, RefType),
}
Expand All @@ -26,6 +29,19 @@ pub enum ValueExpr {
Path(PathOp),
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StructInitExpr {
pub name: Ident,
pub fields: HashMap<Ident, StructInitField>,
pub span: Span,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StructInitField {
pub value: Expression,
pub span: Span,
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum UnaryOp {
ArithNeg,
Expand Down Expand Up @@ -77,31 +93,35 @@ pub enum BitwiseOp {
pub struct MatchExpr {
pub value: Box<Expression>,
pub variants: Vec<MatchVariant>,
pub span: Span,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct IfExpr {
pub value: Box<Expression>,
pub contents: Vec<Statement>,
pub r#else: Option<Vec<Statement>>,
pub span: Span,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct MatchVariant {
pub case: ValueExpr,
pub block: Vec<Statement>,
pub span: Span,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum PathSegment {
FieldAccess(Ident),
ArrayIndex(ValueExpr),
FieldAccess(Ident, Span),
ArrayIndex(ValueExpr, Span),
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct PathOp {
pub first: Ident,
pub extra: Vec<PathSegment>,
pub span: Span,
}

#[derive(Clone, Debug, Eq, PartialEq)]
Expand All @@ -114,4 +134,5 @@ pub struct CastOp {
pub struct FnCallOp {
pub target: Ident,
pub args: Vec<Expression>,
pub span: Span,
}
4 changes: 3 additions & 1 deletion crates/concrete_ast/src/statements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ pub struct LetStmt {
pub is_mutable: bool,
pub target: LetStmtTarget,
pub value: Expression,
pub span: Span,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ReturnStmt {
pub value: Expression,
pub value: Option<Expression>,
pub span: Span,
}

#[derive(Clone, Debug, Eq, PartialEq)]
Expand Down
8 changes: 4 additions & 4 deletions crates/concrete_ast/src/structs.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
use crate::{
common::{DocString, GenericParam, Ident},
common::{GenericParam, Ident, Span},
types::TypeSpec,
};

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct StructDecl {
pub doc_string: Option<DocString>,
pub name: Ident,
pub type_params: Vec<GenericParam>,
pub generics: Vec<GenericParam>,
pub fields: Vec<Field>,
pub span: Span,
}

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Field {
pub doc_string: Option<DocString>,
pub name: Ident,
pub r#type: TypeSpec,
pub span: Span,
}
53 changes: 47 additions & 6 deletions crates/concrete_check/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub fn lowering_error_to_report(
LoweringError::ModuleNotFound { span, module } => {
let offset = span.from;
Report::build(ReportKind::Error, path.clone(), offset)
.with_code("E1")
.with_code("ModuleNotFound")
.with_label(
Label::new((path, span.into()))
.with_message(format!("Module {module:?} not found."))
Expand All @@ -27,18 +27,28 @@ pub fn lowering_error_to_report(
}
LoweringError::FunctionNotFound { span, function } => {
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("EFNNOTFOUND")
.with_code("FunctionNotFound")
.with_label(
Label::new((path, span.into()))
.with_message(format!("Function {function:?} not found."))
.with_color(colors.next()),
)
.finish()
},
LoweringError::StructFieldNotFound { span, name } => {
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("StructFieldNotFound")
.with_label(
Label::new((path, span.into()))
.with_message(format!("Struct field {name:?} not found."))
.with_color(colors.next()),
)
.finish()
},
LoweringError::ImportNotFound { import_span, module_span, symbol } => {
let offset = symbol.span.from;
Report::build(ReportKind::Error, path.clone(), offset)
.with_code("E2")
.with_code("ImportNotFound")
.with_label(
Label::new((path.clone(), module_span.into()))
.with_message("In module this module."),
Expand Down Expand Up @@ -69,13 +79,13 @@ pub fn lowering_error_to_report(
}

Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("EREFMUT")
.with_code("BorrowNotMutable")
.with_labels(labels)
.finish()
},
LoweringError::UnrecognizedType { span, name } => {
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("E3")
.with_code("UnrecognizedType")
.with_label(
Label::new((path, span.into()))
.with_message(format!("Failed to find type {:?}", name))
Expand All @@ -97,13 +107,44 @@ pub fn lowering_error_to_report(
},
LoweringError::NotYetImplemented { span, message } => {
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("TODO")
.with_code("NotYetImplemented")
.with_label(
Label::new((path, span.into()))
.with_message(message)
.with_color(colors.next()),
)
.finish()
},
LoweringError::UnexpectedType { span, found, expected } => {
let mut labels = vec![
Label::new((path.clone(), span.into()))
.with_message(format!("Unexpected type '{}', expected '{}'", found, expected.kind))
.with_color(colors.next())
];

if let Some(span) = expected.span {
labels.push(
Label::new((path.clone(), span.into()))
.with_message(format!("expected '{}' due to this type", expected.kind))
.with_color(colors.next())
);
}

Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("UnexpectedType")
.with_labels(labels)
.with_message(format!("expected type {}.", expected.kind))
.finish()
},
LoweringError::UseOfUndeclaredVariable { span, name } => {
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("UseOfUndeclaredVariable")
.with_label(
Label::new((path, span.into()))
.with_message(format!("Use of undeclared variable {:?}", name))
.with_color(colors.next()),
)
.finish()
},
}
}
2 changes: 1 addition & 1 deletion crates/concrete_codegen_mlir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ concrete_check = { version = "0.1.0", path = "../concrete_check" }
concrete_session = { path = "../concrete_session"}
itertools = "0.12.0"
llvm-sys = "170.0.1"
melior = { version = "0.16.0", features = ["ods-dialects"] }
melior = { version = "0.16.2", features = ["ods-dialects"] }
mlir-sys = "0.2.1"
tracing = { workspace = true }
thiserror = "1.0.57"
Expand Down
Loading

0 comments on commit 8daf8cb

Please sign in to comment.