Skip to content

Commit

Permalink
feat-types
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit cbdda4ff7614bee711d785036544b867f981c0bc
Merge: b898560f 6fa675e
Author: Aljaž Mur Eržen <[email protected]>
Date:   Mon Jul 22 16:43:16 2024 +0200

    Merge branch 'main' into feat-indirections

commit b898560f3e93f13be9c452f85fac36e5e1ae4a7b
Merge: 96844669 755811b0
Author: Aljaž Mur Eržen <[email protected]>
Date:   Wed Jun 26 11:42:24 2024 +0200

    merge main into feat-types

commit 755811b0f56e3d359a97f67881998c88523dad2e
Author: Aljaž Mur Eržen <[email protected]>
Date:   Wed Jun 26 10:52:47 2024 +0200

    Revert "chore: Move `db.` to a new branch (#4349)"

    This reverts commit 76c4f76.

commit 96844669f9c834fe43d18b79a79ceebe588ce6f0
Author: Aljaž Mur Eržen <[email protected]>
Date:   Fri Jun 14 09:31:57 2024 +0200

    fix: infer types for empty arrays

commit 70fd898c8c231c895cab9f3e033b9ef42127a9c4
Merge: e71ae6dd 80e4a1d7
Author: Aljaž Mur Eržen <[email protected]>
Date:   Fri Jun 14 09:20:11 2024 +0200

    merge main into feat-types

commit 80e4a1d7f50e95fecc51100353919d33e754cf2a
Author: Aljaž Mur Eržen <[email protected]>
Date:   Sat Jun 1 18:59:48 2024 +0200

    Revert "chore: Move `db.` to a new branch (#4349)"

    This reverts commit 76c4f76.

commit e71ae6dd4f5eda78472d6ad5fe65555c6bce4597
Author: Aljaž Mur Eržen <[email protected]>
Date:   Sun Jun 2 20:28:46 2024 +0200

    fix: tuple type checking

commit f0627d9
Merge: 041310e f0fd93b
Author: Aljaž Mur Eržen <[email protected]>
Date:   Sat Jun 1 19:29:53 2024 +0200

    merge main into feat-types

commit f0fd93b
Author: Aljaž Mur Eržen <[email protected]>
Date:   Sat Jun 1 18:59:48 2024 +0200

    Revert "chore: Move `db.` to a new branch (#4349)"

    This reverts commit 76c4f76.

commit 041310e
Author: Aljaž Mur Eržen <[email protected]>
Date:   Sun May 19 16:39:12 2024 +0200

    refactor: minor cleanup

commit 5867f62
Author: Aljaž Mur Eržen <[email protected]>
Date:   Sun May 19 16:36:24 2024 +0200

    fix: lowering aggregate

commit 2e67021
Author: Aljaž Mur Eržen <[email protected]>
Date:   Sun May 19 13:51:02 2024 +0200

    refactor: scope

commit fff7a75
Author: Aljaž Mur Eržen <[email protected]>
Date:   Sun May 19 12:14:32 2024 +0200

    feat: infer type as array

commit 87df34f
Author: Aljaž Mur Eržen <[email protected]>
Date:   Wed May 15 21:43:20 2024 +0200

    fix: organize tests, minor fixes

commit d855aa9
Author: Aljaž Mur Eržen <[email protected]>
Date:   Wed May 15 20:38:40 2024 +0200

    fix: excluding fields

commit 1980e03
Author: Aljaž Mur Eržen <[email protected]>
Date:   Wed May 15 19:31:48 2024 +0200

    refactor: cleanup TyFunc

commit 39cb797
Author: Aljaž Mur Eržen <[email protected]>
Date:   Wed May 15 19:17:47 2024 +0200

    feat: nested tuple indirection

commit f5fa4f3
Author: Aljaž Mur Eržen <[email protected]>
Date:   Tue May 14 14:27:45 2024 +0200

    refactor: resolving tuple indirection

commit 043047e
Author: Aljaž Mur Eržen <[email protected]>
Date:   Tue May 14 14:04:22 2024 +0200

    feat: lowering for rq operators and relational literals

commit 35eeb84
Author: Aljaž Mur Eržen <[email protected]>
Date:   Tue May 14 12:13:06 2024 +0200

    feat: finalize global generics after each stmt

commit 983c085
Author: Aljaž Mur Eržen <[email protected]>
Date:   Tue May 14 11:58:50 2024 +0200

    refactor: cleanup LayeredModules

commit 4b060ef
Author: Aljaž Mur Eržen <[email protected]>
Date:   Tue May 14 11:42:26 2024 +0200

    refactor: lowering

commit 9d37888
Author: Aljaž Mur Eržen <[email protected]>
Date:   Tue May 14 10:39:04 2024 +0200

    feat: create generics for all unknown types

commit f13c93d
Author: Aljaž Mur Eržen <[email protected]>
Date:   Mon May 13 20:19:25 2024 +0200

    refactor: remove DeclKind::TableDecl in favor DeclKind::Expr

commit f5d2588
Author: Aljaž Mur Eržen <[email protected]>
Date:   Mon May 13 19:52:06 2024 +0200

    fix: relational functions

commit 6990ff8
Author: Aljaž Mur Eržen <[email protected]>
Date:   Mon May 13 18:40:17 2024 +0200

    fix: lowering and special_functions

commit 5120b9a
Author: Aljaž Mur Eržen <[email protected]>
Date:   Mon May 13 18:17:25 2024 +0200

    feat: local scopes instead of modules

commit 1631528
Author: Aljaž Mur Eržen <[email protected]>
Date:   Mon May 13 13:52:47 2024 +0200

    refactor: move table inference into name resolver

commit db27409
Author: Aljaž Mur Eržen <[email protected]>
Date:   Mon May 13 12:47:25 2024 +0200

    feat: unpack must come last

commit 43255ec
Author: Aljaž Mur Eržen <[email protected]>
Date:   Mon May 13 12:10:04 2024 +0200

    feat!: forbid functions without paramaters

commit 85da349
Author: Aljaž Mur Eržen <[email protected]>
Date:   Sun May 12 12:08:05 2024 +0200

    ignore failed tests

commit 17af072
Author: Aljaž Mur Eržen <[email protected]>
Date:   Mon Apr 15 19:20:12 2024 +0200

    feat: resolve functions without inlining

commit e1ebdc4
Author: Aljaž Mur Eržen <[email protected]>
Date:   Mon Apr 15 15:35:27 2024 +0200

    feat: split pl::FuncApplication from pl::Func

commit 98e26f0
Author: Aljaž Mur Eržen <[email protected]>
Date:   Mon Apr 15 13:19:48 2024 +0200

    refactor: cosmetic tweaks for types

commit 4319c04
Author: Aljaž Mur Eržen <[email protected]>
Date:   Sun Apr 14 20:50:14 2024 +0200

    feat: inference between generics

commit e4f4e40
Author: Aljaž Mur Eržen <[email protected]>
Date:   Sun Apr 14 19:49:57 2024 +0200

    refactor: merge local and global _generic modules

commit 5e5c015
Author: Aljaž Mur Eržen <[email protected]>
Date:   Sun Apr 14 10:45:36 2024 +0200

    refactor: validate_type

commit b8f9895
Author: Aljaž Mur Eržen <[email protected]>
Date:   Thu Apr 4 13:24:04 2024 +0200

    feat: move flatten and special functions into lowering

commit 6d11a77
Author: Aljaž Mur Eržen <[email protected]>
Date:   Thu Apr 4 11:00:25 2024 +0200

    feat: ty tuple exclude

commit 33415ce
Author: Aljaž Mur Eržen <[email protected]>
Date:   Wed Apr 3 12:40:59 2024 +0200

    refactors and fixes

commit 03c6f51
Author: Aljaž Mur Eržen <[email protected]>
Date:   Wed Apr 3 10:04:01 2024 +0200

    fmt

commit ac36f23
Author: Aljaž Mur Eržen <[email protected]>
Date:   Tue Apr 2 13:51:09 2024 +0200

    fix: a few tests

commit f6c29cf
Author: Aljaž Mur Eržen <[email protected]>
Date:   Sun Mar 31 12:23:42 2024 +0200

    feat: global generic arguments for table inference

commit 2d47aeb
Author: Aljaž Mur Eržen <[email protected]>
Date:   Fri Mar 29 16:05:11 2024 +0100

    refactor: generic type parameters

commit 3eac276
Author: Aljaž Mur Eržen <[email protected]>
Date:   Fri Mar 29 15:42:47 2024 +0100

    cleanup inference

commit 2de7286
Author: Aljaž Mur Eržen <[email protected]>
Date:   Fri Mar 29 14:06:38 2024 +0100

    feat: tuple unpacking

commit b33153f
Author: Aljaž Mur Eržen <[email protected]>
Date:   Fri Mar 29 13:14:22 2024 +0100

    feat: wildcard includes and excludes

commit 9aa3397
Author: Aljaž Mur Eržen <[email protected]>
Date:   Fri Mar 29 11:54:19 2024 +0100

    feat: implicit closures and joins

commit 2b3233a
Author: Aljaž Mur Eržen <[email protected]>
Date:   Thu Mar 28 16:53:56 2024 +0100

    feat: remove obsolete type machinery

    This includes:
    - TypeKind::Singleton,
    - TypeKind::Union,
    - type normalization,
    - subtyping,

    This commit also:
    - changes syntax for generic type arguments,
    - adds type annotations to transforms,

    Many tests now fail.

commit 107c22e
Author: Aljaž Mur Eržen <[email protected]>
Date:   Thu Mar 28 12:24:03 2024 +0100

    more lowering & test cases

commit a8040ce
Author: Aljaž Mur Eržen <[email protected]>
Date:   Thu Mar 28 11:49:05 2024 +0100

    feat: rewire lowering to work with indirections

commit 4c53729
Author: Aljaž Mur Eržen <[email protected]>
Date:   Fri Feb 16 19:24:55 2024 +0100

    feat: indirection

commit 43bb7a7
Author: Aljaž Mur Eržen <[email protected]>
Date:   Thu Apr 4 13:27:22 2024 +0200

    refactor: remove `debug eval` command

commit 2e9795d
Author: Aljaž Mur Eržen <[email protected]>
Date:   Thu Mar 28 14:27:20 2024 +0100

    refactor: minor changes to lowering (#4364)

commit 125aafb
Author: Aljaž Mur Eržen <[email protected]>
Date:   Mon Mar 25 17:19:58 2024 +0100

    feat!: resolve declaration names before the resolver (#4353)

commit 7dbe057
Author: Aljaž Mur Eržen <[email protected]>
Date:   Mon Mar 25 14:21:41 2024 +0100

    build: test for feat-types

commit ee6b2ce
Author: Aljaž Mur Eržen <[email protected]>
Date:   Mon Mar 25 12:30:38 2024 +0100

    feat: indirection parsing (#4356)
  • Loading branch information
aljazerzen committed Sep 2, 2024
1 parent 9027941 commit 13b50d1
Show file tree
Hide file tree
Showing 54 changed files with 6,063 additions and 5,815 deletions.
12 changes: 3 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ members = [
"prqlc/prqlc-macros",
"prqlc/prqlc-parser",
"prqlc/prqlc",
"prqlc/prqlc/examples/compile-files", # An example
"lutra/lutra",
"lutra/bindings/python",
"web/book",
Expand Down
25 changes: 24 additions & 1 deletion prqlc/Taskfile.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,44 @@ tasks:
--ignore-unknown \
--log-level=warn
fmt-check:
desc: Validate that source files are formatted
cmds:
- cargo fmt --check {{.packages_core}} {{.packages_addon}}
{{.packages_bindings}}

test-fast:
desc: A fast test used for feedback during compiler development
cmds:
- cmd: |
INSTA_FORCE_PASS=1 cargo nextest run {{.packages_core}} --no-fail-fast
INSTA_FORCE_PASS=1 cargo nextest run {{.packages_core}} -- {{.CLI_ARGS}}
- cmd: cargo insta review

- cmd: cargo clippy --all-targets {{.packages_core}}

test-types:
desc:
A subset of tests that should work on feat-types
cmds:
- cmd: |
INSTA_FORCE_PASS=1 cargo nextest run --package prqlc --test=integration -- sql:: resolving::
- cmd: cargo insta review

- cmd: cargo clippy --all-targets {{.packages_core}}

- cmd: |
echo -e '\n=======\nrunning just ignored tests, to see if any of them passes'
cargo nextest run --package prqlc --test=integration --run-ignored=ignored-only --success-output=never --failure-output=never --status-level=pass --final-status-level=none -- sql:: resolving::
test:
desc: |
A full test of prqlc (excluding --test-dbs-external).
Generates coverage report.
cmds:
- task: fmt-check

- cmd: |
cargo \
llvm-cov --lcov --output-path lcov.info \
Expand Down
10 changes: 6 additions & 4 deletions prqlc/prqlc-parser/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,9 +481,8 @@ where
.then(ctrl(':').ignore_then(expr.clone().map(Box::new)).or_not());

let generic_args = ident_part()
.then_ignore(ctrl(':'))
.then(type_expr().separated_by(ctrl('|')))
.map(|(name, domain)| GenericTypeParam { name, domain })
.then(ctrl(':').ignore_then(type_expr()).or_not())
.map(|(name, bound)| GenericTypeParam { name, bound })
.separated_by(ctrl(','))
.at_least(1)
.delimited_by(ctrl('<'), ctrl('>'))
Expand All @@ -500,7 +499,10 @@ where
.allow_trailing(),
),
// plain
param.repeated().map(|params| (Vec::new(), params)),
param
.repeated()
.at_least(1)
.map(|params| (Vec::new(), params)),
))
.then_ignore(just(TokenKind::ArrowThin))
// return type
Expand Down
2 changes: 1 addition & 1 deletion prqlc/prqlc-parser/src/parser/pr/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ pub struct GenericTypeParam {
/// Assigned name of this generic type argument.
pub name: String,

pub domain: Vec<Ty>,
pub bound: Option<Ty>,
}

/// A value and a series of functions that are to be applied to that value one after another.
Expand Down
50 changes: 17 additions & 33 deletions prqlc/prqlc-parser/src/parser/pr/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use strum::AsRefStr;

use crate::lexer::lr::Literal;
use crate::parser::pr::ident::Ident;
use crate::parser::pr::expr::GenericTypeParam;
use crate::span::Span;

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct Ty {
pub kind: TyKind,

Expand All @@ -25,12 +25,6 @@ pub enum TyKind {
/// Type of a built-in primitive type
Primitive(PrimitiveSet),

/// Type that contains only a one value
Singleton(Literal),

/// Union of sets (sum)
Union(Vec<(Option<String>, Ty)>),

/// Type of tuples (product)
Tuple(Vec<TyTupleField>),

Expand All @@ -40,15 +34,9 @@ pub enum TyKind {
/// Type of functions with defined params and return types.
Function(Option<TyFunc>),

/// Type of every possible value. Super type of all other types.
/// The breaker of chains. Mother of types.
Any,

/// Type that is the largest subtype of `base` while not a subtype of `exclude`.
Difference { base: Box<Ty>, exclude: Box<Ty> },

/// A generic argument. Contains id of the function call node and generic type param name.
GenericArg((usize, String)),
/// Tuples that have fields of `base` tuple, but don't have fields of `except` tuple.
/// Implies that `base` has all fields of `except`.
Exclude { base: Box<Ty>, except: Box<Ty> },
}

impl TyKind {
Expand All @@ -66,9 +54,11 @@ pub enum TyTupleField {
/// Named tuple element.
Single(Option<String>, Option<Ty>),

/// Placeholder for possibly many elements.
/// Means "and other unmentioned columns". Does not mean "all columns".
Wildcard(Option<Ty>),
/// Many tuple elements contained in a type that must eventually resolve to a tuple.
/// In most cases, this starts as a generic type argument.
// TODO: make this non-optional Ty
// TODO: merge this into TyTuple (that does not exist at the moment)
Unpack(Option<Ty>),
}

/// Built-in sets.
Expand Down Expand Up @@ -103,9 +93,11 @@ pub enum PrimitiveSet {
// Type of a function
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct TyFunc {
pub name_hint: Option<Ident>,
pub params: Vec<Option<Ty>>,

pub return_ty: Option<Box<Ty>>,

pub generic_type_params: Vec<GenericTypeParam>,
}

impl Ty {
Expand All @@ -122,14 +114,6 @@ impl Ty {
Ty::new(TyKind::Array(Box::new(tuple)))
}

pub fn never() -> Self {
Ty::new(TyKind::Union(Vec::new()))
}

pub fn is_never(&self) -> bool {
self.kind.as_union().map_or(false, |x| x.is_empty())
}

pub fn as_relation(&self) -> Option<&Vec<TyTupleField>> {
self.kind.as_array()?.kind.as_tuple()
}
Expand All @@ -156,7 +140,7 @@ impl TyTupleField {
pub fn ty(&self) -> Option<&Ty> {
match self {
TyTupleField::Single(_, ty) => ty.as_ref(),
TyTupleField::Wildcard(ty) => ty.as_ref(),
TyTupleField::Unpack(ty) => ty.as_ref(),
}
}
}
Expand All @@ -173,8 +157,8 @@ impl From<TyFunc> for TyKind {
}
}

impl From<Literal> for TyKind {
fn from(value: Literal) -> Self {
TyKind::Singleton(value)
impl PartialEq for Ty {
fn eq(&self, other: &Self) -> bool {
self.kind == other.kind && self.name == other.name
}
}
108 changes: 47 additions & 61 deletions prqlc/prqlc-parser/src/parser/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ use crate::lexer::lr::TokenKind;
pub(crate) fn type_expr() -> impl Parser<TokenKind, Ty, Error = PError> + Clone {
recursive(|nested_type_expr| {
let basic = select! {
TokenKind::Literal(lit) => TyKind::Singleton(lit),
// TokenKind::Literal(lit) => TyKind::Singleton(lit),
TokenKind::Ident(i) if i == "int"=> TyKind::Primitive(PrimitiveSet::Int),
TokenKind::Ident(i) if i == "float"=> TyKind::Primitive(PrimitiveSet::Float),
TokenKind::Ident(i) if i == "bool"=> TyKind::Primitive(PrimitiveSet::Bool),
TokenKind::Ident(i) if i == "text"=> TyKind::Primitive(PrimitiveSet::Text),
TokenKind::Ident(i) if i == "date"=> TyKind::Primitive(PrimitiveSet::Date),
TokenKind::Ident(i) if i == "time"=> TyKind::Primitive(PrimitiveSet::Time),
TokenKind::Ident(i) if i == "timestamp"=> TyKind::Primitive(PrimitiveSet::Timestamp),
TokenKind::Ident(i) if i == "anytype"=> TyKind::Any,
// TokenKind::Ident(i) if i == "anytype"=> TyKind::Any,
};

let ident = ident().map(TyKind::Ident);
Expand All @@ -31,9 +31,9 @@ pub(crate) fn type_expr() -> impl Parser<TokenKind, Ty, Error = PError> + Clone
.then_ignore(just(TokenKind::ArrowThin))
.then(nested_type_expr.clone().map(Box::new).map(Some))
.map(|(params, return_ty)| TyFunc {
name_hint: None,
params,
return_ty,
generic_type_params: vec![],
})
.or_not(),
)
Expand All @@ -42,7 +42,7 @@ pub(crate) fn type_expr() -> impl Parser<TokenKind, Ty, Error = PError> + Clone
let tuple = sequence(choice((
select! { TokenKind::Range { bind_right: true, bind_left: _ } => () }
.ignore_then(nested_type_expr.clone())
.map(|ty| TyTupleField::Wildcard(Some(ty))),
.map(|ty| TyTupleField::Unpack(Some(ty))),
ident_part()
.then_ignore(ctrl('='))
.or_not()
Expand All @@ -63,7 +63,7 @@ pub(crate) fn type_expr() -> impl Parser<TokenKind, Ty, Error = PError> + Clone
.try_map(|fields, span| {
let without_last = &fields[0..fields.len().saturating_sub(1)];

if let Some(unpack) = without_last.iter().find_map(|f| f.as_wildcard()) {
if let Some(unpack) = without_last.iter().find_map(|f| f.as_unpack()) {
let span = unpack.as_ref().and_then(|s| s.span).unwrap_or(span);
return Err(PError::custom(
span,
Expand All @@ -76,32 +76,32 @@ pub(crate) fn type_expr() -> impl Parser<TokenKind, Ty, Error = PError> + Clone
.map(TyKind::Tuple)
.labelled("tuple");

let enum_ = keyword("enum")
.ignore_then(
sequence(
ident_part()
.then(ctrl('=').ignore_then(nested_type_expr.clone()).or_not())
.map(|(name, ty)| {
(
Some(name),
ty.unwrap_or_else(|| Ty::new(TyKind::Tuple(vec![]))),
)
}),
)
.delimited_by(ctrl('{'), ctrl('}'))
.recover_with(nested_delimiters(
TokenKind::Control('{'),
TokenKind::Control('}'),
[
(TokenKind::Control('{'), TokenKind::Control('}')),
(TokenKind::Control('('), TokenKind::Control(')')),
(TokenKind::Control('['), TokenKind::Control(']')),
],
|_| vec![],
)),
)
.map(TyKind::Union)
.labelled("union");
// let enum_ = keyword("enum")
// .ignore_then(
// sequence(
// ident_part()
// .then(ctrl('=').ignore_then(nested_type_expr.clone()).or_not())
// .map(|(name, ty)| {
// (
// Some(name),
// ty.unwrap_or_else(|| Ty::new(TyKind::Tuple(vec![]))),
// )
// }),
// )
// .delimited_by(ctrl('{'), ctrl('}'))
// .recover_with(nested_delimiters(
// TokenKind::Control('{'),
// TokenKind::Control('}'),
// [
// (TokenKind::Control('{'), TokenKind::Control('}')),
// (TokenKind::Control('('), TokenKind::Control(')')),
// (TokenKind::Control('['), TokenKind::Control(']')),
// ],
// |_| vec![],
// )),
// )
// .map(TyKind::Union)
// .labelled("union");

let array = nested_type_expr
.map(Box::new)
Expand All @@ -120,41 +120,27 @@ pub(crate) fn type_expr() -> impl Parser<TokenKind, Ty, Error = PError> + Clone
.map(TyKind::Array)
.labelled("array");

let term = choice((basic, ident, func, tuple, array, enum_))
let term = choice((basic, ident, func, tuple, array))
.map_with_span(TyKind::into_ty)
.boxed();

// exclude
// term.clone()
// .then(ctrl('-').ignore_then(term).repeated())
// .foldl(|left, right| {
// let left_span = left.span.as_ref().unwrap();
// let right_span = right.span.as_ref().unwrap();
// let span = Span {
// start: left_span.start,
// end: right_span.end,
// source_id: left_span.source_id,
// };

// let kind = TyKind::Exclude {
// base: Box::new(left),
// except: Box::new(right),
// };
// into_ty(kind, span)
// });

// union
term.clone()
.then(just(TokenKind::Or).ignore_then(term).repeated())
.map_with_span(|(first, following), span| {
if following.is_empty() {
first
} else {
let mut all = Vec::with_capacity(following.len() + 1);
all.push((None, first));
all.extend(following.into_iter().map(|x| (None, x)));
TyKind::Union(all).into_ty(span)
}
.then(ctrl('-').ignore_then(term).repeated())
.foldl(|left, right| {
let left_span = left.span.as_ref().unwrap();
let right_span = right.span.as_ref().unwrap();
let span = Span {
start: left_span.start,
end: right_span.end,
source_id: left_span.source_id,
};

let kind = TyKind::Exclude {
base: Box::new(left),
except: Box::new(right),
};
TyKind::into_ty(kind, span)
})
})
.labelled("type expression")
Expand Down
Loading

0 comments on commit 13b50d1

Please sign in to comment.